[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
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.