Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

Defining user symbols from more than one thread at the same time, with no undo transaction open, crashes the core

Aperta
#8,531 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 2 giorni

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
48/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
cpp, python

Direzione di ricerca

Reproduce the crash with concurrent_user_symbols.py against /bin/ls, then start at the BNDefineUserSymbol entry point and the undo path used by define_user_symbol when no transaction is open. Compare the failing headless case with begin_undo_actions() and define_auto_symbol; done means concurrent user-symbol operations no longer crash or corrupt memory, with the behavior covered by an appropriate regression test.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

The following issue was identified, triaged and written by Claude Fable 5.1, I have read through it to make sure the information is coherent and useful.


Version and Platform (required):

  • Binary Ninja Version: 6.1.10594-dev
  • Edition: Ultimate
  • OS: macOS
  • OS Version: 26.5.1
  • CPU Architecture: Apple Silicon (arm64)

Bug Description:
Defining user symbols from more than one thread at the same time, with no undo transaction open, crashes the core. With four Python threads each redefining the user symbol at every function start of /bin/ls, the headless process dies on most runs, either with a segmentation fault or with libmalloc aborting on a bad free: ___BUG_IN_CLIENT_OF_LIBMALLOC_POINTER_BEING_FREED_WAS_NOT_ALLOCATED, thirteen frames below BNDefineUserSymbol.

The same loop on one thread never crashes. The same loop with define_auto_symbol in place of define_user_symbol never crashes with eight threads. And the same loop headless with the whole run inside one begin_undo_actions() / commit_undo_actions() pair never crashes either, while the GUI Python console, which runs each command inside a transaction, survived 17 runs. So the fault looks to be in the undo entry that each user-symbol call opens and commits for itself when no transaction is open. The threads do not need to touch the same addresses: giving each thread its own disjoint set of function starts still crashes 2 of 5 runs.

Steps To Reproduce:

  1. Save the script below as concurrent_user_symbols.py.
  2. Run it headless with any Mach-O: python3 concurrent_user_symbols.py /bin/ls
  3. It dies within a second or two. If a run happens to survive, run it again; here it crashed 5 of 5 runs with four threads.
"""Redefining user symbols from several threads at once crashes the core.

Run with any Mach-O, e.g.:  python3 concurrent_user_symbols.py /bin/ls

Each thread walks every function start, undefines whatever symbol is there and defines a user
symbol with a fresh name, four times over. Four threads crash the process on most runs; the same
loop on one thread never does, and neither does the same loop with define_auto_symbol in place of
define_user_symbol.
"""
import sys
import threading

import binaryninja as bn

bv = bn.load(sys.argv[1])
bv.update_analysis_and_wait()
starts = [f.start for f in bv.functions]


def redefine(tag):
    for round in range(4):
        for start in starts:
            existing = bv.get_symbol_at(start)
            if existing is not None:
                if existing.auto:
                    bv.undefine_auto_symbol(existing)
                else:
                    bv.undefine_user_symbol(existing)
            bv.define_user_symbol(bn.Symbol(bn.SymbolType.FunctionSymbol, start, f"{tag}_{round}_{start:x}"))


threads = [threading.Thread(target=redefine, args=(f"t{i}",)) for i in range(4)]
for t in threads:
    t.start()
for t in threads:
    t.join()
print("no crash this run; run it again")

Crash frequency over five runs per configuration, headless, all with BN_DISABLE_USER_PLUGINS=1:

Threads Operation per address Undo transaction Crashes
4 undefine existing, then define_user_symbol none 5 / 5
4 define_user_symbol only none 2 / 5
4 undefine, then define_user_symbol, each thread on disjoint addresses none 2 / 5
4 undefine, then define_user_symbol one, opened before the threads start and committed after they join 0 / 5
4 undefine, then define_user_symbol one per thread 2 / 5
2 undefine, then define_user_symbol none 0 / 5
1, with update_analysis() running alongside undefine, then define_user_symbol none 0 / 5
8 define_auto_symbol only none 0 / 5

Expected Behavior:
Either the calls are safe to make from several threads, as the rest of the BinaryView API is, or the documentation says user-symbol definition must be serialised by the caller, or made inside an undo transaction. Silent memory corruption is neither.

Screenshots/Video Recording:
Not applicable; the crashing thread from the macOS crash report of one run (SIGABRT variant):

exception: EXC_CRASH SIGABRT
  0 libsystem_kernel.dylib             __pthread_kill + 8
  1 libsystem_pthread.dylib            pthread_kill + 296
  2 libsystem_c.dylib                  abort + 148
  3 libsystem_malloc.dylib             malloc_vreport + 892
  4 libsystem_malloc.dylib             malloc_report + 64
  5 libsystem_malloc.dylib             ___BUG_IN_CLIENT_OF_LIBMALLOC_POINTER_BEING_FREED_WAS_NOT_ALLOCATED + 76
  6 libbinaryninjacore.1.dylib         +0xe15010
  7 libbinaryninjacore.1.dylib         +0xe12810
  8 libbinaryninjacore.1.dylib         +0xe123a4
  9 libbinaryninjacore.1.dylib         +0x5a2c08
 10 libbinaryninjacore.1.dylib         +0x95b7a4
 11 libbinaryninjacore.1.dylib         +0x58ef30
 12 libbinaryninjacore.1.dylib         +0x28d45c
 13 libbinaryninjacore.1.dylib         BNDefineUserSymbol + 60
 14 libffi.dylib                       ffi_call_SYSV + 80
 15 libffi.dylib                       ffi_call_int + 1220
 16 _ctypes.cpython-313-darwin.so      _ctypes_callproc + 732
 17 _ctypes.cpython-313-darwin.so      PyCFuncPtr_call + 264
 18 Python                             _PyObject_MakeTpCall + 120
 19 Python                             _PyEval_EvalFrameDefault + 19532
 20 Python                             method_vectorcall + 152
 21 Python                             thread_run + 180

Other runs die with EXC_BAD_ACCESS / SIGSEGV in the same region of the core (frames +0xe15010 and +0xe123a4 recur). The full .ips files can be attached on request.

Binary:
Not binary-specific: /bin/ls from macOS 26.5.1 was used, and any Mach-O with a few dozen functions reproduces it.

Additional Information:
The GUI Python console does not reproduce this: the same loop pasted there survived 17 runs (16 with four threads, one with eight). Headless, it also stops reproducing when the whole run is wrapped in a single bv.begin_undo_actions() / bv.commit_undo_actions() pair (0 of 5), while one transaction per thread still crashes (2 of 5). So the fault appears to be in the undo entry each user-symbol call creates and commits for itself when no transaction is open, which is the situation in every headless script and never in the console. Python 3.13 headless with the API module from the application bundle and no user plugins loaded. The undefine-then-define pair is the shape that crashes most reliably, but define_user_symbol alone from four threads is enough.

Lingua principale
C++
Stelle
1.3k
Fork
297
Merge medio
3g 11h
PR unite (30g)
17

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di Vector35/binaryninja-api

Tutte le issue di Vector35/binaryninja-api

Issue simili

Altre issue su C++

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.