Skip to content

bpo-41654: Fix deallocator of MemoryError to account for subclasses #22020

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

Merged
merged 2 commits into from
Sep 1, 2020

Conversation

pablogsal
Copy link
Member

@pablogsal pablogsal commented Aug 30, 2020

When allocating MemoryError classes, there is some logic to use
pre-allocated instances in a freelist only if the type that is being
allocated is not a subclass of MemoryError. Unfortunately in the
destructor this logic is not present so the freelist is altered even
with subclasses of MemoryError.

https://bugs.python.org/issue41654

@pablogsal pablogsal force-pushed the bpo-41654 branch 4 times, most recently from e204706 to faefcf6 Compare August 31, 2020 11:39
@pablogsal pablogsal force-pushed the bpo-41654 branch 2 times, most recently from 0e25645 to 3941f94 Compare August 31, 2020 20:31
When allocating MemoryError classes, there is some logic to use
pre-allocated instances in a freelist only if the type that is being
allocated is not a subclass of MemoryError. Unfortunately in the
destructor this logic is not present so the freelist is altered even
with subclasses of MemoryError.
return Py_TYPE(self)->tp_free((PyObject *)self);
}

_PyObject_GC_UNTRACK(self);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bugfix. Once this PR is merged, you may propose a PR to fix it in 3.9 and 3.8 as well. I'm surprised that _PyObject_GC_UNTRACK() doesn't crash (assert failure) on subclasses.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR will be backported to all supported branches....do you want a separate PR for them?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"This PR will be backported to all supported branches" oh ok, in this case, there is no need for a separated change ;-)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This bug has been here since forever! 😨

Copy link
Member

@vstinner vstinner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks for the fix @pablogsal!

I tested manually bug.py script attached to https://bugs.python.org/issue41654 : it crashs without the fix, it pass with the fix. I tested Python built in debug mode.

if (type != (PyTypeObject *) PyExc_MemoryError)
/* If this is a subclass of MemoryError, don't use the freelist
* and just return a fresh object */
if (type != (PyTypeObject *) PyExc_MemoryError) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: Can you update this line same like line 2323 after you updated this line ;)

Copy link
Member Author

@pablogsal pablogsal Sep 1, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: Can you update this line same like line 2323 after you updated this line ;)

Here it does not make sense because we don't have an instance yet.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, sorry~. Forget my comment.

Copy link
Member

@shihai1991 shihai1991 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

if (type != (PyTypeObject *) PyExc_MemoryError)
/* If this is a subclass of MemoryError, don't use the freelist
* and just return a fresh object */
if (type != (PyTypeObject *) PyExc_MemoryError) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, sorry~. Forget my comment.

@pablogsal pablogsal merged commit 9b648a9 into python:master Sep 1, 2020
@miss-islington
Copy link
Contributor

Thanks @pablogsal for the PR 🌮🎉.. I'm working now to backport this PR to: 3.6, 3.7, 3.8, 3.9.
🐍🍒⛏🤖

@pablogsal pablogsal deleted the bpo-41654 branch September 1, 2020 18:39
@miss-islington
Copy link
Contributor

Sorry @pablogsal, I had trouble checking out the 3.9 backport branch.
Please backport using cherry_picker on command line.
cherry_picker 9b648a95ccb4c3b14f1e87158f5c9f5dbb2f62c0 3.9

@miss-islington
Copy link
Contributor

Sorry, @pablogsal, I could not cleanly backport this to 3.8 due to a conflict.
Please backport using cherry_picker on command line.
cherry_picker 9b648a95ccb4c3b14f1e87158f5c9f5dbb2f62c0 3.8

@miss-islington
Copy link
Contributor

Sorry @pablogsal, I had trouble checking out the 3.7 backport branch.
Please backport using cherry_picker on command line.
cherry_picker 9b648a95ccb4c3b14f1e87158f5c9f5dbb2f62c0 3.7

@miss-islington
Copy link
Contributor

