-
Notifications
You must be signed in to change notification settings - Fork 782
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
run_closure
and drop_closure
unsoundly drop payload on panic
#2501
Comments
Thanks for reporting! Agree this is a bug - I'll put a fix into the upcoming 0.17 release. |
@LegionMammal978 I'll be looking at this very soon. I see you've been very active regarding this topic on the internals forum. I was wondering if you could confirm what the recommended fix is? I was thinking to add a second |
I asked (someone else) a while ago and they recommended that approach. Personally I think this is very misbehaved and kind of a ridiculous corner case so my preference would be to just abort instead. |
Both are acceptable. In |
I was thinking about this further and I think I'll go for the abort option - panic in panic is an abort, so it seems reasonable that panic on drop of panic payload is also an abort. Both are corner cases we hope never occur in practice! |
Bug Description
These two functions use
catch_unwind
to catch panics and transfer them as Python exceptions (forrun_closure
) or just report them (fordrop_closure
). However, both functions drop the payload returned bycatch_unwind
, which is an operation that can panic. Formally, unwinding fromextern "C"
functions is undefined behavior, but in practice, the program will effectivelylongjmp
out of any C code as it unwinds. While this appears not to cause obvious memory unsafety in CPython, it can cause reference leaks and resource leaks. In particular, unwinding fromrun_closure
prevents the recursion depth from being decremented, and unwinding fromdrop_closure
prevents PyO3 from ever releasing the GIL and also prevents the trashcan mechanism from freeing any objects.Steps to Reproduce
An example of a recursion depth leak from
run_closure
:An example of a GIL leak from
drop_closure
:Backtrace
No response
Your operating system and version
Ubuntu 22.04 LTS
Your Python version (
python --version
)Python 3.10.4
Your Rust version (
rustc --version
)rustc 1.62.0 (a8314ef7d 2022-06-27)
Your PyO3 version
commit a95485c
How did you install python? Did you use a virtualenv?
apt
Additional Info
The error message in
drop_closure
can only ever printAny { .. }
. To print the actual payload, it must be explicitly converted to a string with.downcast_ref::<&str>()
and.downcast_ref::<String>()
.The text was updated successfully, but these errors were encountered: