]> git.ipfire.org Git - thirdparty/ipxe.git/log
thirdparty/ipxe.git
44 min ago[usb] Guard against invalid descriptor lengths in USB configurations master 1808/head
Michael Brown [Fri, 7 Aug 2026 12:48:26 +0000 (13:48 +0100)] 
[usb] Guard against invalid descriptor lengths in USB configurations

A malicious USB device is out of scope for our threat model, but we
already sanity check other descriptor fields, so we should also check
that the reported length of a descriptor contained within a USB device
configuration is adequate for the claimed descriptor type.

Update the two descriptor iterators to skip over descriptors that are
shorter than the length required to contain the iterator type, so that
the loop body can assume that it is safe to dereference any field
within the iterator structure.  Simplify the call sites by integrating
the descriptor type check into the iterator itself, since it fits very
naturally alongside the length check.

Guard against infinite loops by ignoring any descriptors with a length
field that is too short to contain the descriptor header itself.

Validate the descriptor length in usb_endpoint_companion_descriptor(),
which is the only standalone use of usb_next_descriptor() outside of
the two iterators.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
22 hours ago[vmbus] Check for packets shorter than their own header length 1807/head
Michael Brown [Thu, 6 Aug 2026 15:39:36 +0000 (16:39 +0100)] 
[vmbus] Check for packets shorter than their own header length

A malicious hypervisor is out of scope for our threat model, but we
already sanity check other length fields in received packets so we
should also check that the reported header-inclusive length is at
least equal to the reported header length (and thereby avoid a
potential integer underflow).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
23 hours ago[ucode] Remove harmless read beyond end of malformed equivalence table 1806/head
Michael Brown [Thu, 6 Aug 2026 14:41:35 +0000 (15:41 +0100)] 
[ucode] Remove harmless read beyond end of malformed equivalence table

If the AMD microcode equivalence table is malformed and is not an
exact multiple of the entry size, then we may read up to two bytes
beyond the end of the allocated image.

The small out-of-bounds read is harmless since the immediately
following code will reject any image with fewer than eight bytes
remaining after the equivalence table (or will harmlessly return
immediately if the out-of-bounds read value was 0x00000000 and no
previous equivalence table entries were present).

Fix by adjusting the loop condition to ignore partial equivalence
table entries.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
26 hours ago[doc] Add agent-facing instructions 1805/head
Michael Brown [Thu, 6 Aug 2026 10:35:08 +0000 (11:35 +0100)] 
[doc] Add agent-facing instructions

Add the instructions that Claude developed for itself over the course
of a very interactive week-long security audit of the iPXE codebase.
These instructions are to be used to guide any future use of AI agents
to search for security issues in iPXE.

