[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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.