[New-bugs-announce] [issue45825] Heap Segmentation Fault

Bill Borskey report at bugs.python.org
Tue Nov 16 20:55:46 EST 2021


New submission from Bill Borskey <wborskey at gmail.com>:

Dereferencing a python object that does not exist through ctypes caused a segfault in pymalloc_alloc. 

rdi: 0x0000000000000006  rsi: 0x0000000000000006 

0   org.python.python             	0x00000001081ee277 pymalloc_alloc + 74
1   org.python.python             	0x00000001081ed3dc _PyObject_Malloc + 17
2   org.python.python             	0x0000000108296a94 normalizestring + 55
3   org.python.python             	0x0000000108296540 _PyCodec_Lookup + 76

Looks like six was passed to the allocator, not sure exactly what was written to it, or if I can control that. But I guess it was more than six bytes. I don't have the id I used with the debug info above, but: I had a smallish list of characters, overwrote it with zeros, called del on it. I checked the value a couple times with ctypes. What I think happened is the garbage collector finally reclaimed the memory and crashed when I dereferenced again with the bad value.

I checked it out using 0xCC to get an idea of where the value was landing, and I'm overwriting rbx directly. But it doesn't get as far as above and segfaults at O_get rather than the allocator. 

I looked and I see this function:

static PyObject *
O_get(void *ptr, Py_ssize_t size)
{
    PyObject *ob = *(PyObject **)ptr;
    if (ob == NULL) {
        if (!PyErr_Occurred())
            /* Set an error if not yet set */
            PyErr_SetString(PyExc_ValueError,
                            "PyObject is NULL");
        return NULL;
    }
    Py_INCREF(ob);
    return ob;
}

Seems like the code is increasing the reference count on the non-existing python object at 0xCCCCCCCCCCCCCCCC and writing out of bounds. 

$ python3 -X dev
Python 3.9.2 (default, Mar 26 2021, 23:27:12) 
[Clang 12.0.0 (clang-1200.0.32.29)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import ctypes
>>> ctypes.cast(0xCCCCCCCCCCCCCCCC, ctypes.py_object).value
Fatal Python error: Segmentation fault

(below does not have the heap debugger on it seemed to mess with results)

Current thread 0x0000000104b83dc0 (most recent call first):
  File "<stdin>", line 1 in <module>
Segmentation fault: 11

Thread 0 crashed with X86 Thread State (64-bit):
  rax: 0x000000010e1be8c0  rbx: 0xcccccccccccccccc  rcx: 0x000000010e2775c9  rdx: 0x000000010e283890
  rdi: 0x000000010e1be8c0  rsi: 0x0000000000000008  rbp: 0x00007ffee20f24e0  rsp: 0x00007ffee20f24d0
   r8: 0x0000000000000004   r9: 0x6a2bff3e46d2619c  r10: 0x000000010e1d4b80  r11: 0x000000010e1d4bb8
  r12: 0x000000010defc5e0  r13: 0x00007f94edc5c390  r14: 0x000000010e1e1b90  r15: 0x0000000000000000
  rip: 0x000000010e2775d7  rfl: 0x0000000000010286  cr2: 0x000000010e2730f3

----------
components: ctypes
files: debug.txt
messages: 406443
nosy: thewb
priority: normal
severity: normal
status: open
title: Heap Segmentation Fault
type: crash
versions: Python 3.9
Added file: https://bugs.python.org/file50444/debug.txt

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


More information about the New-bugs-announce mailing list