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

Segfault from asyncio.events._running_loop.__setattr__ with invalid name #127190

Closed
devdanzin opened this issue Nov 23, 2024 · 4 comments
Closed
Labels
3.13 bugs and security fixes 3.14 new features, bugs and security fixes extension-modules C modules in the Modules dir type-crash A hard crash of the interpreter, possibly with a core dump

Comments

@devdanzin
Copy link
Contributor

devdanzin commented Nov 23, 2024

Crash report

What happened?

It's possible to segfault the interpreter by calling asyncio.events._running_loop.__setattr__ with a special class as name, as in this example:

import asyncio.events

class Liar1:
    def __eq__(self, other):
        return True

asyncio.events._running_loop.__setattr__(Liar1(), type)

The backtrace is:

#0  _copy_characters (to=<optimized out>, to_start=<optimized out>, from=<optimized out>,
    from_start=<optimized out>, how_many=<optimized out>, check_maxchar=0) at Objects/unicodeobject.c:1530
#1  0x000055555573497b in _copy_characters (check_maxchar=0, how_many=16842781, from_start=0,
    from=0x7ffff71a3cb0, to_start=<optimized out>, to=<optimized out>) at Objects/unicodeobject.c:1435
#2  _PyUnicode_FastCopyCharacters (how_many=16842781, from_start=0, from=0x7ffff71a3cb0,
    to_start=<optimized out>, to=<optimized out>) at Objects/unicodeobject.c:1562
#3  _PyUnicodeWriter_WriteStr (writer=0x7fffffffd660, str=0x7ffff71a3cb0) at Objects/unicodeobject.c:13635
#4  0x0000555555738abd in unicode_fromformat_arg (vargs=0x7fffffffd5d8,
    f=0x5555558d2a04 "U' is read-only", writer=0x7fffffffd660) at Objects/unicodeobject.c:2993
#5  unicode_from_format (writer=writer@entry=0x7fffffffd660,
    format=format@entry=0x5555558d29e8 "'%.100s' object attribute '%U' is read-only",
    vargs=vargs@entry=0x7fffffffd6c0) at Objects/unicodeobject.c:3167
#6  0x0000555555739a1f in PyUnicode_FromFormatV (
    format=format@entry=0x5555558d29e8 "'%.100s' object attribute '%U' is read-only",
    vargs=vargs@entry=0x7fffffffd6c0) at Objects/unicodeobject.c:3201
#7  0x00005555557c7770 in _PyErr_FormatV (vargs=0x7fffffffd6c0,
    format=0x5555558d29e8 "'%.100s' object attribute '%U' is read-only",
    exception=0x555555a89960 <_PyExc_AttributeError>, tstate=0x555555b08c10 <_PyRuntime+313456>)
    at Python/errors.c:1163
#8  PyErr_Format (exception=0x555555a89960 <_PyExc_AttributeError>,
    format=format@entry=0x5555558d29e8 "'%.100s' object attribute '%U' is read-only")
    at Python/errors.c:1198
#9  0x00005555558a613d in local_setattro (self=0x7ffff718d020, name=0x7ffff71a3cb0,
    v=0x555555a9c6e0 <PyType_Type>) at ./Modules/_threadmodule.c:1625
#10 0x00005555556dff7d in wrap_setattr (self=0x7ffff718d020, args=<optimized out>,
    wrapped=0x5555558a6070 <local_setattro>) at Objects/typeobject.c:9172

No threads, free-threading or JIT necessary for this to work.

In a debug built, an assertion fails instead:

Objects/unicodeobject.c:640: _PyUnicode_CheckConsistency: Assertion failed: PyType_HasFeature((_Py_TYPE(((PyObject*)((op))))), ((1UL << 28)))
Enable tracemalloc to get the memory block allocation traceback

object address  : 0x20000549920
object refcount : 2
object type     : 0x200011e2810
object type name: Liar1
object repr     : <__main__.Liar1 object at 0x20000549920>

Fatal Python error: _PyObject_AssertFailed: _PyObject_AssertFailed
Python runtime state: initialized
Aborted

Found using fusil by @vstinner.

CPython versions tested on:

3.13, 3.14, CPython main branch

Operating systems tested on:

Linux

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

Python 3.14.0a2+ experimental free-threading build (heads/main-dirty:a13e94d84bf, Nov 23 2024, 07:16:19) [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 23, 2024
@github-project-automation github-project-automation bot moved this to Todo in asyncio Nov 23, 2024
@picnixz picnixz added extension-modules C modules in the Modules dir 3.13 bugs and security fixes topic-free-threading 3.14 new features, bugs and security fixes topic-JIT labels Nov 23, 2024
@colesbury
Copy link
Contributor

The report says it's not specific to the JIT or free-threading :)

@devdanzin - if you're able to reproduce an issue on both the default (with GIL) build and free threading, it's probably more helpful to report the python -VV output from the main build (instead of free threading).

@vstinner
Copy link
Member

The bug is unrelated to asyncio, it's a bug in threading.local:

import threading

class Loop(threading.local):
    attr = 1

class Liar1:
    def __eq__(self, other):
        return True

loop = Loop()
loop.__setattr__(Liar1(), 2)

It's a minor bug in the error handling of local_setattro(). I'm working on a fix.

vstinner added a commit to vstinner/cpython that referenced this issue Nov 28, 2024
Don't make the assumption that the first argument is a string. Use
repr() to format the argument instead.
vstinner added a commit to vstinner/cpython that referenced this issue Nov 28, 2024
Don't make the assumption that the first argument is a string. Use
repr() to format the argument instead.
vstinner added a commit to vstinner/cpython that referenced this issue Nov 28, 2024
Don't make the assumption that the 'name' argument is a string. Use
repr() to format the 'name' argument instead.
@vstinner
Copy link
Member

I wrote PR #127366 to fix the issue.

vstinner added a commit that referenced this issue Nov 28, 2024
Don't make the assumption that the 'name' argument is a string. Use
repr() to format the 'name' argument instead.
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Nov 28, 2024
Don't make the assumption that the 'name' argument is a string. Use
repr() to format the 'name' argument instead.
(cherry picked from commit 20657fb)

Co-authored-by: Victor Stinner <vstinner@python.org>
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Nov 28, 2024
Don't make the assumption that the 'name' argument is a string. Use
repr() to format the 'name' argument instead.
(cherry picked from commit 20657fb)

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

Fixed by 20657fb. Thanks for your report @devdanzin.

@github-project-automation github-project-automation bot moved this from Todo to Done in asyncio Nov 28, 2024
vstinner added a commit that referenced this issue Nov 28, 2024
…27368)

gh-127190: Fix local_setattro() error handling (GH-127366)

Don't make the assumption that the 'name' argument is a string. Use
repr() to format the 'name' argument instead.
(cherry picked from commit 20657fb)

Co-authored-by: Victor Stinner <vstinner@python.org>
vstinner added a commit that referenced this issue Dec 1, 2024
…27367)

gh-127190: Fix local_setattro() error handling (GH-127366)

Don't make the assumption that the 'name' argument is a string. Use
repr() to format the 'name' argument instead.
(cherry picked from commit 20657fb)

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 extension-modules C modules in the Modules dir type-crash A hard crash of the interpreter, possibly with a core dump
Projects
Status: Done
Development

No branches or pull requests

4 participants