diff options
| author | Aristo Chen <aristo.chen@canonical.com> | 2026-08-18 13:23:21 +0000 |
|---|---|---|
| committer | Tom Rini <trini@konsulko.com> | 2026-08-18 14:36:57 -0600 |
| commit | b09cb251ab88a20efbb4b60806fb2479fcb207b0 (patch) | |
| tree | 5f9d8efd3b89caa58ccb5f695a0d48932b545d81 | |
| parent | f626ba24310c1c2edba80dc1ad945f1146cf4603 (diff) | |
| download | u-boot-b09cb251ab88a20efbb4b60806fb2479fcb207b0.tar.gz u-boot-b09cb251ab88a20efbb4b60806fb2479fcb207b0.zip | |
bootm: size the noload lzma decompression buffer from the header
Add a small static helper bootm_lzma_uncompressed_size() that reads
the uncompressed size out of the .lzma-alone header, and wire it
into bootm_load_os() alongside gzip, lz4, and zstd.
The .lzma-alone format keeps the uncompressed size in a fixed 8-byte
field right after the 5-byte properties block; a marker of all ones
means the size is unknown, and the caller falls back to the 8x
heuristic in that case. Streaming encoders (xz-utils' 'lzma' shim,
Python's lzma.FORMAT_ALONE) write the unknown marker, while LZMA SDK
style encoders record the real size.
Signed-off-by: Aristo Chen <aristo.chen@canonical.com>
| -rw-r--r-- | boot/bootm.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/boot/bootm.c b/boot/bootm.c index c5bdc909053..758edeb964c 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -26,6 +26,7 @@ #include <asm/unaligned.h> #include <linux/sizes.h> #include <linux/zstd.h> +#include <lzma/LzmaDec.h> #include <tpm-v2.h> #include <tpm_tcg2.h> #if defined(CONFIG_CMD_USB) @@ -658,6 +659,28 @@ static ulong bootm_gzip_uncompressed_size(const void *src, ulong len) } #endif +#if CONFIG_IS_ENABLED(LZMA) +/* + * Return the uncompressed size recorded in the lzma stream header, or + * 0 if the buffer is too short or the size field carries the "unknown" + * marker (0xff..ff). The .lzma-alone format keeps the size in a fixed + * 8-byte field right after the 5-byte properties block; nothing else + * is validated since the value is only an allocation hint. + */ +static ulong bootm_lzma_uncompressed_size(const void *src, ulong len) +{ + const u8 *b = src; + u64 usize; + + if (len < LZMA_PROPS_SIZE + 8) + return 0; + usize = get_unaligned_le64(b + LZMA_PROPS_SIZE); + if (usize == U64_MAX || usize > ULONG_MAX) + return 0; + return (ulong)usize; +} +#endif + #if CONFIG_IS_ENABLED(LZ4) /* * Return the lz4 frame's Content_Size, or 0 if the buffer is not an @@ -752,6 +775,12 @@ static int bootm_load_os(struct bootm_headers *images, int boot_progress) image_len); break; #endif +#if CONFIG_IS_ENABLED(LZMA) + case IH_COMP_LZMA: + hdr_size = bootm_lzma_uncompressed_size(image_buf, + image_len); + break; +#endif #if CONFIG_IS_ENABLED(LZ4) case IH_COMP_LZ4: hdr_size = bootm_lz4_uncompressed_size(image_buf, |