Sorry, @pablogsal, I could not cleanly backport this to 3.6 due to a conflict.
Please backport using cherry_picker on command line.
cherry_picker 9b648a95ccb4c3b14f1e87158f5c9f5dbb2f62c0 3.6

@vstinner
Copy link
Member

vstinner commented Sep 1, 2020

@pablogsal: I don't think that this change is related to security. Why do you want to backport it to 3.6 and 3.7? https://bugs.python.org/issue41654 type is "crash", not "security".

@pablogsal
Copy link
Member Author

pablogsal commented Sep 1, 2020

@pablogsal: I don't think that this change is related to security. Why do you want to backport it to 3.6 and 3.7? https://bugs.python.org/issue41654 type is "crash", not "security".

I normally qualify segfaults/buffer overflow as security as they can be maliciously used, but it may be a stretch. Let's backport to 3.8 and 3.9 only.

pablogsal added a commit to pablogsal/cpython that referenced this pull request Sep 1, 2020
…sses (pythonGH-22020)

When allocating MemoryError classes, there is some logic to use
pre-allocated instances in a freelist only if the type that is being
allocated is not a subclass of MemoryError. Unfortunately in the
destructor this logic is not present so the freelist is altered even
with subclasses of MemoryError..
(cherry picked from commit 9b648a9)

Co-authored-by: Pablo Galindo <[email protected]>
@bedevere-bot
Copy link

GH-22045 is a backport of this pull request to the 3.9 branch.

@bedevere-bot bedevere-bot removed the needs backport to 3.9 only security fixes label Sep 1, 2020
@bedevere-bot
Copy link

GH-22046 is a backport of this pull request to the 3.8 branch.

pablogsal added a commit to pablogsal/cpython that referenced this pull request Sep 1, 2020
…subclasses (pythonGH-22020)

When allocating MemoryError classes, there is some logic to use
pre-allocated instances in a freelist only if the type that is being
allocated is not a subclass of MemoryError. Unfortunately in the
destructor this logic is not present so the freelist is altered even
with subclasses of MemoryError..
(cherry picked from commit 9b648a9)

Co-authored-by: Pablo Galindo <[email protected]>.
(cherry picked from commit 87e91ae)

Co-authored-by: Pablo Galindo <[email protected]>
pablogsal added a commit that referenced this pull request Sep 1, 2020
…subclasses (GH-22020) (GH-22046)

When allocating MemoryError classes, there is some logic to use
pre-allocated instances in a freelist only if the type that is being
allocated is not a subclass of MemoryError. Unfortunately in the
destructor this logic is not present so the freelist is altered even
with subclasses of MemoryError..
(cherry picked from commit 9b648a9)

Co-authored-by: Pablo Galindo <[email protected]>.
(cherry picked from commit 87e91ae)

Co-authored-by: Pablo Galindo <[email protected]>
pablogsal added a commit that referenced this pull request Sep 1, 2020
…sses (GH-22020) (GH-22045)

When allocating MemoryError classes, there is some logic to use
pre-allocated instances in a freelist only if the type that is being
allocated is not a subclass of MemoryError. Unfortunately in the
destructor this logic is not present so the freelist is altered even
with subclasses of MemoryError..
(cherry picked from commit 9b648a9)

Co-authored-by: Pablo Galindo <[email protected]>
@python python deleted a comment from bedevere-bot Sep 1, 2020
@python python deleted a comment from bedevere-bot Sep 1, 2020
@python python deleted a comment from bedevere-bot Sep 1, 2020
@python python deleted a comment from bedevere-bot Sep 1, 2020
@python python deleted a comment from bedevere-bot Sep 2, 2020
xzy3 pushed a commit to xzy3/cpython that referenced this pull request Oct 18, 2020
…ythonGH-22020)

When allocating MemoryError classes, there is some logic to use
pre-allocated instances in a freelist only if the type that is being
allocated is not a subclass of MemoryError. Unfortunately in the
destructor this logic is not present so the freelist is altered even
with subclasses of MemoryError.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants