Navigation Menu

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

setting __class__ in __del__ is bad. mmkay. negative ref count! kaboom! #49533

Closed
jwp mannequin opened this issue Feb 16, 2009 · 7 comments
Closed

setting __class__ in __del__ is bad. mmkay. negative ref count! kaboom! #49533

jwp mannequin opened this issue Feb 16, 2009 · 7 comments
Assignees
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) release-blocker type-crash A hard crash of the interpreter, possibly with a core dump

Comments

@jwp
Copy link
Mannequin

jwp mannequin commented Feb 16, 2009

BPO 5283
Nosy @gpshead, @amauryfa, @benjaminp
Files
  • kaboom.py
  • del_changes_class.patch
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = 'https://github.com/amauryfa'
    closed_at = <Date 2009-04-25.00:45:55.313>
    created_at = <Date 2009-02-16.21:23:34.391>
    labels = ['interpreter-core', 'type-crash', 'release-blocker']
    title = 'setting __class__ in __del__ is bad. mmkay. negative ref count! kaboom!'
    updated_at = <Date 2009-04-25.00:45:55.312>
    user = 'https://bugs.python.org/jwp'

    bugs.python.org fields:

    activity = <Date 2009-04-25.00:45:55.312>
    actor = 'benjamin.peterson'
    assignee = 'amaury.forgeotdarc'
    closed = True
    closed_date = <Date 2009-04-25.00:45:55.313>
    closer = 'benjamin.peterson'
    components = ['Interpreter Core']
    creation = <Date 2009-02-16.21:23:34.391>
    creator = 'jwp'
    dependencies = []
    files = ['13110', '13123']
    hgrepos = []
    issue_num = 5283
    keywords = ['patch']
    message_count = 7.0
    messages = ['82272', '82354', '82427', '82439', '82446', '82719', '86442']
    nosy_count = 4.0
    nosy_names = ['gregory.p.smith', 'amaury.forgeotdarc', 'benjamin.peterson', 'jwp']
    pr_nums = []
    priority = 'release blocker'
    resolution = 'fixed'
    stage = 'commit review'
    status = 'closed'
    superseder = None
    type = 'crash'
    url = 'https://bugs.python.org/issue5283'
    versions = ['Python 2.6', 'Python 2.5', 'Python 3.0']

    @jwp
    Copy link
    Mannequin Author

    jwp mannequin commented Feb 16, 2009

    I found this bug by misplacing a line of a code. Yes, I was doing
    naughty things, but in the case of the class that led to the discovery,
    it was inadvertent. :P

    class something_else(object):
     pass
    
    class foo(object):
     def __del__(self):
      self.__class__ = something_else
    
    for _ in range(1000):
     foo()

    That results in a fatal python error due to a negative reference
    count(on the foo class object) in 3.0.

    3.0.1 (release30-maint:69593M, Feb 13 2009, 14:48:10) -> kaboom
    jwp@torch[]:org/pgfoundry/python 134% /src/build/py30/bin/python3.0
    ./kaboom.py
    Fatal Python error: Objects/descrobject.c:10 object at 0x5221b8 has
    negative ref count -1
    zsh: abort /src/build/py30/bin/python3.0 ./kaboom.py

    2.6 (r26:66714, Dec 21 2008, 21:17:32) -> kaboom
    jwp@torch[]:org/pgfoundry/python 0% /sw/bin/python2.6 ./kaboom.py

    Fatal Python error: GC object already tracked
    zsh: abort /sw/bin/python2.6 ./kaboom.py

    2.5.2 (r252:60911, Jun 15 2008, 18:55:39) -> no kaboom (no asserts? eh..)
    ...

    2.5.1 (r251:54863, Apr 15 2008, 22:57:26) -> kaboom (/usr/bin/python2.5)
    jwp@torch[]:org/pgfoundry/python 0% /usr/bin/python2.5 ./kaboom.py
    Assertion failed: (PyType_Check(base)), function _PyType_Lookup, file
    Objects/typeobject.c, line 2035.
    zsh: abort /usr/bin/python2.5 ./kaboom.py

    @jwp jwp mannequin added interpreter-core (Objects, Python, Grammar, and Parser dirs) type-crash A hard crash of the interpreter, possibly with a core dump labels Feb 16, 2009
    @amauryfa
    Copy link
    Member

    Yes, the wrong type is DECREF'd when the object is deallocated.
    Patch attached.

    @benjaminp
    Copy link
    Contributor

    The patch looks correct, but are there more places where the type is
    kept in a local variable while Python code is invoked?

    @amauryfa
    Copy link
    Member

    I carefully looked at all places that store ->ob_type or Py_TYPE() in a
    local variable, and I could not find any exploit. Most places don't
    reuse the type once the method or the slot has been called.

    Two places were harder to analyze: subtype_clear (but an attack would
    use __del__, and use a reference cycle: subtype_clear is never called in
    this case) and PyObject_Generic(Get|Set)Attr (the only escape path to
    python code could be through PyType_Ready; but it has already been
    called for heap types)

    @benjaminp
    Copy link
    Contributor

    On Wed, Feb 18, 2009 at 4:51 PM, Amaury Forgeot d'Arc
    <report@bugs.python.org> wrote:

    Amaury Forgeot d'Arc <amauryfa@gmail.com> added the comment:

    I carefully looked at all places that store ->ob_type or Py_TYPE() in a
    local variable, and I could not find any exploit. Most places don't
    reuse the type once the method or the slot has been called.

    Thanks for looking!

    Two places were harder to analyze: subtype_clear (but an attack would
    use __del__, and use a reference cycle: subtype_clear is never called in
    this case) and PyObject_Generic(Get|Set)Attr (the only escape path to
    python code could be through PyType_Ready; but it has already been
    called for heap types)

    Well, I think we can deal with those if they are reported. Go ahead
    and apply the patch.

    @amauryfa amauryfa self-assigned this Feb 19, 2009
    @gpshead
    Copy link
    Member

    gpshead commented Feb 25, 2009

    Could the PyObject_ClearWeakRefs(self); call in the middle of the lines
    del_changes_class.patch adds also be used to cause python code to set
    __del__ or __dict__ causing the wrong destructor or wrong dict to be
    DECREFed?

    (I'm trying to wrap my head around the possibilities here and come up
    with a test case of that but weakref isn't behaving as i'd expect)

    @devdanzin devdanzin mannequin added the release-blocker label Apr 22, 2009
    @benjaminp
    Copy link
    Contributor

    Fixed in r71860.

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    interpreter-core (Objects, Python, Grammar, and Parser dirs) release-blocker type-crash A hard crash of the interpreter, possibly with a core dump
    Projects
    None yet
    Development

    No branches or pull requests

    3 participants