untrusted comment: verify with openbsd-80-base.pub RWSMSt0erHTctdlPf2/VW/zTaNAd2wbCXwaJUfktt77JK3w7Bjf7ST6imdKJMX7MuY3PdrVGFFuDYW2WJx5SHc/DHykoREb4rQQ= OpenBSD 8.0 errata 011, November 14, 2026: Fix out of bounds reads and writes as well as info leaks in zlib. Apply by doing: signify -Vep /etc/signify/openbsd-80-base.pub -x 011_zlib.patch.sig \ -m - | (cd /usr/src && patch -p0) And then rebuild and install libz: cd /usr/src/lib/libz make obj make make install Index: lib/libz/deflate.c =================================================================== RCS file: /cvs/src/lib/libz/deflate.c,v diff -u -p -r1.31 deflate.c --- lib/libz/deflate.c 19 Mar 2026 15:10:55 -0000 1.31 +++ lib/libz/deflate.c 5 Nov 2026 23:00:20 -0000 @@ -667,7 +667,18 @@ int ZEXPORT deflateResetKeep(z_streamp s adler32(0L, Z_NULL, 0); s->last_flush = -2; - _tr_init(s); + { + /* Retain the hash work done for level 0. */ + int matches = s->level == 0 ? s->matches : 0; + _tr_init(s); + s->matches = matches; + } + + /* Keep the window and the hash, but drop what was left unfinished */ + s->block_start = (long)s->strstart; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; return Z_OK; } @@ -679,6 +690,7 @@ local void lm_init(deflate_state *s) { s->window_size = (ulg)2L*s->w_size; CLEAR_HASH(s); + s->matches = 0; /* the hash is clear */ /* Set the default configuration parameters: */ @@ -741,18 +753,23 @@ int ZEXPORT deflateUsed(z_streamp strm, int ZEXPORT deflatePrime(z_streamp strm, int bits, int value) { deflate_state *s; int put; + int need; if (deflateStateCheck(strm)) return Z_STREAM_ERROR; s = strm->state; -#ifdef LIT_MEM - if (bits < 0 || bits > 16 || - (uchf *)s->d_buf < s->pending_out + ((Buf_size + 7) >> 3)) + if (bits < 0 || bits > 16) return Z_BUF_ERROR; -#else - if (bits < 0 || bits > 16 || - s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3)) + if (s->pending_out != s->pending_buf) { + /* move partially flushed pending output to buffer start */ + Bytef *to = s->pending_buf, *from = s->pending_out; + ulg n = s->pending; + while (n--) + *to++ = *from++; + s->pending_out = s->pending_buf; + } + need = (s->bi_valid + bits) >> 3; + if (s->pending_buf_size - s->pending < (ulg)need) return Z_BUF_ERROR; -#endif do { put = Buf_size - s->bi_valid; if (put > bits) Index: lib/libz/gzlib.c =================================================================== RCS file: /cvs/src/lib/libz/gzlib.c,v diff -u -p -r1.12 gzlib.c --- lib/libz/gzlib.c 19 Mar 2026 15:10:55 -0000 1.12 +++ lib/libz/gzlib.c 5 Nov 2026 23:00:20 -0000 @@ -255,9 +255,9 @@ local gzFile gz_open(const void *path, i if (oflag & O_NONBLOCK) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); #endif -#ifdef O_CLOEXEC +#if defined(O_CLOEXEC) && defined(FD_CLOEXEC) if (oflag & O_CLOEXEC) - fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | O_CLOEXEC); + fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); #endif state->fd = fd; } Index: lib/libz/gzwrite.c =================================================================== RCS file: /cvs/src/lib/libz/gzwrite.c,v diff -u -p -r1.7 gzwrite.c --- lib/libz/gzwrite.c 5 Oct 2026 15:42:49 -0000 1.7 +++ lib/libz/gzwrite.c 5 Nov 2026 23:00:20 -0000 @@ -156,6 +156,11 @@ local int gz_zero(gz_statep state) { unsigned n; z_streamp strm = &(state->strm); + /* allocate memory if this is the first time through -- the input buffer + must exist before it is zeroed below */ + if (state->size == 0 && gz_init(state) == -1) + return -1; + /* consume whatever's left in the input buffer */ if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) return -1; Index: lib/libz/infback.c =================================================================== RCS file: /cvs/src/lib/libz/infback.c,v diff -u -p -r1.14 infback.c --- lib/libz/infback.c 19 Mar 2026 15:10:55 -0000 1.14 +++ lib/libz/infback.c 5 Nov 2026 23:00:20 -0000 @@ -460,8 +460,6 @@ int ZEXPORT inflateBack(z_streamp strm, /* use inflate_fast() if we have enough input and output */ if (have >= 6 && left >= 258) { RESTORE(); - if (state->whave < state->wsize) - state->whave = state->wsize - left; inflate_fast(strm, state->wsize); LOAD(); break; Index: lib/libz/inflate.c =================================================================== RCS file: /cvs/src/lib/libz/inflate.c,v diff -u -p -r1.25 inflate.c --- lib/libz/inflate.c 19 Mar 2026 15:10:55 -0000 1.25 +++ lib/libz/inflate.c 5 Nov 2026 23:08:00 -0000 @@ -545,9 +545,7 @@ int ZEXPORT inflate(z_streamp strm, int } DROPBITS(4); len = BITS(4) + 8; - if (state->wbits == 0) - state->wbits = len; - if (len > 15 || len > state->wbits) { + if (len > 15 || (state->wbits != 0 && len > state->wbits)) { #ifdef SMALL strm->msg = (z_const char *)"error"; #else @@ -556,6 +554,8 @@ int ZEXPORT inflate(z_streamp strm, int state->mode = BAD; break; } + if (state->wbits == 0) + state->wbits = len; state->dmax = 1U << len; state->flags = 0; /* indicate zlib header */ Tracev((stderr, "inflate: zlib header ok\n")); @@ -973,7 +973,7 @@ int ZEXPORT inflate(z_streamp strm, int /* fallthrough */ case LEN: #ifndef SLOW - if (have >= 6 && left >= 258) { + if (have >= 6 && left >= 258 && bits < 8) { RESTORE(); inflate_fast(strm, out); LOAD(); @@ -1391,6 +1391,14 @@ int ZEXPORT inflateSync(z_streamp strm) inflateReset(strm); strm->total_in = in; strm->total_out = out; state->flags = flags; + if (state->wbits == 0) { + /* we never got to see a header for the window size -- set to max */ + if (state->window != Z_NULL) { + ZFREE(strm, state->window); + state->window = Z_NULL; + } + state->wbits = 15; + } state->mode = TYPE; return Z_OK; }