[PATCH 1/2] initrd: fix lz4 decompress with initrd
Sascha Hauer
s.hauer at pengutronix.de
Thu May 22 11:59:04 PDT 2025
This is an adoption of the corresponding Linux commit:
| commit 4d4b866aee039d609c0b40e7e5b27204607ce614
| Author: Yinghai Lu <yinghai at kernel.org>
| Date: Fri Aug 8 14:23:10 2014 -0700
|
| During testing initrd (>2G) support, find decompress/lz4 does not work
| with initrd at all.
|
| decompress_* should support:
| 1. inbuf[]/outbuf[] for kernel preboot.
| 2. inbuf[]/flush() for initramfs
| 3. fill()/flush() for initrd.
|
| in the unlz4 does not handle case 3, as input len is passed as 0, and it
| failed in first try.
|
| Fix that add one extra if (fill) checking, and get out if EOF from the
| fill().
|
| Signed-off-by: Yinghai Lu <yinghai at kernel.org>
| Cc: Kyungsik Lee <kyungsik.lee at lge.com>
| Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
| Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
In barebox case 3 is used when called from uncompress_fd_to_fd() which
is used in the uncompress command. This seems to never have worked with
LZ4 compressed files.
Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
lib/decompress_unlz4.c | 65 +++++++++++++++++++++++++++++++++-----------------
1 file changed, 43 insertions(+), 22 deletions(-)
diff --git a/lib/decompress_unlz4.c b/lib/decompress_unlz4.c
index a18e6591e9fd1e63158ac58c6d265df4f002fdf5..2bb30e71bb1ca1d73ae20f815f0a2be93d4ea7da 100644
--- a/lib/decompress_unlz4.c
+++ b/lib/decompress_unlz4.c
@@ -90,13 +90,20 @@ static inline int unlz4(u8 *input, long in_len,
if (posp)
*posp = 0;
- if (fill)
- fill(inp, 4);
+ if (fill) {
+ size = fill(inp, 4);
+ if (size < 4) {
+ error("data corrupted");
+ goto exit_2;
+ }
+ }
chunksize = get_unaligned_le32(inp);
if (chunksize == ARCHIVE_MAGICNUMBER) {
- inp += 4;
- size -= 4;
+ if (!fill) {
+ inp += 4;
+ size -= 4;
+ }
} else {
error("invalid header");
goto exit_2;
@@ -107,29 +114,44 @@ static inline int unlz4(u8 *input, long in_len,
for (;;) {
- if (fill)
- fill(inp, 4);
+ if (fill) {
+ size = fill(inp, 4);
+ if (size == 0)
+ break;
+ if (size < 4) {
+ error("data corrupted");
+ goto exit_2;
+ }
+ }
chunksize = get_unaligned_le32(inp);
if (chunksize == ARCHIVE_MAGICNUMBER) {
- inp += 4;
- size -= 4;
+ if (!fill) {
+ inp += 4;
+ size -= 4;
+ }
if (posp)
*posp += 4;
continue;
}
- inp += 4;
- size -= 4;
+
if (posp)
*posp += 4;
- if (fill) {
+ if (!fill) {
+ inp += 4;
+ size -= 4;
+ } else {
if (chunksize > lz4_compressbound(uncomp_chunksize)) {
error("chunk length is longer than allocated");
goto exit_2;
}
- fill(inp, chunksize);
+ size = fill(inp, chunksize);
+ if (size < chunksize) {
+ error("data corrupted");
+ goto exit_2;
+ }
}
#ifdef PREBOOT
if (out_len >= uncomp_chunksize) {
@@ -155,18 +177,17 @@ static inline int unlz4(u8 *input, long in_len,
if (posp)
*posp += chunksize;
- size -= chunksize;
+ if (!fill) {
+ size -= chunksize;
- if (size == 0)
- break;
- else if (size < 0) {
- error("data corrupted");
- goto exit_2;
+ if (size == 0)
+ break;
+ else if (size < 0) {
+ error("data corrupted");
+ goto exit_2;
+ }
+ inp += chunksize;
}
-
- inp += chunksize;
- if (fill)
- inp = inp_start;
}
ret = 0;
--
2.39.5
More information about the barebox
mailing list