Tk Source Code

View Ticket
Login
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: 2023-04-26 03:20:42
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)

SUMMARY: AddressSanitizer: heap-use-after-free tclNamesp.c:2596 in Tcl_FindCommand … ==889==ABORTING

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.