[PATCH] lib: decompress_unlz4: drop redundant -4 in wrapper call to unlz4
Ahmad Fatoum
a.fatoum at pengutronix.de
Mon Jun 15 03:00:59 PDT 2026
Hello,
On 6/13/26 11:37 AM, SCHNEIDER Johannes wrote:
> Hoi,
>
>
> please disregard this patch :-S
>
> i've since found out that the root cause lies in the way we build lz4 compressed fitimage parts - there a plain lz4 call, with no 4-byte size trailer is used. And this missing trailer is what triggered the "Error: Fit: data corrupted" - which is non fatal anyway, as the system still booted.
>
> Now i'm wondering why barebox is using this (legacy?) format?
gzip includes the size of the uncompressed data. The kernel
decompressors that barebox imports add that field manually for other
compression algorithms, whose header format lack it.
If you find a way that can accommodate both, we can go with it.
Cheers,
Ahmad
>
>
> gruß
> Johannes
>
> ________________________________________
> From: Johannes Schneider <johannes.schneider at leica-geosystems.com>
> Sent: Saturday, June 13, 2026 07:12
> To: barebox at lists.infradead.org
> Cc: SCHNEIDER Johannes
> Subject: [PATCH] lib: decompress_unlz4: drop redundant -4 in wrapper call to unlz4
>
> decompress_unlz4() passes in_len - 4 to unlz4(), as if the caller had
> already stripped the LZ4 legacy frame magic from the buffer. But unlz4()
> reads the magic itself from buf[0..3] and, in the buffer-input path,
> explicitly accounts for it via:
>
> if (!fill) {
> inp += 4;
> size -= 4;
> }
>
> So the magic is subtracted twice from the running size counter. After
> the last chunk is consumed, the counter underflows to -4 instead of 0,
> which trips the "data corrupted" check at the end of the chunk loop:
>
> if (!fill) {
> size -= chunksize;
> if (size == 0)
> break;
> else if (size < 0) {
> error("data corrupted");
> goto exit_2;
> }
> inp += chunksize;
> }
>
> The bug is benign in practice — by the time the size check fires, all
> chunks have already been successfully decompressed and flushed, and ret
> holds the 0 returned by the last lz4_decompress_unknownoutputsize()
> call. unlz4() returns 0 and the caller treats the operation as
> successful, but a spurious "data corrupted" line is printed on every
> LZ4 decompression. With pr_fmt set by image-fit.c, FIT-image kernel
> boots show:
>
> ERROR: FIT: data corrupted
>
> right between the configuration line and the cmdline-append line.
>
> Pass in_len through unchanged. unlz4() handles the magic itself in both
> the input and fill paths.
>
> Fill-mode callers (e.g. uncompress_fd_to_fd) are unaffected: they pass
> in_len=0, and unlz4() overwrites the initial size on the first fill()
> call.
>
> Assisted-by: Claude:claude-opus-4-7
> Signed-off-by: Johannes Schneider <johannes.schneider at leica-geosystems.com>
> ---
> lib/decompress_unlz4.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/lib/decompress_unlz4.c b/lib/decompress_unlz4.c
> index 2bb30e71bb..17bb4e5de7 100644
> --- a/lib/decompress_unlz4.c
> +++ b/lib/decompress_unlz4.c
> @@ -209,6 +209,6 @@ STATIC int decompress_unlz4(unsigned char *buf, long in_len,
> void(*error)(char *x)
> )
> {
> - return unlz4(buf, in_len - 4, fill, flush, output, posp, error);
> + return unlz4(buf, in_len, fill, flush, output, posp, error);
> }
> #define decompress decompress_unlz4
>
> base-commit: 6c70fb327d486376c1f2e37dfff2212cb9eebb1b
> --
> 2.43.0
>
>
>
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
More information about the barebox
mailing list