File: bug80111.phpt

package info (click to toggle)
php8.4 8.4.16-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 211,276 kB
  • sloc: ansic: 1,176,142; php: 35,419; sh: 11,964; cpp: 7,208; pascal: 4,951; javascript: 3,091; asm: 2,817; yacc: 2,411; makefile: 696; xml: 446; python: 301; awk: 148
file content (62 lines) | stat: -rw-r--r-- 1,440 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
--TEST--
Bug #80111: PHP SplDoublyLinkedList::offsetUnset UAF Sandbox Escape
--FILE--
<?php

function i2s(&$s, $p, $i, $x=8)
{
    for($j=0;$j<$x;$j++)
    {
        $s[$p+$j] = chr($i & 0xff);
        $i >>= 8;
    }
}

class Trigger
{
    function __destruct()
    {
        global $s, $b;
        # Add a reference afterwards
        //$v = new SplDoublyLinkedList();
        //$v->setIteratorMode(SplDoublyLinkedList::IT_MODE_DELETE);
        # Remove element #2 from the list: this has no effect on 
        # intern->traverse_pointer, since it is removed from the list already
        # The element, along with the zval, is freed
        unset($s[0]);
        
        $a = str_shuffle(str_repeat('A', 40-24-1));
        # Build a fake zval (long, value: 12345678)
        i2s($a, 0x00, 12345678); # ptr
        i2s($a, 0x08, 4, 7); # type: long
        
        var_dump($s->current());
        $s->next();
        # The value is our fake zval
        var_dump($s->current());
        print_r('DONE'."\n");
    }
}

# Create a 3-item dllist
$s = new SplDoublyLinkedList();

# This is the UAF trigger
$s->push(new Trigger());

#$b = &$a;
$s->push(3);

# Points intern->traverse_pointer to our object element
$s->rewind();
#$s->next();

# calls SplDoublyLinkedList::offsetUnset, which will remove the element from the
# dllist, and then destruct the object, before clearing traverse_pointer
unset($s[0]);

?>
--EXPECT--
NULL
NULL
DONE