-
-
Notifications
You must be signed in to change notification settings - Fork 30.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use-after-free in unregister() of atexit module #112127
Labels
3.12
bugs and security fixes
3.13
bugs and security fixes
3.14
new features, bugs and security fixes
extension-modules
C modules in the Modules dir
type-crash
A hard crash of the interpreter, possibly with a core dump
Comments
Here's the traceback that I get for
|
is it same with follwing poc? import atexit
cnt = 0
class test(object):
def __eq__(self,o):
pass
def __call__(self):
pass
class test2(object):
def __eq__(self,o):
global cnt
cnt += 1
if cnt == 1:
atexit.unregister(self)
return NotImplemented
def __call__(self):
return
t = test()
atexit.register(test2())
atexit.register(t)
atexit.unregister(t) the poc code has some problem that could not correctly consider recursion |
This one failed successfully:
:) |
arhadthedev
added
type-crash
A hard crash of the interpreter, possibly with a core dump
extension-modules
C modules in the Modules dir
and removed
type-bug
An unexpected behavior, bug, or error
labels
Nov 16, 2023
benjaminJohnson2204
added a commit
to benjaminJohnson2204/cpython
that referenced
this issue
Jan 15, 2024
benjaminJohnson2204
added a commit
to benjaminJohnson2204/cpython
that referenced
this issue
Feb 13, 2024
serhiy-storchaka
added
3.12
bugs and security fixes
3.13
bugs and security fixes
3.14
new features, bugs and security fixes
labels
Jul 17, 2024
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
3.12
bugs and security fixes
3.13
bugs and security fixes
3.14
new features, bugs and security fixes
extension-modules
C modules in the Modules dir
type-crash
A hard crash of the interpreter, possibly with a core dump
Bug report
Bug description:
Version
3.10.13 (tags/v3.10.13:49965601d6, Nov 12 2023, 04:15:18)
bisect from commit 670e692,
Root cause
atexit_unregister
dont’ consider counting reference and reentering other functions includingatexit_unregister
,atexit_clear
.It causes a free
cb-func
in the second loop while the first loop holds that reference.This vulnerability caused by calling
PyObject_RichCompareBool
in c code, which call arbitrary user defined code like eqPoc
Asan
asan
=75703==ERROR: AddressSanitizer: heap-use-after-free on address 0x607000644cb0 at pc 0x563a1a579158 bp 0x7f
feb4ffa460 sp 0x7ffeb4ffa450
READ of size 8 at 0x607000644cb0 thread T0
#0 0x563a1a579157 in _Py_INCREF Include/object.h:472
#1 0x563a1a579157 in _PyEval_MakeFrameVector Python/ceval.c:4826
#2 0x563a1a57a8b7 in _PyEval_Vector Python/ceval.c:5059
#3 0x563a1a3b8c9a in _PyFunction_Vectorcall Objects/call.c:342
#4 0x563a1a494550 in _PyObject_VectorcallTstate Include/cpython/abstract.h:114
#5 0x563a1a494550 in vectorcall_unbound Objects/typeobject.c:1629
#6 0x563a1a494550 in slot_tp_richcompare Objects/typeobject.c:7628
#7 0x563a1a440c51 in do_richcompare Objects/object.c:699
#8 0x563a1a440f93 in PyObject_RichCompare Objects/object.c:743
#9 0x563a1a4410a9 in PyObject_RichCompareBool Objects/object.c:765
#10 0x563a1a71618c in atexit_unregister Modules/atexitmodule.c:241
#11 0x563a1a7ef56d in cfunction_vectorcall_O Objects/methodobject.c:516
#12 0x563a1a548745 in _PyObject_VectorcallTstate Include/cpython/abstract.h:114
#13 0x563a1a551b8f in PyObject_Vectorcall Include/cpython/abstract.h:123
#14 0x563a1a551b8f in call_function Python/ceval.c:5893
#15 0x563a1a574978 in _PyEval_EvalFrameDefault Python/ceval.c:4181
#16 0x563a1a57a95d in _PyEval_EvalFrame Include/internal/pycore_ceval.h:46
#17 0x563a1a57a95d in _PyEval_Vector Python/ceval.c:5067
#18 0x563a1a57af25 in PyEval_EvalCode Python/ceval.c:1134
#19 0x563a1a60c907 in run_eval_code_obj Python/pythonrun.c:1291
#20 0x563a1a60d329 in run_mod Python/pythonrun.c:1312
#21 0x563a1a60d4c3 in pyrun_file Python/pythonrun.c:1208
#22 0x563a1a612b87 in _PyRun_SimpleFileObject Python/pythonrun.c:456
#23 0x563a1a612e80 in _PyRun_AnyFileObject Python/pythonrun.c:90
#24 0x563a1a3939b4 in pymain_run_file_obj Modules/main.c:353
#25 0x563a1a394184 in pymain_run_file Modules/main.c:372
#26 0x563a1a39668b in pymain_run_python Modules/main.c:587
#27 0x563a1a396809 in Py_RunMain Modules/main.c:666
#28 0x563a1a3969f9 in pymain_main Modules/main.c:696
#29 0x563a1a396d71 in Py_BytesMain Modules/main.c:720
#30 0x563a1a393245 in main Programs/python.c:15
#31 0x7f6c90d20d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#32 0x7f6c90d20e3f in __libc_start_main_impl ../csu/libc-start.c:392
#33 0x563a1a393174 in _start (/home/ubuntu/cpython/python+0x1fa174)
0x607000644cb0 is located 32 bytes inside of 72-byte region [0x607000644c90,0x607000644cd8)
freed by thread T0 here:
#0 0x7f6c910ba537 in __interceptor_free ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:127
#1 0x563a1a4460e8 in _PyMem_RawFree Objects/obmalloc.c:127
#2 0x563a1a446e01 in _PyMem_DebugRawFree Objects/obmalloc.c:2538
#3 0x563a1a4476e2 in _PyMem_DebugFree Objects/obmalloc.c:2671
#4 0x563a1a449273 in PyObject_Free Objects/obmalloc.c:709
#5 0x563a1a663cf0 in PyObject_GC_Del Modules/gcmodule.c:2375
#6 0x563a1a46a386 in object_dealloc Objects/typeobject.c:4510
#7 0x563a1a47da06 in subtype_dealloc Objects/typeobject.c:1460
#8 0x563a1a43ed59 in _Py_Dealloc Objects/object.c:2301
#9 0x563a1a7e0a89 in _Py_DECREF Include/object.h:500
#10 0x563a1a7e0a89 in frame_dealloc Objects/frameobject.c:591
#11 0x563a1a43ed59 in _Py_Dealloc Objects/object.c:2301
#12 0x563a1a57acc7 in _Py_DECREF Include/object.h:500
#13 0x563a1a57acc7 in _PyEval_Vector Python/ceval.c:5080
#14 0x563a1a3b8c9a in _PyFunction_Vectorcall Objects/call.c:342
#15 0x563a1a494550 in _PyObject_VectorcallTstate Include/cpython/abstract.h:114
#16 0x563a1a494550 in vectorcall_unbound Objects/typeobject.c:1629
#17 0x563a1a494550 in slot_tp_richcompare Objects/typeobject.c:7628
#18 0x563a1a440b52 in do_richcompare Objects/object.c:693
#19 0x563a1a440f93 in PyObject_RichCompare Objects/object.c:743
#20 0x563a1a4410a9 in PyObject_RichCompareBool Objects/object.c:765
#21 0x563a1a71618c in atexit_unregister Modules/atexitmodule.c:241
#22 0x563a1a7ef56d in cfunction_vectorcall_O Objects/methodobject.c:516
#23 0x563a1a548745 in _PyObject_VectorcallTstate Include/cpython/abstract.h:114
#24 0x563a1a551b8f in PyObject_Vectorcall Include/cpython/abstract.h:123
#25 0x563a1a551b8f in call_function Python/ceval.c:5893
#26 0x563a1a574978 in _PyEval_EvalFrameDefault Python/ceval.c:4181
#27 0x563a1a57a95d in _PyEval_EvalFrame Include/internal/pycore_ceval.h:46
#28 0x563a1a57a95d in _PyEval_Vector Python/ceval.c:5067
#29 0x563a1a57af25 in PyEval_EvalCode Python/ceval.c:1134
#30 0x563a1a60c907 in run_eval_code_obj Python/pythonrun.c:1291
#31 0x563a1a60d329 in run_mod Python/pythonrun.c:1312
#32 0x563a1a60d4c3 in pyrun_file Python/pythonrun.c:1208
#33 0x563a1a612b87 in _PyRun_SimpleFileObject Python/pythonrun.c:456
#34 0x563a1a612e80 in _PyRun_AnyFileObject Python/pythonrun.c:90
#35 0x563a1a3939b4 in pymain_run_file_obj Modules/main.c:353
previously allocated by thread T0 here:
#0 0x7f6c910ba887 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
#1 0x563a1a446164 in _PyMem_RawMalloc Objects/obmalloc.c:99
#2 0x563a1a446c5c in _PyMem_DebugRawAlloc Objects/obmalloc.c:2471
#3 0x563a1a446cbb in _PyMem_DebugRawMalloc Objects/obmalloc.c:2504
#4 0x563a1a447724 in _PyMem_DebugMalloc Objects/obmalloc.c:2656
#5 0x563a1a4491ec in PyObject_Malloc Objects/obmalloc.c:685
#6 0x563a1a661abe in _PyObject_GC_Alloc Modules/gcmodule.c:2280
#7 0x563a1a663816 in _PyObject_GC_Malloc Modules/gcmodule.c:2307
#8 0x563a1a477585 in PyType_GenericAlloc Objects/typeobject.c:1156
#9 0x563a1a47b189 in object_new Objects/typeobject.c:4504
#10 0x563a1a48200c in type_call Objects/typeobject.c:1123
#11 0x563a1a3b9378 in _PyObject_MakeTpCall Objects/call.c:215
#12 0x563a1a548874 in _PyObject_VectorcallTstate Include/cpython/abstract.h:112
#13 0x563a1a551b8f in PyObject_Vectorcall Include/cpython/abstract.h:123
#14 0x563a1a551b8f in call_function Python/ceval.c:5893
#15 0x563a1a574b5d in _PyEval_EvalFrameDefault Python/ceval.c:4213
#16 0x563a1a57a95d in _PyEval_EvalFrame Include/internal/pycore_ceval.h:46
#17 0x563a1a57a95d in _PyEval_Vector Python/ceval.c:5067
#18 0x563a1a57af25 in PyEval_EvalCode Python/ceval.c:1134
#19 0x563a1a60c907 in run_eval_code_obj Python/pythonrun.c:1291
#20 0x563a1a60d329 in run_mod Python/pythonrun.c:1312
#21 0x563a1a60d4c3 in pyrun_file Python/pythonrun.c:1208
#22 0x563a1a612b87 in _PyRun_SimpleFileObject Python/pythonrun.c:456
#23 0x563a1a612e80 in _PyRun_AnyFileObject Python/pythonrun.c:90
#24 0x563a1a3939b4 in pymain_run_file_obj Modules/main.c:353
#25 0x563a1a394184 in pymain_run_file Modules/main.c:372
#26 0x563a1a39668b in pymain_run_python Modules/main.c:587
#27 0x563a1a396809 in Py_RunMain Modules/main.c:666
#28 0x563a1a3969f9 in pymain_main Modules/main.c:696
#29 0x563a1a396d71 in Py_BytesMain Modules/main.c:720
#30 0x563a1a393245 in main Programs/python.c:15
#31 0x7f6c90d20d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:5
SUMMARY: AddressSanitizer: heap-use-after-free Include/object.h:472 in _Py_INCREF
Shadow bytes around the buggy address:
0x0c0e800c0940: fd fd fd fd fd fd fd fd fa fa fa fa fd fd fd fd
0x0c0e800c0950: fd fd fd fd fd fd fa fa fa fa fd fd fd fd fd fd
0x0c0e800c0960: fd fd fd fd fa fa fa fa fd fd fd fd fd fd fd fd
0x0c0e800c0970: fd fd fa fa fa fa fd fd fd fd fd fd fd fd fd fd
0x0c0e800c0980: fa fa fa fa 00 00 00 00 00 00 00 00 00 fa fa fa
=>0x0c0e800c0990: fa fa fd fd fd fd[fd]fd fd fd fd fa fa fa fa fa
0x0c0e800c09a0: 00 00 00 00 00 00 00 00 00 02 fa fa fa fa fd fd
0x0c0e800c09b0: fd fd fd fd fd fd fd fd fa fa fa fa fd fd fd fd
0x0c0e800c09c0: fd fd fd fd fd fd fa fa fa fa fd fd fd fd fd fd
0x0c0e800c09d0: fd fd fd fd fa fa fa fa fd fd fd fd fd fd fd fd
0x0c0e800c09e0: fd fd fa fa fa fa fd fd fd fd fd fd fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==75703==ABORTING
CPython versions tested on:
3.10
Operating systems tested on:
Linux
Linked PRs
The text was updated successfully, but these errors were encountered: