Skip to content

Commit 9f244ce

Browse files
committed
fix oob read on malformed length field in dba flatfile handler
1 parent a7f40d1 commit 9f244ce

2 files changed

Lines changed: 55 additions & 0 deletions

File tree

ext/dba/libflatfile/flatfile.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,9 @@ int flatfile_delete(flatfile *dba, datum key_datum) {
112112
}
113113
num = atoi(buf);
114114
if (num >= buf_size) {
115+
if (num > SIZE_MAX - FLATFILE_BLOCK_SIZE) {
116+
break;
117+
}
115118
buf_size = num + FLATFILE_BLOCK_SIZE;
116119
buf = erealloc(buf, buf_size);
117120
}
@@ -135,6 +138,9 @@ int flatfile_delete(flatfile *dba, datum key_datum) {
135138
}
136139
num = atoi(buf);
137140
if (num >= buf_size) {
141+
if (num > SIZE_MAX - FLATFILE_BLOCK_SIZE) {
142+
break;
143+
}
138144
buf_size = num + FLATFILE_BLOCK_SIZE;
139145
buf = erealloc(buf, buf_size);
140146
}
@@ -162,6 +168,9 @@ int flatfile_findkey(flatfile *dba, datum key_datum) {
162168
}
163169
num = atoi(buf);
164170
if (num >= buf_size) {
171+
if (num > SIZE_MAX - FLATFILE_BLOCK_SIZE) {
172+
break;
173+
}
165174
buf_size = num + FLATFILE_BLOCK_SIZE;
166175
buf = erealloc(buf, buf_size);
167176
}
@@ -178,6 +187,9 @@ int flatfile_findkey(flatfile *dba, datum key_datum) {
178187
}
179188
num = atoi(buf);
180189
if (num >= buf_size) {
190+
if (num > SIZE_MAX - FLATFILE_BLOCK_SIZE) {
191+
break;
192+
}
181193
buf_size = num + FLATFILE_BLOCK_SIZE;
182194
buf = erealloc(buf, buf_size);
183195
}
@@ -202,6 +214,9 @@ datum flatfile_firstkey(flatfile *dba) {
202214
}
203215
num = atoi(buf);
204216
if (num >= buf_size) {
217+
if (num > SIZE_MAX - FLATFILE_BLOCK_SIZE) {
218+
break;
219+
}
205220
buf_size = num + FLATFILE_BLOCK_SIZE;
206221
buf = erealloc(buf, buf_size);
207222
}
@@ -218,6 +233,9 @@ datum flatfile_firstkey(flatfile *dba) {
218233
}
219234
num = atoi(buf);
220235
if (num >= buf_size) {
236+
if (num > SIZE_MAX - FLATFILE_BLOCK_SIZE) {
237+
break;
238+
}
221239
buf_size = num + FLATFILE_BLOCK_SIZE;
222240
buf = erealloc(buf, buf_size);
223241
}
@@ -244,6 +262,9 @@ datum flatfile_nextkey(flatfile *dba) {
244262
}
245263
num = atoi(buf);
246264
if (num >= buf_size) {
265+
if (num > SIZE_MAX - FLATFILE_BLOCK_SIZE) {
266+
break;
267+
}
247268
buf_size = num + FLATFILE_BLOCK_SIZE;
248269
buf = erealloc(buf, buf_size);
249270
}
@@ -254,6 +275,9 @@ datum flatfile_nextkey(flatfile *dba) {
254275
}
255276
num = atoi(buf);
256277
if (num >= buf_size) {
278+
if (num > SIZE_MAX - FLATFILE_BLOCK_SIZE) {
279+
break;
280+
}
257281
buf_size = num + FLATFILE_BLOCK_SIZE;
258282
buf = erealloc(buf, buf_size);
259283
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
--TEST--
2+
DBA FlatFile handler bounds with a malformed (negative) length field
3+
--EXTENSIONS--
4+
dba
5+
--SKIPIF--
6+
<?php
7+
require_once __DIR__ . '/setup/setup_dba_tests.inc';
8+
check_skip('flatfile');
9+
?>
10+
--FILE--
11+
<?php
12+
$db_file = __DIR__ . '/dba_flatfile_oob.db';
13+
// A negative length narrows to a huge size_t and previously overran the read buffer.
14+
file_put_contents($db_file, "-1\n" . str_repeat('A', 200000));
15+
16+
$db = dba_open($db_file, 'r', 'flatfile');
17+
var_dump(dba_firstkey($db));
18+
var_dump(dba_exists("AAAA", $db));
19+
var_dump(dba_fetch("AAAA", $db));
20+
dba_close($db);
21+
echo "done\n";
22+
?>
23+
--CLEAN--
24+
<?php
25+
@unlink(__DIR__ . '/dba_flatfile_oob.db');
26+
?>
27+
--EXPECT--
28+
bool(false)
29+
bool(false)
30+
bool(false)
31+
done

0 commit comments

Comments
 (0)