| Ticket UUID: | 1ab7a5f29956725c6513663c9a3f889aebdd98d4 | |||
| Title: | Aqua: use-after-free in handleReopenApplicationEvent:withReplyEvent: | |||
| Type: | Bug | Version: | 8.6.13 | |
| Submitter: | chrstphrchvz | Created on: | 2023-04-25 13:48:24 | |
| Subsystem: | 66. Aqua Window Operations | Assigned To: | nobody | |
| Priority: | 5 Medium | Severity: | Minor | |
| Status: | Open | Last Modified: | 2026-06-25 22:02:02 | |
| Resolution: | None | Closed By: | nobody | |
| Closed on: | ||||
| Description: |
I observe this with 8.7 (edit: and 8.6.13). While trying to debug an IDLE test which hangs on Aqua during a call to update (see https://github.com/python/cpython/issues/88496; I think update idletasks might work instead), clicking the Tk icon in the dock triggers a use-after-free: ==889==ERROR: AddressSanitizer: heap-use-after-free on address 0x61a0000888a8 at pc 0x00010b6dc1aa bp 0x7ff7bbbc5af0 sp 0x7ff7bbbc5ae8 READ of size 8 at 0x61a0000888a8 thread T0 #0 0x10b6dc1a9 in Tcl_FindCommand tclNamesp.c:2596 #1 0x10cf7eac8 in -[TKApplication(TKHLEvents) handleReopenApplicationEvent:withReplyEvent:] tkMacOSXHLEvents.c:132 #2 0x7ff808a5e723 in -[NSAppleEventManager dispatchRawAppleEvent:withRawReply:handlerRefCon:]+0x133 (Foundation:x86_64+0x34723) (BuildId: cecd498e32483fbaa3c3c2a12369af0e32000000200000000100000000060c00) #3 0x7ff808a5e595 in _NSAppleEventManagerGenericHandler+0x4f (Foundation:x86_64+0x34595) (BuildId: cecd498e32483fbaa3c3c2a12369af0e32000000200000000100000000060c00) #4 0x7ff80e2e546f (AE:x86_64+0xb46f) (BuildId: 2176fd2a75363417abeb4b4190c429a932000000200000000100000000060c00) #5 0x7ff80e2e4cd9 (AE:x86_64+0xacd9) (BuildId: 2176fd2a75363417abeb4b4190c429a932000000200000000100000000060c00) #6 0x7ff80e2de31e in aeProcessAppleEvent+0x1a2 (AE:x86_64+0x431e) (BuildId: 2176fd2a75363417abeb4b4190c429a932000000200000000100000000060c00) #7 0x7ff8108ecce1 in AEProcessAppleEvent+0x35 (HIToolbox:x86_64+0x3fce1) (BuildId: 06fdecd69f69397bb1e2a8226c0ba7ed32000000200000000100000000060c00) #8 0x7ff80a6663c1 in _DPSNextEvent+0x7f3 (AppKit:x86_64+0x3f3c1) (BuildId: f02d178c79143fc4b9f49881945b316532000000200000000100000000060c00) #9 0x7ff80a664629 in -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:]+0x571 (AppKit:x86_64+0x3d629) (BuildId: f02d178c79143fc4b9f49881945b316532000000200000000100000000060c00) #10 0x10cff8045 in TkMacOSXDrawAllViews tkMacOSXNotify.c:394 #11 0x10b8afea9 in TclServiceIdle tclTimer.c:751 #12 0x10b707903 in Tcl_DoOneEvent tclNotify.c:1020 #13 0x10c3dc779 in Tk_UpdateObjCmd tkCmds.c:1211 #14 0x10a9b5cc8 in Dispatch tclBasic.c:4997 #15 0x10a99423e in TclNRRunCallbacks tclBasic.c:5037 #16 0x10a9925ab in Tcl_EvalObjv tclBasic.c:4756 #17 0x108be4899 in Tkapp_Call _tkinter.c:1437 #18 0x104593887 in method_vectorcall_VARARGS descrobject.c:331 #19 0x10455c4d9 in PyObject_Vectorcall call.c:301 #20 0x1049bac73 in _PyEval_EvalFrameDefault bytecodes.c:2533 #21 0x104567ad2 in _PyObject_VectorcallTstate pycore_call.h:92 #22 0x104564595 in method_vectorcall classobject.c:89 #23 0x10455c2cf in _PyVectorcall_Call call.c:247 #24 0x1049bc5c9 in _PyEval_EvalFrameDefault bytecodes.c:3062 #25 0x10455a413 in _PyObject_FastCallDictTstate call.c:143 #26 0x10455d5a1 in _PyObject_Call_Prepend call.c:486 #27 0x1047565f6 in slot_tp_call typeobject.c:8196 #28 0x10455a85f in _PyObject_MakeTpCall call.c:216 #29 0x1049bac73 in _PyEval_EvalFrameDefault bytecodes.c:2533 #30 0x104567ad2 in _PyObject_VectorcallTstate pycore_call.h:92 #31 0x104564595 in method_vectorcall classobject.c:89 #32 0x10455c2cf in _PyVectorcall_Call call.c:247 #33 0x1049bc5c9 in _PyEval_EvalFrameDefault bytecodes.c:3062 #34 0x10455a413 in _PyObject_FastCallDictTstate call.c:143 #35 0x10455d5a1 in _PyObject_Call_Prepend call.c:486 #36 0x1047565f6 in slot_tp_call typeobject.c:8196 #37 0x10455a85f in _PyObject_MakeTpCall call.c:216 #38 0x1049bac73 in _PyEval_EvalFrameDefault bytecodes.c:2533 #39 0x104567ad2 in _PyObject_VectorcallTstate pycore_call.h:92 #40 0x104564595 in method_vectorcall classobject.c:89 #41 0x10455c2cf in _PyVectorcall_Call call.c:247 #42 0x1049bc5c9 in _PyEval_EvalFrameDefault bytecodes.c:3062 #43 0x10455a413 in _PyObject_FastCallDictTstate call.c:143 #44 0x10455d5a1 in _PyObject_Call_Prepend call.c:486 #45 0x1047565f6 in slot_tp_call typeobject.c:8196 #46 0x10455a85f in _PyObject_MakeTpCall call.c:216 #47 0x1049bac73 in _PyEval_EvalFrameDefault bytecodes.c:2533 #48 0x10455a3cd in _PyObject_FastCallDictTstate call.c:154 #49 0x10455d5a1 in _PyObject_Call_Prepend call.c:486 #50 0x104758bd1 in slot_tp_init typeobject.c:8434 #51 0x10474a99e in type_call typeobject.c:1303 #52 0x10455a85f in _PyObject_MakeTpCall call.c:216 #53 0x1049bac73 in _PyEval_EvalFrameDefault bytecodes.c:2533 #54 0x10499ab87 in PyEval_EvalCode ceval.c:556 #55 0x104991758 in builtin_exec bltinmodule.c.h:586 #56 0x1046d9539 in cfunction_vectorcall_FASTCALL_KEYWORDS methodobject.c:438 #57 0x10455c4d9 in PyObject_Vectorcall call.c:301 #58 0x1049bac73 in _PyEval_EvalFrameDefault bytecodes.c:2533 #59 0x10455c2cf in _PyVectorcall_Call call.c:247 #60 0x104c426a5 in pymain_run_module main.c:300 #61 0x104c403a9 in Py_RunMain main.c:689 #62 0x104c41bd9 in pymain_main main.c:719 #63 0x104c42010 in Py_BytesMain main.c:743 #64 0x1106b952d in start+0x1cd (dyld:x86_64+0x552d) (BuildId: 6376ba1620f73c31a5c5a10648ae7b5632000000200000000100000000060c00) 0x61a0000888a8 is located 40 bytes inside of 1304-byte region [0x61a000088880,0x61a000088d98) freed by thread T0 here: #0 0x106053149 in wrap_free+0xa9 (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x49149) (BuildId: bb241bbae85430e08df0156a18518bb92400000010000000000a0a0000030c00) #1 0x10a90f9a4 in TclpFree tclAlloc.c:722 #2 0x10a97ab86 in DeleteInterpProc tclBasic.c:2131 #3 0x10b7c0b8f in Tcl_EventuallyFree tclPreserve.c:295 #4 0x10a974214 in Tcl_DeleteInterp tclBasic.c:1803 #5 0x108be3d24 in Tkapp_Dealloc _tkinter.c:2841 #6 0x10469ea9e in _PyObject_FreeInstanceAttributes dictobject.c:5560 #7 0x10473f9c2 in subtype_dealloc typeobject.c:1641 #8 0x104ad1066 in _PyFrame_ClearExceptCode frame.c:140 #9 0x104a0223b in clear_thread_frame ceval.c:1430 #10 0x1049e3685 in _PyEval_EvalFrameDefault bytecodes.c:640 #11 0x104567ad2 in _PyObject_VectorcallTstate pycore_call.h:92 #12 0x104564595 in method_vectorcall classobject.c:89 #13 0x10455c2cf in _PyVectorcall_Call call.c:247 #14 0x1049bc5c9 in _PyEval_EvalFrameDefault bytecodes.c:3062 #15 0x10455a413 in _PyObject_FastCallDictTstate call.c:143 #16 0x10455d5a1 in _PyObject_Call_Prepend call.c:486 #17 0x1047565f6 in slot_tp_call typeobject.c:8196 #18 0x10455a85f in _PyObject_MakeTpCall call.c:216 #19 0x1049bac73 in _PyEval_EvalFrameDefault bytecodes.c:2533 #20 0x104567ad2 in _PyObject_VectorcallTstate pycore_call.h:92 #21 0x104564595 in method_vectorcall classobject.c:89 #22 0x10455c2cf in _PyVectorcall_Call call.c:247 #23 0x1049bc5c9 in _PyEval_EvalFrameDefault bytecodes.c:3062 #24 0x10455a413 in _PyObject_FastCallDictTstate call.c:143 #25 0x10455d5a1 in _PyObject_Call_Prepend call.c:486 #26 0x1047565f6 in slot_tp_call typeobject.c:8196 #27 0x10455a85f in _PyObject_MakeTpCall call.c:216 #28 0x1049bac73 in _PyEval_EvalFrameDefault bytecodes.c:2533 #29 0x10455a3cd in _PyObject_FastCallDictTstate call.c:154 #30 0x10455d5a1 in _PyObject_Call_Prepend call.c:486 #31 0x104758bd1 in slot_tp_init typeobject.c:8434 #32 0x10474a99e in type_call typeobject.c:1303 #33 0x10455a85f in _PyObject_MakeTpCall call.c:216 #34 0x1049bac73 in _PyEval_EvalFrameDefault bytecodes.c:2533 #35 0x10499ab87 in PyEval_EvalCode ceval.c:556 #36 0x104991758 in builtin_exec bltinmodule.c.h:586 #37 0x1046d9539 in cfunction_vectorcall_FASTCALL_KEYWORDS methodobject.c:438 #38 0x10455c4d9 in PyObject_Vectorcall call.c:301 #39 0x1049bac73 in _PyEval_EvalFrameDefault bytecodes.c:2533 #40 0x10455c2cf in _PyVectorcall_Call call.c:247 #41 0x104c426a5 in pymain_run_module main.c:300 #42 0x104c403a9 in Py_RunMain main.c:689 #43 0x104c41bd9 in pymain_main main.c:719 #44 0x104c42010 in Py_BytesMain main.c:743 #45 0x1106b952d in start+0x1cd (dyld:x86_64+0x552d) (BuildId: 6376ba1620f73c31a5c5a10648ae7b5632000000200000000100000000060c00) previously allocated by thread T0 here: #0 0x106053000 in wrap_malloc+0xa0 (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x49000) (BuildId: bb241bbae85430e08df0156a18518bb92400000010000000000a0a0000030c00) #1 0x10a90f984 in TclpAlloc tclAlloc.c:699 #2 0x10aa20172 in Tcl_Alloc tclCkalloc.c:1037 #3 0x10a956bbd in Tcl_CreateInterp tclBasic.c:805 #4 0x108be105e in Tkapp_New _tkinter.c:564 #5 0x108bdee92 in _tkinter_create _tkinter.c.h:797 #6 0x1046d9438 in cfunction_vectorcall_FASTCALL methodobject.c:422 #7 0x10455c4d9 in PyObject_Vectorcall call.c:301 #8 0x1049bac73 in _PyEval_EvalFrameDefault bytecodes.c:2533 #9 0x10455a413 in _PyObject_FastCallDictTstate call.c:143 #10 0x10455d5a1 in _PyObject_Call_Prepend call.c:486 #11 0x104758bd1 in slot_tp_init typeobject.c:8434 #12 0x10474a99e in type_call typeobject.c:1303 #13 0x10455a85f in _PyObject_MakeTpCall call.c:216 #14 0x1049bac73 in _PyEval_EvalFrameDefault bytecodes.c:2533 #15 0x104567ad2 in _PyObject_VectorcallTstate pycore_call.h:92 #16 0x104564595 in method_vectorcall classobject.c:89 #17 0x10455c2cf in _PyVectorcall_Call call.c:247 #18 0x1049bc5c9 in _PyEval_EvalFrameDefault bytecodes.c:3062 #19 0x10455a413 in _PyObject_FastCallDictTstate call.c:143 #20 0x10455d5a1 in _PyObject_Call_Prepend call.c:486 #21 0x1047565f6 in slot_tp_call typeobject.c:8196 #22 0x10455a85f in _PyObject_MakeTpCall call.c:216 #23 0x1049bac73 in _PyEval_EvalFrameDefault bytecodes.c:2533 #24 0x104567ad2 in _PyObject_VectorcallTstate pycore_call.h:92 #25 0x104564595 in method_vectorcall classobject.c:89 #26 0x10455c2cf in _PyVectorcall_Call call.c:247 #27 0x1049bc5c9 in _PyEval_EvalFrameDefault bytecodes.c:3062 #28 0x10455a413 in _PyObject_FastCallDictTstate call.c:143 #29 0x10455d5a1 in _PyObject_Call_Prepend call.c:486 #30 0x1047565f6 in slot_tp_call typeobject.c:8196 #31 0x10455a85f in _PyObject_MakeTpCall call.c:216 #32 0x1049bac73 in _PyEval_EvalFrameDefault bytecodes.c:2533 #33 0x10455a3cd in _PyObject_FastCallDictTstate call.c:154 #34 0x10455d5a1 in _PyObject_Call_Prepend call.c:486 #35 0x104758bd1 in slot_tp_init typeobject.c:8434 #36 0x10474a99e in type_call typeobject.c:1303 #37 0x10455a85f in _PyObject_MakeTpCall call.c:216 #38 0x1049bac73 in _PyEval_EvalFrameDefault bytecodes.c:2533 #39 0x10499ab87 in PyEval_EvalCode ceval.c:556 #40 0x104991758 in builtin_exec bltinmodule.c.h:586 #41 0x1046d9539 in cfunction_vectorcall_FASTCALL_KEYWORDS methodobject.c:438 #42 0x10455c4d9 in PyObject_Vectorcall call.c:301 #43 0x1049bac73 in _PyEval_EvalFrameDefault bytecodes.c:2533 #44 0x10455c2cf in _PyVectorcall_Call call.c:247 #45 0x104c426a5 in pymain_run_module main.c:300 #46 0x104c403a9 in Py_RunMain main.c:689 #47 0x104c41bd9 in pymain_main main.c:719 #48 0x104c42010 in Py_BytesMain main.c:743 #49 0x1106b952d in start+0x1cd (dyld:x86_64+0x552d) (BuildId: 6376ba1620f73c31a5c5a10648ae7b5632000000200000000100000000060c00) Although the use-after-free can be avoided by doing Tcl_Preserve(interp) from _setup:, there should then also be a Tcl_Release(_eventInterp) call somewhere to avoid a leak (along with setting _eventInterp to NULL to avoid a stale reference), but I do not know where to do this. | |||
| User Comments: |
marc_culler (claiming to be Marc Culler) added on 2026-06-25 22:02:02:
This bug has appeared again in Python, in a more serious way which is causing segfaults during the tkinter tests. I have created a bug-fix branch with one possible "fix". This does not preserve the main (i.e. first) interpreter, whose address is stored in the private NSApplication attribute named _eventInterp. Instead it adds a Destroy proc the that interpreter which sets the _eventInterp to NULL when the main interpreter is destroyed. I think that all uses of _eventInterp are guarded by a test for NULL. So I think this prevents crashes. It prevents the crash described in this report, anyway. Possibly this is not as good as preserving the main interpreter. I am not sure. It wasn't clear to me that interpreters are reference counted. (I had lost track of this ticket and was responding to the Python ticket.) It is also not clear to me what the correct behavior should be for the macOS Application Menu when the main interpreter is destroyed. chrstphrchvz added on 2025-11-04 21:19:18: Another issue which I believe has the same cause (and workaround) is the one reported by Marc at https://github.com/python/cpython/issues/123204 It can be triggered from tclsh using: interp create i interp eval i package require Tk package require Tk interp delete i Then switch to Tk and click on the File menu. This reliably crashes even for builds without -DPURIFY -fsanitize=address because tclsh will abort instead. jan.nijtmans added on 2025-11-04 21:07:10: Ping chrstphrchvz added on 2025-11-04 20:53:18: One way of triggering this issue from tclsh (reliably crashes a -DPURIFY -fsanitize=address build): interp create i interp eval i package require Tk interp delete i package require Tk Then click on the dock icon for Tk. | |||
Home
Timeline
Branches
Tags
Forum
Tickets
Download
Wiki