]> git.ipfire.org Git - thirdparty/zlib-ng.git/commitdiff
Fix integer overflow in gz_compress_mmap
authorVladislav Shchapov <vladislav@shchapov.ru>
Sat, 17 Jan 2026 13:46:50 +0000 (18:46 +0500)
committerHans Kristian Rosbach <hk-github@circlestorm.org>
Wed, 21 Jan 2026 17:00:36 +0000 (18:00 +0100)
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
test/fuzz/fuzzer_minigzip.c
test/minigzip.c

index 6e388819625897d6e8bf81d9719815738221659b..3f58f4a299dcd8fdf763b820277998c07cfe8d1a 100644 (file)
@@ -70,26 +70,27 @@ static void error(const char *msg) {
  * success, Z_ERRNO otherwise.
  */
 static int gz_compress_mmap(FILE *in, gzFile out) {
-    int len;
     int err;
     int ifd = fileno(in);
-    char *buf;      /* mmap'ed buffer for the entire input file */
-    off_t buf_len;  /* length of the input file */
+    void *buf;      /* mmap'ed buffer for the entire input file */
+    size_t buf_len; /* length of the input file */
+    size_t len;
     struct stat sb;
 
     /* Determine the size of the file, needed for mmap: */
     if (fstat(ifd, &sb) < 0) return Z_ERRNO;
-    buf_len = sb.st_size;
-    if (buf_len <= 0) return Z_ERRNO;
+    /* Check size_t overflow */
+    if (sb.st_size <= 0 || sb.st_size > PTRDIFF_MAX) return Z_ERRNO;
+    buf_len = (size_t)sb.st_size;
 
     /* Now do the actual mmap: */
-    buf = mmap((void *)0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
-    if (buf == (char *)(-1)) return Z_ERRNO;
+    buf = mmap(NULL, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
+    if (buf == MAP_FAILED) return Z_ERRNO;
 
     /* Compress the whole file at once: */
-    len = PREFIX(gzwrite)(out, (char *)buf, (unsigned)buf_len);
+    len = PREFIX(gzfwrite)(buf, 1, buf_len, out);
 
-    if (len != (int)buf_len) error(PREFIX(gzerror)(out, &err));
+    if (len != buf_len) error(PREFIX(gzerror)(out, &err));
 
     munmap(buf, buf_len);
     fclose(in);
index 446b12e652db75fd23fc8d9e653eced91f482d4f..9f86018a6bc13ef8e94cb93a048ea803380fcc21 100644 (file)
@@ -85,25 +85,26 @@ static void gz_fatal(gzFile file) {
  * success, Z_ERRNO otherwise.
  */
 static int gz_compress_mmap(FILE *in, gzFile out) {
-    int len;
     int ifd = fileno(in);
-    char *buf;      /* mmap'ed buffer for the entire input file */
-    off_t buf_len;  /* length of the input file */
+    void *buf;      /* mmap'ed buffer for the entire input file */
+    size_t buf_len; /* length of the input file */
+    size_t len;
     struct stat sb;
 
     /* Determine the size of the file, needed for mmap: */
     if (fstat(ifd, &sb) < 0) return Z_ERRNO;
-    buf_len = sb.st_size;
-    if (buf_len <= 0) return Z_ERRNO;
+    /* Check size_t overflow */
+    if (sb.st_size <= 0 || sb.st_size > PTRDIFF_MAX) return Z_ERRNO;
+    buf_len = (size_t)sb.st_size;
 
     /* Now do the actual mmap: */
-    buf = mmap((void *)0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
-    if (buf == (char *)(-1)) return Z_ERRNO;
+    buf = mmap(NULL, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
+    if (buf == MAP_FAILED) return Z_ERRNO;
 
     /* Compress the whole file at once: */
-    len = PREFIX(gzwrite)(out, buf, (unsigned)buf_len);
+    len = PREFIX(gzfwrite)(buf, 1, buf_len, out);
 
-    if (len != (int)buf_len) gz_fatal(out);
+    if (len != buf_len) gz_fatal(out);
 
     munmap(buf, buf_len);
     fclose(in);