Skip to content

SIGSEV with method descriptors called without a second argument #132747

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

Closed
Changaco opened this issue Apr 20, 2025 · 8 comments
Closed

SIGSEV with method descriptors called without a second argument #132747

Changaco opened this issue Apr 20, 2025 · 8 comments
Assignees
Labels
3.13 bugs and security fixes 3.14 new features, bugs and security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs) type-crash A hard crash of the interpreter, possibly with a core dump

Comments

@Changaco
Copy link

Changaco commented Apr 20, 2025

Crash report

What happened?

Since Python 3.12, the following code triggers a segmentation fault:

import _io, sys; _io._TextIOBase.detach.__get__(sys.stderr)

CPython versions tested on:

3.9, 3.11, 3.12, 3.13, 3.14

Operating systems tested on:

Linux

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

No response

Linked PRs

@Changaco Changaco added the type-crash A hard crash of the interpreter, possibly with a core dump label Apr 20, 2025
@picnixz picnixz added extension-modules C modules in the Modules dir 3.12 only security fixes 3.13 bugs and security fixes 3.14 new features, bugs and security fixes labels Apr 20, 2025
@picnixz
Copy link
Member

picnixz commented Apr 20, 2025

It appears that there is some issue with method resolution. When using _io.TextIOWrapper, it's fine but not when using _io._TextIOBase.

Note: _io.TextIOWrapper.detach is a different function by the way.
Note 2: It actually happens with all method descriptors of _TextIOBase.

@picnixz picnixz changed the title Segfault in _io module SIGSEV with method descriptors of _io.TextIOBase on sys.stderr Apr 20, 2025
@picnixz picnixz changed the title SIGSEV with method descriptors of _io.TextIOBase on sys.stderr SIGSEV with method descriptors of _io._TextIOBase Apr 20, 2025
@picnixz
Copy link
Member

picnixz commented Apr 20, 2025

This also crashes:

import io, _io
_io._TextIOBase.read.__get__(io.StringIO())

@Alexandr153
Copy link
Contributor

Alexandr153 commented Apr 20, 2025

It appears that there is some issue with method resolution. When using _io.TextIOWrapper, it's fine but not when using _io._TextIOBase.

As I understand it, the _TextIOBase class is an abstract class because it inherits from the abstract IOBase class and does not implement all of its methods. TextIOWrapper, on the other hand, implements all the methods of the parent abstract class and executes its methods directly.

@picnixz
Copy link
Member

picnixz commented Apr 20, 2025

Actually, I'm not sure about the resolution. It's as if there was a missing tp_flag somewhere or something else. It doesn't seem to occur with other static types. I don't have time to investigate though.

@Changaco
Copy link
Author

In addition to _TextIOBase, the _IOBase, _BufferedIOBase, BufferedReader and BufferedWriter classes are also affected.

Example: import io, _io; _io._IOBase.truncate.__get__(io.StringIO()).

@ZeroIntensity
Copy link
Member

From what I can tell, this is a nasty bug related to descriptors themselves, not _io. You can trigger the same crash with _queue, for example:

import _queue
print(_queue.SimpleQueue.get.__get__(_queue.SimpleQueue()))

This seems to affect all heap types with methods. The issue is that method_get doesn't expect the type to be NULL. I think we just need a guard.

I'm really suprised that nobody noticed this for this long.

@ZeroIntensity ZeroIntensity self-assigned this Apr 21, 2025
@Changaco
Copy link
Author

Changaco commented Apr 21, 2025

I guess nobody noticed this bug before because nobody calls those __get__ methods with only one argument. I only found it accidentally by running Python code that calls all the non-Python __get__ methods it can find on objects in memory, without passing the second argument.

@ZeroIntensity ZeroIntensity removed the 3.12 only security fixes label Apr 21, 2025
ZeroIntensity added a commit to ZeroIntensity/cpython that referenced this issue Apr 21, 2025
…s `__get__` manually (pythonGH-132772)

(cherry picked from commit fa70bf8)

Co-authored-by: Peter Bierma <zintensitydev@gmail.com>
JelleZijlstra pushed a commit that referenced this issue Apr 21, 2025
…et__` manually (GH-132772) (#132786)

(cherry picked from commit fa70bf8)

Co-authored-by: Peter Bierma <zintensitydev@gmail.com>
@picnixz picnixz changed the title SIGSEV with method descriptors of _io._TextIOBase SIGSEV with method descriptors called without a second argument Apr 24, 2025
@picnixz picnixz added interpreter-core (Objects, Python, Grammar, and Parser dirs) and removed extension-modules C modules in the Modules dir labels Apr 24, 2025
@picnixz
Copy link
Member

picnixz commented Apr 24, 2025

Thanks for the report @Changaco and the fix @ZeroIntensity

@picnixz picnixz closed this as completed Apr 24, 2025
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 interpreter-core (Objects, Python, Grammar, and Parser dirs) type-crash A hard crash of the interpreter, possibly with a core dump
Projects
None yet
Development

No branches or pull requests

4 participants