-
Notifications
You must be signed in to change notification settings - Fork 766
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
leak references for safety in PyWeakRefMethods::upgrade_borrowed
#4590
Conversation
* 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
6ea1e1d
to
675e505
Compare
2a89e17
to
f31271f
Compare
To get on with shipping 0.24 I will merge this now; I can't see a way we can do anything reasonable other than leak. |
= ID: RUSTSEC-2024-0378 = Advisory: https://rustsec.org/advisories/RUSTSEC-2024-0378 = The family of functions to read "borrowed" values from Python weak references were fundamentally unsound, because the weak reference does itself not have ownership of the value. At any point the last strong reference could be cleared and the borrowed value would become dangling. In PyO3 0.22.4 these functions have all been deprecated and patched to leak a strong reference as a mitigation. PyO3 0.23 will remove these functions entirely. = Announcement: PyO3/pyo3#4590 = Solution: Upgrade to >=0.22.4 (try `cargo update -p pyo3`) = pyo3 v0.22.2 └── pumpkin-py v0.1.0
= ID: RUSTSEC-2024-0378 = Advisory: https://rustsec.org/advisories/RUSTSEC-2024-0378 = The family of functions to read "borrowed" values from Python weak references were fundamentally unsound, because the weak reference does itself not have ownership of the value. At any point the last strong reference could be cleared and the borrowed value would become dangling. In PyO3 0.22.4 these functions have all been deprecated and patched to leak a strong reference as a mitigation. PyO3 0.23 will remove these functions entirely. = Announcement: PyO3/pyo3#4590 = Solution: Upgrade to >=0.22.4 (try `cargo update -p pyo3`) = pyo3 v0.22.2 └── pumpkin-py v0.1.0
It may be the lesser evil in this case, but I have found out the hard way that python lacks overflow checking on it's reference counts. So a reference count leak, repeated a sufficiently large number of times on the same object, can lead to a use after free. "sufficiently large number of times" is unlikely to happen on 64-bit platforms but is far more plausible on 32-bit platforms. |
Hmm, that's a good point. I mean this also just straight-up ensures a memory leak before the overflow too, so it's definitely unpleasant for users and they should move to the owned methods which don't have any of this mess. |
Note: this is a patch fix for 0.22.4, the PR is targeting that branch, not
main
.As per discussion in #4528, borrowing from a weakref is definitely unsafe and high risk for use-after-free; any arbitrary Python code could in theory remove the last strong reference.
In 0.23 we will straight-up remove these unsound methods, but in 0.22.4 we can't really do that so the mitigation proposed here is to switch to leak the upgraded reference when "borrowing" from the weakref. This avoids use-after-free in favour of the more gentle memory leak. The methods are also all deprecated as a nudge for users to shift away from them ASAP.