untrusted comment: verify with openbsd-80-base.pub RWSMSt0erHTctdZhdL5rXJHq/gfn9EnwFVdXKivs6eRNS9IrZxgNq0XNZ8oZFCW/AyWpFcMy+grIWGulBZGjkEq2YQxvzeWopQg= OpenBSD 8.0 errata 012, 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 012_syszlib.patch.sig \ -m - | (cd /usr/src && patch -p0) And then rebuild and install a new kernel: KK=`sysctl -n kern.osversion | cut -d# -f1` cd /usr/src/sys/arch/`machine`/compile/$KK make obj make config make make install Index: sys/lib/libz/deflate.c =================================================================== RCS file: /cvs/src/sys/lib/libz/deflate.c,v diff -u -p -r1.24 deflate.c --- sys/lib/libz/deflate.c 19 Mar 2026 15:14:51 -0000 1.24 +++ sys/lib/libz/deflate.c 5 Nov 2026 23:08: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: sys/lib/libz/infback.c =================================================================== RCS file: /cvs/src/sys/lib/libz/infback.c,v diff -u -p -r1.15 infback.c --- sys/lib/libz/infback.c 19 Mar 2026 15:14:51 -0000 1.15 +++ sys/lib/libz/infback.c 5 Nov 2026 23:08: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: sys/lib/libz/inflate.c =================================================================== RCS file: /cvs/src/sys/lib/libz/inflate.c,v diff -u -p -r1.29 inflate.c --- sys/lib/libz/inflate.c 19 Mar 2026 15:14:51 -0000 1.29 +++ sys/lib/libz/inflate.c 5 Nov 2026 23:09:30 -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, 1U << state->wbits); + state->window = Z_NULL; + } + state->wbits = 15; + } state->mode = TYPE; return Z_OK; }