Repository navigation
segfault/debug abort from perf_map_write_entry with lone surrogate in filename or qualname #156114
Copy link
Copy link
Closed
Labels
interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)type-crashA hard crash of the interpreter, possibly with a core dumpA hard crash of the interpreter, possibly with a core dump
Description
Crash report
What happened?
import sys
import sysconfig
import types
assert not sysconfig.get_config_var("PY_HAVE_PERF_TRAMPOLINE")
sys.activate_stack_trampoline("perf")
code = compile("pass", "bad\ud800file", "exec")
eval(code)python3: Python/generated_cases.c.h:13862: PyObject *_PyEval_EvalFrameDefault(PyThreadState *, _PyInterpreterFrame *, int): Assertion `!_PyErr_Occurred(tstate)' failed.
Aborted
perf_map_write_entry does not check that the calls to PyUnicde_AsUTF8 succeed, resulting in null pointers being passed to snprintf. This is UB, and may crash in some libc versions, or may be replaced with a placeholder value.
Regardless, a failed conversion leaves a stale exception around, which then will trigger a debug abort a bit later (in debug builds):
cpython/Python/perf_trampoline.c
Lines 251 to 262 in e8158d1
| perf_map_write_entry(void *state, const void *code_addr, | |
| size_t code_size, PyCodeObject *co) | |
| { | |
| const char *entry = ""; | |
| if (co->co_qualname != NULL) { | |
| entry = PyUnicode_AsUTF8(co->co_qualname); | |
| } | |
| const char *filename = ""; | |
| if (co->co_filename != NULL) { | |
| filename = PyUnicode_AsUTF8(co->co_filename); | |
| } | |
| size_t perf_map_entry_size = snprintf(NULL, 0, "py::%s:%s", entry, filename) + 1; |
Seems trivial to check the result value here. I notice that perf_jit_trampoline (similar code) uses a common helper function that checks the values and replaces them with "" if NULL
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Output from running 'python -VV' on the command line:
Python 3.16.0a0 (heads/main-dirty:20e6c2f, Aug 19 2026, 15:22:30) [Clang 22.1.8 ]
Linked PRs
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)type-crashA hard crash of the interpreter, possibly with a core dumpA hard crash of the interpreter, possibly with a core dump
Activity
Merge branch 'main' into pythongh-156114
Merge branch 'main' into pythongh-156114
Merge branch 'main' into pythongh-156114
gh-156114: Fix crash in perf trampoline with unencodable code names (#…
[3.13] gh-156114: Fix crash in perf trampoline with unencodable code …
[3.14] gh-156114: Fix crash in perf trampoline with unencodable code …
[3.15] gh-156114: Fix crash in perf trampoline with unencodable code …