[PATCH v2 7/8] bootm: size the noload lzma decompression buffer from the header
Aristo Chen <[email protected]>
| Newsgroups | org.u-boot-project.lists.u-boot |
|---|---|
| Message-ID | <[email protected]> |
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 <[email protected]> --- boot/bootm.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) 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, -- 2.43.0