Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

_pyrepl._minimal_curses.tigetstr segfaults #126456

Closed
devdanzin opened this issue Nov 5, 2024 · 2 comments
Closed

_pyrepl._minimal_curses.tigetstr segfaults #126456

devdanzin opened this issue Nov 5, 2024 · 2 comments
Labels
3.13 bugs and security fixes 3.14 new features, bugs and security fixes topic-repl Related to the interactive shell type-crash A hard crash of the interpreter, possibly with a core dump

Comments

@devdanzin
Copy link
Contributor

devdanzin commented Nov 5, 2024

Crash report

What happened?

Calling tigetstr from the _pyrepl._minimal_curses module segfaults, on free-threading or normal builds:

python -c "from _pyrepl._minimal_curses import tigetstr; tigetstr('')"
Segmentation fault

It happens in the return line of the function, on access of the .value attribute:

def tigetstr(cap):
if not isinstance(cap, bytes):
cap = cap.encode("ascii")
result = clib.tigetstr(cap)
if ctypes.cast(result, ctypes.c_void_p).value == ERR:
return None
return ctypes.cast(result, ctypes.c_char_p).value

Backtrace looks like:

#0  __strlen_avx2 () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:510
#1  0x00007ffff7c335ff in z_get (ptr=<optimized out>, size=<optimized out>) at ./Modules/_ctypes/cfield.c:1382
#2  0x00007ffff7c20f0a in Simple_get_value (self=0x200009b0fe0, _unused_ignored=<optimized out>) at ./Modules/_ctypes/_ctypes.c:5062
#3  0x0000555555691b7a in getset_get (self=self@entry=<getset_descriptor at remote 0x20000ac5410>,
    obj=obj@entry=<c_char_p() at remote 0x200009b0fe0>, type=<optimized out>) at Objects/descrobject.c:193
#4  0x000055555570a99d in _PyObject_GenericGetAttrWithDict (obj=<c_char_p() at remote 0x200009b0fe0>, name='value',
    dict=dict@entry=0x0, suppress=suppress@entry=0) at Objects/object.c:1659
#5  0x000055555570b538 in PyObject_GenericGetAttr (obj=<optimized out>, name=<optimized out>) at Objects/object.c:1741
#6  0x000055555570a740 in PyObject_GetAttr (v=v@entry=<c_char_p() at remote 0x200009b0fe0>, name='value') at Objects/object.c:1255
#7  0x000055555585be7e in _PyEval_EvalFrameDefault (tstate=tstate@entry=0x555555d2c2a0 <_PyRuntime+359904>, frame=0x7ffff7fb0088,
    throwflag=throwflag@entry=0) at ./Include/internal/pycore_stackref.h:74
#8  0x000055555586fb1f in _PyEval_EvalFrame (throwflag=0, frame=<optimized out>, tstate=0x555555d2c2a0 <_PyRuntime+359904>)
    at ./Include/internal/pycore_ceval.h:116
#9  _PyEval_Vector (tstate=tstate@entry=0x555555d2c2a0 <_PyRuntime+359904>, func=func@entry=0x20000ad32d0,
    locals=locals@entry={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <type at remote 0x20000276e10>, '__spec__': None, '__builtins__': <module at remote 0x2000025c640>, 'tigetstr': <function at remote 0x200008b24d0>},
    args=args@entry=0x0, argcount=argcount@entry=0, kwnames=kwnames@entry=0x0) at Python/ceval.c:1886
#10 0x000055555586fd6c in PyEval_EvalCode (co=co@entry=<code at remote 0x20000a87450>,
    globals=globals@entry={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <type at remote 0x20000276e10>, '__spec__': None, '__builtins__': <module at remote 0x2000025c640>, 'tigetstr': <function at remote 0x200008b24d0>},
    locals=locals@entry={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <type at remote 0x20000276e10>, '__spec__': None, '__builtins__': <module at remote 0x2000025c640>, 'tigetstr': <function at remote 0x200008b24d0>})
    at Python/ceval.c:662
#11 0x000055555595452a in run_eval_code_obj (tstate=tstate@entry=0x555555d2c2a0 <_PyRuntime+359904>, co=co@entry=0x20000a87450,
    globals=globals@entry={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <type at remote 0x20000276e10>, '__spec__': None, '__builtins__': <module at remote 0x2000025c640>, 'tigetstr': <function at remote 0x200008b24d0>},
    locals=locals@entry={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <type at remote 0x20000276e10>, '__spec__': None, '__builtins__': <module at remote 0x2000025c640>, 'tigetstr': <function at remote 0x200008b24d0>})
    at Python/pythonrun.c:1338

This issue doesn't affect curses.tigetstr.

Found using fusil by @vstinner.

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Output from running 'python -VV' on the command line:

Python 3.14.0a1+ experimental free-threading build (heads/main-dirty:bfc1d2504c, Nov 4 2024, 07:55:58) [GCC 11.4.0]

Linked PRs

@devdanzin devdanzin added the type-crash A hard crash of the interpreter, possibly with a core dump label Nov 5, 2024
@ZeroIntensity ZeroIntensity added 3.13 bugs and security fixes 3.14 new features, bugs and security fixes topic-repl Related to the interactive shell labels Nov 6, 2024
vstinner added a commit to vstinner/cpython that referenced this issue Nov 6, 2024
@vstinner
Copy link
Member

vstinner commented Nov 6, 2024

I wrote #126472 to fix it.

miss-islington pushed a commit to miss-islington/cpython that referenced this issue Nov 13, 2024
(cherry picked from commit b2bbdc5)

Co-authored-by: Victor Stinner <vstinner@python.org>
@vstinner
Copy link
Member

Fixed in the main branch, the backport to 3.13 will follow. Thanks for your bug report @devdanzin.

vstinner added a commit that referenced this issue Nov 13, 2024
gh-126456: Fix _pyrepl curses tigetstr() (GH-126472)
(cherry picked from commit b2bbdc5)

Co-authored-by: Victor Stinner <vstinner@python.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.13 bugs and security fixes 3.14 new features, bugs and security fixes topic-repl Related to the interactive shell type-crash A hard crash of the interpreter, possibly with a core dump
Projects
None yet
Development

No branches or pull requests

3 participants