GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |||||||||||||||||||
GeezerVison is showing github.com — gh-106092: Fix use-after-free crash in frame_dealloc by andersk · Pull Request #106875 · python/cpython Conversation
|
|
I think it better to ensure that Do you have a reproducer that doesn't need third-party modules? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Note that
Couldn’t that incorrectly skip the deallocation of
Not at present—further minimization is probably possible but difficult, because the segfault requires a specific coincidence of the position of the stack pointer within the current stack chunk, the GC threshold, and the trashcan recursion depth. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
A reproducer that causes an assertion failure would be good enough, I think. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| if (f->f_frame->owner == FRAME_OWNED_BY_FRAME_OBJECT) { | ||
| assert(f->f_frame == (_PyInterpreterFrame *)f->_f_frame_data); | ||
| _PyInterpreterFrame *frame = (_PyInterpreterFrame *)f->_f_frame_data; | ||
| if (f->f_frame == frame && frame->owner == FRAME_OWNED_BY_FRAME_OBJECT) { |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
This looks correct.
Note:
In theory, f->f_frame == frame and frame->owner == FRAME_OWNED_BY_FRAME_OBJECT should be equivalent, but in practice they are not.
We can't just check frame->owner == FRAME_OWNED_BY_FRAME_OBJECT because of the Trashcan mechanism, and we can't just check f->f_frame == frame because of this.
So we need both checks here.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Should this check be put in other places too? We are currently investigating the root cause of segfaults in 3.11.5 with call stacks ending with
#0 0x0000000000635d9a in ?? ()
#1 0x00000000004d8e27 in PyFrame_FastToLocalsWithError ()
#2 0x00000000004d8e3e in ?? ()
#3 0x000000000054e5f6 in _PyObject_GenericGetAttrWithDict ()
What we are trying to access here is frame.f_locals. The frame object is obtained from looping over all thread states and calling PyThreadState_GetFrame on them (so we know we have a strong reference to it). Because of the inlining it's not immediately obvious where in PyFrame_FastToLocalsWithError we are segfaulting exactly, but our current hunch is that it is because the referenced _PyInterpreterState might have been deallocated. We're still investigating this.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Thanks @andersk for the PR, and @markshannon for merging it 🌮🎉.. I'm working now to backport this PR to: 3.12. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
GH-107532 is a backport of this pull request to the 3.12 branch. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Thanks @andersk for the PR, and @markshannon for merging it 🌮🎉.. I'm working now to backport this PR to: 3.11. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
GH-107533 is a backport of this pull request to the 3.11 branch. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
…106875) It was possible for the trashcan to delay the deallocation of a PyFrameObject until after its corresponding _PyInterpreterFrame has already been freed. So frame_dealloc needs to avoid dereferencing the f_frame pointer unless it first checks that the pointer still points to the interpreter frame within the frame object. (cherry picked from commit 557b05c) Co-authored-by: Anders Kaseorg <[email protected]> Signed-off-by: Anders Kaseorg <[email protected]>
…106875) It was possible for the trashcan to delay the deallocation of a PyFrameObject until after its corresponding _PyInterpreterFrame has already been freed. So frame_dealloc needs to avoid dereferencing the f_frame pointer unless it first checks that the pointer still points to the interpreter frame within the frame object. (cherry picked from commit 557b05c) Co-authored-by: Anders Kaseorg <[email protected]> Signed-off-by: Anders Kaseorg <[email protected]>
… (#107532) gh-106092: Fix use-after-free crash in frame_dealloc (GH-106875) It was possible for the trashcan to delay the deallocation of a PyFrameObject until after its corresponding _PyInterpreterFrame has already been freed. So frame_dealloc needs to avoid dereferencing the f_frame pointer unless it first checks that the pointer still points to the interpreter frame within the frame object. (cherry picked from commit 557b05c) Signed-off-by: Anders Kaseorg <[email protected]> Co-authored-by: Anders Kaseorg <[email protected]>
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
Segmentation fault in 3.11.4, 3.12.0b3; _PyInterpreterFrame ownership issue
There was an error while loading. Please reload this page.