Commit Graph

6163 Commits (ba20ba42731b8b03a5db2f81f876fccd56257b0f)
 

Author SHA1 Message Date
Michael Brown 8606204595 [dhcp] Continue transmitting DHCPDISCOVER while link is blocked
Continue to transmit DHCPDISCOVER while waiting for a blocked link, in
order to support mechanisms such as Cisco MAC Authentication Bypass
that require repeated transmission attempts in order to trigger the
action that will result in the link becoming unblocked.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2021-01-19 12:21:28 +00:00
Omgalof 0fb37a48a9 [build] Include xorrisofs as a viable mkisofs equivalent
Add support for xorrisofs, a GNU mkisofs equivalent that is available
in most distro repositories.

Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2021-01-18 12:48:00 +00:00
Michael Brown 8e3826aa10 [build] Inhibit spurious array bounds warning on some versions of gcc
Some versions of gcc (observed with gcc 9.3.0 on NixOS Linux) produce
a spurious warning about an out-of-bounds array access for the
isa_extra_probe_addrs[] array.

Work around this compiler bug by redefining the array index as a
signed long, which seems to somehow avoid this spurious warning.

Debugged-by: Manuel Mendez <mmendez534@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2021-01-15 20:54:27 +00:00
Manuel Mendez a5fb41873d [isa] Add missing #include <config/isa.h>
Signed-off-by: Manuel Mendez <mmendez534@gmail.com>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2021-01-13 23:01:27 +00:00
Michael Brown 79c0173d6d [build] Create util/genfsimg for building filesystem-based images
Generalise util/geniso, util/gensdsk, and util/genefidsk to create a
single script util/genfsimg that can be used to build either FAT
filesystem images or ISO images.

Extend the functionality to allow for building multi-architecture UEFI
bootable ISO images and combined BIOS+UEFI images.

For example:

  ./util/genfsimg -o combined.iso \
      bin-x86_64-efi/ipxe.efi \
      bin-arm64-efi/ipxe.efi \
      bin/ipxe.lkrn

would generate a hybrid image that could be used as a CDROM (or hard
disk or USB key) on legacy BIOS, x86_64 UEFI, or ARM64 UEFI.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2021-01-13 17:58:02 +00:00
Michael Brown c42f31bc8a [xhci] Avoid false positive Coverity warning
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2021-01-04 09:37:59 +00:00
Michael Brown 5aa389593d [efi] Leave asynchronous USB endpoints open until device is removed
Some UEFI device drivers will react to an asynchronous USB transfer
failure by dubiously terminating the scheduled transfer from within
the completion handler.

