summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMarek Vasut <[email protected]>2026-01-28 20:40:40 +0100
committerTom Rini <[email protected]>2026-02-06 09:29:48 -0600
commit02ffe4a0c9d2885899648a5ffe22090e6c7ff9a5 (patch)
tree242bc4e2523263250e58eccc88ac0cf617a43647 /lib
parent2e6b5185bd509d5c39bbdf900bf6ac9c12f2ed59 (diff)
gunzip: Fix len parameter in function signature
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 <[email protected]> Signed-off-by: Marek Vasut <[email protected]>
Diffstat (limited to 'lib')
-rw-r--r--lib/gunzip.c32
1 files changed, 17 insertions, 15 deletions
diff --git a/lib/gunzip.c b/lib/gunzip.c
index a05dcde9a75..76f3397fced 100644
--- a/lib/gunzip.c
+++ b/lib/gunzip.c
@@ -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;
}