Issue45825
This issue tracker has been migrated to GitHub,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2021-11-17 01:55 by thewb, last changed 2022-04-11 14:59 by admin.
Files | ||||
---|---|---|---|---|
File name | Uploaded | Description | Edit | |
debug.txt | thewb, 2021-11-17 01:55 |
Messages (3) | |||
---|---|---|---|
msg406443 - (view) | Author: Bill Borskey (thewb) | Date: 2021-11-17 01:55 | |
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 |
|||
msg406470 - (view) | Author: Zachary Ware (zach.ware) * | Date: 2021-11-17 14:08 | |
In general, as soon as you touch ctypes you're on your own :). ctypes has no protections for this kind of case, so you need to protect yourself. If you came across this some way that *should* have been safe, please provide more information. But just passing a random memory address to ctypes is likely to cause segfaults or worse. |
|||
msg406472 - (view) | Author: Bill Borskey (thewb) | Date: 2021-11-17 15:11 | |
No worries. I find bugs in my day job, thought this might be a useful segfault but it segfaults because it’s incrementing that reference count on the pyobj that don’t exist. So pretty lame. I did spend an hour tracking it down so I thought I’d let y’all know in case you wanted to fix it. Cheers > On Nov 17, 2021, at 6:08 AM, Zachary Ware <report@bugs.python.org> wrote: > > > Zachary Ware <zachary.ware@gmail.com> added the comment: > > In general, as soon as you touch ctypes you're on your own :). ctypes has no protections for this kind of case, so you need to protect yourself. > > If you came across this some way that *should* have been safe, please provide more information. But just passing a random memory address to ctypes is likely to cause segfaults or worse. > > ---------- > nosy: +zach.ware > resolution: -> not a bug > status: open -> pending > > _______________________________________ > Python tracker <report@bugs.python.org> > <https://bugs.python.org/issue45825> > _______________________________________ |
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-04-11 14:59:52 | admin | set | github: 89983 |
2021-11-17 15:11:42 | thewb | set | status: pending -> open messages: + msg406472 |
2021-11-17 14:08:53 | zach.ware | set | status: open -> pending nosy: + zach.ware messages: + msg406470 resolution: not a bug |
2021-11-17 01:55:46 | thewb | create |