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

Add PyWeakref_GetRef and use it in weakref wrappers. #4528

Merged
merged 9 commits into from
Oct 2, 2024

Conversation

ngoldbaum
Copy link
Contributor

@ngoldbaum ngoldbaum commented Sep 4, 2024

Refs #4265. Also ping @SuperJappie08.

The compat definition is adapted from the C implementation in pythoncapi-compat.

See also my comment in the weakref issue about whether we should add a new API based on PyWeakref_GetRef that doesn't panic or return borrowed references.

pyo3-ffi/src/compat/py_3_13.rs Outdated Show resolved Hide resolved
pyo3-ffi/src/weakrefobject.rs Outdated Show resolved Hide resolved
@SuperJappie08
Copy link
Contributor

@ngoldbaum, Cool that you looked at it. (Sorry for the slow response on my side, though)
When finalizing the initial Weakref PR, I already saw the proposed API changes, but it's building for bete/pre-release 3.13 versions had just started, so I decided to leave it for another time.

Everything looks good, except I'm wondering if it would be better to drop get_object_borrowed since it cannot be supported across all versions.

@ngoldbaum ngoldbaum mentioned this pull request Sep 20, 2024
3 tasks
Copy link
Member

@davidhewitt davidhewitt left a comment

Choose a reason for hiding this comment

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

Thanks, lgtm to merge 👍

Copy link
Member

@davidhewitt davidhewitt left a comment

Choose a reason for hiding this comment

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

Actually apologies, changed my mind. I think this has dug up a more serious problem.

@@ -758,15 +758,26 @@ pub trait PyWeakrefMethods<'py> {
/// [`weakref.ref`]: https://docs.python.org/3/library/weakref.html#weakref.ref
#[track_caller]
// TODO: This function is the reason every function tracks caller, however it only panics when the weakref object is not actually a weakreference type. So is it this neccessary?
// TODO: we should deprecate this because it relies on the semantics of a deprecated C API item
Copy link
Member

Choose a reason for hiding this comment

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

Actually I think this is fundamentally unsafe even not on the freethreaded build because a GIL thread switch could theoretically remove the last strong reference, and using this borrow further would then be a use-after-free? So I think we have to

  1. remove this API immediately in 0.23
  2. backport a fix to 0.22.4 which adds an immediate deprecation to this API and leaks the object in question here. Pretty bad, but I think better than possible UAF. Most users should be using the higher-level APIs, I hope, so shouldn't be too breaking and is definitely necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There are a number of other functions that rely on the semantics of get_object_borrowed, so I deleted those as well for the same soundness reason.

@davidhewitt davidhewitt mentioned this pull request Sep 26, 2024
fn get_object(&self) -> Bound<'py, PyAny> {
// PyWeakref_GetObject does some error checking, however we ensure the passed object is Non-Null and a Weakref type.
self.get_object_borrowed().to_owned()
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I guess you'll need to keep this and tell clippy to ignore the warning on 0.22.4? Or I guess just backport the compat function too.

Copy link
Member

@davidhewitt davidhewitt left a comment

Choose a reason for hiding this comment

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

Thanks! I'll get on with backporting shortly...

@davidhewitt davidhewitt added this pull request to the merge queue Oct 1, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to no response for status checks Oct 1, 2024
@ngoldbaum
Copy link
Contributor Author

When the merge fails like that, how do you see what happened? I don't see anything on the merge queue page.

@davidhewitt davidhewitt added this pull request to the merge queue Oct 2, 2024
@davidhewitt
Copy link
Member

I think it just timed out, CI was a bit saturated last night.

Merged via the queue into PyO3:main with commit 26abde5 Oct 2, 2024
42 of 43 checks passed
davidhewitt pushed a commit to davidhewitt/pyo3 that referenced this pull request Oct 2, 2024
* add FFI bindings and a compat definition for PyWeakref_GetRef

* implement get_object method of weakref wrappers using PyWeakref_GetRef

* add changelog

* rename _ref argument to reference

* mark PyWeakref_GetObject as deprecated

* mark test as using deprecated API item

* update docs to reference PyWeakref_GetRef semantics

* remove weakref methods that return borrowed references

* fix lints about unused imports
davidhewitt pushed a commit to davidhewitt/pyo3 that referenced this pull request Oct 4, 2024
* add FFI bindings and a compat definition for PyWeakref_GetRef

* implement get_object method of weakref wrappers using PyWeakref_GetRef

* add changelog

* rename _ref argument to reference

* mark PyWeakref_GetObject as deprecated

* mark test as using deprecated API item

* update docs to reference PyWeakref_GetRef semantics

* remove weakref methods that return borrowed references

* fix lints about unused imports
davidhewitt added a commit that referenced this pull request Oct 4, 2024
…4590)

* Add PyWeakref_GetRef and use it in weakref wrappers. (#4528)

* deprecate weakref methods that return borrowed references

---------

Co-authored-by: Nathan Goldbaum <nathan.goldbaum@gmail.com>
davidhewitt added a commit that referenced this pull request Oct 12, 2024
…4590)

* Add PyWeakref_GetRef and use it in weakref wrappers. (#4528)

* deprecate weakref methods that return borrowed references

---------

Co-authored-by: Nathan Goldbaum <nathan.goldbaum@gmail.com>
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.

4 participants