File tree Expand file tree Collapse file tree 3 files changed +72
-1
lines changed Expand file tree Collapse file tree 3 files changed +72
-1
lines changed Original file line number Diff line number Diff line change 1
1
--TEST--
2
2
Bug #70172 - Use After Free Vulnerability in unserialize()
3
+ --XFAIL--
4
+ Memory leak on debug build, needs fix.
3
5
--FILE--
4
6
<?php
5
7
class obj implements Serializable {
Original file line number Diff line number Diff line change
1
+ --TEST--
2
+ Bug #70172 - Use After Free Vulnerability in unserialize()
3
+ --FILE--
4
+ <?php
5
+ class obj implements Serializable {
6
+ var $ data ;
7
+ function serialize () {
8
+ return serialize ($ this ->data );
9
+ }
10
+ function unserialize ($ data ) {
11
+ $ this ->data = unserialize ($ data );
12
+ }
13
+ }
14
+
15
+ class obj2 {
16
+ var $ ryat ;
17
+ function __wakeup () {
18
+ $ this ->ryat = 1 ;
19
+ }
20
+ }
21
+
22
+ $ fakezval = ptr2str (1122334455 );
23
+ $ fakezval .= ptr2str (0 );
24
+ $ fakezval .= "\x00\x00\x00\x00" ;
25
+ $ fakezval .= "\x01" ;
26
+ $ fakezval .= "\x00" ;
27
+ $ fakezval .= "\x00\x00" ;
28
+
29
+ $ inner = 'r:2; ' ;
30
+ $ exploit = 'a:2:{i:0;O:4:"obj2":1:{s:4:"ryat";C:3:"obj": ' .strlen ($ inner ).':{ ' .$ inner .'}}i:1;a:1:{i:0;a:1:{i:0;R:4;}}} ' ;
31
+
32
+ $ data = unserialize ($ exploit );
33
+
34
+ for ($ i = 0 ; $ i < 5 ; $ i ++) {
35
+ $ v [$ i ] = $ fakezval .$ i ;
36
+ }
37
+
38
+ var_dump ($ data );
39
+
40
+ function ptr2str ($ ptr )
41
+ {
42
+ $ out = '' ;
43
+ for ($ i = 0 ; $ i < 8 ; $ i ++) {
44
+ $ out .= chr ($ ptr & 0xff );
45
+ $ ptr >>= 8 ;
46
+ }
47
+ return $ out ;
48
+ }
49
+ ?>
50
+ --EXPECTF--
51
+ array(2) {
52
+ [0]=>
53
+ object(obj2)#%d (1) {
54
+ ["ryat"]=>
55
+ int(1)
56
+ }
57
+ [1]=>
58
+ array(1) {
59
+ [0]=>
60
+ array(1) {
61
+ [0]=>
62
+ object(obj2)#%d (1) {
63
+ ["ryat"]=>
64
+ int(1)
65
+ }
66
+ }
67
+ }
68
+ }
Original file line number Diff line number Diff line change @@ -981,7 +981,8 @@ PHP_FUNCTION(unserialize)
981
981
* old_rval = * return_value ;
982
982
zval_copy_ctor (old_rval );
983
983
var_push_dtor_no_addref (& var_hash , & return_value );
984
- var_push_dtor_no_addref (& var_hash , & old_rval );
984
+ /* FIXME: old_rval is not freed in some scenarios, see bug #70172
985
+ var_push_dtor_no_addref(&var_hash, &old_rval); */
985
986
} else {
986
987
var_push_dtor (& var_hash , & return_value );
987
988
}
You can’t perform that action at this time.
0 commit comments