aboutsummaryrefslogtreecommitdiff
path: root/src/interface
AgeCommit message (Collapse)AuthorFilesLines
2024-04-16[efi] Veto the Dhcp6Dxe driver on all platformsvetodhcp6Michael Brown1-0/+30
The reference implementation of Dhcp6Dxe in EDK2 has a fatal flaw: the code in EfiDhcp6Stop() will poll the network in a tight loop until either a response is received or a timer tick (at TPL_CALLBACK) occurs. When EfiDhcp6Stop() is called at TPL_CALLBACK or higher, this will result in an endless loop and an apparently frozen system. Since this is the reference implementation of Dhcp6Dxe, it is likely that almost all platforms have the same problem. Fix by vetoing the broken driver. If the upstream driver is ever fixed and a new version number issued, then we could plausibly test against the version number exposed via the driver binding protocol. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-04-15[efi] Do not attempt to download autoexec.ipxe without a valid base URIMichael Brown1-0/+10
If we do not have a current working URI (after applying the EFI device path settings and any cached DHCP settings), then an attempt to download autoexec.ipxe will fail since there is no base URI from which to resolve the full autoexec.ipxe URI. Avoid this potentially confusing error message by attempting the download only if we have successfully obtained a current working URI. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-04-03[efi] Restructure handling of autoexec.ipxe scriptMichael Brown2-378/+122
We currently attempt to obtain the autoexec.ipxe script via early use of the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL or EFI_PXE_BASE_CODE_PROTOCOL interfaces to obtain an opaque block of memory, which is then registered as an image at an appropriate point during our startup sequence. The early use of these existent interfaces allows us to obtain the script even if our subsequent actions (e.g. disconnecting drivers in order to connect up our own) may cause the script to become inaccessible. This mirrors the approach used under BIOS, where the autoexec.ipxe script is provided by the prefix (e.g. as an initrd image when using the .lkrn build of iPXE) and so must be copied into a normally allocated image from wherever it happens to previously exist in memory. We do not currently have support for downloading an autoexec.ipxe script if we were ourselves downloaded via UEFI HTTP boot. There is an EFI_HTTP_PROTOCOL defined within the UEFI specification, but it is so poorly designed as to be unusable for the simple purpose of downloading an additional file from the same directory. It provides almost nothing more than a very slim wrapper around EFI_TCP4_PROTOCOL (or EFI_TCP6_PROTOCOL). It will not handle redirection, content encoding, retries, or even fundamentals such as the Content-Length header, leaving all of this up to the caller. The UEFI HTTP Boot driver will install an EFI_LOAD_FILE_PROTOCOL instance on the loaded image's device handle. This looks promising at first since it provides the LoadFile() API call which is specified to accept an arbitrary filename parameter. However, experimentation (and inspection of the code in EDK2) reveals a multitude of problems that prevent this from being usable. Calling LoadFile() will idiotically restart the entire DHCP process (and potentially pop up a UI requiring input from the user for e.g. a wireless network password). The filename provided to LoadFile() will be ignored. Any downloaded file will be rejected unless it happens to match one of the limited set of types expected by the UEFI HTTP Boot driver. The list of design failures and conceptual mismatches is fairly impressive. Choose to bypass every possible aspect of UEFI HTTP support, and instead use our own HTTP client and network stack to download the autoexec.ipxe script over a temporary MNP network device. Since this approach works for TFTP as well as HTTP, drop the direct use of EFI_PXE_BASE_CODE_PROTOCOL. For consistency and simplicity, also drop the direct use of EFI_SIMPLE_FILE_SYSTEM_PROTOCOL and rely upon our existing support to access local files via "file:" URIs. This approach results in console output during the "iPXE initialising devices...ok" message that appears while startup is in progress. Remove the trailing "ok" so that this intermediate output appears at a sensible location on the screen. The welcome banner that will be printed immediately afterwards provides an indication that startup has completed successfully even absent the explicit "ok". Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-03-29[efi] Allow for allocating EFI devices from arbitrary handlesMichael Brown1-42/+65
Split out the code that allocates our internal struct efi_device representations, to allow for the creation of temporary MNP devices in order to download the autoexec.ipxe script. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-03-29[efi] Add error table entry for local filesystem EFI_NOT_FOUND errorMichael Brown1-1/+18
Add an abbreviated "Not found" error message for an EFI_NOT_FOUND error encountered when attempting to open a file on a local filesystem, so that any automatic attempt to download a non-existent autoexec.ipxe script produces only a minimal error message. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-03-29[efi] Report local file errors during download, rather than on openingMichael Brown1-124/+130
iPXE is designed around fully asynchronous I/O, including asynchronous connection opening. Almost all errors are therefore necessarily reported as occurring during an in-progress download, rather than occurring at the time that the URI is opened. Local file access is currently an exception to this: errors such as nonexistent files will be encountered while opening the URI. This results in mildly unexpected error messages of the form "Could not start download", rather than the usual pattern of showing the URI, the initial progress dots, and then the error message. Fix this inconsistency by deferring the local filesystem access until the local file download process is running. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-03-26[efi] Extract basic network settings from loaded image device pathMichael Brown1-0/+241
The UEFI HTTP boot mechanism is extraordinarily badly designed, even by the standards of the UEFI specification in general. It has the symptoms of a feature that has been designed entirely in terms of user stories, without any consideration at all being given to the underlying technical architecture. It does work, provided that you are doing precisely and only what was envisioned by the product owner. If you want to try anything outside the bounds of the product owner's extremely limited imagination, then you are almost certainly about to enter a world of pain. As one very minor example of this: the cached DHCP packet is not available when using HTTP boot. The UEFI HTTP boot code does perform DHCP, but it pointlessly and unhelpfully throws away the DHCP packet and trashes the network interface configuration before handing over to the downloaded executable. Work around this imbecility by parsing and applying the few network configuration settings that are persisted into the loaded image's device path. This is limited to very basic information such as the IP address, gateway address, and DNS server address, but it does at least provide enough for a functional routing table. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-03-26[efi] Add efi_path_mac() to parse a MAC address from an EFI device pathMichael Brown1-0/+24
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-03-25[efi] Allow for drivers to be located via child handlesMichael Brown1-2/+8
When using a service binding protocol, CreateChild() will create a new protocol instance (and optionally a new handle). The caller will then typically open this new protocol instance with BY_DRIVER attributes, since the service binding mechanism has no equivalent of the driver binding protocol's Stop() method, and there is therefore no other way for the caller to be informed if the protocol instance is about to become invalid (e.g. because the service driver wants to remove the child). The caller cannot ask CreateChild() to install the new protocol instance on the original handle (i.e. the service binding handle), since the whole point of the service binding protocol is to allow for the existence of multiple children, and UEFI does not permit multiple instances of the same protocol to be installed on a handle. Our current drivers all open the original handle (as passed to our driver binding's Start() method) with BY_DRIVER attributes, and so the same handle will be passed to our Stop() method. This changes when our driver must use a separate handle, as described above. Add an optional "child handle" field to struct efi_device (on the assumption that we will not have any drivers that need to create multiple children), and generalise efidev_find() to match on either the original handle or the child handle. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-03-25[efi] Add helper functions for service binding protocolsMichael Brown1-0/+138
The EFI service binding abstraction is used to add and remove child handles for multiple different protocols. Provide a common interface for doing so. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-03-19[efi] Set current working URI from our own device path URI, if presentMichael Brown1-0/+11
When booted via HTTP, our loaded image's device path will include the URI from which we were downloaded. Set this as the current working URI, so that an embedded script may perform subsequent downloads relative to the iPXE binary, or construct explicit relative paths via the ${cwduri} setting. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-03-19[efi] Add efi_path_uri() to parse a URI from an EFI device pathMichael Brown1-0/+40
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-03-15[efi] Provide a multiprocessor API for EFIMichael Brown1-0/+112
Provide an implementation of the iPXE multiprocessor API for EFI, based on using EFI_MP_SERVICES to start up a wrapper function on all application processors. Note that the processor numbers used by EFI_MP_SERVICES are opaque integers that bear no relation to the underlying CPU identity (e.g. the APIC ID), and so we must rely on our own (architecture- specific) implementation to determine the relevant CPU identifiers. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-03-07[efi] Do not report return status from efi_block_local()Michael Brown1-1/+5
The return status from efi_block_local() indicates whether or not the handle is eligible to be assigned a local virtual drive number. There will always be several enumerated EFI_BLOCK_IO_PROTOCOL handles that are not eligible for a local virtual drive number (e.g. the handles corresponding to partitions, rather than to complete disks), and this is not an interesting error to report. Do not report errors from efi_block_local() as the overall error status for a SAN boot, since doing so would be likely to mask a much more relevant error from having previously attempted to scan for a matching filesystem within an eligible block device handle. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-03-07[block] Allow SAN boot device to be identified by filesystem labelMichael Brown1-0/+73
Add a "--label" option that can be used to specify a filesystem label, to be matched against the FAT volume label. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-03-07[block] Allow SAN boot device to be identified by an extra filenameMichael Brown1-26/+59
Add an "--extra" option that can be used to specify an extra (non-boot) filename that must exist within the booted filesystem. Note that only files within the FAT-formatted bootable partition will be visible to this filter. Files within the operating system's root disk (e.g. "/etc/redhat-release") are not generally accessible to the firmware and so cannot be used as the existence check filter filename. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-03-06[block] Allow SAN boot device to be identified by UUIDMichael Brown1-0/+18
Add a "--uuid" option which may be used to specify a boot device UUID, to be matched against the GPT partition GUID. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-03-06[efi] Add efi_path_guid() utility functionMichael Brown1-0/+43
EFI provides no API for determining the partition GUID (if any) for a specified device handle. The partition GUID appears to be exposed only as part of the device path. Add efi_path_guid() to extract the partition GUID (if any) from a device path. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-03-06[block] Allow for additional SAN boot parameters alongside filenameMichael Brown1-10/+13
The drive specification alone does not necessarily contain enough information to perform a SAN boot (or local disk boot) under UEFI. If the next-stage bootloader is installed in the EFI system partition under a non-standard name (e.g. "\EFI\debian\grubx64.efi") then this explicit boot filename must also be specified. Generalise this concept to use a "SAN boot configuration parameters" structure (currently containing only the optional explicit boot filename), to allow for easy expansion to provide other parameters such as the partition UUID or volume label. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-03-05[efi] Allow booting from local disks via the "sanboot" commandMichael Brown1-21/+156
Extend the EFI SAN boot code to allow for booting from a local disk, as is already possible with the BIOS SAN boot code. There is unfortunately no direct UEFI equivalent of the BIOS drive number. The UEFI shell does provide numbered mappings fs0:, blk0:, etc, but these numberings exist only while the UEFI shell is running and are not necessarily stable between shell invocations or across reboots. A substantial amount of existing third-party documentation for iPXE will suggest using "sanboot --drive 0x80" to boot from a local disk (when no SAN drives are present), since this suggestion has been present in the official documentation for the "sanboot" command for almost thirteen years. We therefore aim to ensure that this instruction will also work for UEFI, i.e. that in a situation where there are local disks but no SAN disks, then the first local disk will be treated as being drive 0x80. We therefore assign local disks the virtual drive numbers 0x80, 0x81, etc, matching the numbering typically used in a BIOS environment. Where a SAN disk is already occupying one of these drive numbers, the local disks' virtual drive numbers will be incremented as necessary. This provides a rough approximation of the equivalent functionality under BIOS, where existing local disks' drive numbers are remapped to make way for SAN disks. We do not make any attempt to sort the list of local disks: the order used for allocating virtual drive numbers will be whatever order is returned by LocateHandle(). This will typically match the creation order of the EFI handles, which will typically match the hardware enumeration order of the devices, which will typically match user expectations as to which local disk is first, second, etc. We explicitly do not attempt to match the numbering used by the UEFI shell (which initially sorts in increasing order of device path, but does not renumber when new devices are added or removed). We can never guarantee matching this partly transient UEFI shell numbering, so it is best not to set any expectation that it will be matched. (Using local drive numbers starting at 0x80 helps to avoid setting up this impossible expectation, since the UEFI shell uses local drive numbers starting at zero.) Since floppy disks are essentially non-existent in any plausible UEFI system, overload "--drive 0" to mean "boot from any drive containing the specified (or default) boot filename". Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-03-04[efi] Generalise block device boot to support arbitrary EFI handlesMichael Brown1-47/+66
SAN devices created by iPXE are visible to the firmware, and may be accessed using the firmware's standard block I/O device interface (e.g. INT 13 for BIOS, or EFI_BLOCK_IO_PROTOCOL for UEFI). The iPXE code to perform a SAN boot acts as a client of this standard block I/O device interface, even when the underlying block I/O is being performed by iPXE itself. We rely on this separation to allow the "sanboot" command to be used to boot from a local disk: since the code to perform a SAN boot does not need direct access to an underlying iPXE SAN device, it may be used to boot from any device providing the firmware's standard block I/O device interface. Clean up the EFI SAN boot code to require only a drive number and an EFI_BLOCK_IO_PROTOCOL handle, in preparation for adding support for booting from a local disk under UEFI. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-03-04[efi] Use file system protocol to check for SAN boot filename existenceMichael Brown1-86/+218
The "sanboot" command allows a custom boot filename to be specified via the "--filename" option. We currently rely on LoadImage() to perform both the existence check and to load the image ready for execution. This may give a false negative result if Secure Boot is enabled and the boot file is not correctly signed. Carry out the existence check using EFI_SIMPLE_FILE_SYSTEM_PROTOCOL separately from loading the image via LoadImage(). Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-03-04[block] Use drive number as debug message stream IDMichael Brown1-43/+39
We currently use the SAN device pointer as the debug message stream identifier. This pointer is not always available: for example, when booting from a local disk there is no underlying SAN device. Switch to using the drive number as the debug message colour stream identifier, so that all block device debug messages may be colourised consistently. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-03-04[efi] Use long forms of device paths in debug messagesMichael Brown1-1/+1
We currently call ConvertDevicePathToText() with DisplayOnly=TRUE when constructing a device path to appear within a debug message. For ATAPI device paths, this will unfortunately omit some key information: the textual representation will not indicate which ATA bus or drive is represented. This can lead to misleading debug messages that appear to refer to identical devices. Fix by setting DisplayOnly=FALSE to select the long form of device path textual representations. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-02-27[efi] Work around broken boot services table manipulation by UEFI shimMichael Brown1-49/+43
The UEFI shim installs wrappers around several boot services functions before invoking its next stage bootloader, in an attempt to enforce its desired behaviour upon the aforementioned bootloader. For example, shim checks that the bootloader has either invoked StartImage() or has called into the "shim lock protocol" before allowing an ExitBootServices() call to proceed. When invoking a shim, iPXE will also install boot services function wrappers in order to work around assorted bugs in the UEFI shim code that would otherwise prevent it from being used to boot a kernel. For details on these workarounds, see commits 28184b7 ("[efi] Add support for executing images via a shim") and 5b43181 ("[efi] Support versions of shim that perform SBAT verification"). Using boot services function wrappers in this way is not intrinsically problematic, provided that wrappers are installed before starting the wrapped program, and uninstalled only after the wrapped program exits. This strict ordering requirement ensures that all layers of wrappers are called in the expected order, and that no calls are issued through a no-longer-valid function pointer. Unfortunately, the UEFI shim does not respect this strict ordering requirement, and will instead uninstall (and reinstall) its wrappers midway through the execution of the wrapped program. This leaves the wrapped program with an inconsistent view of the boot services table, leading to incorrect behaviour. This results in a boot failure when a first shim is used to boot iPXE, which then uses a second shim to boot a Linux kernel: - First shim installs StartImage() and ExitBootServices() wrappers - First shim invokes iPXE via its own PE loader - iPXE installs ExitBootServices() wrapper - iPXE invokes second shim via StartImage() At this point, the first shim's StartImage() wrapper will illegally uninstall its ExitBootServices() wrapper, without first checking that nothing else has modified the ExitBootServices function pointer. This effectively bypasses iPXE's own ExitBootServices() wrapper, which causes a boot failure since the code within that wrapper does not get called. A proper fix would be for shim to install its wrappers before starting the image and uninstall its wrappers only after the started image has exited. Instead of repeatedly uninstalling and reinstalling its wrappers while the wrapped program is running, shim should simply use a flag to keep track of whether or not it needs to modify the behaviour of the wrapped calls. Experience shows that there is unfortunately no point in trying to get a fix for this upstreamed into shim. We therefore work around the shim bug by removing our ExitBootServices() wrapper and moving the relevant code into our GetMemoryMap() wrapper. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-12-29[smbios] Support scanning for the 64-bit SMBIOS3 entry pointsmbios3Michael Brown1-13/+65
Support scanning for the 64-bit SMBIOS3 entry point in addition to the 32-bit SMBIOS2 entry point. Prefer use of the 32-bit entry point if present, since this is guaranteed to be within accessible memory. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-11-29[efi] Avoid modifying PE/COFF debug filenameMichael Brown1-2/+2
The function efi_pecoff_debug_name() (called by efi_handle_name()) is used to extract a filename from the debug data directory entry located within a PE/COFF image. The name is copied into a temporary static buffer to allow for modifications, but the code currently erroneously modifies the original name within the loaded PE/COFF image. Fix by performing the modification on the copy in the temporary buffer, as originally intended. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-09-13[netdevice] Allocate private data for each network upper-layer driverMichael Brown1-3/+6
Allow network upper-layer drivers (such as LLDP, which attaches to each network device in order to provide a corresponding LLDP settings block) to specify a size for private data, which will be allocated as part of the network device structure (as with the existing private data allocated for the underlying device driver). This will allow network upper-layer drivers to be simplified by omitting memory allocation and freeing code. If the upper-layer driver requires a reference counter (e.g. for interface initialisation), then it may use the network device's existing reference counter, since this is now the reference counter for the containing block of memory. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-23[efi] Process veto objects in reverse order of enumerationMichael Brown1-7/+11
While not guaranteed by the UEFI specification, the enumeration of handles, protocols, and openers will generally return results in order of creation. Processing these objects in reverse order (as is already done when calling DisconnectController() on the list of all handles) will generally therefore perform the forcible uninstallation operations in reverse order of object creation, which minimises the number of implicit operations performed (e.g. when disconnecting a controller that itself still has existent child controllers). Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-23[efi] Check for protocols opened by vetoed driver and image handlesMichael Brown1-1/+4
The UEFI specification states that the AgentHandle may be either the driving binding protocol handle or the image handle. Check for both handles when searching for stale handles to be forcibly closed on behalf of a vetoed driver. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-23[efi] Unload vetoed drivers by image handle rather than driver handleMichael Brown1-3/+6
In most cases, the driver handle will be the image handle itself. However, this is not required by the UEFI specification, and some images will install multiple driver binding handles. Use the image handle (extracted from the driver binding protocol instance) when attempting to unload the driver's image. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-23[efi] Pass more detailed driver information to veto methodsMichael Brown1-36/+58
Pass the driver binding handle, the driver binding protocol instance, the image handle, and the loaded image protocol instance to all veto methods. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-22[efi] Show manufacturer in veto debug outputMichael Brown1-0/+1
Simplify the process of adding new entries to the veto list by including the manufacturer name within the standard debug output. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-09[efi] Provide read-only access to EFI variables via settings mechanismMichael Brown1-0/+236
EFI variables do not map neatly to the iPXE settings mechanism, since the EFI variable identifier includes a namespace GUID that cannot cleanly be supplied as part of a setting name. Creating a new EFI variable requires the variable's attributes to be specified, which does not fit within iPXE's settings concept. However, EFI variable names are generally unique even without the namespace GUID, and EFI does provide a mechanism to iterate over all existent variables. We can therefore provide read-only access to EFI variables by comparing only the names and ignoring the namespace GUIDs. Provide an "efi" settings block that implements this mechanism using a syntax such as: echo Platform language is ${efi/PlatformLang:string} show efi/SecureBoot:int8 Settings are returned as raw binary values by default since an EFI variable may contain boolean flags, integer values, ASCII strings, UCS-2 strings, EFI device paths, X.509 certificates, or any other arbitrary blob of data. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-08[efi] Veto the VMware UefiPxeBcDxe driverMichael Brown1-0/+35
The EDK2 UefiPxeBcDxe driver includes some remarkably convoluted and unsafe logic in its driver binding protocol Start() and Stop() methods in order to support a pair of nominally independent driver binding protocols (one for IPv4, one for IPv6) sharing a single dynamically allocated data structure. This PXEBC_PRIVATE_DATA structure is installed as a dummy protocol on the NIC handle in order to allow both IPv4 and IPv6 driver binding protocols to locate it as needed. The error handling code path in the UefiPxeBcDxe driver's Start() method may attempt to uninstall the dummy protocol but fail to do so. This failure is ignored and the containing memory is subsequently freed anyway. On the next invocation of the driver binding protocol, it will find and use this already freed block of memory. At some point another memory allocation will occur, the PXEBC_PRIVATE_DATA structure will be corrupted, and some undefined behaviour will occur. The UEFI firmware used in VMware ESX 8 includes some proprietary changes which attempt to install copies of the EFI_LOAD_FILE_PROTOCOL and EFI_PXE_BASE_CODE_PROTOCOL instances from the IPv4 child handle onto the NIC handle (along with a VMware-specific protocol with GUID 5190120d-453b-4d48-958d-f0bab3bc2161 and a NULL instance pointer). This will inevitably fail with iPXE, since the NIC handle already includes an EFI_LOAD_FILE_PROTOCOL instance. These VMware proprietary changes end up triggering the unsafe error handling code path described above. The typical symptom is that an attempt to exit from iPXE back to the UEFI firmware will crash the VM with a General Protection fault from within the UefiPxeBcDxe driver: this happens when the UefiPxeBcDxe driver's Stop() method attempts to call through a function pointer in the (freed) PXEBC_PRIVATE_DATA structure, but the function pointer has by then been overwritten by UCS-2 character data from an unrelated memory allocation. Work around this failure by adding the VMware UefiPxeBcDxe driver to the driver veto list. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-08[efi] Include protocol interface address in debug outputMichael Brown1-5/+29
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-07[efi] Add UefiPxeBcDxe module GUIDMichael Brown1-0/+8
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-07[efi] Add HttpBootDxe module GUIDMichael Brown1-0/+8
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-07[efi] Add new IScsiDxe module GUIDMichael Brown1-1/+9
The old IPv4-only IScsiDxe driver in MdeModulePkg/Universal/Network was replaced by a dual-stack IScsiDxe driver in NetworkPkg. Add the module GUID for this driver. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-07[efi] Add HTTP header and GUID definitionsMichael Brown2-0/+13
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-07[efi] Add DNS headers and GUID definitionsMichael Brown2-0/+26
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-07[efi] Add Ip4Config2 header and GUID definitionMichael Brown2-0/+7
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-07[efi] Add IPv6 versions of existing IPv4 headers and GUID definitionsMichael Brown2-0/+72
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-05-23[efi] Support versions of shim that perform SBAT verificationMichael Brown1-3/+147
The UEFI shim implements a fairly nicely designed revocation mechanism designed around the concept of security generations. Unfortunately nobody in the shim community has thus far added the relevant metadata to the Linux kernel, with the result that current versions of shim are incapable of booting current versions of the Linux kernel. Experience shows that there is unfortunately no point in trying to get a fix for this upstreamed into shim. We therefore default to working around this undesirable behaviour by patching data read from the "SbatLevel" variable used to hold SBAT configuration. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-05-23[efi] Separate GetMemoryMap() wrapper from shim unlockerMichael Brown1-27/+34
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-05-22[efi] Add support for executing images via a shimMichael Brown1-0/+251
Add support for using a shim as a helper to execute an EFI image. When a shim has been specified via shim(), the shim image will be passed to LoadImage() instead of the selected EFI image and the command line will be prepended with the name of the selected EFI image. The selected EFI image will be accessible to the shim via the virtual filesystem as a hidden file. Reduce the Secure Boot attack surface by removing, where possible, the spurious requirement for a third party second stage loader binary such as GRUB to be used solely in order to call the "shim lock protocol" entry point. Do not install the EFI PXE APIs when using a shim, since if shim finds EFI_PXE_BASE_CODE_PROTOCOL on the loaded image's device handle then it will attempt to download files afresh instead of using the files already downloaded by iPXE and exposed via the EFI_SIMPLE_FILE_SYSTEM protocol. (Experience shows that there is no point in trying to get a fix for this upstreamed into shim.) Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-05-22[efi] Add definitions for the UEFI shim lock protocolMichael Brown2-0/+7
The UEFI shim includes a "shim lock protocol" that can be used by a third party second stage loader such as GRUB to verify a kernel image. Add definitions for the relevant portions of this protocol interface. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-05-22[efi] Add efi_asprintf() and efi_vasprintf()Michael Brown1-0/+44
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-05-17[image] Generalise concept of selected imageMichael Brown1-1/+1
Most image flags are independent values: any combination of flags may be set for any image, and the flags for one image are independent of the flags for any other image. The "selected" flag does not follow this pattern: at most one image may be marked as selected at any time. When invoking a kernel via the UEFI shim, there will be multiple "special" images: the selected kernel itself, the shim image, and potentially a shim-signed GRUB binary to be used as a crutch to assist shim in loading the kernel (since current versions of the UEFI shim are not capable of directly loading a Linux kernel). Remove the "selected" image flag and replace it with a general concept of an image tag with the same semantics: a given tag may be assigned to at most one image, an image may be found by its tag only while the image is currently registered, and a tag will survive unregistration and reregistration of an image (if it has not already been assigned to a new image). For visual consistency, also replace the current image pointer with a current image tag. The image pointer stored within the image tag holds only a weak reference to the image, since the selection of an image should not prevent that image from being freed. (The strong reference to the currently executing image is held locally within the execution scope of image_exec(), and is logically separate from the current image pointer.) Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-05-05[efi] Allow currently selected image to be opened as "grub*.efi"Michael Brown1-0/+11
Versions 15.4 and earlier of the UEFI shim are incapable of correctly parsing the command line in order to extract the second stage loader filename, and will always attempt to load "grubx64.efi" or equivalent. Versions 15.3 and later of the UEFI shim are currently incapable of loading a Linux kernel directly anyway, since the kernel does not include SBAT metadata. These versions will require a genuine shim-signed GRUB binary to be used as a crutch to assist shim in loading a Linux kernel. This leaves versions 15.2 and earlier of the UEFI shim (as currently used in e.g. RHEL7) as being capable of directly loading a Linux kernel, but incorrectly attempting to load it using the filename "grubx64.efi" or equivalent. To support the bugs in these older versions of the UEFI shim, allow the currently selected image to be opened via any filename of the form "grub*.efi". Signed-off-by: Michael Brown <mcb30@ipxe.org>