Commit 86fd1ab for zlib
commit 86fd1ab4c014d7d4df44d57a77f9b7cc7b1b5482
Author: ronald.eytchison@trailofbits.com <ronald.eytchison@trailofbits.com>
Date: Fri Jun 5 19:10:15 2026 +0000
Reject exclusive gzopen mode without O_EXCL.
zlib.h says that 'x' when writing creates the file exclusively,
failing if the file already exists. Where O_EXCL is not defined,
'x' was silently ignored, and an existing file was truncated. Fail
the open instead. This applies only when writing to a path, since
'x' does not apply to reading or to gzdopen().
Reported by Trail of Bits (TOB-ZLIB-009).
diff --git a/gzlib.c b/gzlib.c
index a7aec74..18bc6fb 100644
--- a/gzlib.c
+++ b/gzlib.c
@@ -88,9 +88,7 @@ local gzFile gz_open(const void *path, int fd, const char *mode) {
gz_statep state;
z_size_t len;
int oflag = 0;
-#ifdef O_EXCL
int exclusive = 0;
-#endif
/* check input */
if (path == NULL || mode == NULL)
@@ -136,11 +134,9 @@ local gzFile gz_open(const void *path, int fd, const char *mode) {
oflag |= O_CLOEXEC;
break;
#endif
-#ifdef O_EXCL
case 'x':
exclusive = 1;
break;
-#endif
case 'f':
state->strategy = Z_FILTERED;
break;
@@ -196,6 +192,14 @@ local gzFile gz_open(const void *path, int fd, const char *mode) {
/* if reading, direct == 1 for auto-detect, -1 for gzip only; if writing or
appending, direct == 0 for gzip, 1 for transparent (copy in to out) */
+#ifndef O_EXCL
+ if (exclusive && state->mode != GZ_READ && fd < 0) {
+ /* exclusive creation request can't be honored -- fail out */
+ free(state);
+ return NULL;
+ }
+#endif
+
/* save the path name for error messages */
#ifdef WIDECHAR
if (fd == -2) {