]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
gunzip: Fix len parameter in function signature
authorMarek Vasut <marek.vasut+renesas@mailbox.org>
Wed, 28 Jan 2026 19:40:40 +0000 (20:40 +0100)
committerTom Rini <trini@konsulko.com>
Fri, 6 Feb 2026 15:29:48 +0000 (09:29 -0600)
The only call site of gzwrite() is cmd/unzip.c do_gzwrite(), where
the 'len' parameter passed to gzwrite(..., len, ...) function is of
type unsigned long. This usage is correct, the 'len' parameter is
an unsigned integer, and the gzwrite() function currently supports
input data 'len' of up to 4 GiB - 1 .

The function signature of gzwrite() function in both include/gzip.h
and lib/gunzip.c does however list 'len' as signed integer, which
is not correct, and ultimatelly limits the implementation to only
2 GiB input data 'len' .

Fix this, update gzwrite() function parameter 'len' data type to
size_t consistently in include/gzip.h and lib/gunzip.c .

Furthermore, update gzwrite() function 'szwritebuf' parameter in
lib/gunzip.c from 'unsigned long' to 'size_t' to be synchronized
with include/gzip.h . Rewrite the other parameters to size_t and
off_t and propagate the change too.

Since the gzwrite() function currently surely only supports input
data size of 4 GiB - 1, add input data size check. The limitation
comes from the current use of zlib z_stream .avail_in parameter,
to which the gzwrite() function sets the entire input data size,
and which is of unsigned int type, which cannot accept any number
beyond 4 GiB - 1. This limitation will be removed in future commit.

Reported-by: Yuya Hamamachi <yuya.hamamachi.sx@renesas.com>
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
cmd/unzip.c
include/gzip.h
lib/gunzip.c

index e7a3f9808b2c51fa1acf18ac1344298977665635..da958f1280393f52d5758f95a1eecdb70d0b261b 100644 (file)
@@ -53,8 +53,8 @@ static int do_gzwrite(struct cmd_tbl *cmdtp, int flag,
        unsigned char *addr;
        unsigned long length;
        unsigned long writebuf = 1<<20;
-       u64 startoffs = 0;
-       u64 szexpected = 0;
+       off_t startoffs = 0;
+       size_t szexpected = 0;
 
        if (argc < 5)
                return CMD_RET_USAGE;
index 304002ffc42b6ae48d31b4d046045429c6bc2bc8..fe8e21dc2a9f7aadc126c6a9412e67de719694bd 100644 (file)
@@ -58,11 +58,11 @@ int zunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp,
  *     gzwrite_progress_finish called at end of loop to
  *             indicate success (retcode=0) or failure
  */
-void gzwrite_progress_init(ulong expected_size);
+void gzwrite_progress_init(size_t expected_size);
 
-void gzwrite_progress(int iteration, ulong bytes_written, ulong total_bytes);
+void gzwrite_progress(int iteration, ulong bytes_written, size_t total_bytes);
 
-void gzwrite_progress_finish(int retcode, ulong totalwritten, ulong totalsize,
+void gzwrite_progress_finish(int retcode, ulong totalwritten, size_t totalsize,
                             u32 expected_crc, u32 calculated_crc);
 
 /**
@@ -77,8 +77,8 @@ void gzwrite_progress_finish(int retcode, ulong totalwritten, ulong totalsize,
  *             for files under 4GiB
  * Return: 0 if OK, -1 on error
  */
-int gzwrite(unsigned char *src, int len, struct blk_desc *dev, ulong szwritebuf,
-           ulong startoffs, ulong szexpected);
+int gzwrite(unsigned char *src, size_t len, struct blk_desc *dev,
+           size_t szwritebuf, off_t startoffs, size_t szexpected);
 
 /**
  * gzip()- Compress data into a buffer using the gzip algorithm
index a05dcde9a757c774fb1f6da260bb27ef63351041..76f3397fcedb4cc51fe775a8690e7c562eb4238b 100644 (file)
@@ -84,7 +84,7 @@ __rcode int gunzip(void *dst, int dstlen, unsigned char *src, unsigned long *len
 
 #ifdef CONFIG_CMD_UNZIP
 __weak
-void gzwrite_progress_init(ulong expectedsize)
+void gzwrite_progress_init(size_t expectedsize)
 {
        putc('\n');
 }
@@ -92,35 +92,32 @@ void gzwrite_progress_init(ulong expectedsize)
 __weak
 void gzwrite_progress(int iteration,
                     ulong bytes_written,
-                    ulong total_bytes)
+                    size_t total_bytes)
 {
        if (0 == (iteration & 3))
-               printf("%lu/%lu\r", bytes_written, total_bytes);
+               printf("%lu/%zu\r", bytes_written, total_bytes);
 }
 
 __weak
 void gzwrite_progress_finish(int returnval,
                             ulong bytes_written,
-                            ulong total_bytes,
+                            size_t total_bytes,
                             u32 expected_crc,
                             u32 calculated_crc)
 {
        if (0 == returnval) {
-               printf("\n\t%lu bytes, crc 0x%08x\n",
+               printf("\n\t%zu bytes, crc 0x%08x\n",
                       total_bytes, calculated_crc);
        } else {
-               printf("\n\tuncompressed %lu of %lu\n"
+               printf("\n\tuncompressed %lu of %zu\n"
                       "\tcrcs == 0x%08x/0x%08x\n",
                       bytes_written, total_bytes,
                       expected_crc, calculated_crc);
        }
 }
 
-int gzwrite(unsigned char *src, int len,
-           struct blk_desc *dev,
-           unsigned long szwritebuf,
-           ulong startoffs,
-           ulong szexpected)
+int gzwrite(unsigned char *src, size_t len, struct blk_desc *dev,
+           size_t szwritebuf, off_t startoffs, size_t szexpected)
 {
        int i, flags;
        z_stream s;
@@ -130,13 +127,18 @@ int gzwrite(unsigned char *src, int len,
        ulong totalfilled = 0;
        lbaint_t blksperbuf, outblock;
        u32 expected_crc;
-       u32 payload_size;
+       size_t payload_size;
        int iteration = 0;
 
+       if (len > 0xffffffff) {
+               log_err("Input size over 4 GiB in size not supported\n");
+               return -1;
+       }
+
        if (!szwritebuf ||
            (szwritebuf % dev->blksz) ||
            (szwritebuf < dev->blksz)) {
-               printf("%s: size %lu not a multiple of %lu\n",
+               printf("%s: size %zu not a multiple of %lu\n",
                       __func__, szwritebuf, dev->blksz);
                return -1;
        }
@@ -182,12 +184,12 @@ int gzwrite(unsigned char *src, int len,
        if (szexpected == 0) {
                szexpected = le32_to_cpu(szuncompressed);
        } else if (szuncompressed != (u32)szexpected) {
-               printf("size of %lx doesn't match trailer low bits %x\n",
+               printf("size of %zx doesn't match trailer low bits %x\n",
                       szexpected, szuncompressed);
                return -1;
        }
        if (lldiv(szexpected, dev->blksz) > (dev->lba - outblock)) {
-               printf("%s: uncompressed size %lu exceeds device size\n",
+               printf("%s: uncompressed size %zu exceeds device size\n",
                       __func__, szexpected);
                return -1;
        }