summaryrefslogtreecommitdiff
path: root/boot
AgeCommit message (Collapse)Author
5 daystools: fit: sign all config image referencesJames Hilliard
Target-side configuration verification builds the signed-region list from every image-reference property in the selected configuration. Host-side signing still uses either the signature node sign-images property or the legacy kernel/fdt/script default list. This lets mkimage generate configuration signatures which U-Boot cannot verify when the configuration references other image types, such as firmware, loadables or ramdisk entries. It also lets the host and target disagree when sign-images names only a subset of the configuration images. Build the host-side signing list from the configuration properties in the same way as target-side verification. Use one shared property classifier so the host and target cannot drift apart again. This makes signed configurations cover the root node, the configuration node, every referenced image node, and its hash, cipher and dm-verity subnodes, regardless of image type. Warn when a legacy sign-images property is present, since it no longer limits the signed image list. Require every referenced image to have at least one hash subnode. Add sandbox coverage proving that a firmware reference omitted from sign-images is still recorded in hashed-nodes and verified. Update the signed-configuration documentation to describe the same rule and the hash-subnode requirement. Fixes: 2092322b31cc ("boot: Add fit_config_get_hash_list() to build signed node list") Signed-off-by: James Hilliard <[email protected]> Reviewed-by: Simon Glass <[email protected]>
6 daysMerge tag 'v2026.10-rc3' into nextTom Rini
6 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]>
9 daysbootstd: rauc: Clear bootmeth_priv after freeing it when bootingAristo Chen
distro_rauc_boot() deep-frees the private data once the boot script has been loaded and run, but leaves bflow->bootmeth_priv pointing at the freed memory. The bootflow being booted is the one stored in the bootstd list, so if the boot script returns (bootflow_boot() treats this as an error), the stale pointer is kept and bootflow_free() frees it a second time when the bootflow is removed, for example by the next 'bootflow scan'. Clear bflow->bootmeth_priv after freeing, as the scan error path does. Also check priv before using it, like the other users of bootmeth_priv in this file: after a failed boot attempt, a retry now finds bootmeth_priv NULL and must not hand it to get_slot(), which would dereference it. Fixes: 498e423457a0 ("bootstd: rauc: Free private data when booting") Signed-off-by: Aristo Chen <[email protected]>
9 daysbootstd: Free abandoned bootflows while scanningAristo Chen
bootflow_scan_first()/bootflow_scan_next() try each candidate (bootdev, method, partition) in turn. When a candidate fails and is not returned to the caller (no BOOTFLOWIF_ALL), the bootflow is simply abandoned: the next candidate's bootflow_init() memsets the struct, orphaning everything the failed attempt allocated, starting with the name allocated in bootdev_find_in_blk(). Each failed candidate therefore leaks its allocations on every scan. A single failing 'bootflow scan' on a sandbox MMC with a RAUC A/B layout leaks about 1 KB across ~30 abandoned candidates, and scans can be retried indefinitely from the U-Boot prompt. Free the bootflow when it failed and is not passed back to the caller. Add a check to the bootflow_rauc test that repeating a failing scan does not change the number of allocated bytes. Together with the previous RAUC fixes this makes the failed-scan path leak-free. Fixes: a8f5be178db5 ("bootstd: Add support for bootflows") Signed-off-by: Aristo Chen <[email protected]>
9 daysbootstd: rauc: Fix leak of the strsep() source buffersAristo Chen
distro_rauc_read_bootflow() duplicates the default boot order and the partition list with strdup(), then parses both with strsep(), which advances the pointers until they are NULL. The error path then calls free() on the advanced pointers, which is a no-op, and the success path does not free them at all. The two buffers leak on every RAUC read_bootflow() call. This also removes a landmine: if the two lists ever had different lengths, the leftover pointer would point into the middle of its buffer and free() would be called on an interior pointer, corrupting the heap. Parse via separate cursor variables and free the original pointers on both paths. Fixes: 7e5c2c782fb9 ("bootstd: Add implementation for bootmeth rauc") Signed-off-by: Aristo Chen <[email protected]>
9 daysbootstd: cros: Clear bootmeth_priv after freeing it on errorAristo Chen
cros_read_bootflow() stores priv in bflow->bootmeth_priv and then calls cros_read_info(). If that fails, priv is freed but bflow->bootmeth_priv keeps pointing at the freed memory. With 'bootflow scan -a', failed bootflows are stored in the bootstd list, so the stale pointer is kept and bootflow_free() later frees it a second time, corrupting the heap. This is the same problem recently fixed in the RAUC bootmeth. Clear bflow->bootmeth_priv after freeing, as bootmeth_android already does. Fixes: 71f634b822ae ("bootstd: cros: Allow detection of any kernel partition") Signed-off-by: Aristo Chen <[email protected]>
9 daysbootstd: rauc: Free string lists on error pathsAristo Chen
str_to_list() allocates a copy of the input string plus a pointer array, which must be released with str_free_list(). Several error paths return early without doing so and leak both allocations: - distro_rauc_scan_parts() when BOOT_ORDER names an unknown slot - distro_rauc_read_bootflow() and find_active_slot() when reading or writing a BOOT_*_LEFT variable fails The scan_parts leak is the most visible one: a stray BOOT_ORDER entry leaks the list on every scan attempt, and scans can be retried indefinitely from the U-Boot prompt. Free the list before each early return. Fixes: 7e5c2c782fb9 ("bootstd: Add implementation for bootmeth rauc") Fixes: f271b0627001 ("bootstd: rauc: Only scan all partitions instead of boot files") Signed-off-by: Aristo Chen <[email protected]>
9 daysbootstd: rauc: Clear bootmeth_priv after freeing it on errorAristo Chen
distro_rauc_read_bootflow() stores priv in bflow->bootmeth_priv before calling distro_rauc_scan_parts(). If the scan fails, the error path frees priv via distro_rauc_priv_free() but leaves bflow->bootmeth_priv pointing at the freed memory. With 'bootflow scan -a', failed bootflows are stored in the bootstd list, so the stale pointer is kept. The next scan (or any other bootflow removal) calls bootflow_free(), which frees bootmeth_priv again. On sandbox, dlmalloc catches the double free: common/dlmalloc.c:816: do_check_inuse_chunk: Assertion `inuse(p)' failed. The scan can fail this way whenever no slot has a valid filesystem, or when BOOT_ORDER names an unknown slot. Clear bflow->bootmeth_priv after freeing, as bootmeth_android already does. Extend the bootflow_rauc test to run a failing scan with -a and then rescan. Fixes: 284855320282 ("bootstd: rauc: Free memory during error handling") Signed-off-by: Aristo Chen <[email protected]>
9 daysbootstd: rauc: Fix NULL dereference in get_slot()Aristo Chen
priv->slots is a NULL-terminated array of pointers, but get_slot() tests priv->slots[i]->name in its loop condition, dereferencing each entry before checking it against NULL. When slot_name does not match any configured slot, the loop reaches the terminator and dereferences a NULL pointer. This is reachable from the BOOT_ORDER environment variable: an entry naming a slot that is not listed in CONFIG_BOOTMETH_RAUC_PARTITIONS crashes U-Boot in distro_rauc_scan_parts() or distro_rauc_boot(). Since BOOT_ORDER is typically stored in a disk-resident environment written by the OS, a stray or corrupted value must not crash the bootloader. Test the array entry itself before using its name, as distro_rauc_priv_free() already does. Both callers already handle a NULL return. Extend the bootflow_rauc test to scan with a BOOT_ORDER naming an unconfigured slot. Without this fix the test crashes with SIGSEGV. Fixes: 7e5c2c782fb9 ("bootstd: Add implementation for bootmeth rauc") Signed-off-by: Aristo Chen <[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]>