-
Notifications
You must be signed in to change notification settings - Fork 803
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
A soundness issue with GIL-bound references #687
Comments
NB: I don’t actually know if That being said, the issue here is fairly theoretical at this point due to the fact that each FFI call is acting as a compiler barrier of sorts, preventing any dangerous optimisations, I think... |
A related possible issue with PyO3 giving out #[pyclass]
struct MyClass {
lock: std::Mutex<String>,
}
fn my_fn(value: &PyAny) -> PyResult<()> {
let mut_ref1: &mut MyClass = FromPyObject::extract(value)?;
let mut_ref2: &mut MyClass = FromPyObject::extract(value)?;
assert!(std::ptr::eq(mut_ref1, mut_ref2),
"we shouldn't have two &mut references to the same object!!!");
// cause unsynchronized access:
rayon::join(
|| mut_ref1.get_mut().unwrap().clear(),
|| println!("{}", mut_ref2.get_mut().unwrap()),
);
Ok(())
} |
Rather than UnsafeCell, perhaps we just should store *mut PyObject in these types? If we take the design proposal of
Storing |
Closing unless anyone disagrees with me. |
I think @pganssle’s comment in #679 ultimately reveals a soundness issue in PyO3.
Remember, that Rust has very strict invariants for its references:
&mut
reference to the same object (not too relevant to as, but do note that object here is not the python object);&
references to the same object but only theUnsafeCell
fields (interior mutability) of the object may change while there any live references to the object.The existence of
&PyNativeType
potentially violates the 2nd invariant as soon as the GIL is unlocked as part of some FFI orallow_threads(|| ...)
call. Consider this example and potential way things could go wrong (presume some super-optimised implementation of the functions used here)We already solved an soundness bug by making these references
!Send
and thus preventing invalidPython::assume_gil_acquired()
calls, but what we really need is a prohibition to unlock the GIL at all. At least while these references exist.An alternative, and more pragmatic, option would be to make all these types have interior mutability by adding an
UnsafeCell
into them.The text was updated successfully, but these errors were encountered: