Skip to content

Commit 4377a8e

Browse files
committed
Sanity-check array/object lengths during unserialization
Avoid OOM conditions in unserialize due to overly large array or object length specifications.
1 parent 6417c50 commit 4377a8e

File tree

3 files changed

+29
-3
lines changed

3 files changed

+29
-3
lines changed

ext/standard/tests/serialize/bug74101.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ var_dump(unserialize($s));
88
--EXPECTF--
99
Warning: unserialize(): %s in %sbug74101.php on line %d
1010

11-
Notice: unserialize(): Error at offset 48 of 74 bytes in %sbug74101.php on line %d
11+
Notice: unserialize(): Error at offset 46 of 74 bytes in %sbug74101.php on line %d
1212
bool(false)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--TEST--
2+
Unserializing payload with unrealistically large element counts
3+
--FILE--
4+
<?php
5+
6+
var_dump(unserialize("a:1000000000:{}"));
7+
var_dump(unserialize("O:1000000000:\"\":0:{}"));
8+
var_dump(unserialize("O:1:\"X\":1000000000:{}"));
9+
var_dump(unserialize("C:1:\"X\":1000000000:{}"));
10+
11+
?>
12+
--EXPECTF--
13+
Notice: unserialize(): Error at offset 14 of 15 bytes in %s on line %d
14+
bool(false)
15+
16+
Notice: unserialize(): Error at offset 2 of 20 bytes in %s on line %d
17+
bool(false)
18+
19+
Notice: unserialize(): Error at offset 18 of 21 bytes in %s on line %d
20+
bool(false)
21+
22+
Warning: Insufficient data for unserializing - 1000000000 required, 1 present in %s on line %d
23+
24+
Notice: unserialize(): Error at offset 20 of 21 bytes in %s on line %d
25+
bool(false)

ext/standard/var_unserializer.re

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -953,7 +953,7 @@ use_double:
953953
*p = YYCURSOR;
954954
if (!var_hash) return 0;
955955
956-
if (elements < 0 || elements >= HT_MAX_SIZE) {
956+
if (elements < 0 || elements >= HT_MAX_SIZE || elements > max - YYCURSOR) {
957957
return 0;
958958
}
959959
@@ -1124,10 +1124,11 @@ object ":" uiv ":" ["] {
11241124
}
11251125

11261126
elements = parse_iv2(*p + 2, p);
1127-
if (elements < 0) {
1127+
if (elements < 0 || elements > max - YYCURSOR) {
11281128
zend_string_release_ex(class_name, 0);
11291129
return 0;
11301130
}
1131+
11311132
*p += 2;
11321133

11331134
has_unserialize = !incomplete_class

0 commit comments

Comments
 (0)