Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # 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.

@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>
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants