From: Neil Horman Date: Wed, 7 Jan 2026 16:52:09 +0000 (-0500) Subject: Fix heap buffer overflow in BIO_f_linebuffer X-Git-Tag: openssl-3.0.19~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=475c466ef2fbd8fc1df6fae1c3eed9c813fc8ff6;p=thirdparty%2Fopenssl.git Fix heap buffer overflow in BIO_f_linebuffer When a FIO_f_linebuffer is part of a bio chain, and the next BIO preforms short writes, the remainder of the unwritten buffer is copied unconditionally to the internal buffer ctx->obuf, which may not be sufficiently sized to handle the remaining data, resulting in a buffer overflow. Fix it by only copying data when ctx->obuf has space, flushing to the next BIO to increase available storage if needed. Fixes openssl/srt#48 Fixes CVE-2025-68160 Reviewed-by: Nikola Pajkovsky Reviewed-by: Eugene Syromiatnikov Reviewed-by: Saša Nedvědický Reviewed-by: Tomas Mraz MergeDate: Mon Jan 26 19:41:40 2026 (cherry picked from commit b21663c35a6f0ed4c8de06855bdc7a6a21f00c2f) --- diff --git a/crypto/bio/bf_lbuf.c b/crypto/bio/bf_lbuf.c index 2c1969cf5c4..08800bc4ca0 100644 --- a/crypto/bio/bf_lbuf.c +++ b/crypto/bio/bf_lbuf.c @@ -189,14 +189,34 @@ static int linebuffer_write(BIO *b, const char *in, int inl) } while (foundnl && inl > 0); /* * We've written as much as we can. The rest of the input buffer, if - * any, is text that doesn't and with a NL and therefore needs to be - * saved for the next trip. + * any, is text that doesn't end with a NL and therefore we need to try + * free up some space in our obuf so we can make forward progress. */ - if (inl > 0) { - memcpy(&(ctx->obuf[ctx->obuf_len]), in, inl); - ctx->obuf_len += inl; - num += inl; + while (inl > 0) { + size_t avail = (size_t)ctx->obuf_size - (size_t)ctx->obuf_len; + size_t to_copy; + + if (avail == 0) { + /* Flush buffered data to make room */ + i = BIO_write(b->next_bio, ctx->obuf, ctx->obuf_len); + if (i <= 0) { + BIO_copy_next_retry(b); + return num > 0 ? num : i; + } + if (i < ctx->obuf_len) + memmove(ctx->obuf, ctx->obuf + i, ctx->obuf_len - i); + ctx->obuf_len -= i; + continue; + } + + to_copy = inl > (int)avail ? avail : (size_t)inl; + memcpy(&(ctx->obuf[ctx->obuf_len]), in, to_copy); + ctx->obuf_len += (int)to_copy; + in += to_copy; + inl -= (int)to_copy; + num += (int)to_copy; } + return num; }