7786 Commits
Author SHA1 Message Date
Michael Brown eaf987535e [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>
2026-08-04 10:54:58 +01:00
Michael Brown 3812a69c7f [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>
2026-08-04 09:59:02 +01:00
Michael Brown 897c87a8fa [velocity] Correct direction of endianness conversion
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-08-04 08:46:24 +01:00
Michael Brown 3b06e419a9 [uhci] Add missing little-endian conversion
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-08-04 08:43:01 +01:00
Michael Brown 8cd4a0c6cd [intelxl] Add missing little-endian conversions
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-08-04 08:38:10 +01:00
Michael Brown 1e8f4fed41 [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>
2026-08-04 00:19:00 +01:00
Michael Brown 07a0d64fb6 [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>
2026-08-03 23:56:59 +01:00
Michael Brown d2df712ce5 [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>
2026-08-03 23:56:59 +01:00
Michael Brown 354a7dd7e2 [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>
2026-08-03 23:56:57 +01:00
Michael Brown 1cfaada2c3 [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>
2026-08-03 22:37:50 +01:00
Michael Brown d152ea8d98 [xen] Fix failure path in hvm_ioremap()
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-08-03 22:20:47 +01:00
Michael Brown da52150a78 [xhci] Allow for residual byte counts exceeding 64kB
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-08-03 22:04:54 +01:00
Michael Brown 24a4bff85f [intelxl] Remove wasted space in ice_magic_mac[] array
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-08-03 21:33:35 +01:00
Michael Brown 781b397ee9 [pci] Allow dumping interrupt state for arbitrary MSI-X vector numbers
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-08-03 21:27:22 +01:00
Michael Brown 8866e412b7 [spi] Fix assertion expressions
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-08-03 21:15:35 +01:00
Michael Brown ef4b2fb7b1 [doc] Add documentation of the composable error handling pattern
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-08-03 17:58:17 +01:00
Michael Brown 1475250140 [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>
2026-08-03 16:45:33 +01:00
Michael Brown 0471d6d131 [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>
2026-08-03 16:11:34 +01:00
Michael Brown 75fe3d50ce [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>
2026-08-03 15:50:34 +01:00
Michael Brown efc59a787c [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>
2026-08-03 15:23:46 +01:00
Michael Brown 79d88f3dff [srp] Avoid potential integer overflow in parsing response data
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-08-03 15:08:29 +01:00
Michael Brown d5116a1588 [fcp] Avoid potential integer overflow in parsing response data
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-08-03 13:27:16 +01:00
Michael Brown 766fa99194 [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>
2026-08-03 13:09:50 +01:00
Michael Brown 5d173b24b2 [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>
2026-08-03 12:41:34 +01:00
Michael Brown 979c86f412 [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>
2026-08-03 12:24:08 +01:00
Michael Brown 3a7e42d8e3 [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>
2026-08-03 12:11:58 +01:00
Michael Brown 832e592b90 [doc] Expand documentation for ssnprintf()
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-08-02 18:54:11 +01:00
Michael Brown 26ed5054ad [doc] Expand documentation for memory allocation
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-08-02 18:02:16 +01:00
Michael Brown 6599c15f7b [doc] Expand documentation for data transfer buffers
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-08-02 16:50:02 +01:00
Michael Brown 8ee510e69e [doc] Expand documentation for assert()
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-08-02 16:22:26 +01:00
Michael Brown e4df748edd [doc] Expand documentation for I/O buffer usage
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-08-02 15:12:13 +01:00
Michael Brown 93b84db61e [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>
2026-08-02 14:03:59 +01:00
Michael Brown 3c5f8b9297 [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>
2026-08-02 13:14:47 +01:00
Michael Brown 1eef1a80e6 [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>
2026-08-02 13:14:27 +01:00
Michael Brown 9f3ebb9ac6 [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>
2026-08-02 12:29:01 +01:00
Michael Brown 9dcedc175f [iscsi] Reject SCSI PDUs received when no command is in progress
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-08-02 09:07:28 +01:00
Michael Brown 400920db3b [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>
2026-08-01 23:46:44 +01:00
Michael Brown dc84a9779a [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>
2026-08-01 22:31:59 +01:00
Michael Brown 9f7e0c97cb [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>
2026-08-01 20:49:18 +01:00
Michael Brown 874cbd9f58 [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>
2026-08-01 19:14:14 +01:00
Michael Brown 404588d5f7 [doc] Provide overview of ASN.1 parsing helper functions
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-07-30 21:37:16 +01:00
Michael Brown 8d3cbb25da [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>
2026-07-30 17:47:02 +01:00
Michael Brown 18dd4483ce [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>
2026-07-30 16:58:52 +01:00
Michael Brown 48c04ec047 [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>
2026-07-30 14:59:33 +01:00
Michael Brown 12fd767594 [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>
2026-07-30 14:24:47 +01:00
Michael Brown de43024908 [bitmap] Allow bitmap_set() to report an error
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-07-30 13:49:31 +01:00
Michael Brown 678f84ff3a [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>
2026-07-30 12:44:40 +01:00
Michael Brown fa779b1bce [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>
2026-07-30 10:27:01 +01:00
Michael Brown 08c989f364 [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>
2026-07-29 17:45:43 +01:00
Michael Brown 9c70e9b27e [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>
2026-07-29 11:25:28 +01:00