From 9f244cea8d6c7e589e3ad91a7d37d183828ae72b Mon Sep 17 00:00:00 2001 From: alhudz Date: Wed, 10 Jun 2026 11:15:01 +0530 Subject: [PATCH] fix oob read on malformed length field in dba flatfile handler --- ext/dba/libflatfile/flatfile.c | 24 ++++++++++++++++++++++ ext/dba/tests/dba_flatfile_oob.phpt | 31 +++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 ext/dba/tests/dba_flatfile_oob.phpt diff --git a/ext/dba/libflatfile/flatfile.c b/ext/dba/libflatfile/flatfile.c index 561766777f6f..c6192351d1c6 100644 --- a/ext/dba/libflatfile/flatfile.c +++ b/ext/dba/libflatfile/flatfile.c @@ -112,6 +112,9 @@ int flatfile_delete(flatfile *dba, datum key_datum) { } num = atoi(buf); if (num >= buf_size) { + if (num > SIZE_MAX - FLATFILE_BLOCK_SIZE) { + break; + } buf_size = num + FLATFILE_BLOCK_SIZE; buf = erealloc(buf, buf_size); } @@ -135,6 +138,9 @@ int flatfile_delete(flatfile *dba, datum key_datum) { } num = atoi(buf); if (num >= buf_size) { + if (num > SIZE_MAX - FLATFILE_BLOCK_SIZE) { + break; + } buf_size = num + FLATFILE_BLOCK_SIZE; buf = erealloc(buf, buf_size); } @@ -162,6 +168,9 @@ int flatfile_findkey(flatfile *dba, datum key_datum) { } num = atoi(buf); if (num >= buf_size) { + if (num > SIZE_MAX - FLATFILE_BLOCK_SIZE) { + break; + } buf_size = num + FLATFILE_BLOCK_SIZE; buf = erealloc(buf, buf_size); } @@ -178,6 +187,9 @@ int flatfile_findkey(flatfile *dba, datum key_datum) { } num = atoi(buf); if (num >= buf_size) { + if (num > SIZE_MAX - FLATFILE_BLOCK_SIZE) { + break; + } buf_size = num + FLATFILE_BLOCK_SIZE; buf = erealloc(buf, buf_size); } @@ -202,6 +214,9 @@ datum flatfile_firstkey(flatfile *dba) { } num = atoi(buf); if (num >= buf_size) { + if (num > SIZE_MAX - FLATFILE_BLOCK_SIZE) { + break; + } buf_size = num + FLATFILE_BLOCK_SIZE; buf = erealloc(buf, buf_size); } @@ -218,6 +233,9 @@ datum flatfile_firstkey(flatfile *dba) { } num = atoi(buf); if (num >= buf_size) { + if (num > SIZE_MAX - FLATFILE_BLOCK_SIZE) { + break; + } buf_size = num + FLATFILE_BLOCK_SIZE; buf = erealloc(buf, buf_size); } @@ -244,6 +262,9 @@ datum flatfile_nextkey(flatfile *dba) { } num = atoi(buf); if (num >= buf_size) { + if (num > SIZE_MAX - FLATFILE_BLOCK_SIZE) { + break; + } buf_size = num + FLATFILE_BLOCK_SIZE; buf = erealloc(buf, buf_size); } @@ -254,6 +275,9 @@ datum flatfile_nextkey(flatfile *dba) { } num = atoi(buf); if (num >= buf_size) { + if (num > SIZE_MAX - FLATFILE_BLOCK_SIZE) { + break; + } buf_size = num + FLATFILE_BLOCK_SIZE; buf = erealloc(buf, buf_size); } diff --git a/ext/dba/tests/dba_flatfile_oob.phpt b/ext/dba/tests/dba_flatfile_oob.phpt new file mode 100644 index 000000000000..3328e1dcba90 --- /dev/null +++ b/ext/dba/tests/dba_flatfile_oob.phpt @@ -0,0 +1,31 @@ +--TEST-- +DBA FlatFile handler bounds with a malformed (negative) length field +--EXTENSIONS-- +dba +--SKIPIF-- + +--FILE-- + +--CLEAN-- + +--EXPECT-- +bool(false) +bool(false) +bool(false) +done