For a compressed kernel_noload image, bootm_load_os() currently sizes
the decompression buffer as ALIGN(image_len * 8, SZ_1M). The 8x
heuristic works for typical kernels, but any well-compressed payload
(e.g. a long run of zeros) can exceed it, and no fixed multiplier is
safe against arbitrarily compressible input.

This series reads the real uncompressed size from the compressor
header instead. A new helper image_decomp_get_uncompressed_size()
returns the size from gzip ISIZE, lzma's fixed 8-byte header field,
lz4's Content_Size (when the FLG bit is set), or zstd's
Frame_Content_Size. Where the format lacks a size (bzip2, lzo, xz) or
the specific stream omits it (lzma "unknown", lz4 without
--content-size), bootm falls back to the existing 8x heuristic. The
header-derived value is attacker-controlled, so it is capped at
CONFIG_SYS_BOOTM_LEN before use.

Patch 1 adds the helper and wires it into bootm_load_os().

Patch 2 covers gzip, lz4 (with --content-size), and zstd end-to-end
through bootm on sandbox. Every noload_decomp test now carries the
compressor in its name (test_fit_kernel_noload_decomp_<comp>_*); the
lz4 and zstd cases are guarded with requiredtool markers so they skip
cleanly on hosts that don't ship the corresponding compressor. The
lying-header case is exercised for gzip only, because the
CONFIG_SYS_BOOTM_LEN cap lives in one format-agnostic branch of
bootm_load_os() that every parser feeds into.

Patch 3 covers the lzma branch of the helper via a C-level unit test
with a hand-crafted static blob, because standard Ubuntu's xz-utils
lzma shim and Python's lzma.FORMAT_ALONE both write the header size
as "unknown".

Tested on sandbox; the five kernel_noload_decomp pytests pass, the
new compression_test_image_decomp_lzma unit test passes alongside the
14 existing compression unit tests, and each commit builds in
isolation.

Aristo Chen (3):
  bootm: size the noload decompression buffer from the compressor header
  test: fit: cover the kernel_noload header-size and lying-header paths
  test: lib: cover image_decomp_get_uncompressed_size() for lzma streams

 boot/bootm.c              |  20 +++--
 boot/image.c              |  79 +++++++++++++++++
 include/image.h           |  25 ++++++
 test/lib/compression.c    |  66 ++++++++++++++
 test/py/tests/test_fit.py | 182 +++++++++++++++++++++++++++++++++-----
 5 files changed, 346 insertions(+), 26 deletions(-)

-- 
2.43.0

Reply via email to