Merge branch 'PHP-8.2'

* PHP-8.2:
  unserialize: Strictly check for `:{` at object start (#10214)
This commit is contained in:
Tim Düsterhus 2023-01-12 19:57:22 +01:00
commit 013e0f98ac
No known key found for this signature in database
GPG Key ID: 8FF75566094168AF
7 changed files with 97 additions and 3 deletions

View File

@ -8,5 +8,5 @@ $str = 'C:3:"GMP":4:{s:6666666666:""}';
var_dump(unserialize($str));
?>
--EXPECTF--
Warning: unserialize(): Error at offset 13 of 29 bytes in %s on line %d
Warning: unserialize(): Error at offset 17 of 29 bytes in %s on line %d
bool(false)

View File

@ -3,6 +3,13 @@ Bug #73029: Missing type check when unserializing SplArray
--FILE--
<?php
try {
$a = 'C:11:"ArrayObject":19:{x:i:0;r:2;;m:a:0:{}}';
$m = unserialize($a);
$x = $m[2];
} catch(UnexpectedValueException $e) {
print $e->getMessage() . "\n";
}
try {
$a = 'C:11:"ArrayObject":19:0x:i:0;r:2;;m:a:0:{}}';
$m = unserialize($a);
$x = $m[2];
@ -11,6 +18,10 @@ $x = $m[2];
}
?>
DONE
--EXPECT--
--EXPECTF--
Error at offset 10 of 19 bytes
Warning: unserialize(): Error at offset 22 of 43 bytes in %s on line %d
Warning: Trying to access array offset on value of type bool in %s on line %d
DONE

View File

@ -2,6 +2,13 @@
Bug #73144 (Use-afte-free in ArrayObject Deserialization)
--FILE--
<?php
try {
$token = 'a:2:{i:0;O:1:"0":2:{s:1:"0";i:0;s:1:"0";a:1:{i:0;C:11:"ArrayObject":7:{x:i:0;r}';
$obj = unserialize($token);
} catch(Exception $e) {
echo $e->getMessage()."\n";
}
try {
$token = 'a:2:{i:0;O:1:"0":2:0s:1:"0";i:0;s:1:"0";a:1:{i:0;C:11:"ArrayObject":7:{x:i:0;r}';
$obj = unserialize($token);
@ -20,5 +27,7 @@ unserialize($exploit);
--EXPECTF--
Error at offset 6 of 7 bytes
Warning: unserialize(): Error at offset 19 of 79 bytes in %s on line %d
Warning: ArrayObject::unserialize(): Unexpected end of serialized data in %sbug73341.php on line %d
Error at offset 24 of 34 bytes

View File

@ -6,5 +6,5 @@ $s = 'O:8:"stdClass":00000000';
var_dump(unserialize($s));
?>
--EXPECTF--
Warning: unserialize(): Error at offset 25 of 23 bytes in %s on line %d
Warning: unserialize(): Error at offset 23 of 23 bytes in %s on line %d
bool(false)

View File

@ -0,0 +1,17 @@
--TEST--
Object serialization / unserialization: Strict format
--FILE--
<?php
class A {public $a;}
var_dump(unserialize('O:1:"A":1x{s:1:"a";N;}'));
//0123456789012345678901
var_dump(unserialize('O:1:"A":1:xs:1:"a";N;}'));
//0123456789012345678901
?>
--EXPECTF--
Warning: unserialize(): Error at offset 9 of 22 bytes in %s on line %d
bool(false)
Warning: unserialize(): Error at offset 10 of 22 bytes in %s on line %d
bool(false)

View File

@ -0,0 +1,33 @@
--TEST--
Object serialization / unserialization: Strict format (2)
--FILE--
<?php
class A implements Serializable {
public function serialize() {}
public function unserialize($data) {}
public function __serialize() {}
public function __unserialize($data) {}
}
var_dump(unserialize('C:1:"A":3x{foo}'));
//012345678901234
var_dump(unserialize('C:1:"A":3:xfoo}'));
//012345678901234
var_dump(unserialize('C:1:"A":3:{foox'));
//012345678901234
var_dump(unserialize('C:1:"A":'));
//01234567
?>
--EXPECTF--
Warning: unserialize(): Error at offset 9 of 15 bytes in %s on line %d
bool(false)
Warning: unserialize(): Error at offset 10 of 15 bytes in %s on line %d
bool(false)
Warning: unserialize(): Error at offset 14 of 15 bytes in %s on line %d
bool(false)
Warning: unserialize(): Error at offset 8 of 8 bytes in %s on line %d
bool(false)

View File

@ -744,6 +744,19 @@ static inline int object_custom(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
datalen = parse_iv2((*p) + 2, p);
if (max - (*p) < 2) {
return 0;
}
if ((*p)[0] != ':') {
return 0;
}
if ((*p)[1] != '{') {
(*p) += 1;
return 0;
}
(*p) += 2;
if (datalen < 0 || (max - (*p)) <= datalen) {
@ -755,6 +768,7 @@ static inline int object_custom(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
* with unserialize reading past the end of the passed buffer if the string is not
* appropriately terminated (usually NUL terminated, but '}' is also sufficient.) */
if ((*p)[datalen] != '}') {
(*p) += datalen;
return 0;
}
@ -1294,6 +1308,16 @@ object ":" uiv ":" ["] {
return 0;
}
YYCURSOR = *p;
if (*(YYCURSOR) != ':') {
return 0;
}
if (*(YYCURSOR+1) != '{') {
*p = YYCURSOR+1;
return 0;
}
*p += 2;
has_unserialize = !incomplete_class && ce->__unserialize;