aboutsummaryrefslogtreecommitdiff
AgeCommit message (Collapse)AuthorFilesLines
2023-06-30[build] Use separate code segment if supported by linkersepcodeMichael Brown1-0/+7
Some versions of ld will complain that the automatically created (and unused by our build process) ELF program headers include a "LOAD segment with RWX permissions". Silence this warning by adding "-z separate-code" to the linker options, where supported. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-30[build] Inhibit linker warnings about an implied executable stackGeert Stappers32-0/+33
Signed-off-by: Geert Stappers <stappers@stappers.it> Modified-by: Michael Brown <mcb30@ipxe.org> Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-30[build] Avoid using multiple target patterns in pattern rulesMichael Brown2-3/+13
Multiple target patterns in pattern rules are treated as grouped targets regardless of the separator character. Newer verions of make will generate "warning: pattern recipe did not update peer target" to warn that the rule was expected to update all of the (implicitly) grouped targets. Fix by splitting all multiple target pattern rules into single target pattern rules. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-29[loong64] Add support for building EFI binariesXiaotian Wu2-0/+19
Signed-off-by: Xiaotian Wu <wuxiaotian@loongson.cn> Modified-by: Michael Brown <mcb30@ipxe.org> Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-29[loong64] Add CPU sleeping API for EFI LoongArch64Xiaotian Wu4-1/+75
Signed-off-by: Xiaotian Wu <wuxiaotian@loongson.cn> Modified-by: Michael Brown <mcb30@ipxe.org> Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-29[loong64] Add I/O API for LoongArch64Xiaotian Wu3-0/+130
Signed-off-by: Xiaotian Wu <wuxiaotian@loongson.cn> Modified-by: Michael Brown <mcb30@ipxe.org> Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-29[ioapi] Centralise definitions for dummy PIOMichael Brown3-50/+70
There is no common standard for I/O-space access for non-x86 CPU families, and non-MMIO peripherals are vanishingly rare. Generalise the existing ARM definitions for dummy PIO to allow for reuse by other CPU architectures. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-29[arm] Add missing arch/arm/core source directoryMichael Brown2-2/+4
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-29[arm] Remove redundant inclusion of io.hMichael Brown1-2/+0
The PCI I/O API (supporting accesses to PCI configuration space) is not related to the general I/O API (supporting accesses to memory-mapped I/O peripherals). Remove the spurious inclusion of ipxe/io.h from the PCI I/O header. 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-21[efi] Always poll for TX completionsdell3440bMichael Brown1-5/+5
Polling for TX completions is arguably redundant when there are no transmissions currently in progress. Commit c6c7e78 ("[efi] Poll for TX completions only when there is an outstanding TX buffer") switched to setting the PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS flag only when there is an in-progress transmission awaiting completion, in order to reduce reported TX errors and debug message noise from buggy NII implementations that report spurious TX completions whenever the transmit queue is empty. Some other NII implementations (observed with the Realtek driver in a Dell Latitude 3440) seem to have a bug in the transmit datapath handling which results in the transmit ring freezing after sending a few hundred packets under heavy load. The symptoms are that the TPPoll register's NPQ bit remains set and the 256-entry transmit ring contains a large number of uncompleted descriptors (with the OWN bit set), the first two of which have identical data buffer addresses. Though iPXE will submit at most one in-progress transmission via NII, the Dell/Realtek driver seems to make a page-aligned copy of each transmit data buffer and to report TX completions immediately without waiting for the packet to actually be transmitted. These synthetic TX completions continue even after the hardware transmit ring freezes. Setting PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS on every poll reduces the probability of this Dell/Realtek driver bug being triggered by a factor of around 500, which brings the failure rate down to the point that it can sensibly be managed by external logic such as the "--timeout" option for image downloads. Closing and reopening the interface (via "ifclose"/"ifopen") will clear the error condition and allow transmissions to resume. Revert to setting PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS on every poll, and silently ignore situations in which the hardware reports a completion when no transmission is in progress. This approximately matches the behaviour of the SnpDxe driver, which will also generally set PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS on every poll. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-09[efi] Provide read-only access to EFI variables via settings mechanismMichael Brown5-0/+244
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 Brown2-5/+42
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 Brown4-0/+531
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-07[efi] Add DNS headers and GUID definitionsMichael Brown5-0/+1103
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-07[efi] Add Ip4Config2 header and GUID definitionMichael Brown4-0/+326
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-07[efi] Add IPv6 versions of existing IPv4 headers and GUID definitionsMichael Brown9-0/+4436
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-07[efi] Update to current EDK2 headersMichael Brown8-40/+266
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-07[efi] Disable static assertions in EFI headers on non-EFI platformsMichael Brown1-0/+9
The EDK2 headers may be included even in builds for non-EFI platforms. Commits such as 9de6c45 ("[arm] Use -fno-short-enums for all 32-bit ARM builds") have so far ensured that the compile-time checks within the EDK2 headers will pass even when building for a non-EFI platform. As a more general solution, temporarily disable static assertions while including UefiBaseType.h if building on a non-EFI platform. This avoids the need to modify the ABI on other platforms. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-02[crypto] Add support for PKCS#8 private key formatpkcs8Michael Brown4-2/+105
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-05-24[efi] Implement "shim" as a dummy command on non-EFI platformsMichael Brown3-2/+15
The "shim" command will skip downloading the shim binary (and is therefore a conditional no-op) if there is already a selected EFI image that can be executed directly via LoadImage()/StartImage(). This allows the same iPXE script to be used with Secure Boot either enabled or disabled. Generalise this further to provide a dummy "shim" command that is an unconditional no-op on non-EFI platforms. This then allows the same iPXE script to be used for BIOS, EFI with Secure Boot disabled, or EFI with Secure Boot enabled. The same effect could be achieved by using "iseq ${platform} efi" within the script, but this would complicate end-user documentation. To minimise the code size impact, the dummy "shim" command is a pure no-op that does not call parse_options() and so will ignore even standardised arguments such as "--help". Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-05-23[efi] Support versions of shim that perform SBAT verificationMichael Brown5-6/+160
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 "shim" commandMichael Brown4-0/+117
Allow a shim to be used to facilitate booting a kernel using a script such as: kernel /images/vmlinuz console=ttyS0,115200n8 initrd /images/initrd.img shim /images/shimx64.efi boot Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-05-22[efi] Add support for executing images via a shimMichael Brown8-3/+413
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 Brown4-0/+39
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 Brown4-10/+53
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-05-17[image] Generalise concept of selected imageMichael Brown6-50/+85
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-17[efi] Attempt to detect EFI images that fail Secure Boot verificationMichael Brown1-5/+71
An EFI image that is rejected by LoadImage() due to failing Secure Boot verification is still an EFI image. Unfortunately, the extremely broken UEFI Secure Boot model provides no way for us to unambiguously determine that a valid EFI executable image was rejected only because it failed signature verification. We must therefore use heuristics to guess whether not an image that was rejected by LoadImage() could still be loaded via a separate PE loader such as the UEFI shim. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-05-15[ci] Work around Ubuntu packaging metadata issuesMichael Brown1-1/+2
The libc6-dbg:i386 package has spontaneously started failing to install from the Azure package repositories used by the GitHub Actions runners, with the somewhat recalcitrant error message: libc6:i386: Depends: libgcc-s1:i386 but it is not going to be installed Work around this unexplained issue by explicitly requesting installation of the libgcc-s1:i386 package. 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>
2023-05-05[efi] Allow currently executing image to be opened via virtual filesystemMichael Brown1-0/+10
When invoking a kernel via the UEFI shim, the kernel image must be accessible via EFI_SIMPLE_FILE_SYSTEM_PROTOCOL but must not be present in the magic initrd constructed from all registered images. Re-register a currently executing EFI image and mark it as hidden, thereby allowing it to be accessed via the virtual filesystem exposed via EFI_SIMPLE_FILE_SYSTEM_PROTOCOL without appearing in the magic initrd contents. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-05-05[image] Allow for images to be hidden from lists of all imagesMichael Brown5-19/+39
When invoking a kernel via the UEFI shim, the kernel (and potentially also a helper binary such as GRUB) must be accessible via the virtual filesystem exposed via EFI_SIMPLE_FILE_SYSTEM_PROTOCOL but must not be present in the magic initrd constructed from all registered images. Allow for images to be flagged as hidden, which will cause them to be excluded from API-level lists of all images such as the virtual filesystem directory contents, the magic initrd, or the Multiboot module list. Hidden images remain visible to iPXE commands including "imgstat", which will show a "[HIDDEN]" flag for such images. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-05-05[efi] Show original filenames in debug messagesMichael Brown1-8/+16
Show the original filename as used by the consumer when calling our EFI_SIMPLE_FILE_SYSTEM_PROTOCOL's Open() method. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-05-05[efi] Allow downloaded images to take precedence over constructed filesMichael Brown1-22/+33
Try searching for a matching registered image before checking for fixed filenames (such as "initrd.magic" for the dynamically generated magic initrd file). This minimises surprise by ensuring that an explicitly downloaded image will always be used verbatim. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-04-10[efi] Allow for sections to be excluded from the generated PE fileMichael Brown1-6/+17
Hybrid bzImage and UEFI binaries (such as wimboot) include a bzImage header within a section starting at offset zero, with the PE header effectively occupying unused space within this section. This section should not appear as a named section in the resulting PE file. Allow for the existence of hidden sections that do not result in a section header being written to the PE file. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-04-10[efi] Allow elf2efi to be used for hybrid binariesMichael Brown1-6/+27
Hybrid 32-bit BIOS and 64-bit UEFI binaries (such as wimboot) may include R_X86_64_32 relocation records for the 32-bit BIOS portions. These should be ignored when generating PE relocation records, since they apply only to code that cannot be executed within the context of the 64-bit UEFI binary, and creating a 4-byte relocation record is invalid in a binary that may be relocated anywhere within the 64-bit address space (see commit 907cffb "[efi] Disallow R_X86_64_32 relocations"). Add a "--hybrid" option to elf2efi, which will cause R_X86_64_32 relocation records to be silently discarded. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-04-10[efi] Shrink size of data directory in PE headerMichael Brown1-4/+13
Hybrid bzImage and UEFI binaries (such as wimboot) require the PE header to be kept as small as possible, since the bzImage header starts at a fixed offset 0x1f1. The EFI_IMAGE_OPTIONAL_HEADER structures in PeImage.h define an optional header containing 16 data directory entries, of which the last eight are unused in binaries that we create. Shrink the data directory to contain only the first eight entries, to minimise the overall size of the PE header. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-04-10[efi] Remove redundant zero padding in PE headerMichael Brown1-1/+0
Hybrid bzImage and UEFI binaries (such as wimboot) require the PE header to be kept as small as possible, since the bzImage header starts at a fixed offset 0x1f1. The PE header currently includes 128 bytes of zero padding between the DOS and NT header portions. This padding has been present since commit 81d92c6 ("[efi] Add EFI image format and basic runtime environment") first added support for EFI images in iPXE, and was included on the basis of matching the observed behaviour of the Microsoft toolchain. There appears to be no requirement for this padding to exist: EDK2 binaries built with gcc include only 64 bytes of zero padding, Linux kernel binaries include 66 bytes of non-zero padding, and wimboot binaries include no padding at all. Remove the unnecessary padding between the DOS and NT header portions to minimise the overall size of the PE header. Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-03-30[tls] Handle fragmented handshake recordstlsfrag3Michael Brown2-18/+26
Originally-implemented-by: Christopher Schenk <christopher@cschenk.net> Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-03-30[tls] Pass I/O buffer to received record handlersMichael Brown1-58/+98
Prepare for the possibility that a record handler may choose not to consume the entire record by passing the I/O buffer and requiring the handler to mark consumed data using iob_pull(). Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-03-30[tls] Clean up change cipher spec record handlingMichael Brown2-4/+18
Define and use data structures and constants for the (single-byte) change cipher spec records. Signed-off-by: Michael Brown <mcb30@ipxe.org>