[PATCH v2 0/2] spl: fit: bound external data-size in load_simple_fit()

Aristo Chen aristo.chen at canonical.com
Wed Jul 8 12:34:47 CEST 2026


Link to v1:
https://lore.kernel.org/u-boot/20260618154750.180675-1-aristo.chen@canonical.com/

Changes from v1 (all from Simon's review of patch 1):

- Move the shared error label to the end of the function so no goto
  jumps into an if-body. Both bound checks now goto too_big and the
  printf/return sits after the final return 0.
- Rewrite the comment on the early len > max_size check. The real
  reason it exists is to keep get_aligned_image_size() from running
  its int arithmetic on a hostile value; the block-aligned size
  check further down is the mathematically binding one because size
  is len rounded up.
- Include the data-size value in the diagnostic printf so a real
  failure is triageable from a board log.
- Note in the fix commit message that CONFIG_SYS_BOOTM_LEN is a
  conservative ceiling for the firmware/loadables/FDT/FPGA callers
  rather than the exact capacity at the destination. The overlay
  caller remains the one that is actually tight against its buffer.

---

This series closes a pre-authentication memory corruption window in
the SPL FIT loader. load_simple_fit() in common/spl/spl_fit.c reads
external image data from the boot device with a transfer sized from
the FIT data-size property, and only verifies the image hash after
the read has already happened. data-size is in the exc_prop[]
exclusion list in boot/image-fit-sig.c, so it is not covered by the
configuration signature and stays under the control of anyone able
to modify the boot medium even when CONFIG_SPL_FIT_SIGNATURE is on.
An inflated value drives info->read() into the destination before
fit_image_verify_with_data() can reject the image. The device-tree
overlay path is the sharpest case, because there the destination is
a fixed CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ heap buffer rather
than a sized load region.

Patch 1 adds a max_size argument to load_simple_fit() and rejects
both the raw data-size and the block-aligned transfer length with
-EFBIG before the device read is issued. The size check is the
mathematically binding one because size is len rounded up to the
device block length; the early len check exists so
get_aligned_image_size() never runs on a hostile value, where its
int arithmetic would invoke signed-integer overflow. Callers that
load into a memory region pass CONFIG_SYS_BOOTM_LEN, the same limit
spl_parse_legacy_validate() already applies to legacy images. The
overlay path passes the size of its temporary buffer.

Patch 2 adds a sandbox regression test in test/image/spl_load.c. It
builds a FIT with external data, then rewrites the data-size
property in place to a value far beyond both the image buffer and
any plausible load region, and asserts that spl_load_simple_fit()
returns -EFBIG instead of overrunning the destination. Without the
fix the test crashes inside the test-harness read callback when
memcpy() walks past the small calloc'd image; with the fix the load
is rejected cleanly.

Verified on sandbox_spl_defconfig: the new test passes, and the full
SPL unit test suite reports 20 run, 1 skipped, 0 failures. Also
cross-built am335x_hs_evm_defconfig and am335x_hs_evm_spi_defconfig
with arm-linux-gnueabihf-, both within the SRAM budget.

On the size question from v1 review: the cleaner shape (single
too_big label at end of function) plus the expanded printf now
costs 71 bytes text on am335x_hs_evm (vs the 57 bytes v1 quoted
for the goto-into-if shape). text+data lands at 45132 out of the
CONFIG_SPL_MAX_SIZE = 0xb0b0 = 45232 budget, so 100 bytes of
headroom.

Aristo Chen (2):
  spl: fit: bound the external data size before reading it
  test: spl: check load_simple_fit() rejects an oversized data-size

 common/spl/spl_fit.c  | 51 ++++++++++++++++++++++++++++++++++++++-----
 test/image/spl_load.c | 49 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 94 insertions(+), 6 deletions(-)

-- 
2.43.0



More information about the U-Boot mailing list