Skip to content

bpo-38395: Fix ownership in weakref.proxy methods #16632

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 6 commits into from
Oct 8, 2019

Conversation

pablogsal
Copy link
Member

@pablogsal pablogsal commented Oct 8, 2019

The implementation of weakref.proxy's methods call back into the Python
API using a borrowed references of the weakly referenced object
(acquired via PyWeakref_GET_OBJECT). This API call may delete the last
reference to the object (either directly or via GC), leaving a dangling
pointer, which can be subsequently dereferenced.

To fix this, claim temporarily ownership of the referenced object when
calling the appropiate method. Some functions because at the moment they
do not need to access the borrowed referent, but to protect against
future changes to these functions, ownership needs to be fixed in
all potentially affected methids.

https://bugs.python.org/issue38395

The implementation of weakref.proxy's methods call back into the Python
API using a borrowed references of the weakly referenced object
(acquired via PyWeakref_GET_OBJECT). This API call may delete the last
reference to the object (either directly or via GC), leaving a dangling
pointer, which can be subsequently dereferenced.

To fix this, claim temporarily ownership of the referenced object when
calling the appropiate method. Some functions because at the moment they
do not need to access the borrowed referent, but to protect against
future changes to these functions, ownership needs to be fixed in
all potentially affected methids.
Copy link
Member

@pitrou pitrou left a comment

Choose a reason for hiding this comment

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

LGTM, thank you

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.

weakref_hash() doesn't seem to hold a strong reference to call PyObject_Hash() which may execute arbitrary Python code, no?

Same remark for weakref_repr(), weakref_richcompare(), proxy_bool().

@pablogsal
Copy link
Member Author

@vstinner Done, can you review again?

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.

Hum, WRAP_UNARY(), WRAP_BINARY(), WRAP_TERNARY() and WRAP_METHOD() still have the same bug, no?

By the way, UNWRAP_I() is no longer used and so can be removed.

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. Goodbye borrowed references!

@pablogsal pablogsal merged commit 10cd00a into python:master Oct 8, 2019
@pablogsal pablogsal deleted the bpo-38395 branch October 8, 2019 15:30
@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.
🐍🍒⛏🤖

@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 10cd00a9e3c22af37c748ea5a417f6fb66601e21 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 10cd00a9e3c22af37c748ea5a417f6fb66601e21 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 10cd00a9e3c22af37c748ea5a417f6fb66601e21 3.6

pablogsal added a commit to pablogsal/cpython that referenced this pull request Oct 8, 2019
The implementation of weakref.proxy's methods call back into the Python
API using a borrowed references of the weakly referenced object
(acquired via PyWeakref_GET_OBJECT). This API call may delete the last
reference to the object (either directly or via GC), leaving a dangling
pointer, which can be subsequently dereferenced.

To fix this, claim a temporary ownership of the referenced object when
calling the appropriate method. Some functions because at the moment they
do not need to access the borrowed referent, but to protect against
future changes to these functions, ownership need to be fixed in
all potentially affected methods.

(cherry picked from commit 10cd00a)
pablogsal added a commit to pablogsal/cpython that referenced this pull request Oct 8, 2019
The implementation of weakref.proxy's methods call back into the Python
API using a borrowed references of the weakly referenced object
(acquired via PyWeakref_GET_OBJECT). This API call may delete the last
reference to the object (either directly or via GC), leaving a dangling
pointer, which can be subsequently dereferenced.

To fix this, claim a temporary ownership of the referenced object when
calling the appropriate method. Some functions because at the moment they
do not need to access the borrowed referent, but to protect against
future changes to these functions, ownership need to be fixed in
all potentially affected methods..
(cherry picked from commit 10cd00a)

Co-authored-by: Pablo Galindo <[email protected]>
@python python deleted a comment from bedevere-bot Oct 8, 2019
pablogsal added a commit to pablogsal/cpython that referenced this pull request Oct 8, 2019
The implementation of weakref.proxy's methods call back into the Python
API using a borrowed references of the weakly referenced object
(acquired via PyWeakref_GET_OBJECT). This API call may delete the last
reference to the object (either directly or via GC), leaving a dangling
pointer, which can be subsequently dereferenced.

To fix this, claim a temporary ownership of the referenced object when
calling the appropriate method. Some functions because at the moment they
do not need to access the borrowed referent, but to protect against
future changes to these functions, ownership need to be fixed in
all potentially affected methods..
(cherry picked from commit 10cd00a)

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

GH-16663 is a backport of this pull request to the 3.7 branch.

@vstinner
Copy link
Member

vstinner commented Oct 8, 2019

@pablogsal pablogsal removed the needs backport to 3.6 label 1 hour ago

I don't think that this change can be qualified as a fix for a security issue, and 3.6 no longer accept bugfixes. So yeah, no need to backport to 3.6 :-)

pablogsal added a commit to pablogsal/cpython that referenced this pull request Oct 8, 2019
The implementation of weakref.proxy's methods call back into the Python
API using a borrowed references of the weakly referenced object
(acquired via PyWeakref_GET_OBJECT). This API call may delete the last
reference to the object (either directly or via GC), leaving a dangling
pointer, which can be subsequently dereferenced.

To fix this, claim a temporary ownership of the referenced object when
calling the appropriate method. Some functions because at the moment they
do not need to access the borrowed referent, but to protect against
future changes to these functions, ownership need to be fixed in
all potentially affected methods..
(cherry picked from commit 10cd00a)

Co-authored-by: Pablo Galindo <[email protected]>
pablogsal added a commit that referenced this pull request Oct 8, 2019
…H-16662)

The implementation of weakref.proxy's methods call back into the Python
API using a borrowed references of the weakly referenced object
(acquired via PyWeakref_GET_OBJECT). This API call may delete the last
reference to the object (either directly or via GC), leaving a dangling
pointer, which can be subsequently dereferenced.

To fix this, claim a temporary ownership of the referenced object when
calling the appropriate method. Some functions because at the moment they
do not need to access the borrowed referent, but to protect against
future changes to these functions, ownership need to be fixed in
all potentially affected methods..
(cherry picked from commit 10cd00a)

Co-authored-by: Pablo Galindo <[email protected]>
miss-islington pushed a commit that referenced this pull request Oct 11, 2019
…H-16663)

The implementation of weakref.proxy's methods call back into the Python
API using a borrowed references of the weakly referenced object
(acquired via PyWeakref_GET_OBJECT). This API call may delete the last
reference to the object (either directly or via GC), leaving a dangling
pointer, which can be subsequently dereferenced.

To fix this, claim a temporary ownership of the referenced object when
calling the appropriate method. Some functions because at the moment they
do not need to access the borrowed referent, but to protect against
future changes to these functions, ownership need to be fixed in
all potentially affected methods..
(cherry picked from commit 10cd00a)

Co-authored-by: Pablo Galindo <[email protected]>





https://bugs.python.org/issue38395
jacobneiltaylor pushed a commit to jacobneiltaylor/cpython that referenced this pull request Dec 5, 2019
The implementation of weakref.proxy's methods call back into the Python
API using a borrowed references of the weakly referenced object
(acquired via PyWeakref_GET_OBJECT). This API call may delete the last
reference to the object (either directly or via GC), leaving a dangling
pointer, which can be subsequently dereferenced.

To fix this, claim a temporary ownership of the referenced object when
calling the appropriate method. Some functions because at the moment they
do not need to access the borrowed referent, but to protect against
future changes to these functions, ownership need to be fixed in
all potentially affected methods.
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.

6 participants