We already have code from commit fbb776f ("[efi] Leave USB endpoint
descriptors in existence until device is removed") that avoids freeing
memory in this situation, in order to avoid use-after-free bugs.  This
is not sufficient to avoid potential problems, since with an xHCI
controller the act of closing the endpoint requires issuing a command
and awaiting completion via the event ring, which may in turn dispatch
further USB transfer completion events.

Avoid these problems by leaving the USB endpoint open (but with the
refill timer stopped) until the device is finally removed, as is
already done for control and bulk transfers.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2021-01-03 20:23:51 +00:00
Michael Brown 7ce3b84050 [xhci] Show meaningful error messages after command failures
Ensure that any command failure messages are followed up with an error
message indicating what the failed command was attempting to perform.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2021-01-03 19:12:00 +00:00
Michael Brown 017b345d5a [xhci] Fail attempts to issue concurrent commands
The xHCI driver can handle only a single command TRB in progress at
any one time.  Immediately fail any attempts to issue concurrent
commands (which should not occur in normal operation).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2021-01-03 19:08:49 +00:00
Michael Brown 988d2c13cd [efi] Use segment and bus number to identify PCI root bridge I/O protocol
There may be multiple instances of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL for
a single PCI segment.  Use the bus number range descriptor from the
ACPI resource list to identify the correct protocol instance.

There is some discrepancy between the ACPI and UEFI specifications
regarding the interpretation of values within the ACPI resource list.

The ACPI specification defines the min/max field values to be within
the secondary (device-side) address space, and defines the offset
field value as "the offset that must be added to the address on the
secondary side to obtain the address on the primary side".

The UEFI specification states instead that the offset field value is
the "offset to apply to the starting address to convert it to a PCI
address", helpfully omitting to clarify whether "to apply" in this
context means "to add" or "to subtract".  The implication of the
wording is also that the "starting address" is not already a "PCI
address" and must therefore be a host-side address rather than the
ACPI-defined device-side address.

Code comments in the EDK2 codebase seem to support the latter
(non-ACPI) interpretation of these ACPI structures.  For example, in
the PciHostBridgeDxe driver there can be found the comment

  Macros to translate device address to host address and vice versa.
  According to UEFI 2.7, device address = host address + translation
  offset.

along with a pair of macros TO_HOST_ADDRESS() and TO_DEVICE_ADDRESS()
which similarly negate the sense of the "translation offset" from the
definition found in the ACPI specification.

The existing logic in efipci_ioremap() (based on a presumed-working
externally contributed patch) applies the non-ACPI interpretation: it
assumes that min/max field values are host-side addresses and that the
offset field value is negated.

Match this existing logic by assuming that min/max field values are
host-side bus numbers.  (The bus number offset value is therefore not
required and so can be ignored.)

As noted in commit 9b25f6e ("[efi] Fall back to assuming identity
mapping of MMIO address space"), some systems seem to fail to provide
MMIO address space descriptors.  Assume that some systems may
similarly fail to provide bus number range descriptors, and fall back
in this situation to assuming that matching on segment number alone is
sufficient.

Testing any of this is unfortunately impossible without access to
esoteric hardware that actually uses non-zero translation offsets.

Originally-implemented-by: Thomas Walker <twalker@twosigma.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-12-31 21:03:10 +00:00
Michael Brown dced22d6de [smbios] Add support for the 64-bit SMBIOS3 entry point
Support UEFI systems that provide only 64-bit versions of the SMBIOS
entry point.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-12-29 14:41:50 +00:00
b1f6c1c4 485f8ce554 [efi] Allow for longer device paths in debug messages
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-12-29 13:16:22 +00:00
Martin Habets da491eaae7 [sfc] Update email addresses
Email from solarflare.com will stop working, so update those.  Remove
email for Shradha Shah, as she is not involved with this any more.
Update copyright notices for files touched.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-12-28 18:41:55 +00:00
Josh McSavaney 68f1914aae [x509] Clarify debug message for an untrusted X.509 issuer
We surface this debugging information in cases where a cert actually
lacks an issuer, but also in cases where it *has* an issuer, but we
cannot trust it (e.g. due to issues in establishing a trust chain).

Signed-off-by: Josh McSavaney <me@mcsau.cc>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-12-28 18:18:58 +00:00
Mohammed Taha ce841946df [golan] Add new PCI IDs
Signed-off-by: Mohammed <mohammedt@mellanox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-12-28 13:55:30 +00:00
Michael Brown 47098d7cb1 [efi] Allow EFI_USB_IO_PROTOCOL interfaces to be nullified and leaked
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-12-17 21:46:52 +00:00
Michael Brown 6769a7c3c6 [efi] Skip interface uninstallation during shutdown
iPXE seems to be almost alone in the UEFI world in attempting to shut
down cleanly, free resources, and leave hardware in a well-defined
reset state before handing over to the booted operating system.

The UEFI driver model does allow for graceful shutdown via
uninstallation of protocol interfaces.  However, virtually no other
UEFI drivers do this, and the external code paths that react to
uninstallation are consequently poorly tested.  This leads to a
proliferation of bugs found in UEFI implementations in the wild, as
described in commits such as 1295b4a ("[efi] Allow initialisation via
SNP interface even while claimed") or b6e2ea0 ("[efi] Veto the HP
XhciDxe Driver").

Try to avoid triggering such bugs by unconditionally skipping the
protocol interface uninstallation during UEFI boot services shutdown,
leaving the interfaces present but nullified and deliberately leaking
the containing memory.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-12-17 21:32:49 +00:00
Michael Brown fb91542f2a [efi] Nullify interfaces unconditionally on error and shutdown paths
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-12-17 19:52:41 +00:00
Michael Brown f47a45ea2d [iphone] Add iPhone tethering driver
USB tethering via an iPhone is unreasonably complicated due to the
requirement to perform a pairing operation that involves establishing
a TLS session over a completely unrelated USB function that speaks a
protocol that is almost, but not quite, entirely unlike TCP.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-12-16 13:29:06 +00:00
Michael Brown f43a8f8b9f [crypto] Allow private key to be specified as a TLS connection parameter
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-12-15 16:54:06 +00:00
Michael Brown 6a8664d9ec [tls] Include root of trust within definition of TLS session
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-12-15 16:28:33 +00:00
Michael Brown 3475f9162b [x509] Make root of trust a reference-counted structure
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-12-09 16:45:50 +00:00
Michael Brown e3eedb0be5 [efi] Avoid using potentially uninitialised driver name in veto checks
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-12-08 15:52:25 +00:00
Michael Brown 39f5293492 [x509] Record root of trust used when validating a certificate
Record the root of trust used at the point that a certificate is
validated, redefine validation as checking a certificate against a
specific root of trust, and pass an explicit root of trust when
creating a TLS connection.

This allows a custom TLS connection to be used with a custom root of
trust, without causing any validated certificates to be treated as
valid for normal purposes.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-12-08 15:04:28 +00:00
Michael Brown 6e92d6213d [ocsp] Remove dummy OCSP certificate root
OCSP currently calls x509_validate() with an empty root certificate
list, on the basis that the OCSP signer certificate (if existent) must
be signed directly by the issuer certificate.

Using an empty root certificate list is not required to achieve this
goal, since x509_validate() already accepts an explicit issuer
certificate parameter.  The explicit empty root certificate list
merely prevents the signer certificate from being evaluated as a
potential trusted root certificate.

Remove the dummy OCSP root certificate list and use the default root
certificate list when calling x509_validate().

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-12-08 15:04:28 +00:00
Michael Brown be47c2c72c [http] Hide HTTP transport-layer filter implementation details
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-12-08 15:04:28 +00:00
Michael Brown 1b112e9d18 [asn1] Define ASN1_SHORT() for constructing short tagged values
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-12-08 12:38:45 +00:00
Michael Brown e4b6328c84 [asn1] Rename ASN1_OID_CURSOR to ASN1_CURSOR
There is nothing OID-specific about the ASN1_OID_CURSOR macro.  Rename
to allow it to be used for constructing ASN.1 cursors with arbitrary
contents.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-12-08 12:38:45 +00:00
Michael Brown e33f521081 [asn1] Add constant for UTF-8 string tag
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-12-07 13:55:12 +00:00
Michael Brown 25b53afa5b [tls] Allow provision of a client certificate chain
Use the existing certificate store to automatically append any
available issuing certificates to the selected client certificate.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-12-07 13:53:48 +00:00
Michael Brown 2b6b02ee7e [tls] Use intf_insert() to add TLS to an interface
Restructure the use of add_tls() to insert a TLS filter onto an
existing interface.  This allows for the possibility of using
add_tls() to start TLS on an existing connection (as used in several
protocols which will negotiate the choice to use TLS before the
ClientHello is sent).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-12-07 13:51:46 +00:00
Michael Brown 09fe2bbd34 [interface] Provide intf_insert() to insert a filter interface
Generalise the filter interface insertion logic from block_translate()
and expose as intf_insert(), allowing a filter interface to be
inserted on any existing interface.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-12-07 13:50:24 +00:00
Michael Brown cb0ba2f825 [interface] Ignore any attempts to plug in the null interface
Allow intf_plug() and intf_plug_plug() to be called safely on
interfaces that may be the null interface.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-12-07 13:48:35 +00:00
Michael Brown b6e2ea03b0 [efi] Veto the HP XhciDxe Driver
The HP XhciDxe driver (observed on an HP EliteBook 840 G6) does not
respond correctly to driver disconnection, and will leave the PciIo
protocol instance opened with BY_DRIVER attributes even after
returning successfully from its Stop() method.  This prevents iPXE
from subsequently connecting to the PCI device handle.

Veto this driver if the iPXE build includes a native xHCI driver.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-11-30 19:34:57 +00:00
Michael Brown 63625b43e9 [efi] Allow vetoing of drivers that cannot be unloaded
Some UEFI drivers (observed with the "Usb Xhci Driver" on an HP
EliteBook) are particularly badly behaved: they cannot be unloaded and
will leave handles opened with BY_DRIVER attributes even after
disconnecting the driver, thereby preventing a replacement iPXE driver
from opening the handle.

Allow such drivers to be vetoed by falling back to a brute-force
mechanism that will disconnect the driver from all handles, uninstall
the driver binding protocol (to prevent it from attaching to any new
handles), and finally close any stray handles that the vetoed driver
has left open.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-11-30 19:34:57 +00:00
Michael Brown 354c252ee1 [efi] Provide manufacturer and driver names to all veto checking methods
Most veto checks are likely to use the manufacturer name and driver
name, so pass these as parameters to minimise code duplication.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-11-30 17:54:22 +00:00
Michael Brown be49380f55 [efi] Split out dbg_efi_opener() as a standalone function
Allow external code to dump the information for an opened protocol
information entry via DBG_EFI_OPENER() et al.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-11-30 16:36:08 +00:00
Michael Brown 13a6d17296 [xhci] Update driver to use DMA API
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-11-29 11:25:40 +00:00
Michael Brown 6e01b74a8a [dma] Provide dma_umalloc() for allocating large DMA-coherent buffers
Some devices (e.g. xHCI USB host controllers) may require the use of
large areas of host memory for private use by the device.  These
allocations cannot be satisfied from iPXE's limited heap space, and so
are currently allocated using umalloc() which will allocate external
system memory (and alter the system memory map as needed).

Provide dma_umalloc() to provide such allocations as part of the DMA
API, since there is otherwise no way to guarantee that the allocated
regions are usable for coherent DMA.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-11-29 11:25:40 +00:00
Michael Brown a8442750e6 [efi] Avoid requesting zero-length DMA mappings
The UEFI specification does not prohibit zero-length DMA mappings.
However, there is a reasonable chance that at least one implementation
will treat it as an invalid parameter.  As a precaution, avoid calling
EFI_PCI_IO_PROTOCOL.Map() with a length of zero.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-11-29 11:25:40 +00:00
Michael Brown a2e5cf1a3f [netdevice] Fix misleading comment on netdev_rx()
Unlike netdev_rx_err(), there is no valid circumstance under which
netdev_rx() may be called with a null I/O buffer, since a call to
netdev_rx() represents the successful reception of a packet.  Fix the
code comment to reflect this.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-11-29 11:25:40 +00:00
Michael Brown 9ff61ab28d [netdevice] Do not attempt to unmap a null I/O buffer
netdev_tx_err() may be called with a null I/O buffer (e.g. to record a
transmit error with no associated buffer).  Avoid a potential null
pointer dereference in the DMA unmapping code path.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-11-29 11:25:40 +00:00
Michael Brown 8d337ecdae [dma] Move I/O buffer DMA operations to iobuf.h
Include a potential DMA mapping within the definition of an I/O
buffer, and move all I/O buffer DMA mapping functions from dma.h to
iobuf.h.  This avoids the need for drivers to maintain a separate list
of DMA mappings for each I/O buffer that they may handle.

Network device drivers typically do not keep track of transmit I/O
buffers, since the network device core already maintains a transmit
queue.  Drivers will typically call netdev_tx_complete_next() to
complete a transmission without first obtaining the relevant I/O
buffer pointer (and will rely on the network device core automatically
cancelling any pending transmissions when the device is closed).

To allow this driver design approach to be retained, update the
netdev_tx_complete() family of functions to automatically perform the
DMA unmapping operation if required.  For symmetry, also update the
netdev_rx() family of functions to behave the same way.

As a further convenience for drivers, allow the network device core to
automatically perform DMA mapping on the transmit datapath before
calling the driver's transmit() method.  This avoids the need to
introduce a mapping error handling code path into the typically
error-free transmit methods.

With these changes, the modifications required to update a typical
network device driver to use the new DMA API are fairly minimal:

- Allocate and free descriptor rings and similar coherent structures
  using dma_alloc()/dma_free() rather than malloc_phys()/free_phys()

- Allocate and free receive buffers using alloc_rx_iob()/free_rx_iob()
  rather than alloc_iob()/free_iob()

- Calculate DMA addresses using dma() or iob_dma() rather than
  virt_to_bus()

- Set a 64-bit DMA mask if needed using dma_set_mask_64bit() and
  thereafter eliminate checks on DMA address ranges

- Either record the DMA device in netdev->dma, or call iob_map_tx() as
  part of the transmit() method

- Ensure that debug messages use virt_to_phys() when displaying
  "hardware" addresses

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-11-28 20:26:28 +00:00
Michael Brown 70e6e83243 [dma] Record DMA device as part of DMA mapping if needed
Allow for dma_unmap() to be called by code other than the DMA device
driver itself.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-11-28 18:56:50 +00:00
Michael Brown cf12a41703 [dma] Modify DMA API to simplify calculation of medial addresses
Redefine the value stored within a DMA mapping to be the offset
between physical addresses and DMA addresses within the mapped region.

Provide a dma() wrapper function to calculate the DMA address for any
pointer within a mapped region, thereby simplifying the use cases when
a device needs to be given addresses other than the region start
address.

On a platform using the "flat" DMA implementation the DMA offset for
any mapped region is always zero, with the result that dma_map() can
be optimised away completely and dma() reduces to a straightforward
call to virt_to_phys().

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-11-25 16:15:55 +00:00
Michael Brown 24ef743778 [intelxl] Configure DMA mask as 64-bit
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-11-24 17:47:42 +00:00
Michael Brown 9e280aecb7 [intel] Configure DMA mask as 64-bit
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-11-24 17:46:39 +00:00
Michael Brown 0b5467b658 [efi] Report correct error when failing to unload a vetoed driver
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-11-24 15:42:43 +00:00
Michael Brown 1295b4acff [efi] Allow initialisation via SNP interface even while claimed
iPXE will currently fail all SNP interface methods with EFI_NOT_READY
while the network devices are claimed for use by iPXE's own network
stack.

As of commit c70b3e0 ("[efi] Always enable recursion when calling
ConnectController()"), this exposes latent UEFI firmware bugs on some
systems at the point of calling ExitBootServices().

With recursion enabled, the MnpDxe driver will immediately attempt to
consume the SNP protocol instance provided by iPXE.  Since the network
devices are claimed by iPXE at this point, the calls by MnpDxe to
Start() and Initialize() will both fail with EFI_NOT_READY.

This unfortunately triggers a broken error-handling code path in the
Ip6Dxe driver.  Specifically: Ip6DriverBindingStart() will call
Ip6CreateService(), which will call Ip6ServiceConfigMnp(), which will
return an error.  The subsequent error handling code path in
Ip6CreateService() simply calls Ip6CleanService().  The code in
Ip6CleanService() will attempt to leave the all-nodes multicast group,
which will fail since the group was never joined.  This will result in
Ip6CleanService() returning an error and omitting most of the required
clean-up operations.  In particular, the MNP protocol instance will
remain opened with BY_DRIVER attributes even though the Ip6Dxe driver
start method has failed.

When ExitBootServices() is eventually called, iPXE will attempt to
uninstall the SNP protocol instance.  This results in the UEFI core
calling Ip6DriverBindingStop(), which will fail since there is no
EFI_IP6_SERVICE_BINDING_PROTOCOL instance installed on the handle.

A failure during a call to UninstallMultipleProtocolInterfaces() will
result in the UEFI core attempting to reinstall any successfully
uninstalled protocols.  This is an intrinsically unsafe operation, and
represents a fundamental design flaw in UEFI.  Failure code paths
cannot be required to themselves handle failures, since there is no
well-defined correct outcome of such a situation.

With a current build of OVMF, this results in some unexpected debug
messages occurring at the time that the loaded operating system calls
ExitBootServices().  With the UEFI firmware in Hyper-V, the result is
an immediate reboot.

Work around these UEFI design and implementation flaws by allowing the
calls to our EFI_SIMPLE_NETWORK_PROTOCOL instance's Start() and
Initialize() methods to return success even when the network devices
are claimed for exclusive use by iPXE.  This is sufficient to allow
MnpDxe to believe that it has successfully initialised the device, and
thereby avoids the problematic failure code paths in Ip6Dxe.

Debugged-by: Aaron Heusser <aaron_heusser@hotmail.com>
Debugged-by: Pico Mitchell <pico@randomapplications.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-11-23 22:30:04 +00:00
Michael Brown 03314e8da9 [intelxl] Update driver to use DMA API
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-11-21 13:35:11 +00:00