Agents that follow these instructions are expected to surface only
relevant information, write up suitably minimalistic reports (unlike
the typical unguided AI slop that resulted in iPXE's current "(Ab)use
of AI" policy), and guide submission through the appropriate channels
that have been set up and documented in the security policy.  Any
AI-authored reports are directed towards the "ipxe/aipxe" sandbox
repository, which exists to provide a clear separation between
human-generated and AI-generated content.

Given that repeated passes with Claude Opus 4.8 (and a cross-check
with Claude Fable) have converged to a clean state, it is expected
that publishing these instructions will lead to at most a trickle of
submissions, and that any such submissions should end up being
genuinely useful.

These instructions were written by Claude (with many hours of guidance
and refinement) and have not been modified, on the basis that an AI
agent knows best about what documentation it will itself find useful.
Unnecessary duplication has been avoided by documenting the key points
(e.g. bounds contracts) within the code's own Doxygen comments for
reference by both humans and agents, and ensuring that Claude's own
instructions refer and defer to this authoritative documentation.

Claude has not authored any code that was committed as part of this
week-long project.  The AI agent instructions added by this commit
remain the only AI-authored content present in the tree.  I have set
myself as the commit author (with an appropriate Authored-by credit
for Claude), written this commit message myself, and added my own
signoff, to confirm that I am the human owner taking long-term
responsibility for this contribution, regardless of its origin.

Authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
39 hours ago[doc] Add security policy document 1804/head
Michael Brown [Wed, 5 Aug 2026 22:11:48 +0000 (23:11 +0100)] 
[doc] Add security policy document

With suitable guidance, AI agents such as Claude Code are capable of
scanning effectively for potential vulnerabilities, and reporting them
in a concise and actionable format.

These tools are now widely available to malicious actors, and so any
vulnerabilities that they are capable of finding must be fixed now
before they are inevitably found and potentially exploited.

The recent batch of commits over the past week closes all potential
vulnerabilities that were detectable by either Opus 4.8 or Fable in
multiple passes over the code.  No serious security impact was found,
and there is nothing that would merit a UEFI Secure Boot revocation.

A concrete threat model is now documented, along with the explicit
bounds contracts for several internal APIs (such as ASN.1 parsing and
I/O buffer pointer manipulation).  Some entire classes of nominal
defect (e.g. technically undefined behaviour arising from constant
left shifts into the sign bit) have been eliminated.  False positives
that were raised several times and that could not be silenced through
reporting guidelines were fixed in the code, even when the code change
had no real-world impact.  It is now possible to ask an appropriately
instructed AI agent to search for vulnerabilities in the iPXE codebase
and to be reasonably confident that anything that it reports is worth
investigating further.

Add a security policy to formally document the expectations upon both
humans and AI agents in terms of reporting potential vulnerabilities,
and update the contribution guidelines to grant a limited exception to
the blanket ban on AI-generated text.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
46 hours ago[ci] Add a workflow to trigger synchronisation in forks synctest
Michael Brown [Wed, 5 Aug 2026 15:29:27 +0000 (16:29 +0100)] 
[ci] Add a workflow to trigger synchronisation in forks

Add a workflow that dispatches the synchronisation workflow in a
repository-defined list of downstream forks.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2 days ago[ci] Add a workflow to run in forks to synchronise from the upstream
Michael Brown [Wed, 5 Aug 2026 13:50:19 +0000 (14:50 +0100)] 
[ci] Add a workflow to run in forks to synchronise from the upstream

Add a workflow that can be dispatched within a fork to synchronise it
from the upstream repository.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2 days ago[settings] Fix limited out-of-bounds read in fetch_numeric_setting() 1803/head
Michael Brown [Wed, 5 Aug 2026 12:17:16 +0000 (13:17 +0100)] 
[settings] Fix limited out-of-bounds read in fetch_numeric_setting()

The code in fetch_numeric_setting() reads the setting value into a
local fixed-size buffer but then passes the full setting length to
numeric_setting_value().  If the setting length exceeds the size of
the fixed-size buffer, then numeric_setting_value() will continue to
read bytes from the stack.

The number of bytes read is constrained: numeric_setting_value() will
exit with -ERANGE as soon as the value being constructed exceeds the
range of an unsigned long.  The existence of a return address on the
stack thus provides an upper bound on how far numeric_setting_value()
can read before terminating with an error.

Creating a setting with a length of more than an unsigned long is
trivial, for example:

  set thing:hexraw 00000000000000000000000000000000

However, the out-of-bounds read can be reached only via calls to the
fetch_[u]int[z]_setting() family of internal helper functions.
Reading the setting in a script via e.g. ${thing:uint32} goes via a
different code path that does not use a fixed-length buffer.

The fetch_[u]int[z]_setting() functions are called from only a few
places.  Most uses are for boolean flags or bit masks.  A few are
genuinely used as numeric values: the settings mechanism itself reads
and uses the "priority" setting, the network core reads the "mtu"
setting, and the SAN boot mechanism reads the drive number and retry
count.

An extremely determined attacker could potentially obtain up to eight
bytes of information from the stack (in a 64-bit build) by, for
example, creating two sibling settings blocks where one has an
overlength "priority" setting value, and then repeatedly manipulating
the priority in the other settings block and testing to see which
block ends up with the higher priority.  The information that could be
obtained in this way is limited to the temporary values stored on the
stack by fetch_numeric_setting() itself, along with its own return
address.  None of this information is security-sensitive, and so any
information leakage is a mere curiosity.

Fix by allocating a temporary copy within fetch_numeric_setting()
instead of using a fixed-size buffer.  This has the downside of
introducing an otherwise unnecessary memory allocation (which could
potentially itself fail), but guarantees consistency with other
numeric interpretations of setting values.  (The alternative approach
of rejecting overlength setting values would introduce a potential
inconsistency between the value returned by fetch_numeric_setting()
and the value obtained by formatting a setting using a numeric setting
type, or by numerating the setting.)

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2 days ago[ipv4] Remove harmless but technically undefined left shift 1802/head
Michael Brown [Tue, 4 Aug 2026 17:37:12 +0000 (18:37 +0100)] 
[ipv4] Remove harmless but technically undefined left shift

A DHCP static route option is capable of encoding an invalid subnet
mask width of greater than 32 bits.  This leads to a technically
undefined left shift when calculating the 32-bit subnet mask.

There is no security impact of this undefined shift: the only possible
outcome is that the subnet mask for the improperly defined static
route ends up holding an invalid value.

Fix by checking the range before performing the shift, to eliminate
future reporting noise.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2 days ago[doc] Document the threat model relevant to iPXE 1801/head
Michael Brown [Tue, 4 Aug 2026 14:33:15 +0000 (15:33 +0100)] 
[doc] Document the threat model relevant to iPXE

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 days ago[fcoe] Add assorted length checks 1800/head
Michael Brown [Tue, 4 Aug 2026 12:51:08 +0000 (13:51 +0100)] 
[fcoe] Add assorted length checks

Add an assortment of missing length checks that can currently result
in reads of uninitialised data from within the Ethernet frame padding
region of a received I/O buffer.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 days ago[efi] Avoid reading beyond end of command line 1799/head
Michael Brown [Tue, 4 Aug 2026 12:17:53 +0000 (13:17 +0100)] 
[efi] Avoid reading beyond end of command line

The EFI command line is not necessarily terminated with a wNUL
character.  We currently use snprintf() with an output buffer size to
constrain the write to the correct size and ensure that a NUL
terminator exists (as required for the image data), but nothing
prevents snprintf() from continuing to pointlessly read beyond the end
of the wide-character command line until it happens to encounter a
wNUL somewhere.

Fix by creating a temporary wNUL-terminated copy of the EFI command
line and then converting that (in situ) to ASCII.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 days ago[efi] Guard against invalid IpCnt values in the PXE IP address filter 1798/head
Michael Brown [Tue, 4 Aug 2026 11:32:07 +0000 (12:32 +0100)] 
[efi] Guard against invalid IpCnt values in the PXE IP address filter

A caller that places an invalid value in the IpCnt field would cause
iPXE to read beyond the end of the IpList array.

This has no meaningful security impact: there is no out-of-bounds
write, and a caller with the ability to place an invalid value in the
IpCnt field would already have to be a Secure Boot signed binary (if
Secure Boot is enabled).

Fix by limiting the traversal of IpList to the lower of IpCnt or the
array size, to reduce unwanted noise from security reviewers.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 days ago[efi] Treat invalid device path components as ending the path 1797/head
Michael Brown [Tue, 4 Aug 2026 11:06:11 +0000 (12:06 +0100)] 
[efi] Treat invalid device path components as ending the path

EFI device paths generally have no externally defined length: the only
way to calculate the length is to scan the device path itself (and
therefore to implicitly assume that the path is valid).

There is no way to guard against a malformed device path (absent the
atypical existence of an external length), but we can at least prevent
infinite loops from a device path component that encodes a zero
length.

Treat any device path component with a length too short to contain the
device path header as ending the device path.  This does not prevent
invalid device paths from being accepted, but it does at least guard
against a silent system hang from an infinite loop, and ensures that
callers may safely subtract the length of the device path header from
the length of the path component without underflowing.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 days ago[efi] Fix check for well-formed device paths
Michael Brown [Tue, 4 Aug 2026 10:52:48 +0000 (11:52 +0100)] 
[efi] Fix check for well-formed device paths

EFI device paths generally have no externally defined length: the only
way to calculate the length is to scan the device path itself (and
therefore to implicitly assume that the path is valid).

The EFI load option structure does have an externally defined length
field, and we currently attempt to validate against this.  The
validation logic is missing a crucial step which renders it
ineffective: the overall effect is essentially equivalent to trusting
that the system's configured load option structures are well-formed.
(This is a reasonable assumption: the length check exists primarily as
a defence against external bugs, and an attacker with the ability to
change the system load options has already compromised the system.)

Fix by updating the remaining length correctly as we traverse the
device path.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 days ago[elf] Avoid harmless integer overflows in image length checks 1796/head
Michael Brown [Tue, 4 Aug 2026 09:54:58 +0000 (10:54 +0100)] 
[elf] Avoid harmless integer overflows in image length checks

Fix the checks against reading beyond the image length when executing
an ELF image.

As with the equivalent commit 979c86f ("[nbi] Avoid harmless integer
overflows in image length checks"), this change has absolutely no
security impact: an ELF image will obtain control of the system in
ring 0 anyway, and so a "malicious" ELF image with malformed length
fields cannot do anything that it would not already be able to do
simply by being executed.  However, fixing these harmless integer
overflows costs very little and reduces unwanted noise from security
reviewers.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 days ago[uhci] Fix descriptor count for zero-length stream transfers 1795/head
Michael Brown [Tue, 4 Aug 2026 08:16:55 +0000 (09:16 +0100)] 
[uhci] Fix descriptor count for zero-length stream transfers

The descriptor count for a zero-length stream transfer with no
explicit terminating zero-length packet is currently calculated
incorrectly as requiring zero descriptors.  This will cause
uhci_enqueue() to attempt to allocate a zero-length block of transfer
descriptors, which will fail and return -ENOMEM.

There is no internal code path within iPXE that can ever submit a
zero-length stream transfer without an explicit terminating
zero-length packet.  This condition is reachable only via the
EFI_USB_IO_PROTOCOL interface that we expose on UEFI platforms to
allow existing firmware drivers to reconnect after we take control of
the host controller.

Fix by ensuring that the descriptor count is set to one for a
zero-length stream transfer with no explicit terminating zero-length
packet, as is already done for EHCI and XHCI.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 days ago[velocity] Correct direction of endianness conversion
Michael Brown [Tue, 4 Aug 2026 07:46:24 +0000 (08:46 +0100)] 
[velocity] Correct direction of endianness conversion

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 days ago[uhci] Add missing little-endian conversion
Michael Brown [Tue, 4 Aug 2026 07:42:01 +0000 (08:42 +0100)] 
[uhci] Add missing little-endian conversion

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 days ago[intelxl] Add missing little-endian conversions
Michael Brown [Tue, 4 Aug 2026 07:38:10 +0000 (08:38 +0100)] 
[intelxl] Add missing little-endian conversions

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 days ago[build] Enable strict shift overflow warnings 1793/head
Michael Brown [Mon, 3 Aug 2026 22:52:01 +0000 (23:52 +0100)] 
[build] Enable strict shift overflow warnings

Left shifts into the sign bit are often reported as potential
undefined behaviour by automated tools, which distracts from real
issues.

Now that all offending constant left shifts have been eliminated from
the codebase, enable -Wshift-overflow=2 to ensure that such shifts
cannot be reintroduced in future.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 days ago[build] Fix technically undefined left shifts in disreputable code
Michael Brown [Mon, 3 Aug 2026 22:49:30 +0000 (23:49 +0100)] 
[build] Fix technically undefined left shifts in disreputable code

Fix the technically undefined constant left shifts into the sign bit
in ancient, messy, and third-party code.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 days ago[build] Fix technically undefined left shifts in reputable code
Michael Brown [Mon, 3 Aug 2026 22:45:45 +0000 (23:45 +0100)] 
[build] Fix technically undefined left shifts in reputable code

Fix the technically undefined constant left shifts into the sign bit
in code where there is some value in attempting to minimise the
aesthetic disruption from doing so.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 days ago[ipv4] Make the IPV4() macro available to non-test code
Michael Brown [Mon, 3 Aug 2026 22:29:30 +0000 (23:29 +0100)] 
[ipv4] Make the IPV4() macro available to non-test code

Clean up the IPV4() macro used to construct literal IPv4 addresses in
test cases, and make it generally available to all code.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 days ago[iphone] Fix debug printing of received log messages 1792/head
Michael Brown [Mon, 3 Aug 2026 21:32:25 +0000 (22:32 +0100)] 
[iphone] Fix debug printing of received log messages

The log message length is calculated incorrectly, causing the first
byte after the I/O buffer data to be both read and written (with a
fixed zero value).  A log message of precisely 4079 bytes will
therefore result in a zero byte being written outside the I/O buffer's
heap allocation.

Fix by using the correct length for the log message.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 days ago[xen] Fix failure path in hvm_ioremap()
Michael Brown [Mon, 3 Aug 2026 21:20:47 +0000 (22:20 +0100)] 
[xen] Fix failure path in hvm_ioremap()

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 days ago[xhci] Allow for residual byte counts exceeding 64kB 1791/head
Michael Brown [Mon, 3 Aug 2026 21:04:54 +0000 (22:04 +0100)] 
[xhci] Allow for residual byte counts exceeding 64kB

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 days ago[intelxl] Remove wasted space in ice_magic_mac[] array
Michael Brown [Mon, 3 Aug 2026 20:33:35 +0000 (21:33 +0100)] 
[intelxl] Remove wasted space in ice_magic_mac[] array

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 days ago[pci] Allow dumping interrupt state for arbitrary MSI-X vector numbers 1790/head
Michael Brown [Mon, 3 Aug 2026 20:27:22 +0000 (21:27 +0100)] 
[pci] Allow dumping interrupt state for arbitrary MSI-X vector numbers

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 days ago[spi] Fix assertion expressions
Michael Brown [Mon, 3 Aug 2026 20:15:35 +0000 (21:15 +0100)] 
[spi] Fix assertion expressions

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 days ago[doc] Add documentation of the composable error handling pattern
Michael Brown [Mon, 3 Aug 2026 16:58:17 +0000 (17:58 +0100)] 
[doc] Add documentation of the composable error handling pattern

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 days ago[crypto] Remove harmless but technically undefined left shift 1789/head
Michael Brown [Mon, 3 Aug 2026 15:38:06 +0000 (16:38 +0100)] 
[crypto] Remove harmless but technically undefined left shift

The unsigned 8-bit value from the keyUsage bit string is promoted to a
(signed) int before being shifted left by up to 24 bits, which is
technically undefined behaviour.

Explicitly cast the 8-bit value to an unsigned int before shifting, to
inhibit this class of false positive warning.  There is no difference
to the resulting object code.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 days ago[crypto] Avoid false positive warnings about mutating static state 1788/head
Michael Brown [Mon, 3 Aug 2026 15:08:16 +0000 (16:08 +0100)] 
[crypto] Avoid false positive warnings about mutating static state

iPXE is single-threaded by design, but automated tools still tend to
erroneously report the mutation of static state as being unsafe,
especially when that mutation happens within cryptographic code.

At the cost of six bytes in the 32-bit BIOS binary, allocate the
reference algorithm ASN.1 cursor on the stack to eliminate this class
of false positive warning.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 days ago[crypto] Avoid false positive warnings about out-of-bounds access 1787/head
Michael Brown [Mon, 3 Aug 2026 14:50:34 +0000 (15:50 +0100)] 
[crypto] Avoid false positive warnings about out-of-bounds access

The last byte within a non-empty ASN.1 bit string object always
exists, but automated tools tend to erroneously report the way in
which we access it as being out of bounds.

Move the assignment of the last byte pointer to be ahead of the
shrinking of the cursor, to eliminate this class of false positive
warning.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 days ago[crypto] Remove harmless but technically undefined right shift 1786/head
Michael Brown [Mon, 3 Aug 2026 14:23:46 +0000 (15:23 +0100)] 
[crypto] Remove harmless but technically undefined right shift

Automated reporting tools tend to pick up the right-shift by an
attacker-controllable shift amount as a potential defect, since a
right-shift by greater than the word size is technically undefined
behaviour.

The result of an undefined shift is already ignored by the following
range check on the shift amount, and the separate "unused_mask"
variable exists only to make the code clearer to read.  Sacrifice this
very small improvement in legibility for the sake of reducing future
reporting noise.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 days ago[srp] Avoid potential integer overflow in parsing response data 1785/head
Michael Brown [Mon, 3 Aug 2026 14:08:29 +0000 (15:08 +0100)] 
[srp] Avoid potential integer overflow in parsing response data

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 days ago[fcp] Avoid potential integer overflow in parsing response data 1784/head
Michael Brown [Mon, 3 Aug 2026 12:27:16 +0000 (13:27 +0100)] 
[fcp] Avoid potential integer overflow in parsing response data

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 days ago[build] Mark ONC RPC protocol as forbidden for UEFI Secure Boot
Michael Brown [Mon, 3 Aug 2026 12:09:50 +0000 (13:09 +0100)] 
[build] Mark ONC RPC protocol as forbidden for UEFI Secure Boot

The NFS protocol code was marked as forbidden for UEFI Secure Boot in
commit 3094898 ("[build] Mark existing files as explicitly forbidden
for Secure Boot"), but the file net/tcp/oncrpc.c was missed due to
being outside of the net/oncrpc directory.

Add the missing explicit FILE_SECBOOT() declaration.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 days ago[build] Mark SCSI RDMA protocol as forbidden for UEFI Secure Boot
Michael Brown [Mon, 3 Aug 2026 11:41:34 +0000 (12:41 +0100)] 
[build] Mark SCSI RDMA protocol as forbidden for UEFI Secure Boot

The SCSI RDMA protocol (as implemented in iPXE) allows a remote entity
full write access to host memory, and so would provide an immediate
Secure Boot exploit.

The SCSI RDMA protocol is already implicitly forbidden for UEFI Secure
Boot (by not having any FILE_SECBOOT marker).  Make this explicit.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 days ago[nbi] Avoid harmless integer overflows in image length checks 1783/head
Michael Brown [Mon, 3 Aug 2026 11:24:08 +0000 (12:24 +0100)] 
[nbi] Avoid harmless integer overflows in image length checks

Fix the checks against reading beyond the image length when executing
an NBI image.

This change has absolutely no security impact: an NBI image will
obtain control of the system in ring 0 anyway, and so a "malicious"
NBI image with malformed length fields cannot do anything that it
would not already be able to do simply by being executed.  However,
fixing these harmless integer overflows costs very little and reduces
unwanted noise from security reviewers.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 days ago[eoib] Ensure that transmit address vector cannot go out of scope 1782/head
Michael Brown [Mon, 3 Aug 2026 10:21:18 +0000 (11:21 +0100)] 
[eoib] Ensure that transmit address vector cannot go out of scope

The peer cache entries are subject to the cache discarder, and could
therefore potentially be freed during calls to ib_resolve_path(),
eoib_duplicate(), or ib_post_send().

Create an on-stack copy of the destination address vector, instead of
passing around a pointer to the address vector within the peer cache
entry.

Since the LID within the peer cache entry will no longer be updated by
ib_resolve_path(), change the receive-side logic to update the peer
cache unconditionally.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 days ago[doc] Expand documentation for ssnprintf()
Michael Brown [Sun, 2 Aug 2026 17:54:11 +0000 (18:54 +0100)] 
[doc] Expand documentation for ssnprintf()

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 days ago[doc] Expand documentation for memory allocation
Michael Brown [Sun, 2 Aug 2026 17:00:27 +0000 (18:00 +0100)] 
[doc] Expand documentation for memory allocation

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 days ago[doc] Expand documentation for data transfer buffers
Michael Brown [Sun, 2 Aug 2026 15:49:09 +0000 (16:49 +0100)] 
[doc] Expand documentation for data transfer buffers

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 days ago[doc] Expand documentation for assert()
Michael Brown [Sun, 2 Aug 2026 15:22:26 +0000 (16:22 +0100)] 
[doc] Expand documentation for assert()

Signed-off-by: Michael Brown <mcb30@ipxe.org>
5 days ago[doc] Expand documentation for I/O buffer usage
Michael Brown [Sun, 2 Aug 2026 14:06:48 +0000 (15:06 +0100)] 
[doc] Expand documentation for I/O buffer usage

Signed-off-by: Michael Brown <mcb30@ipxe.org>
5 days ago[crypto] Use consistent lengths when constructing OCSP URI strings 1779/head
Michael Brown [Sun, 2 Aug 2026 12:54:56 +0000 (13:54 +0100)] 
[crypto] Use consistent lengths when constructing OCSP URI strings

The construction of the OCSP URI erroneously attempts to URI-encode
the terminating NUL of the Base64-encoded string, but does so using a
bounded write into a buffer that was sized precisely (i.e. without
space for the spurious encoded NUL), and so ends up constructing the
correct string anyway.

Reduce confusion by passing the same input value to both calls to
uri_encode(), and add assertions on the return values from both
base64_encode() and uri_encode().

Signed-off-by: Michael Brown <mcb30@ipxe.org>
5 days ago[malloc] Correct unsigned overflow check for allocated size 1778/head
Michael Brown [Sun, 2 Aug 2026 11:51:45 +0000 (12:51 +0100)] 
[malloc] Correct unsigned overflow check for allocated size

The existing overflow check for the allocated memory block size has a
logic gap: a size that is close to the maximum value with a suitable
offset can end up being rounded to heap->align rather than to zero.

This overflow is not reachable via malloc().  With the internal heap,
we have:

   align = heap->ptr_align = sizeof ( void * )

   offset = -offsetof ( struct autosized_block, data )
          = -sizeof ( size_t )
  = -sizeof ( void * )
  = -align

and therefore

   offset & ( align - 1 ) == 0

and so any integer overflow in actual_size will produce a zero result
and will be caught by the existing check.

The overflow is also not reachable via malloc_phys(), since these
allocations are made for DMA and I/O buffers, where the size cannot be
arbitrarily controlled by an attacker.

The overflow is reachable via umalloc() on the BIOS and RISC-V SBI
platforms where umalloc() is backed by the external user heap.  The
overflow is not reachable via umalloc() on UEFI platforms where
umalloc() is instead backed by AllocatePages(), or on Linux platforms
where umalloc() is backed by mmap().

Fix by checking for overflow in the standard way, rather than relying
erroneously upon the assumption that overflow will always produce a
zero result in actual_size.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
5 days ago[malloc] Convert allocation assertions to runtime checks
Michael Brown [Sun, 2 Aug 2026 11:37:57 +0000 (12:37 +0100)] 
[malloc] Convert allocation assertions to runtime checks

There is no way for heap_alloc_block() to be called with a size of
zero or with an alignment that is not a power of two, and so asserting
these conditions is justifiable.

However, given the criticality of memory allocation to security, it is
worth converting these to runtime checks to guard against future code
changes that could, for example, allow for a variable alignment to be
passed in without being rounded up.

Convert the zero-size assertion and the power-of-two-alignment
assertion into runtime checks, and document the reasoning.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
5 days ago[malloc] Correct assertion that requested alignment is a power of two
Michael Brown [Sun, 2 Aug 2026 11:27:19 +0000 (12:27 +0100)] 
[malloc] Correct assertion that requested alignment is a power of two

A requested alignment of zero is logically unsatisfiable: the
resulting pointer can never be a multiple of zero.  No existing caller
ever attempts to allocate memory with an alignment of zero.

Correct the relevant assertions, and drop the misleading handling of
zero as a special-cased value when masking the alignment offset.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
5 days ago[iscsi] Reject SCSI PDUs received when no command is in progress 1777/head
Michael Brown [Sun, 2 Aug 2026 08:07:28 +0000 (09:07 +0100)] 
[iscsi] Reject SCSI PDUs received when no command is in progress

Signed-off-by: Michael Brown <mcb30@ipxe.org>
5 days ago[lacp] Fix stripping of trailing padding 1775/head
Michael Brown [Sat, 1 Aug 2026 22:46:44 +0000 (23:46 +0100)] 
[lacp] Fix stripping of trailing padding

The iob_unput() to strip any trailing padding is currently sign
reversed, causing the buffer to be extended rather than truncated.

This can result in uninitialised data within the receive I/O buffer
being passed to the LACP or marker receive handlers and subsequently
echoed back to the sender.

Fix by reversing the subtraction.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
5 days ago[crypto] Fix out-of-bounds memset() with invalid RSA modulus 1774/head
Michael Brown [Sat, 1 Aug 2026 21:00:01 +0000 (22:00 +0100)] 
[crypto] Fix out-of-bounds memset() with invalid RSA modulus

The length checks in rsa_pkcs1_encode() and rsa_pkcs1_encrypt()
subtract the 11-byte fixed encoding length from the modulus size,
which can underflow in the case of a malicious RSA key with an
absurdly small modulus.

Signature verification for validating X.509 certificates is already
gated behind the validation status of the issuer certificate.  It is
therefore impossible to exploit this via X.509 without explicitly
trusting a malicious certificate (e.g. via the TRUST=... build-time
parameter).

However, commit 05e6256 ("[tls] Parse ServerKeyExchange record
immediately") changed the timing of the TLS protocol parsing such that
the verification of the ServerKeyExchange message is now performed
immediately upon receipt, rather than deferring this check until the
certificate has been validated.  It is therefore possible to use a
malicious TLS server certificate to trigger this underflow before the
certificate is validated.  This commit is less than two weeks old and
has never been included in a Secure Boot signed build.

Fix by performing the length checks using addition rather than
subtraction.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
5 days ago[dhcp] Fix potential read of byte following DHCP options block 1773/head
Michael Brown [Sat, 1 Aug 2026 19:34:11 +0000 (20:34 +0100)] 
[dhcp] Fix potential read of byte following DHCP options block

The DHCP options parsing code is approximately twenty years old and
dates back to a time when code size considerations were dominant.  The
dhcp_option_len() function may currently read up to one byte beyond
the end of the options data.  There is no impact from this (since the
immediately following range check will cause the loop to terminate),
but it is technically an out-of-bounds read.

Fix by passing the remaining length to dhcp_option_len() and treating
a malformed tag at the end of the options data as having a length of
one byte.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
5 days ago[png] Check for overflow when constructing raw data buffer length 1772/head
Michael Brown [Sat, 1 Aug 2026 18:14:14 +0000 (19:14 +0100)] 
[png] Check for overflow when constructing raw data buffer length

Writing to the raw (i.e. decompressed) data buffer is already strictly
bounded by its allocated length.  However, reading from the raw data
buffer to construct the pixel buffer content is not.  A maliciously
formed PNG file can therefore result in undefined external heap memory
being read, interpreted, and used to construct the picture shown on
screen to the user.

There is no way for this data to subsequently be obtained over the
network, though a particularly determined attacker could potentially
reconstruct the contents of other image files by capturing the
on-screen video output.

Fix by checking for overflow at each stage of constructing the raw
buffer length.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
7 days ago[doc] Provide overview of ASN.1 parsing helper functions
Michael Brown [Thu, 30 Jul 2026 20:35:32 +0000 (21:35 +0100)] 
[doc] Provide overview of ASN.1 parsing helper functions

Signed-off-by: Michael Brown <mcb30@ipxe.org>
7 days ago[eapol] Fix stripping of trailing padding 1770/head
Michael Brown [Thu, 30 Jul 2026 16:45:28 +0000 (17:45 +0100)] 
[eapol] Fix stripping of trailing padding

The iob_unput() to strip any trailing padding is currently sign
reversed, causing the buffer to be extended rather than truncated.

This can result in uninitialised data within the receive I/O buffer
being passed to the EAP request handler.  This uninitialised data
would then erroneously be hashed as part of the MD5 or MSCHAPv2
challenge.

Fix by reversing the subtraction, and adjust the variable names so
that the correct order is more immediately obvious.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
7 days ago[eap] Verify header length for all EAP packet types 1769/head
Michael Brown [Thu, 30 Jul 2026 15:56:03 +0000 (16:56 +0100)] 
[eap] Verify header length for all EAP packet types

The header length field exists for all packet types.  Validate this
length wihtin eap_rx() for all packet types, rather than performing
validation only for EAP requests in eap_rx_request().

Signed-off-by: Michael Brown <mcb30@ipxe.org>
8 days ago[http] Avoid potentially comparing TCP header bytes against CRLF 1768/head
Michael Brown [Thu, 30 Jul 2026 13:56:18 +0000 (14:56 +0100)] 
[http] Avoid potentially comparing TCP header bytes against CRLF

The optimisation to check for a trailing CRLF in http_rx_chunk_data()
could potentially underflow and look for the CR and LF bytes in the
I/O buffer data that immediately precedes the HTTP content (i.e. in
the TCP header).

Fix by avoiding the potential underflow.  Update the code to use a
dedicated CRLF structure, to reduce the proliferation of magic numbers
within the function.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
8 days ago[dhcp] Reject underlength DHCP packets 1767/head
Michael Brown [Thu, 30 Jul 2026 13:09:54 +0000 (14:09 +0100)] 
[dhcp] Reject underlength DHCP packets

Reject underlength DHCP packets before calling dhcppkt_init(), which
takes a struct dhcphdr pointer and so may legitimately assume that the
structure is complete (i.e. that the length is at least large enough
to contain a struct dhcphdr).

Do not modify the dhcppkt_init() parameters to pass the options length
rather than the total length.  This alternative approach would make it
impossible to pass an invalid length: the check in dhcp_deliver()
would then become a check for integer underflow, which would be more
obviously necessary.  However, all callers of dhcppkt_init() have the
total length more readily available than the options length, and
callers such as cachedhcp_record() deal with fixed-size structures
such as EFI_PXE_BASE_CODE_PACKET and so do not have to worry about
potential underlength packets.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
8 days ago[bitmap] Allow bitmap_set() to report an error 1766/head
Michael Brown [Thu, 30 Jul 2026 12:25:58 +0000 (13:25 +0100)] 
[bitmap] Allow bitmap_set() to report an error

Signed-off-by: Michael Brown <mcb30@ipxe.org>
8 days ago[ipv6] Use correct length when checking for truncated packets 1765/head
Michael Brown [Thu, 30 Jul 2026 11:44:40 +0000 (12:44 +0100)] 
[ipv6] Use correct length when checking for truncated packets

The IPv6 header length field contains the payload length (excluding
the length of the IPv6 header itself).  The IPv6 packet parser
calculates the length of the received packet correctly, but wrongly
uses the payload length (rather than the full packet length) when
checking for truncated packets.

Fix by calculating the packet length exactly once and using it for
both purposes.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
8 days ago[libc] Allow out-of-range months in mktime() 1764/head
Michael Brown [Thu, 30 Jul 2026 09:27:01 +0000 (10:27 +0100)] 
[libc] Allow out-of-range months in mktime()

POSIX specifies that the values of members of the broken-down time
structure are "not restricted to the ranges", and defines the way in
which out-of-range values are to be handled.

For most fields, the arithmetic is already purely linear and so
out-of-range values are handled automatically.  Out-of-range months
are an exception: these are used as array indices and so must be
normalised before use.

Restructure mktime() to make it more immediately visible when values
are being read from and written back to the broken-down time
structure, add the required normalisation for the month number, and
add test cases to cover out-of-range months.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
8 days ago[crypto] Add confidentiality flag for cipher algorithms
Michael Brown [Wed, 29 Jul 2026 16:41:45 +0000 (17:41 +0100)] 
[crypto] Add confidentiality flag for cipher algorithms

Add a flag that indicates whether or not a cipher is capable of
providing confidentiality.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
9 days ago[malloc] Add zfree() to zero and then free a memory block
Michael Brown [Tue, 28 Jul 2026 12:07:23 +0000 (13:07 +0100)] 
[malloc] Add zfree() to zero and then free a memory block

For memory that may contain secrets, it is good practice to zero the
memory before returning it to the heap.

Add a zfree() function that can be used to zero and then free any
memory allocated using malloc(), and use it in place of free() for any
existing code that is obviously managing secrets held in dynamically
allocated memory.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
9 days ago[intelxl] Add support for Intel E610 and E835 adapters 1762/head
Guanghua Zhang [Tue, 28 Jul 2026 19:33:00 +0000 (20:33 +0100)] 
[intelxl] Add support for Intel E610 and E835 adapters

Signed-off-by: Michael Brown <mcb30@ipxe.org>
10 days ago[mime] Fix the use of MIME images without an explicit encoding 1758/head
Michael Brown [Mon, 27 Jul 2026 14:14:57 +0000 (15:14 +0100)] 
[mime] Fix the use of MIME images without an explicit encoding

The Content-Transfer-Encoding header is optional: if not present then
the default "7bit" encoding should be assumed.  iPXE already includes
logic to set a default encoding name, but the default encoding name
then fails to match against any entries in the known encodings list
since it is terminated with a NUL (rather than with the semicolon or
whitespace character that would terminate the encoding name found
within a Content-Transfer-Encoding header).

Fix by removing the default encoding name and instead treating a NULL
encoding name as indicating that the default encoding should be used,
and add a test case that omits the Content-Transfer-Encoding header.

Reported-by: Huzaifa Ali Zar <zar@amazon.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
11 days ago[test] Simplify the use of inline text for test images
Michael Brown [Mon, 27 Jul 2026 13:58:37 +0000 (14:58 +0100)] 
[test] Simplify the use of inline text for test images

When specifying the content of a test image (e.g. a MIME archive file)
using C string literals, there is no easy way to indicate that the
terminating NUL should be excluded from the byte array.

Provide BINFILE(), TEXTFILE(), and FILE_ARRAY() helper macros that can
be used to simplify the initialisation of a byte array passed as
either a raw byte value list or a string literal.  For example:

  #define TEST_CASE( name, file ) do {                        \
      static uint8_t name ## _bytes FILE_ARRAY ( file );      \
      ...                                                     \
      } while ( 0 )

  TEST_CASE ( test1, BINFILE ( 0x68, 0x65, 0x6c, 0x6c, 0x6f ) );

  TEST_CASE ( test2, TEXTFILE ( "hello" ) );

Both of the above TEST_CASE() lines will end up producing a five-byte
array:

  static uint8_t test1_bytes[] = { 0x68, 0x65, 0x6c, 0x6c, 0x6f };

  static uint8_t test2_bytes[5] = "hello";

This allows us to remove the stray NUL that otherwise appears at the
end of any test images that are specified using string literals.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2 weeks ago[dns] Pass a non-null peer socket address to xfer_open_socket()
Michael Brown [Tue, 21 Jul 2026 12:28:23 +0000 (13:28 +0100)] 
[dns] Pass a non-null peer socket address to xfer_open_socket()

Commit 3662065 ("[dns] Use all configured DNS servers") changed the
logic from opening a single defined nameserver address to opening an
unspecified peer socket address and then specifying the full peer
address for each transmitted packet.

The peer socket address was left unspecified by passing a null pointer
to xfer_open_socket().  This is supported by the UDP socket opener,
but technically violates the internal API (which allows the local
socket address to be a null pointer, but not the peer socket address).
In particular, in a debug build using DEBUG=open, the debug code will
itself dereference the peer address pointer.

Fix by embedding the name server socket address within the DNS request
structure, and passing this to xfer_open_socket().

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2 weeks ago[xfer] Do not attempt to find an opener for a null URI scheme 1755/head
Michael Brown [Tue, 21 Jul 2026 11:34:16 +0000 (12:34 +0100)] 
[xfer] Do not attempt to find an opener for a null URI scheme

With no current working URI, even a fully resolved URI may not have a
scheme.  Attempting to open such a URI will currently result in
xfer_uri_opener() calling strcasecmp() with a null pointer.  On a
system that guards against null pointer dereferences, this will result
in a segfault (or the equivalent, such as a Synchronous Exception on
arm64 UEFI).

Fix by checking that the URI is absolute (i.e. has a scheme) before
calling xfer_uri_opener(), as is already done elsewhere.

Reported-by: Matt Fleming <matt@readmodwrite.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2 weeks ago[tls] Parse ServerKeyExchange record immediately
Michael Brown [Sun, 19 Jul 2026 14:08:57 +0000 (15:08 +0100)] 
[tls] Parse ServerKeyExchange record immediately

As of commit 433a8f5 ("[tls] Retain a reference in the key schedule to
the bound identity"), the act of binding the server identity is
logically separated from the act of validating the server identity.
We may therefore bind the server identity (by verifying the signature
over the Diffie-Hellman parameters) and agree the ephemeral shared
secret immediately upon receiving the ServerKeyExchange record, rather
than deferring the verification until we have a validated identity.

This provides a closer match to the flow required for TLS version 1.3,
where the ephemeral shared secret is used for all messages after
ServerHello, and so must always be agreed prior to validation.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 weeks ago[image] Allow download progress messages to be silenced
Michael Brown [Fri, 17 Jul 2026 10:55:04 +0000 (11:55 +0100)] 
[image] Allow download progress messages to be silenced

Add a "--quiet" option to each image-acquiring command that currently
accepts a "--timeout" option, to allow the displaying of the download
URI and the progress dots to be inhibited.

This is particularly useful with "data:" URIs to inhibit the echoing
of the full data URI contents:

    iPXE> imgfetch -n hw data:,hello%20world
    data:,hello%20world... ok
    iPXE>

vs.

    iPXE> imgfetch -q -n hw data:,hello%20world
    iPXE>

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 weeks ago[dmesg] Add an in-memory ring buffer console
Michael Brown [Thu, 16 Jul 2026 14:01:57 +0000 (15:01 +0100)] 
[dmesg] Add an in-memory ring buffer console

Add a trivial ring buffer console that can be used to extract the most
recent 8kB of (non-UI) console output as the ${dmesg} setting.

This allows previous console output to be displayed after the screen
has been cleared, such as when a background picture has been loaded.
For example:

    #!ipxe
    console -p http://boot.ipxe.org/ipxe.png
    show -q dmesg

It also allows console output to be captured and sent as part of an
HTTP POST, to allow for remote diagnostics.  For example:

    #!ipxe
    params
    param dmesg ${dmesg:base64}
    imgfetch http://192.168.0.1/api/diags##params

The recorded console output may be cleared if necessary by clearing
the setting:

    clear builtin/dmesg

The name ${dmesg} is chosen as being unlikely to collide with any
existing variables used in end-user scripts.  A separate "dmesg"
command is not provided, but could easily be added if useful.

Note that iPXE supports recursive variable expansion in shell
commands.  Typing an interactive command such as "echo ${dmesg}" or
"param dmesg ${dmesg}" is therefore a great way to exercise the memory
allocator to the point of exhaustion.  Use "show -q dmesg" to show the
ring buffer contents.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 weeks ago[uri] Escape the "+" character within HTTP form parameters
Michael Brown [Thu, 16 Jul 2026 15:31:33 +0000 (16:31 +0100)] 
[uri] Escape the "+" character within HTTP form parameters

Within application/x-www-form-urlencoded values, a "+" character needs
to be escaped to avoid its being interpreted as a space.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 weeks ago[settings] Add "--quiet" option to "show" command
Michael Brown [Thu, 16 Jul 2026 14:46:57 +0000 (15:46 +0100)] 
[settings] Add "--quiet" option to "show" command

Allow the "show -q" command to be used to display a setting's value
without also showing its origin and type metadata.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 weeks ago[uri] Add support for "data:" URIs 1753/head
Michael Brown [Thu, 16 Jul 2026 11:55:53 +0000 (12:55 +0100)] 
[uri] Add support for "data:" URIs

Add support for "data:" URIs as defined in RFC 2397.  These can be
used to construct image content under control of an iPXE script.  For
example:

  # Inject the message "Hello from iPXE" as /etc/motd
  initrd -n motd data:,Hello%20from%20iPXE%0A /etc/motd

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 weeks ago[blob] Add an abstraction of an openable data blob
Michael Brown [Wed, 15 Jul 2026 22:28:38 +0000 (23:28 +0100)] 
[blob] Add an abstraction of an openable data blob

Within the iPXE data transfer interface model, openers are fully
asynchronous and may not deliver any data until after the opener has
returned.

Provide a trivial openable data blob object (as a generalisation of
the "hello world" data transfer interface example code) that will
simply deliver a single fixed blob of data to its parent interface and
then close itself.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 weeks ago[cloud] Add support for Alibaba Cloud IMDSv2
Michael Brown [Tue, 14 Jul 2026 12:47:36 +0000 (13:47 +0100)] 
[cloud] Add support for Alibaba Cloud IMDSv2

The design of IMDSv2 within Alibaba Cloud is identical to AWS IMDSv2,
with the header names changed from "X-aws-ec2-*" to "X-aliyun-ecs-*".

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 weeks ago[cloud] Add support for AWS IMDSv2
Michael Brown [Tue, 14 Jul 2026 12:10:19 +0000 (13:10 +0100)] 
[cloud] Add support for AWS IMDSv2

Use an HTTP PUT request to fetch a session token, and pass this token
value as a header when fetching the user-data script.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 weeks ago[cmdline] Add "imgset" command
Michael Brown [Tue, 14 Jul 2026 11:45:32 +0000 (12:45 +0100)] 
[cmdline] Add "imgset" command

A commonly requested feature is to allow a setting to be populated
with the contents of an HTTP response.  This currently requires a
somewhat ugly workaround of having the HTTP endpoint generate an iPXE
executable script fragment that includes the "#!ipxe" shebang and the
relevant "set" command.

For HTTP endpoints that are under the end user's control, this
workaround is viable (though still ugly).  For HTTP endpoints that are
outside the user's control (such as the AWS metadata endpoints), this
workaround cannot be used.

Add an "imgset" command that can be used to store downloaded content
directly into a setting.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 weeks ago[http] Allow issuing requests with an explicitly specified HTTP method
Michael Brown [Mon, 13 Jul 2026 14:39:00 +0000 (15:39 +0100)] 
[http] Allow issuing requests with an explicitly specified HTTP method

The design of IMDSv2 within both AWS and Alibaba Cloud requires the
client to obtain a temporary token via an HTTP PUT request.  There is
no authentication on this request and there is no associated request
body: the requirement to use PUT exists solely to reduce the attack
surface for SSRF attacks (since vulnerable servers are much more
likely to be able to be tricked into issuing a GET request than a PUT
request).

iPXE can currently issue requests using HTTP GET (if the request body
is empty) or HTTP POST (if the request body includes form parameters).
There is no support for issuing a PUT request, or for allowing a
script to explicitly specify the HTTP method.

Add a "--method" option to the "params" command to allow an arbitrary
request method name to be specified, and use this as the HTTP request
method.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 weeks ago[http] Show parameter headers in debug output
Michael Brown [Mon, 13 Jul 2026 15:15:25 +0000 (16:15 +0100)] 
[http] Show parameter headers in debug output

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 weeks ago[params] Avoid calling strcmp() with a NULL parameter list name
Michael Brown [Mon, 13 Jul 2026 14:32:43 +0000 (15:32 +0100)] 
[params] Avoid calling strcmp() with a NULL parameter list name

If a named parameter block is created and then a URI is parsed that
attempts to use a nonexistent unnamed parameter block (or vice versa),
then the code in find_parameters() will currently call strcmp() with a
NULL argument, resulting in a read-only access to undefined memory.

Fix by calling strcmp() only for non-NULL names.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 weeks ago[mime] Add support for MIME multipart images
Michael Brown [Mon, 13 Jul 2026 10:51:14 +0000 (11:51 +0100)] 
[mime] Add support for MIME multipart images

Some public clouds (such as AWS and Alibaba Cloud) allow for only a
single user metadata blob.  The official iPXE cloud images will
attempt to download and boot from this user metadata, expecting it to
contain an iPXE script.

This works, but causes conflicts when another consumer (such as
cloud-init) also wants to use the same metadata blob.  There are
workarounds (such as publishing the cloud-init script at an
alternative URI outside of the instance metadata service, and using
the iPXE script to direct cloud-init to use the alternative URI via
kernel command-line arguments), but these are cumbersome and may
weaken security since the alternative URI cannot provide the same
level of guaranteed access restrictions.

There is support within cloud-init for parsing a multipart MIME
archive, which may contain additional shell scripts, JSON data, etc,
alongside the cloud-init configuration itself.  This is the standard
and documented method that cloud-init has chosen to solve the issue of
obtaining multiple data sources from a single user metadata blob.

Add support for multipart MIME as an archive image format from which
iPXE will extract the first body part that has the "text/x-ipxe" MIME
type.  This allows the iPXE boot script to be placed alongside
cloud-init configuration within a single user metadata blob.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 weeks ago[test] Generalise archive extraction self-tests
Michael Brown [Mon, 13 Jul 2026 09:38:48 +0000 (10:38 +0100)] 
[test] Generalise archive extraction self-tests

The zlib and gzip test definitions are almost identical.  Create a
single definition of an archive test to reduce duplication.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 weeks ago[libc] Add strcasestr()
Michael Brown [Mon, 13 Jul 2026 09:11:06 +0000 (10:11 +0100)] 
[libc] Add strcasestr()

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 weeks ago[hermon] Add missing write barrier after initiating reset 1752/head
Michael Brown [Fri, 10 Jul 2026 15:29:52 +0000 (16:29 +0100)] 
[hermon] Add missing write barrier after initiating reset

Ensure that the reset register write does not get reordered behind the
first PCI configuration space read that checks to see if the reset has
completed.

Debugged-by: Jaroslav Svoboda <multi.flexi@seznam.cz>
Tested-by: Jaroslav Svoboda <multi.flexi@seznam.cz>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 weeks ago[image] Make text-based image data usable by string functions
Michael Brown [Fri, 10 Jul 2026 11:35:27 +0000 (12:35 +0100)] 
[image] Make text-based image data usable by string functions

Using standard string functions for parsing text-based image formats
is currently cumbersome since there is no guaranteed NUL terminator,
and so code must laboriously keep track of the remaining image length
and use only those string functions that accept a length limit.

Ensure that the byte immediately following the image data is always a
NUL, thereby allowing all string functions to be used when parsing
images.  Provide a "const char *text" pointer aliased to the image
data, to make it explicit that image data may always be treated as a
NUL-terminated string.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 weeks ago[xferbuf] Provide an image-backed data transfer buffer
Michael Brown [Fri, 10 Jul 2026 14:19:44 +0000 (15:19 +0100)] 
[xferbuf] Provide an image-backed data transfer buffer

Define and use a data transfer buffer that is directly backed by an
image, rather than downloading into a umalloc()-based data transfer
buffer and then transferring ownership to the image.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 weeks ago[libc] Add strchrnul()
Michael Brown [Fri, 10 Jul 2026 10:50:35 +0000 (11:50 +0100)] 
[libc] Add strchrnul()

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 weeks ago[hermon] Check for failure from pci_ioremap()
Michael Brown [Fri, 10 Jul 2026 09:35:03 +0000 (10:35 +0100)] 
[hermon] Check for failure from pci_ioremap()

Reported-by: Jaroslav Svoboda <multi.flexi@seznam.cz>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 weeks ago[tls] Retain a reference in the key schedule to the bound identity
Michael Brown [Wed, 8 Jul 2026 22:27:05 +0000 (23:27 +0100)] 
[tls] Retain a reference in the key schedule to the bound identity

Change the "bound" field from being a boolean flag to being a
reference to the server identity (i.e. the certificate) to which the
shared secret has been bound.

This reduces the chances for future bugs that could be caused by
potentially losing track of which identity has been bound, and also
provides a natural way to extend the field to be able to represent an
identity that has not yet been validated (as will be required for TLS
version 1.3 key exchange).

Add a check that the bound identity has been validated at the point of
sending our client Finished handshake.  We must defer sending the
client Finished until validation has completed, to prevent the server
from sending application traffic until we are ready to receive it, and
so this provides a natural point at which we know that the bound
identity must have been validated.

Since the validity check is now deferred until the point of sending
the client Finished, and since commit 6ba010e ("[tls] Reject incorrect
server names before completing validation") already ensures that the
certificate must have the correct name, there is no need to extract
and store the certificate's public key separately after validation has
completed.

We also update the session key (and related parameters) only if the
bound identity has been validated.  This creates an invariant that if
a server certificate is stored in the session then it is always
guaranteed to be valid, which simplifies reasoning about session
resumption flows.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 weeks ago[tls] Reject incorrect server names before completing validation
Michael Brown [Wed, 8 Jul 2026 13:44:55 +0000 (14:44 +0100)] 
[tls] Reject incorrect server names before completing validation

We currently verify the certificate name only after completing
validation of the certificate chain.  Perform this check instead at
the point of parsing the Certificate record, to create an invariant
that the recorded server certificate always has the correct name (even
if not yet validated).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 weeks ago[tls] Guard against resuming from an empty resumption master secret
Michael Brown [Wed, 8 Jul 2026 10:50:20 +0000 (11:50 +0100)] 
[tls] Guard against resuming from an empty resumption master secret

There should be no circumstance that leads to a session being resumed
without having a valid session resumption secret that was stored by a
successfully established previous connection.

As an additional layer of defence in depth, clear the "keyed" and
"bound" flags in the key schedule if it is ever resumed from an empty
session resumption secret.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 weeks ago[tls] Poison initial resumption master secret
Michael Brown [Wed, 8 Jul 2026 11:02:51 +0000 (12:02 +0100)] 
[tls] Poison initial resumption master secret

There should be no circumstance that leads to a session being resumed
without having a valid session resumption secret that was stored by a
successfully established previous connection.

As an additional layer of defence in depth, poison the initial session
resumption master secret so that a predictable all-zero secret can
never be used accidentally in future.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 weeks ago[tls] Poison initial key derivation function master secret
Michael Brown [Wed, 8 Jul 2026 10:14:50 +0000 (11:14 +0100)] 
[tls] Poison initial key derivation function master secret

A freshly initialised key derivation function master secret has the
"keyed" flag clear and so cannot accidentally be used to establish a
full TLS connection.

As an additional layer of defence in depth, poison the initial key
derivation master secret so that a predictable all-zero secret can
never be used accidentally in future.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 weeks ago[tls] Track and check key schedule state
Michael Brown [Tue, 7 Jul 2026 14:19:02 +0000 (15:19 +0100)] 
[tls] Track and check key schedule state

TLS already allows for several different paths to the establishment of
a shared secret channel.  The shared secret may be generated by the
client and encrypted using RSA key transport, or negotiated as a
Diffie-Hellman shared secret (via FFDHE or ECDHE), or mutually agreed
to be restored from a previously saved session resumption secret.

TLS version 1.3 defines several new paths to exist alongside these:
ephemeral key exchange is moved to the ClientHello and ServerHello
messages, server identity is verified using a CertificateVerify
message (instead of a signed ServerKeyExchange or an encrypted
ClientKeyExchange), and session resumption is handled via a new
pre-shared key mechanism.

While TLS version 1.3 in isolation is substantially simpler and
cleaner than earlier versions, the requirement to support both new and
old versions in the same code comes with a significant complexity
cost.

Guard against the possibility of future bugs by defining two
properties for the key schedule:

- a "keyed" flag indicating that the key schedule actually holds some
  shared secret key material (e.g. from ECDHE)

- a "bound" flag indicating that the shared secret key material in the
  key schedule has been bound to the identity represented by the
  server's certificate

These flags are updated when relevant key schedule events happen, and
validated before processing the server's Finished message.  If we
somehow end up receiving a Finished message without having established
and authenticated a shared secret, this check prevents us from marking
the connection as ready for application data.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 weeks ago[tls] Guard against a premature server Finished
Michael Brown [Mon, 6 Jul 2026 12:43:05 +0000 (13:43 +0100)] 
[tls] Guard against a premature server Finished

A malicious server that immediately sends a Finished record (without
ever having sent a ServerHello) will currently cause tls_prf() to get
stuck in an infinite loop attempting to generate pseudorandom data
using the null digest algorithm.

Fix by checking that the key schedule digest size is non-zero
(i.e. that the digest is not the null digest) before attempting to
process the Finished record.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 weeks ago[tls] Send closure alert only when we are initiating the closure
Michael Brown [Mon, 6 Jul 2026 11:14:34 +0000 (12:14 +0100)] 
[tls] Send closure alert only when we are initiating the closure

When the TLS connection is closed by the underlying socket, the
closure alert will not be able to be sent.  This currently results in
a harmless but mildly irritating error message when debugging is
enabled.

Fix by sending the closure alert only when we are actively choosing to
close the connection.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 weeks ago[tls] Handle key exchange within key schedule
Michael Brown [Mon, 6 Jul 2026 10:38:55 +0000 (11:38 +0100)] 
[tls] Handle key exchange within key schedule

Ephemeral key exchange is currently handled as part of sending the
ClientKeyExchange handshake record, with almost entirely separate
implementations for DHE and ECDHE.

Create wrappers around the underlying key exchange algorithm to handle
the TLS-specific aspects (such as padding and stripping leading zeros
for DHE), and use these for both DHE and ECDHE key exchange.

Signed-off-by: Michael Brown <mcb30@ipxe.org>