Skip to content

Commit 3840112

Browse files
nhormant8m
authored andcommitted
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 <nikolap@openssl.org> Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org> Reviewed-by: Saša Nedvědický <sashan@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> MergeDate: Mon Jan 26 19:41:40 2026 (cherry picked from commit b21663c)
1 parent d75b309 commit 3840112

1 file changed

Lines changed: 26 additions & 6 deletions

File tree

crypto/bio/bf_lbuf.c

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -186,14 +186,34 @@ static int linebuffer_write(BIO *b, const char *in, int inl)
186186
} while (foundnl && inl > 0);
187187
/*
188188
* We've written as much as we can. The rest of the input buffer, if
189-
* any, is text that doesn't and with a NL and therefore needs to be
190-
* saved for the next trip.
189+
* any, is text that doesn't end with a NL and therefore we need to try
190+
* free up some space in our obuf so we can make forward progress.
191191
*/
192-
if (inl > 0) {
193-
memcpy(&(ctx->obuf[ctx->obuf_len]), in, inl);
194-
ctx->obuf_len += inl;
195-
num += inl;
192+
while (inl > 0) {
193+
size_t avail = (size_t)ctx->obuf_size - (size_t)ctx->obuf_len;
194+
size_t to_copy;
195+
196+
if (avail == 0) {
197+
/* Flush buffered data to make room */
198+
i = BIO_write(b->next_bio, ctx->obuf, ctx->obuf_len);
199+
if (i <= 0) {
200+
BIO_copy_next_retry(b);
201+
return num > 0 ? num : i;
202+
}
203+
if (i < ctx->obuf_len)
204+
memmove(ctx->obuf, ctx->obuf + i, ctx->obuf_len - i);
205+
ctx->obuf_len -= i;
206+
continue;
207+
}
208+
209+
to_copy = inl > (int)avail ? avail : (size_t)inl;
210+
memcpy(&(ctx->obuf[ctx->obuf_len]), in, to_copy);
211+
ctx->obuf_len += (int)to_copy;
212+
in += to_copy;
213+
inl -= (int)to_copy;
214+
num += (int)to_copy;
196215
}
216+
197217
return num;
198218
}
199219

0 commit comments

Comments
 (0)