bio_ok.c: Integer Overflow in BIO_f_reliable record parser leads to Out-of-Bounds Read

Reviewed-by: Paul Dale <ppzgs1@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/28504)

(cherry picked from commit 312904b216)
This commit is contained in:
Luigino Camastra 2025-09-10 12:13:11 +02:00 committed by Tomas Mraz
parent 6dfd73d6e0
commit 192ac44aaf
1 changed files with 13 additions and 10 deletions

View File

@ -556,7 +556,7 @@ static int block_in(BIO *b)
{
BIO_OK_CTX *ctx;
EVP_MD_CTX *md;
unsigned long tl = 0;
size_t tl = 0;
unsigned char tmp[EVP_MAX_MD_SIZE];
int md_size;
@ -567,15 +567,18 @@ static int block_in(BIO *b)
goto berr;
assert(sizeof(tl) >= OK_BLOCK_BLOCK); /* always true */
tl = ctx->buf[0];
tl <<= 8;
tl |= ctx->buf[1];
tl <<= 8;
tl |= ctx->buf[2];
tl <<= 8;
tl |= ctx->buf[3];
tl = ((size_t)ctx->buf[0] << 24)
| ((size_t)ctx->buf[1] << 16)
| ((size_t)ctx->buf[2] << 8)
| ((size_t)ctx->buf[3]);
if (ctx->buf_len < tl + OK_BLOCK_BLOCK + md_size)
if (tl > OK_BLOCK_SIZE)
goto berr;
if (tl > SIZE_MAX - OK_BLOCK_BLOCK - (size_t)md_size)
goto berr;
if (ctx->buf_len < tl + OK_BLOCK_BLOCK + (size_t)md_size)
return 1;
if (!EVP_DigestUpdate(md,
@ -583,7 +586,7 @@ static int block_in(BIO *b)
goto berr;
if (!EVP_DigestFinal_ex(md, tmp, NULL))
goto berr;
if (memcmp(&(ctx->buf[tl + OK_BLOCK_BLOCK]), tmp, md_size) == 0) {
if (memcmp(&(ctx->buf[tl + OK_BLOCK_BLOCK]), tmp, (size_t)md_size) == 0) {
/* there might be parts from next block lurking around ! */
ctx->buf_off_save = tl + OK_BLOCK_BLOCK + md_size;
ctx->buf_len_save = ctx->buf_len;