-
Notifications
You must be signed in to change notification settings - Fork 506
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
Potential unsoundness in DrainProducer around drop_in_place on mutable reference #1029
Comments
The usage of |
Well this sounds a little familiar -- see #851 / #852 (and later #907), and the cited UCG#77 still isn't resolved. I think this case is actually on more solid ground, because we're not dealing with uninitialized data (dropping is different), but I'm willing to try a more conservative approach here.
I don't see how -- the references we get from |
Do you think this suffices? diff --git a/src/vec.rs b/src/vec.rs
index c804b0f339bb..900b3b9785bd 100644
--- a/src/vec.rs
+++ b/src/vec.rs
@@ -226,7 +226,8 @@ impl<'data, T: 'data + Send> Producer for DrainProducer<'data, T> {
impl<'data, T: 'data + Send> Drop for DrainProducer<'data, T> {
fn drop(&mut self) {
// use `Drop for [T]`
- unsafe { ptr::drop_in_place(self.slice) };
+ let slice = mem::take(&mut self.slice) as *mut [T];
+ unsafe { ptr::drop_in_place(slice) };
}
}
|
The docs on drop_in_place are kinda squirrelly about this, they say that the dropped pointer should never be read from, but it does seem like in the current plans for the unsafe model there is no difference between having a reference and reading from it. I plan to file an issue upstream about what precisely drop_in_place does when it comes to validity.
No, because ultimately |
Why is |
Oh! Yes, that should be fine. |
See #1030. |
1030: Be more cautious about drain drops r=cuviper a=cuviper This makes a greater effort to ensure that in all cases where either `DrainProducer` or `SliceDrain` will drop data, there are no references left pointing to that memory. It's not actually clear that this would be a problem anyway, as long as there's nothing accessing that zombie data, but it's not too much trouble to avoid it. Fixes #1029. Co-authored-by: Josh Stone <[email protected]>
rayon/src/vec.rs
Lines 226 to 231 in 7069695
This code takes
&mut Self
, which itself contains an&mut [T]
, and runs drop glue for the elements in the slice.While
ptr::drop_in_place()
does not explicitly say that the resultant value is invalid, it says it is "invalid to read". My understanding of the Rust unsafe model is that it is UB to have a live reference to a type that is invalid to read, in this case we are violating the validity constraints of&mut [T]
, which in turn violates validity of&mut Self
.The type does come from
ManuallyDrop
, but it's still UB to invalidate that whilst it has live references to it.I think this should probably be a raw pointer + phantomdata?
The text was updated successfully, but these errors were encountered: