summaryrefslogtreecommitdiff
path: root/boot
AgeCommit message (Collapse)Author
5 daysboot: image-fdt: Restore suppression of irrelevant ERROR messageJonas Karlman
The commit 623f6c5b6ab7 ("boot: image-fdt: free old dtb reservations") removed the suppression of ERROR messages when -EINVAL was returned due to the memory region not being part of the LMB memory map. This causes an irrelevant ERROR message during boot, e.g.: Model: Radxa ROCK 3B [...] ERROR: reserving fdt memory region failed (addr=10f000 size=100 flags=2): -22 or Model: Rockchip RK3288 Asus Tinker Board S [...] ERROR: reserving fdt memory region failed (addr=fe000000 size=1000000 flags=4): -22 FDT correctly contains reserved-memory for 10f000 or fe000000 and U-Boot correctly does not make these regions available in the LMB memory map: memory[0] [0x200000-0xefffffff], 0xefe00000 bytes, flags: none memory[1] [0x100000000-0x1ffffffff], 0x100000000 bytes, flags: none or memory[0] [0x0-0x7fffffff], 0x80000000 bytes, flags: none With lmb_alloc_mem() and lmb_free() both returning -EFAULT when the requested memory region is not part of the LMB memory map it should be safe to ignore these errors when FDT memreserve and reserved-memory is being processed. Print -EFAULT errors using a debug message to restore suppression of this irrelevant ERROR message when memory region is not part of the LMB memory map. Fixes: 623f6c5b6ab7 ("boot: image-fdt: free old dtb reservations") Signed-off-by: Jonas Karlman <[email protected]> Reviewed-by: Randolph Sapp <[email protected]>
2026-08-12bootstd: android: bound the boot image read by its partition sizeShahriyar Jalayeri
read_slotted_partition() loads an Android boot/vendor_boot image into the load address, sizing the read from the image header: num_blks = DIV_ROUND_UP(image_size, desc->blksz); ... blk_dread(desc, partition.start, num_blks, map_sysmem(addr, 0)); image_size is priv->boot_img_size / priv->vendor_boot_img_size, taken from the boot image header and never bounded by the partition. A header claiming a size larger than the partition makes blk_dread read past the partition and write past the load buffer: an out-of-bounds write of attacker-controlled length on media a physical attacker can supply. It is reached during boot on a device where AVB does not gate the read (AVB disabled, or an unlocked device). Reject an image that does not fit in its partition before issuing the read. Both the boot and vendor_boot reads go through this function. Fixes: abadcda24b10 ("bootstd: android: don't read whole partition sizes") Signed-off-by: Shahriyar Jalayeri <[email protected]> Reviewed-by: Simon Glass <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Mattijs Korpershoek <[email protected]>
2026-08-10bootretry: only reinitialize retry_time when bootretry env variable has been ↵Rasmus Villemoes
touched Commit aa5ef3c0a752 ("bootretry: check for bootretry variable changes") broke the feature where one can define different keys for "delaying" versus "stopping" boot. The way the latter is implemented is by the code in autoboot.c calling bootretry_dont_retry() when the stop sequence has been detected, and that simply sets the retry_time variable in bootretry.c to -1. However, with the mentioned commit, that is unconditionally overridden on every command, since it gets re-initialized from either the bootretry environment variable or CONFIG_BOOT_RETRY_TIME, thus making "delay" and "stop" effectively the same. To fix that, while still picking up changes to the bootretry environment variable, use the proper mechanism for C code to be notified about changes to environment variables. Since the callback is invoked before the change has actually been done to the environment (callbacks can reject the change from taking effect), we cannot simply call the existing bootretry_init_cmd_timeout() from the callback, as its env_get() would not see the new value. Instead, refactor most of it to an internal bootretry_parse(), and call that with the new value (which is NULL in the case bootretry is being deleted, so that works exactly as it should). Signed-off-by: Rasmus Villemoes <[email protected]>
2026-08-10Merge patch series "boot: fit: authenticate the dm-verity roothash"Tom Rini
Daniel Golle <[email protected]> says: A signed FIT configuration can delegate the integrity of a (potentially large) root filesystem image to the kernel's dm-verity instead of having U-Boot hash the whole payload at boot: the FIT carries a "dm-verity" subnode with the roothash, salt and block parameters, U-Boot passes the roothash to Linux through the dm-mod.create bootargs, and dm-verity then validates the filesystem block by block against it. For that to be safe the roothash has to be trusted, and in a signed configuration the only thing that establishes trust is the configuration signature. The roothash was not covered by it. fit_config_add_hash() collected the image node, its hash subnodes and its cipher subnode into the signed region, but not the dm-verity subnode, so the roothash, the sole integrity anchor for the filesystem, was left unsigned. The result is a verified-boot bypass for the root filesystem: an attacker who can rewrite the boot medium can replace the filesystem, recompute a matching dm-verity tree, write the new roothash into the unsigned dm-verity subnode, and the configuration signature still verifies. dm-verity then faithfully validates the malicious filesystem against the attacker's roothash. This series closes the gap. Link: https://lore.kernel.org/r/[email protected]
2026-08-10test: fit: verify dm-verity roothash is covered by the config signatureDaniel Golle
A dm-verity protected filesystem image is not hashed by U-Boot; its integrity is delegated to the kernel, which trusts the roothash taken from the FIT dm-verity subnode. For that chain of trust to hold, the roothash (and salt) must be part of the region covered by the configuration signature, otherwise an attacker can replace both the filesystem and the roothash while keeping the signature valid. Add two independent checks of this property: - test/py/tests/test_fit_verity_sign.py signs a configuration that references a filesystem image carrying a dm-verity subnode, then confirms that tampering the roothash or the salt is rejected by fit_check_sign. A control that tampers a byte known to be signed proves the check can fail. A matching page is added under doc/develop/pytest/ so the module documentation is rendered with the rest of the generated docs. - test/boot/fit_verity.c gains a runtime unit test that builds the exact node list the configuration signature is computed over, turns it into hashed regions and checks both that the roothash bytes fall inside a signed region and that tampering them changes the hash. It needs no private key, so it also runs on real devices and uses the same hash path a device would. To let the unit test build the signed-region node list, rename the config node-list helper to fit_config_get_signed_nodes(), make it non-static and declare it in image.h. Signed-off-by: Daniel Golle <[email protected]> Reviewed-by: Simon Glass <[email protected]>
2026-08-10boot: fit: cover the dm-verity roothash with the config signatureDaniel Golle
A dm-verity protected filesystem image is not hashed by U-Boot when it is loaded; its integrity is delegated to the kernel, which validates the filesystem on the fly against the roothash taken from the FIT dm-verity subnode. The roothash is therefore the sole integrity anchor for the filesystem, yet fit_config_add_hash() only adds the image node, its hash subnodes and its cipher subnode to the signed region, leaving the dm-verity subnode (roothash, salt and block parameters) unsigned. An attacker able to rewrite the boot medium could then replace both the filesystem and the roothash, recompute a matching dm-verity tree and keep the configuration signature valid, defeating verified boot for the root filesystem. Add the dm-verity subnode to the list of nodes covered by the configuration signature, both when signing (tools/image-host.c) and when verifying (boot/image-fit-sig.c), so the roothash and salt are authenticated together with the rest of the configuration. Signed-off-by: Daniel Golle <[email protected]> Reviewed-by: Tom Rini <[email protected]> Reviewed-by: Simon Glass <[email protected]>
2026-08-10boot: fit: factor out node-path collection in fit_config_add_hash()Daniel Golle
Both the boot-side and host-side fit_config_add_hash() repeat the same sequence to append a node's path to the hashed-node list three times: for the image node, for each hash subnode and for the cipher subnode. Extract it into a helper, fit_config_add_node(), in each file, with no functional change. Signed-off-by: Daniel Golle <[email protected]> Reviewed-by: Tom Rini <[email protected]> Reviewed-by: Simon Glass <[email protected]>
2026-07-28Merge tag 'u-boot-dfu-20260728' of ↵Tom Rini
https://git.u-boot-project.org/u-boot/custodians/u-boot-dfu u-boot-dfu-20260728 CI: https://git.u-boot-project.org/u-boot/custodians/u-boot-dfu/-/pipelines/769 Android: * avb: Update libavb to AOSP 1.3.0 * avb: Fix memory leak on mmc_part * bootmeth_android: Fix memory leaks for AvbOps and verify-data * bootmeth_android: Fix out-of-bounds access in bootconfig parsing USB Gadget: * cmd: ums: Set serial# on iSerial device descriptor * dwc2: Set maxpacket_limit and endpoint capabilities to prepare for udc core migration * ci_udc: Fix ep type in ep_enable() * ci_udc: Set usb request status to handle complete callback * ci_udc: Ensure dtds are inactive before completing request
2026-07-24fit: prefer the default configuration on best-match tiesCarlo Caione
With CONFIG_FIT_BEST_MATCH, fit_conf_find_compat() selects the configuration matching the most specific U-Boot compatible string; on equal matches the first listed configuration wins and the configurations node 'default' property is never consulted. A FIT whose configurations all share the same base devicetree compatible (e.g. one manifest carrying a base tree plus overlay combinations for a single board) therefore always boots the first configuration, silently ignoring the default chosen by the manifest author. Break score ties in favour of the default configuration. A strictly better compatible match still wins over it, and FITs without a default keep the current first-listed behaviour. Reviewed-by: Simon Glass <[email protected]> Reviewed-by: Tom Rini <[email protected]> Signed-off-by: Carlo Caione <[email protected]>
2026-07-24boot: android: fix AvbOps and verify-data leaks in AVB pathIgor Opaniuk
run_avb_verification() allocates an AvbOps via avb_ops_alloc() but never frees it on any return path. Every Android boot attempt therefore leaks the AvbOpsData structure and, when CONFIG_OPTEE_TA_AVB is enabled, leaves the OP-TEE session open (it is only closed inside avb_ops_free()). In addition, the AvbSlotVerifyData returned by avb_slot_verify() is only released on the failure branches. The successful "return 0" paths (both the locked GREEN/OK case and the unlocked ORANGE/ERROR_VERIFICATION case) return without freeing it, leaking the whole out_data (cmdline and loaded partition metadata) on every good boot. Route all exit paths through a single cleanup label that frees both out_data and avb_ops. Fixes: 125d9f3306ea ("bootstd: Add a bootmeth for Android") Signed-off-by: Igor Opaniuk <[email protected]> Reviewed-by: Mattijs Korpershoek <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Mattijs Korpershoek <[email protected]>
2026-07-23bootm: teach handle_decomp_error() about the noload decompression bufferAristo Chen
For a compressed kernel_noload image, bootm_load_os() allocates a per-image decompression buffer of ALIGN(image_len * 8, SZ_1M) rather than the global CONFIG_SYS_BOOTM_LEN. When decompression fails on that path, handle_decomp_error() still prints Image too large: increase CONFIG_SYS_BOOTM_LEN which is misleading: increasing CONFIG_SYS_BOOTM_LEN does not help because the smaller per-image buffer is the actual bound. Commit 2ff26c1e378d ("bootm: fix overflow of the noload kernel decompression buffer") worked around this by printing a follow-up note right after handle_decomp_error() returned, but the boot log then reads as two contradictory sentences. Introduce enum bootm_decomp_limit and pass it into handle_decomp_error() so the helper picks the right message in one place. For the per-image path it now prints Image too large for the per-image decompression buffer (0x100000 bytes) quoting the actual buffer size; the global path is unchanged. Drop the trailing note in bootm_load_os() so only one line is printed. Suggested-by: Simon Glass <[email protected]> Signed-off-by: Aristo Chen <[email protected]> Reviewed-by: Tom Rini <[email protected]> Reviewed-by: Simon Glass <[email protected]>
2026-07-22boot: android: fix out-of-bounds access in bootconfig parsingAlexey Charkov
When android_image_get_vendor_bootimg_size is called, its buffer is only allocated with enough space for the bootconfig header, but the android_vendor_boot_image_v3_v4_parse_hdr helper attempts to append a bootconfig trailer to it, causing an out-of-bounds access and heap corruption in some cases (e.g. triggered in sandbox test builds when extra bootmeths are added, resulting in a segfault of the sandbox process). Skip the dangerous memcpy operations altogether when the android_vendor_boot_image_v3_v4_parse_hdr helper is only called for size calculation purposes, and only append the bootconfig trailer when called from the actual bootconfig parsing code path. Fixes: 57e405e1f474 ("android: boot: support bootconfig") Signed-off-by: Alexey Charkov <[email protected]> Reviewed-by: Simon Glass <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Mattijs Korpershoek <[email protected]>
2026-07-16Merge patch series "vbe: bound FIT external-data reads against the firmware ↵Tom Rini
area" Aristo Chen <[email protected]> says: vbe_read_fit() loads a firmware-phase FIT from a fixed firmware area on a block device and then issues a follow-up blk_read() to pull in the image, and optionally an FDT, referenced by the FIT's image node. The source offset on the device and the read length both come from the FIT itself, via data-position or data-offset and data-size. Those properties live on mutable boot media and can be controlled by an attacker with write access to the firmware area. On the TPL or VPL path, and on the bootmeth bootflow path reached via abrec_read_bootflow_fw() and vbe_simple_read_bootflow_fw(), the follow-up blk_read() runs before any signature or hash check on the loaded phase. Patch 1 is a sandbox test-tree preparation. The firmware1 node in arch/sandbox/dts/test.dts declared area-size = 0xe00000 (14 MiB), but the binman fw-update section in sandbox_vpl.dtsi is 32 MiB and the FIT inside it carries ~16 MiB of external data, so the FIT already extended past the declared area. The mismatch was tolerated because no caller bounded the external-data load against area_size. Patch 1 raises area-size to match the binman section size so test_vbe_vpl keeps passing once the bound is enforced. The patches are ordered so the test is never broken in the middle of the series. Patch 2 adds the missing range check, confining the FIT-supplied [load_addr, load_addr + len) window to [addr, addr + area_size] before block numbers and lengths are computed, and applying the same constraint to fdt_load_addr and fdt_size. The check is written in subtraction-only form against the trusted area_size so the comparison cannot itself overflow. Patch 3 adds two sandbox unit tests under test/boot/ that construct synthetic FITs with out-of-range data-position and oversized data-size, write them to mmc1, and confirm vbe_read_fit() returns -E2BIG for each before issuing the follow-up blk_read(). Deferring the external-data blk_read() until after the phase has been signature-verified would be a stronger structural fix and was discussed on the v1 thread. Simon confirmed the bounded read is the right first step and that the verify-then-load change should be a separate series, so this v3 stays scoped to the bound. Link: https://lore.kernel.org/r/[email protected]
2026-07-16vbe: bound FIT external-data offset and size before blk_readAristo Chen
vbe_read_fit() loads a firmware-phase FIT from the trusted firmware area and then issues a blk_read() to pull in the image, and optionally an FDT, referenced by the FIT image node. The source offset on the device and the read length both come from the FIT's data-position or data-offset property and its data-size property, which live on mutable boot media and can be controlled by an attacker with prior write access to the firmware area. Without a range check the resulting blk_read() can read past the firmware area on the device and, on the non-SPL path, write an attacker-chosen number of blocks past the malloc(aligned_size) FIT buffer into adjacent memory. Only the SPL branch routes through spl_load_simple_fit(), which hashes the data. The external-data block reached from TPL or VPL, and from the bootflow path via abrec_read_bootflow_fw() and vbe_simple_read_bootflow_fw(), runs before any signature or hash check on the loaded phase. Confine the FIT-supplied [load_addr, load_addr + len) window to [addr, addr + area_size] before computing block numbers and lengths, and apply the same constraint to fdt_load_addr and fdt_size. The checks are written in subtraction-only form against the trusted area_size so the comparison itself cannot overflow. Reviewed-by: Simon Glass <[email protected]> Signed-off-by: Aristo Chen <[email protected]>
2026-07-13cmd: fdt: keep control FDT during checksignJames Hilliard
The fdt checksign command accepts an optional address for an FDT containing public keys. It currently installs that blob as gd->fdt_blob before verifying the FIT configuration. This breaks verification with DM-backed crypto drivers which have not probed yet, since the later probe path expects gd->fdt_blob to remain U-Boot's control FDT. For example, an ECDSA verifier can be bound from the control FDT but fail to probe after fdt checksign points gd->fdt_blob at the key-only DTB. Add a FIT config verification helper that takes the key blob explicitly and use it from fdt checksign. This keeps gd->fdt_blob unchanged while still allowing the command to verify against an external key DTB. Signed-off-by: James Hilliard <[email protected]>
2026-07-03bootdev: scan boot devices at each priority levelDenis Mukhin
Currently, default 'bootflow scan -lb' will stop booting the board if any of higher-priority bootdevs fail to be hunted even if there are bootdevs of lower priority. For example, if the board has both NVMe (priority 4) and USB MSD devices (priority 5), and if NVMe bootdev hunt fails (in the event of a bad NVMe firmware update), USB (which may be a recovery bootdev) is never hunted automatically, leaving the board at the U-Boot prompt (user intervention is needed, e.g. something like 'bootflow scan usb' to hunt USB). Fix bootdev_next_prio() to scan bootdevs at the lower priority level by not exiting the scan loop early. Keep the existing logging verbosity unchanged and rely on the failing subsystem to provide a suitable diagnostic message. Signed-off-by: Denis Mukhin <[email protected]> Reviewed-by: Simon Glass <[email protected]>
2026-07-03Merge patch series "bootm: fix flush_cache() with IH_TYPE_KERNEL_NOLOAD"Tom Rini
This patch series from Nora Schiffer <[email protected]> addresses a few issues with correctly handling IH_TYPE_KERNEL_NOLOAD in a few cases. Link: https://lore.kernel.org/r/[email protected]
2026-07-03bootm: allow omitting entry point for IH_TYPE_KERNEL_NOLOADNora Schiffer
For IH_TYPE_KERNEL_NOLOAD, the entry point is given relative to the image start, making 0 a valid default, and for IH_OS_EFI, it is ignored altogether, so it may be preferable to omit it. Signed-off-by: Nora Schiffer <[email protected]> Reviewed-by: Simon Glass <[email protected]>
2026-07-03bootm: warn about load address for IH_TYPE_KERNEL_NOLOAD in FITNora Schiffer
The load address is ignored for IH_TYPE_KERNEL_NOLOAD. Instead of failing the boot when none is set, it makes more sense to warn when it *is* set. Signed-off-by: Nora Schiffer <[email protected]> Reviewed-by: Simon Glass <[email protected]>
2026-07-03bootm: fix flush_cache() with IH_TYPE_KERNEL_NOLOADNora Schiffer
`flush_start` must be set after `load` has been assigned. Fixes: 69544c4fd8b1 ("bootm: Support kernel_noload with compression") Signed-off-by: Nora Schiffer <[email protected]> Reviewed-by: Simon Glass <[email protected]>
2026-07-01bootm: move OS index bound check into the legacy pathAristo Chen
Commit 103b1e7ce8cc ("bootm: bound-check OS index in bootm_os_get_boot_func()") added a range check to the shared accessor so an out-of-range OS id can no longer drive an out-of-bounds read of boot_os[]. That accessor is reached by every image format, but only a legacy uImage can deliver an unchecked value. bootm_find_os() takes the raw 8-bit ih_os byte straight from image_get_os() for legacy images, whereas the FIT path reaches the accessor only after fit_image_load() has rejected any image whose os is not one of the supported types, and the Android path hardcodes IH_OS_LINUX. The check can therefore never fail for FIT, where it only adds confusion and code. Move the test to the legacy branch of bootm_find_os(), rejecting an out-of-range OS where the untrusted byte enters. This keeps the FIT path clear and lets the check be compiled out when CONFIG_LEGACY_IMAGE_FORMAT is disabled. A valid OS id that has no handler is still reported by the existing NULL return path in bootm_run_states(). Suggested-by: Simon Glass <[email protected]> Signed-off-by: Aristo Chen <[email protected]> Reviewed-by: Simon Glass <[email protected]>
2026-06-25Kconfig: boot: restyleJohan Jonker
Restyle all Kconfigs for "boot": Menu entries : no space left Menu attributes: 1 TAB Help text : 1 TAB + 2 spaces Replace '---help---' by 'help' Signed-off-by: Johan Jonker <[email protected]>
2026-06-24treewide: move bi_dram[] from bd to gdIlias Apalodimas
Currently, the bi_dram[] information is stored in the board info structure (bd). Because bd is only valid after reserve_board(), dram_init_banksize() must be called late in the initialization process. This limitation is problematic, as it forces us to rely on a variety of bespoke functions to determine board RAM, bank memory sizes, and other early setup requirements. By moving bi_dram[] into the global data (gd), we can run it earlier. This is particularly convenient since boards define their own dram_init_banksize() routines, which do not always rely on parsing Device Tree (DT) memory nodes. Additionally, U-Boot defaults to relocating to the top of the first memory bank. While boards currently use custom functions to override this behavior, having the DRAM bank information available earlier in gd makes relocating to a different bank trivial and standardizes the process. Reviewed-by: Anshul Dalal <[email protected]> Tested-by: Michal Simek <[email protected]> # Versal Gen 2 Vek385 Tested-by: Anshul Dalal <[email protected]> Reviewed-by: Simon Glass <[email protected]> Signed-off-by: Ilias Apalodimas <[email protected]> Tested-by: Christophe Leroy (CS GROUP) <[email protected]>
2026-06-22Merge tag 'v2026.07-rc5' into nextTom Rini
Prepare v2026.07-rc5
2026-06-17Merge patch series "Fixes, cleanup and a test for the SPL FIT "full" loader"Tom Rini
Francesco Valla <[email protected]> says: This patch set contains a collection of small fixes and cleanups for the "full" FIT loader that can be used for the SPL. The main beneficiary is the falcon boot flow, but the same loader can be used also for U-Boot proper. Patch 1 was part of another set, but I decided to put it here for a better separation between plumbing (here) and new features (there). I kept the Reviewed-by tag collected from Simon in that occasion. Patch 6 introduces a new unit test covering most of the code that is being cleaned up. The set was tested on a i.MX93 FRDM, both with and without signature and to boot both U-Boot proper and the Linux kernel directly (i.e., falcon boot). Link: https://lore.kernel.org/r/[email protected]
2026-06-17boot: fit: fix FIT verification in SPLFrancesco Valla
Align the behavior of fit_image_verify() called in SPL to the one in full U-Boot. In particular, this function is called when both CONFIG_SPL_LOAD_FIT_FULL and CONFIG_SPL_FIT_SIGNATURE are set (which can happen e.g. in case of secure falcon boot). Reviewed-by: Simon Glass <[email protected]> Signed-off-by: Francesco Valla <[email protected]>
2026-06-17bootm: increase kernel_noload decompression headroom from 4x to 8xAristo Chen
For a compressed kernel_noload image, bootm_load_os() allocates a buffer of ALIGN(image_len * 4, SZ_1M). The 4x factor is at the edge of what modern compressors (zstd, xz) achieve on real kernels, so a well-compressed vendor kernel can fail to boot at runtime with no intervening warning. Bump the headroom to 8x. The buffer is still bounded by the compressed image size, and the SZ_1M alignment keeps the overhead below 1 MiB on small kernels. Suggested-by: Simon Glass <[email protected]> Signed-off-by: Aristo Chen <[email protected]>
2026-06-17bootm: fix overflow of the noload kernel decompression bufferAristo Chen
For a compressed kernel_noload image, bootm_load_os() allocates a decompression buffer sized to ALIGN(image_len * 4, SZ_1M), assuming the kernel compresses by no more than a factor of four. It then passes CONFIG_SYS_BOOTM_LEN, rather than the size of that buffer, to image_decomp() as the output limit. The decompressors honour the limit they are given, so a kernel that decompresses to more than four times its compressed size is written past the end of the allocated buffer and corrupts adjacent memory. Pass the allocation size to image_decomp() and handle_decomp_error() so decompression stops at the buffer boundary and fails cleanly when the image is too large, instead of overflowing. The regular non-noload paths are unchanged and continue to use CONFIG_SYS_BOOTM_LEN. When the failure is triggered by the smaller per-image buffer, print a note so that handle_decomp_error()'s generic advice to increase CONFIG_SYS_BOOTM_LEN does not mislead the reader. Fixes: 69544c4fd8b1 ("bootm: Support kernel_noload with compression") Reviewed-by: Simon Glass <[email protected]> Signed-off-by: Aristo Chen <[email protected]>
2026-06-17Merge patch series "bootm: bound noload kernel decompression to the ↵Tom Rini
allocated buffer" Aristo Chen <[email protected]> says: For a compressed kernel_noload image, bootm_load_os() allocates a decompression buffer of ALIGN(image_len * 4, SZ_1M) and then passes CONFIG_SYS_BOOTM_LEN (typically 128 MiB on arm64) to image_decomp() as the output limit. The decompressors honour whatever limit they are given, so a kernel that decompresses to more than four times its compressed size runs past the end of the allocated buffer and silently corrupts adjacent memory. A 4x compression ratio is at the edge of what modern compressors (zstd, xz) achieve on real kernels, and is trivially exceeded by crafted, highly compressible payloads, so this is reachable both accidentally and intentionally. The overflow can land on already-loaded boot artefacts (FDT, ramdisk, loadables), U-Boot's own data, or memory-mapped device registers; the existing post-decompression overlap check in bootm_load_os() only catches overlap with the FIT itself. Patch 1 plumbs the actual allocation size through to image_decomp() and handle_decomp_error() via a single decomp_len variable, so decompression stops at the buffer boundary and fails cleanly when the image is too large. The non-noload code path is unchanged and continues to use CONFIG_SYS_BOOTM_LEN. A clarifying note is printed when the failure is gated by the per-image buffer, so the generic "increase CONFIG_SYS_BOOTM_LEN" advice does not mislead. Patch 2 raises the noload-decompression headroom from 4x to 8x. The 4x factor is at the edge of what zstd and xz achieve on real kernels, so well-compressed vendor kernels can fail to boot at runtime once the bound is enforced. 8x covers them comfortably while remaining bounded. Patch 3 adds two sandbox py-tests against the per-image buffer at the final 8x value: one that exceeds the buffer and must be rejected, and one that matches the buffer exactly and must succeed (guarding the boundary). Tested on sandbox: both new tests pass; the existing test_fit_compressed_images_load (which covers the load-address path) and the other tests in test/py/tests/test_fit.py continue to pass. Link: https://lore.kernel.org/r/[email protected]
2026-06-17bootm: increase kernel_noload decompression headroom from 4x to 8xAristo Chen
For a compressed kernel_noload image, bootm_load_os() allocates a buffer of ALIGN(image_len * 4, SZ_1M). The 4x factor is at the edge of what modern compressors (zstd, xz) achieve on real kernels, so a well-compressed vendor kernel can fail to boot at runtime with no intervening warning. Bump the headroom to 8x. The buffer is still bounded by the compressed image size, and the SZ_1M alignment keeps the overhead below 1 MiB on small kernels. Suggested-by: Simon Glass <[email protected]> Signed-off-by: Aristo Chen <[email protected]>
2026-06-17bootm: fix overflow of the noload kernel decompression bufferAristo Chen
For a compressed kernel_noload image, bootm_load_os() allocates a decompression buffer sized to ALIGN(image_len * 4, SZ_1M), assuming the kernel compresses by no more than a factor of four. It then passes CONFIG_SYS_BOOTM_LEN, rather than the size of that buffer, to image_decomp() as the output limit. The decompressors honour the limit they are given, so a kernel that decompresses to more than four times its compressed size is written past the end of the allocated buffer and corrupts adjacent memory. Pass the allocation size to image_decomp() and handle_decomp_error() so decompression stops at the buffer boundary and fails cleanly when the image is too large, instead of overflowing. The regular non-noload paths are unchanged and continue to use CONFIG_SYS_BOOTM_LEN. When the failure is triggered by the smaller per-image buffer, print a note so that handle_decomp_error()'s generic advice to increase CONFIG_SYS_BOOTM_LEN does not mislead the reader. Fixes: 69544c4fd8b1 ("bootm: Support kernel_noload with compression") Reviewed-by: Simon Glass <[email protected]> Signed-off-by: Aristo Chen <[email protected]>
2026-06-15Merge patch series "various memory related fixups"Tom Rini
[email protected] <[email protected]> says: From: Randolph Sapp <[email protected]> Nitpicks and fixes from the discovery thread on adding PocketBeagle2 support [1]. This does a lot of general setup required for the device, but these modifications themselves aren't device specific. For those specifically interested in PocketBeagle2 support and don't care about these details, my development branch is public [2]. That first patch may provoke some opinions, but honestly if that warning was still present I wouldn't have spent a week poking holes in both the EFI and LMB allocations systems. Please let me know if there is a specific usecase that it breaks though. [1] https://lore.kernel.org/all/[email protected]/ [2] https://github.com/StaticRocket/u-boot/tree/feature/pocketbeagle2 Link: https://lore.kernel.org/r/[email protected]
2026-06-15boot: image-fdt: free old dtb reservationsRandolph Sapp
Add a free flag and an initial call to free allocations covered by the global FDT. This assumes that all calls to boot_fdt_add_mem_rsv_regions occur before the transition to the new device tree, thus we can access the currently active device tree through the global data pointer. This allows us to clearly indicate to the user when a device tree reservation fails. How we handle this can still use some improvement. Right now we'll keep the default behavior and try to boot anyway. Fixes: 5a6aa7d5913 ("boot: fdt: Handle already reserved memory in boot_fdt_reserve_region()") Signed-off-by: Randolph Sapp <[email protected]> Acked-by: Ilias Apalodimas <[email protected]> Reviewed-by: Simon Glass <[email protected]> Fixes: tag with a 12-char hash: Fixes: 5a6aa7d59133 ("boot: fdt: Handle already reserved memory in
2026-06-15android_ab: fix slot selectionColin Pinnell McAllister
The boot selection rules state that a slot is bootable if it is not corrupted and either has tries remaining or has already booted successfully. However, slots that have tries_remaining == 0 and successful_boot == 1 will be disregarded when picking the slot to attempt. Updates the selection logic so slots marked successful remain eligible even when their tries counter is zero. Debug message now also includes the successful_boot value. Signed-off-by: Colin Pinnell McAllister <[email protected]> Reviewed-by: Mattijs Korpershoek <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Mattijs Korpershoek <[email protected]>
2026-06-13fdt: Check return value of fdt_get_name() callsAnton Ivanov
fdt_get_name() can return NULL and set len to a negative error code. fdt_find_regions() does not check for this, leading to a potential NULL pointer dereference and a buffer out-of-bounds write during signature verification of an untrusted FIT. fdt_next_region(), fdt_check_full(), and display_fdt_by_regions() also lack validation. Add NULL checks and propagate the error code from fdt_get_name() to the caller. Signed-off-by: Anton Ivanov <[email protected]> Reviewed-by: Simon Glass <[email protected]>
2026-06-12image-fit: Validate external data offset and sizeAnton Ivanov
fit_image_get_data() uses the data-position, data-offset, and data-size FIT properties without bounds checking. A crafted FIT image can specify values that cause out-of-bounds read during signature verification of an untrusted FIT. Validate that the external data offset and size are non-negative, and that the data region fits within the FIT image bounds. Signed-off-by: Anton Ivanov <[email protected]> Reviewed-by: Simon Glass <[email protected]>
2026-06-12image-fit: Limit recursion depth in fdt_check_no_at()Anton Ivanov
fdt_check_no_at() recurses into every subnode without a depth limit. A deeply nested FIT image can exhaust the stack and crash U-Boot during signature verification of an untrusted FIT. Add a depth check using FDT_MAX_DEPTH to bound the recursion. Signed-off-by: Anton Ivanov <[email protected]>
2026-06-12fdt_region: Check return value of fdt_get_property_by_offset() callsAnton Ivanov
fdt_get_property_by_offset() returns NULL for FDT with version less than 0x10. fdt_find_regions() dereferences the result without checking, leading to a NULL pointer dereference during signature verification of an untrusted FIT. fdt_add_alias_regions() and fdt_next_region() also lack validation. Add NULL checks before accessing the returned property pointer. Also add a missing NULL check for fdt_string() in fdt_add_alias_regions() and fdt_next_region(). Signed-off-by: Anton Ivanov <[email protected]>
2026-06-12image-fit-sig: Validate hashed-strings region sizeAnton Ivanov
fit_config_check_sig() reads the hashed-strings property and uses its size value without validation when building the region list for signature verification. A crafted FIT image can specify an arbitrary size, causing the hash calculation to read beyond the end of the FIT image. The property length is also not checked, so a truncated hashed-strings property causes strings[1] to be read past the end of the property. This may result in the out-of-bounds read during signature verification of an untrusted FIT. Validate both the property length and that the declared strings region fits within bounds before adding it to the region list. Signed-off-by: Anton Ivanov <[email protected]>
2026-06-11Merge patch series "fdt_support: validate property lengths in chosen and ↵Tom Rini
dma-range fixups" Aristo Chen <[email protected]> says: boot/fdt_support.c contains a number of helpers that fix up the kernel devicetree handed to the OS during bootm/booti. Several of those helpers consume fdt_getprop() results without validating the returned length against the per-entry size implied by the surrounding cell-count arithmetic. When the OS devicetree is not signature-verified, for example an unsigned FIT, a DT loaded from $fdtaddr or $fdtcontroladdr, or a DT supplied over a network boot, the property is attacker-influenced and the missing checks turn into out-of-bounds reads or writes on the FDT blob and on stack buffers. The first patch targets fdt_fixup_stdout(). The function copies the value of /aliases/serialN into a fixed 256-byte stack buffer before publishing it as /chosen/linux,stdout-path, but does not check that the property fits. The patch rejects an oversized property with a debug-only message and -FDT_ERR_NOSPACE so the unbounded memcpy cannot run. The second patch addresses fdt_get_dma_range(). The function reads one full dma-ranges entry of (na + pna + ns) * sizeof(u32) bytes after checking only that the returned length is non-zero. A dma-ranges property shorter than one entry causes the subsequent fdt_read_number() and fdt_translate_dma_address() calls to read past the property within the FDT blob. The patch validates the length against one full entry and returns -EINVAL when the property is too short, matching the existing failure paths in this function. Both rejection paths use debug() rather than printf() so production builds do not pay any .text or .rodata growth for the new diagnostic text. Measured against master on real cross-compiled targets, the v1 printf form added 88 bytes of .text on CMPCPRO_defconfig (which links the fdt_fixup_stdout check) and 119 bytes on rpi_arm64_defconfig (which links fdt_get_dma_range). The v2 debug form adds 0 bytes on CMPCPRO and 20 bytes on rpi_arm64; the 20-byte residual is the length-check branch itself, not the diagnostic. Build tested with kontron_sl28_defconfig (aarch64), CMPCPRO_defconfig (powerpc, which enables both CONFIG_OF_STDOUT_VIA_ALIAS and CONFIG_CONS_INDEX and therefore links the new bounds check in fdt_fixup_stdout), rpi_arm64_defconfig (aarch64, links fdt_get_dma_range) and sandbox_defconfig. All builds are clean and scripts/checkpatch.pl reports no errors, warnings, or checks on either patch. Link: https://lore.kernel.org/r/[email protected]
2026-06-11fdt_support: validate dma-ranges length in fdt_get_dma_rangeAristo Chen
fdt_get_dma_range() fetches the dma-ranges property with fdt_getprop() and checks only that the length is non-zero before reading one full entry from it. The entry size depends on na, pna and ns cells returned by count_cells, which come from the parent buses in the devicetree. A dma-ranges property shorter than (na + pna + ns) * sizeof(u32) bytes causes fdt_read_number() and fdt_translate_dma_address() to read past the end of the property within the FDT blob, an out-of-bounds read of attacker-influenced data when the OS devicetree is not signature verified. Reject the property when its length is smaller than one full entry and return -EINVAL, matching the existing failure paths in this function. Use debug() rather than printf() for the rejection text so that production builds do not pay any .text or .rodata growth for the new diagnostic. Signed-off-by: Aristo Chen <[email protected]>
2026-06-11fdt_support: bound serialN alias length before copying to stackAristo Chen
fdt_fixup_stdout() reads the path stored in /aliases/serialN with fdt_getprop() and then memcpys it into a fixed 256-byte stack buffer. The length returned by libfdt is the raw on-disk property size and is not bounded by any console-path convention, so an oversized property in a malformed or untrusted devicetree overflows the buffer with attacker-controlled length and contents. The "/* long enough */" comment next to tmp[] codifies an unchecked assumption. Reject lengths that exceed sizeof(tmp) with a debug-only message and return -FDT_ERR_NOSPACE. The fixup runs during fdt_chosen() on every booted kernel when CONFIG_OF_STDOUT_VIA_ALIAS is enabled, and when the OS devicetree is not signature-verified the property is reachable from an attacker-influenced blob. Using debug() rather than printf() keeps the rejection text out of production builds so there is no .text or .rodata growth on space-constrained targets. Signed-off-by: Aristo Chen <[email protected]>
2026-06-11bootm: bound-check OS index in bootm_os_get_boot_func()Aristo Chen
The boot_os[] table in bootm_os.c is a sparse array whose compile-time size is set by its largest designated initializer (IH_OS_ELF), giving it IH_OS_ELF + 1 entries. The accessor bootm_os_get_boot_func() returns boot_os[os] without any bound check, even though the caller in bootm_run_states() passes images->os.os straight through. That field is populated by image_get_os() from the raw 8-bit ih_os byte of a legacy uImage, and by fit_image_get_os() for a FIT, neither of which clamps the value against the table size. An attacker-supplied image whose OS field falls outside the populated range therefore drives an out-of-bounds read of boot_os[]. The caller only rejects a NULL return, so a non-NULL adjacent global is accepted as a valid handler and invoked through the indirect call in boot_selected_os(), turning an unsigned image with a malformed header into a jump through an attacker-influenced function pointer. FIT signature verification covers the os property and mitigates this path for signed images, but legacy bootm and unsigned FIT do not. Reject out-of-range indices in bootm_os_get_boot_func() so the existing NULL handling in bootm_run_states() reports an unsupported OS and declines to boot the image. Signed-off-by: Aristo Chen <[email protected]>
2026-06-11Merge patch series "allow control DTB to double as "FIT image""Tom Rini
Rasmus Villemoes <[email protected]> says: The commit message for patch 1 explains what it is I'd like to be able to do, but here's some more background: For a long time, we've embedded the boot script in the U-Boot binary by building a bootscript.itb, and using a .dtsi like / { config { bootscript = /incbin/("/path/to/bootscript.itb"); }; }; which in turn is mentioned in CONFIG_DEVICE_TREE_INCLUDES, that bootscript.itb FIT image has been embedded in U-Boot's control dtb. Running that was then a matter of doing fdt addr ${fdtcontroladdr} && fdt get addr bsaddr /config bootscript && source ${bsaddr} There are a couple of advantage of having the bootscript (and other script logic) embedded in the U-Boot binary. First, there's no need to figure out some separate partition to store the script in, and making sure that gets updated whenever the bootloader itself does. Second, one doesn't need to worry about verifying the script; whatever steps one needs to take to implement secure boot for U-Boot itself will by necessity also cover the control dtb (if nothing else then because that's where the public key for the kernel verification lives). And third, the boot script is automatically updated together with U-Boot itself; and if U-Boot is stored in an eMMC boot partition, that update is guaranteed to be atomic. Now with the stricter requirements of libfdt starting from v2026.04, the above command no longer worked, or only half the time, because the embedded FIT image may not land on an 8-byte aligned address. So that line had to be changed a little (line breaks added) fdt addr ${fdtcontroladdr} && fdt get addr bsaddr /config bootscript && fdt get size bssize /config bootscript && cp.b ${bsaddr} ${loadaddr} ${bssize} && source ${loadaddr} which is getting quite unwieldy. Then it struck me that one could perhaps simplify all of this quite a lot: Cut out the intermediate bootscript.itb, just create a .dtsi which directly puts a /images node inside the control dtb / { images { default = "bootscript"; bootscript { description = "Boot script"; data = /incbin/("/path/to/bootscript.sh"); type = "script"; compression = "none"; }; }; }; and treat the control dtb itself as a FIT image; so the command to put in $bootcmd becomes simply source ${fdtcontroladdr}:bootscript and embedding other pieces of callable scripts is quite trivial. And that almost works out-of-the-box, except for the fit_check_format() sanity check. Introduce a CONFIG_ knob that allows one to opt out of those sanity checks, for the special case of the address being checked being identical to gd->fdt_blob. Link: https://lore.kernel.org/r/[email protected]
2026-06-11image-fit.c: introduce CONTROL_DTB_AS_FIT config knobRasmus Villemoes
Having scripts embedded one way or the other in the U-Boot binary means they are automatically verified/trusted by whatever mechanism verifies U-Boot. Writing those scripts in the built-in environment leads to backslatitis and missing or wrong quoting and is generally not very readable or maintainable. Maintaining scripts in external files allows one to have both syntax highlighting and to some extent apply shellcheck on it (though U-Boot's shell is of course not quite POSIX sh, so some '#shellcheck disable' directives are needed). Getting those into the U-Boot binary is then a matter of having a suitable .dtsi file such as / { images { default = "boot"; boot { description = "Bootscript"; data = /incbin/("boot.sh"); type = "script"; compression = "none"; }; factory-reset { description = "Script for performing factory reset"; data = /incbin/("factory-reset.sh"); type = "script"; compression = "none"; }; }; }; and making that part of CONFIG_DEVICE_TREE_INCLUDES, so that U-Boot's control DTB effectively doubles as a FIT image containing a few "script" entries. At run-time, one's default bootcommand can then simply be source ${fdtcontroladdr}:boot Except of course that the control DTB is in fact not quite a FIT image. The lack of timestamp and description properties could potentially be worked around (by just adding those via that same .dtsi), but the no-@ check is not possible to get around. But since the control dtb is by definition trusted, we can make an exception for that particular address, if the new CONTROL_DTB_AS_FIT config option is enabled. One can of course build an ordinary FIT image with those scripts. However, that requires extra steps in the boot command for loading that script from storage, requires one to use "configurations" for pointing at a single script to run, and signing the FIT image using the same key used for verifying the kernel. Moreover, in certain situations, such as bootstrapping/production, there is no place to load that FIT image from, and it is much simpler to just have the necessary scripts be part of the U-Boot image itself. Reviewed-by: Simon Glass <[email protected]> Signed-off-by: Rasmus Villemoes <[email protected]>
2026-06-10treewide: prefer __func__ over __FUNCTION__ and __PRETTY_FUNCTION__Aristo Chen
__FUNCTION__ and __PRETTY_FUNCTION__ are gcc extensions that predate the C99 __func__ identifier. scripts/checkpatch.pl emits a warning for any new use of __FUNCTION__ and recommends __func__ instead. In C (unlike C++) __PRETTY_FUNCTION__ is identical to __func__ because C function names do not carry signature information, so the distinction has no behavioural effect here. The majority of the tree already uses __func__, but a handful of older files in arch/, board/, boot/, drivers/, examples/ and include/ still carry the gcc spellings (55 occurrences of __FUNCTION__ across 19 files plus one __PRETTY_FUNCTION__ in drivers/usb/musb-new/omap2430.c). Convert them all to the C99 form so the tree is consistent and new patches in these areas do not have to follow an outdated local style. Ten "Unnecessary ftrace-like logging - prefer using ftrace" warnings remain on the printf("%s\n", __func__) and dbg("%s\n", __func__) function-entry traces in drivers/net/rtl8169.c (behind DEBUG_RTL8169* preprocessor guards) and drivers/usb/host/ohci-hcd.c. checkpatch matches the literal "%s\n", __func__ shape regardless of the wrapper, so silencing those warnings would require changing the debug message text or removing the traces entirely. Signed-off-by: Aristo Chen <[email protected]> Reviewed-by: Tom Rini <[email protected]>
2026-06-08Merge tag 'v2026.07-rc4' into nextTom Rini
Prepare v2026.07-rc4
2026-06-03boot: pxe_utils: Fix potential initrd_filesize buffer overflowFrancois Berder
ulong is 64 bits on 64-bit platforms. Hence, simple_xtoa can produce up to 16 hex characters + NULL byte. The initrd_filesize buffer is only 10 bytes which can cause a buffer overflow on every PXE boot that loads an initrd on an address greater than 4GB. Increase buffer size to 17 bytes to hold the maximum hex representation of a 64-bit address. Signed-off-by: Francois Berder <[email protected]> Reviewed-by: Jerome Forissier <[email protected]>
2026-06-02Merge patch series "Clean up bloblist initialization"Tom Rini
Tom Rini <[email protected]> says: This series does a few small but important cleanups to how we check for, and initialize a bloblist. The first thing is that the way things are done today, our HANDOFF code can only work with a fixed bloblist location, so express that requirement in Kconfig. Next, we demote the scary message about "Bloblist at ... not found" to a debug because we most often see that because the bloblist doesn't (and can't) exist yet. Finally, we remove bloblist_maybe_init and split this in to an exists and a real init. This results in practically no growth (between 8 bytes growth to 12 bytes saved, with some outliers saving much more thanks to knowing it's impossible to have been passed a bloblist yet). This also cleans up some of the code around checking for / knowing about a bloblist existing. Link: https://lore.kernel.org/r/[email protected]
2026-05-29boot: cedit: Check ofnode_read_prop return valueFrancois Berder
In h_read_settings, val variable could be NULL due to ofnode_read_prop returning an error. This variable would then be used as the src in strcpy. Add a NULL check after calling ofnode_read_prop. Signed-off-by: Francois Berder <[email protected]> Reviewed-by: Simon Glass <[email protected]>