Skip to content

AddressSanitizer: heap-use-after-free in timerJobWrapper #341

@philippedistributive

Description

@philippedistributive

Issue type

Bug

How did you install PythonMonkey?

None

OS platform and distribution

No response

Python version (python --version)

No response

PythonMonkey version (pip show pythonmonkey)

No response

Bug Description

Please investigate whether this heap-use-after-free report from AddressSanitizer in timerJobWrapper while running ping.py (https://github.com/wesgarland/python-launch-job/blob/main/ping.py) is legit and needs fixing:

build pm with

image

or using the newly introduced
export BUILD_TYPE=Sanitize

run with
export ASAN_OPTIONS=detect_leaks=1;export LSAN_OPTIONS=suppressions=suppr.txt;export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libasan.so.8

where suppr.txt is
leak:_PyObject_Malloc
leak:_PyObject_Realloc
leak:__interceptor_malloc
leak:__interceptor_realloc
leak:JobQueue::JobQueue
leak:DictType::getPyObject
leak:ListType::getPyObject
leak:JSFunctionProxyMethodDefinitions::JSFunctionProxy_new
leak:BufferType::toJsTypedArray
leak:JSMethodProxyMethodDefinitions::JSMethodProxy_new
leak:eval

Report:

==398494==ERROR: AddressSanitizer: heap-use-after-free on address 0x61100026ee38 at pc 0x7e12d4a7c201 bp 0x7ffc221a18d0 sp 0x7ffc221a18c0
READ of size 1 at 0x61100026ee38 thread T0
#0 0x7e12d4a7c200 in std::__atomic_base::load(std::memory_order) const /usr/include/c++/13/bits/atomic_base.h:505
#1 0x7e12d4a7c200 in std::atomic::operator bool() const /usr/include/c++/13/atomic:87
#2 0x7e12d4a7c200 in PyEventLoop::AsyncHandle::removeRef() /home/philippe/Sources/PythonMonkey/include/PyEventLoop.hh:124
#3 0x7e12d4a7c200 in timerJobWrapper /home/philippe/Sources/PythonMonkey/src/PyEventLoop.cc:51
#4 0x7e12d7fb1db4 in cfunction_call Objects/methodobject.c:553
#5 0x7e12d7f60320 in _PyObject_MakeTpCall Objects/call.c:214
#6 0x7e12d8077273 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:90
#7 0x7e12d8077273 in context_run Python/context.c:673
#8 0x7e12d7fb2455 in cfunction_vectorcall_FASTCALL_KEYWORDS Objects/methodobject.c:443
#9 0x7e12d7f05955 in do_call_core Python/ceval.c:7352
#10 0x7e12d7f05955 in _PyEval_EvalFrameDefault Python/ceval.c:5376
#11 0x7e12d805d7f3 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:73
#12 0x7e12d805d7f3 in _PyEval_Vector Python/ceval.c:6434
#13 0x7e12d805d7f3 in PyEval_EvalCode Python/ceval.c:1148
#14 0x7e12d80a8078 in run_eval_code_obj Python/pythonrun.c:1710
#15 0x7e12d80a8078 in run_mod Python/pythonrun.c:1731
#16 0x7e12d80a9a0d in pyrun_file Python/pythonrun.c:1626
#17 0x7e12d80a9a0d in _PyRun_SimpleFileObject Python/pythonrun.c:440
#18 0x7e12d80aa08f in _PyRun_AnyFileObject Python/pythonrun.c:79
#19 0x7e12d80cae5f in pymain_run_file_obj Modules/main.c:360
#20 0x7e12d80cae5f in pymain_run_file Modules/main.c:379
#21 0x7e12d80cae5f in pymain_run_python Modules/main.c:601
#22 0x7e12d80cae5f in Py_RunMain Modules/main.c:680
#23 0x7e12d80cb3fd in pymain_main Modules/main.c:710
#24 0x7e12d80cb3fd in Py_BytesMain Modules/main.c:734
#25 0x7e12d7a2814f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#26 0x7e12d7a28208 in __libc_start_main_impl ../csu/libc-start.c:360
#27 0x57a6da8c0094 in _start (/home/philippe/.pyenv/versions/3.11.7/bin/python3.11+0x1094) (BuildId: 7798d529d8030c06d05aff3210bfcc29680c1679)

0x61100026ee38 is located 248 bytes inside of 256-byte region [0x61100026ed40,0x61100026ee40)
freed by thread T0 here:
#0 0x7e12d84e0c50 in operator delete(void*, unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:164
#1 0x7e12d4a7cbcb in std::__new_allocatorPyEventLoop::AsyncHandle::deallocate(PyEventLoop::AsyncHandle*, unsigned long) /usr/include/c++/13/bits/new_allocator.h:168
#2 0x7e12d4a7cbcb in std::allocatorPyEventLoop::AsyncHandle::deallocate(PyEventLoop::AsyncHandle*, unsigned long) /usr/include/c++/13/bits/allocator.h:210
#3 0x7e12d4a7cbcb in std::allocator_traits<std::allocatorPyEventLoop::AsyncHandle >::deallocate(std::allocatorPyEventLoop::AsyncHandle&, PyEventLoop::AsyncHandle*, unsigned long) /usr/include/c++/13/bits/alloc_traits.h:516
#4 0x7e12d4a7cbcb in std::_Vector_base<PyEventLoop::AsyncHandle, std::allocatorPyEventLoop::AsyncHandle >::_M_deallocate(PyEventLoop::AsyncHandle*, unsigned long) /usr/include/c++/13/bits/stl_vector.h:387
#5 0x7e12d4a7cbcb in void std::vector<PyEventLoop::AsyncHandle, std::allocatorPyEventLoop::AsyncHandle >::_M_realloc_insertPyEventLoop::AsyncHandle(__gnu_cxx::__normal_iterator<PyEventLoop::AsyncHandle*, std::vector<PyEventLoop::AsyncHandle, std::allocatorPyEventLoop::AsyncHandle > >, PyEventLoop::AsyncHandle&&) /usr/include/c++/13/bits/vector.tcc:519
#6 0x7e12d4a7cbcb in PyEventLoop::AsyncHandle& std::vector<PyEventLoop::AsyncHandle, std::allocatorPyEventLoop::AsyncHandle >::emplace_backPyEventLoop::AsyncHandle(PyEventLoop::AsyncHandle&&) /usr/include/c++/13/bits/vector.tcc:123
#7 0x7e12d4a7cbcb in std::vector<PyEventLoop::AsyncHandle, std::allocatorPyEventLoop::AsyncHandle >::push_back(PyEventLoop::AsyncHandle&&) /usr/include/c++/13/bits/stl_vector.h:1296
#8 0x7e12d4a7cbcb in PyEventLoop::AsyncHandle::getUniqueId(PyEventLoop::AsyncHandle&&) /home/philippe/Sources/PythonMonkey/include/PyEventLoop.hh:74
#9 0x7e12d4a7cbcb in PyEventLoop::AsyncHandle::newEmpty() /home/philippe/Sources/PythonMonkey/include/PyEventLoop.hh:51
#10 0x7e12d4a7cbcb in PyEventLoop::enqueueWithDelay(_object*, double, bool) /home/philippe/Sources/PythonMonkey/src/PyEventLoop.cc:88
#11 0x7e12d4ababc2 in enqueueWithDelay /home/philippe/Sources/PythonMonkey/src/internalBinding/timers.cc:34
#12 0x7e1251caa697 ()
#13 0x7e1251c09acb ()
#14 0x7e1251bff4e8 ()
#15 0x7e12d2cda6e6 in js::jit::MaybeEnterJit(JSContext*, js::RunState&) (/home/philippe/Sources/PythonMonkey/python/pythonmonkey/libmozjs-115.so+0x8da6e6) (BuildId: a8d6e6a0d612ea95c5db4e0a2f2155e199b41e0e)

previously allocated by thread T0 here:
#0 0x7e12d84dfba8 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:95
#1 0x7e12d4a7c92a in std::__new_allocatorPyEventLoop::AsyncHandle::allocate(unsigned long, void const*) /usr/include/c++/13/bits/new_allocator.h:147
#2 0x7e12d4a7c92a in std::allocatorPyEventLoop::AsyncHandle::allocate(unsigned long) /usr/include/c++/13/bits/allocator.h:198
#3 0x7e12d4a7c92a in std::allocator_traits<std::allocatorPyEventLoop::AsyncHandle >::allocate(std::allocatorPyEventLoop::AsyncHandle&, unsigned long) /usr/include/c++/13/bits/alloc_traits.h:482
#4 0x7e12d4a7c92a in std::_Vector_base<PyEventLoop::AsyncHandle, std::allocatorPyEventLoop::AsyncHandle >::_M_allocate(unsigned long) /usr/include/c++/13/bits/stl_vector.h:378
#5 0x7e12d4a7c92a in void std::vector<PyEventLoop::AsyncHandle, std::allocatorPyEventLoop::AsyncHandle >::_M_realloc_insertPyEventLoop::AsyncHandle(__gnu_cxx::__normal_iterator<PyEventLoop::AsyncHandle*, std::vector<PyEventLoop::AsyncHandle, std::allocatorPyEventLoop::AsyncHandle > >, PyEventLoop::AsyncHandle&&) /usr/include/c++/13/bits/vector.tcc:459
#6 0x7e12d4a7c92a in PyEventLoop::AsyncHandle& std::vector<PyEventLoop::AsyncHandle, std::allocatorPyEventLoop::AsyncHandle >::emplace_backPyEventLoop::AsyncHandle(PyEventLoop::AsyncHandle&&) /usr/include/c++/13/bits/vector.tcc:123
#7 0x7e12d4a7c92a in std::vector<PyEventLoop::AsyncHandle, std::allocatorPyEventLoop::AsyncHandle >::push_back(PyEventLoop::AsyncHandle&&) /usr/include/c++/13/bits/stl_vector.h:1296
#8 0x7e12d4a7c92a in PyEventLoop::AsyncHandle::getUniqueId(PyEventLoop::AsyncHandle&&) /home/philippe/Sources/PythonMonkey/include/PyEventLoop.hh:74
#9 0x7e12d4a7c92a in PyEventLoop::AsyncHandle::newEmpty() /home/philippe/Sources/PythonMonkey/include/PyEventLoop.hh:51
#10 0x7e12d4a7c92a in PyEventLoop::enqueueWithDelay(_object*, double, bool) /home/philippe/Sources/PythonMonkey/src/PyEventLoop.cc:88
#11 0x7e12d4ababc2 in enqueueWithDelay /home/philippe/Sources/PythonMonkey/src/internalBinding/timers.cc:34
#12 0x7e12d25514e3 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) (/home/philippe/Sources/PythonMonkey/python/pythonmonkey/libmozjs-115.so+0x1514e3) (BuildId: a8d6e6a0d612ea95c5db4e0a2f2155e199b41e0e)

SUMMARY: AddressSanitizer: heap-use-after-free /usr/include/c++/13/bits/atomic_base.h:505 in std::__atomic_base::load(std::memory_order) const
Shadow bytes around the buggy address:
0x61100026eb80: fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa
0x61100026ec00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x61100026ec80: 00 00 00 00 00 00 00 00 00 00 00 fa fa fa fa fa
0x61100026ed00: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
0x61100026ed80: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x61100026ee00: fd fd fd fd fd fd fd[fd]fa fa fa fa fa fa fa fa
0x61100026ee80: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x61100026ef00: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x61100026ef80: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
0x61100026f000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x61100026f080: 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa fa
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
==398494==ABORTING

Standalone code to reproduce the issue

No response

Relevant log output or backtrace

No response

Additional info if applicable

No response

What branch of PythonMonkey were you developing on? (If applicable)

No response

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

Status

Done

Relationships

None yet

Development

No branches or pull requests

Issue actions