[PATCH v2 5/8] bootm: size the noload lz4 decompression buffer from Content_Size
Aristo Chen <[email protected]>
| Newsgroups | org.u-boot-project.lists.u-boot |
|---|---|
| Message-ID | <[email protected]> |
Add a small static helper bootm_lz4_uncompressed_size() that parses the lz4 frame header and returns Content_Size when the FLG bit is set, and wire it into bootm_load_os() alongside gzip and zstd. The header parse mirrors ulz4fn()'s validation (magic, version==1, reserved bits, independent-block flag) so the helper does not accept a frame the decoder itself would reject. Only Content_Size is extracted; the full validation still runs inside ulz4fn() during the actual decompression call. The lz4 command needs the --content-size option to set the FLG bit that carries the size; frames produced without it fall back to the existing 8x heuristic. Signed-off-by: Aristo Chen <[email protected]> --- boot/bootm.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/boot/bootm.c b/boot/bootm.c index e4284fe9844..c5bdc909053 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -658,6 +658,36 @@ static ulong bootm_gzip_uncompressed_size(const void *src, ulong len) } #endif +#if CONFIG_IS_ENABLED(LZ4) +/* + * Return the lz4 frame's Content_Size, or 0 if the buffer is not an + * lz4 frame or the frame does not carry the size. The header parse + * mirrors ulz4fn()'s validation so we do not accept a stream the + * decoder itself would refuse. + */ +static ulong bootm_lz4_uncompressed_size(const void *src, ulong len) +{ + const u8 *b = src; + u8 flg, version, indep_blocks, has_content_size, bd; + u64 cs; + + if (len < 4 + 2 || get_unaligned_le32(b) != LZ4F_MAGIC) + return 0; + flg = b[4]; + bd = b[5]; + version = (flg >> 6) & 3; + indep_blocks = (flg >> 5) & 1; + has_content_size = (flg >> 3) & 1; + if (version != 1 || !indep_blocks || (flg & 3) || (bd & 0x8f) || + !has_content_size) + return 0; + if (len < 4 + 2 + 8) + return 0; + cs = get_unaligned_le64(b + 6); + return cs > ULONG_MAX ? 0 : (ulong)cs; +} +#endif + #if CONFIG_IS_ENABLED(ZSTD) /* * Return the zstd frame's Frame_Content_Size, or 0 if the header does @@ -722,6 +752,12 @@ static int bootm_load_os(struct bootm_headers *images, int boot_progress) image_len); break; #endif +#if CONFIG_IS_ENABLED(LZ4) + case IH_COMP_LZ4: + hdr_size = bootm_lz4_uncompressed_size(image_buf, + image_len); + break; +#endif #if CONFIG_IS_ENABLED(ZSTD) case IH_COMP_ZSTD: hdr_size = bootm_zstd_uncompressed_size(image_buf, -- 2.43.0