-
Notifications
You must be signed in to change notification settings - Fork 16
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
Soundness problems? #15
Comments
Regarding #3: StableDeref is only intended to guarantee validity as long as the parent object is not dropped. You could say the same thing about any type. E.g. taking a pointer to string data and then dropping the string will also result in a dangling pointer. Regarding #4, it is not valid to mutate through a const pointer unless the target is inside an unsafecell. But even if it was, writing to pointers is unsafe, and anyone messing about with pointers knows what they are getting into. As for the rest, I'm not sure what can be done in that case other than get rid of owning_ref entirely. |
Sorry, my use of fn main() {
let mut x = 1i32;
let y = &mut x;
let ptr = &*y as *const i32;
let _z = y;
unsafe {
println!("{}", *ptr);
}
}
This program is accepted by Miri: fn main() {
let x = std::rc::Rc::new(1);
unsafe {
let ptr = std::rc::Rc::as_ptr(&x);
core::ptr::write(ptr as *mut i32, 2);
}
println!("{:?}", x);
}
True, but this is besides my point. This crate provides a
This is a tangent, but this statement is demonstrably false. For example, |
Yeah, I forgot that there's no const/mut pointer distinction in stacked borrows. Still, pointers require unsafe to use, so it's clearly out of bounds as far as the safety guarantees go. Anyway, it seems like there are two main issues here
It doesn't seem like there's anything I can do about this, other than maybe add a warning telling people that they probably shouldn't use owning_ref and its ilk. |
That's not how this works at all. From the nomicon:
Unsafe traits provide their guarantees even in the face of unsafe code, that's the whole point. When you're writing unsafe code, you can't rely on safe code doing what it documents. But you can rely on unsafe code doing what it documents (otherwise you can't rely on anything at all). No matter what unsafe code I write, so long as it isn't unsound on its own, I must be able to rely on the guarantees that this crate's unsafe traits make. I think the problem with this crate is this wording:
This just happened to remain correct until Rust 1.45, when
The core problem here is that this crate tries to make guarantees about types that it doesn't control. This crate relies on an undocumented property of another project, then advertises that property as a stable guarantee. It's great to provide an abstraction layer over the standard library's APIs that is is ever-cautious about providing its own traits for. But it's not great to do this by relying on undocumented properties of the types, especially properties that can be broken by adding features. |
Farther more, from source code of |
I think there are a few problems with this crate, which or may not be soundness problems depending on how you squint.
This crate is intended to support
owning_ref
which has a few soundness problems, andrental
which is debatably sound as well, and now unmaintained.This crate provides an implementation of
StableDeref
forBox
. Under Stacked Borrows (which is a prototype model and may not be adopted) this is technically true ofBox
, but useless. A pointer to the contents of aBox
may point to the same address after theBox
is moved, but said pointer is invalidated by the move and dereferencing it is UB. This is checked by Miri. This pattern may also be unsound for real, right now because rustc currently applies LLVM'snoalias
toBox
. Users interested in an RAII heap allocation without the uniqueness property thatBox
has may be interested in aliasable.I think the fact that
&mut
implementsStableDeref
suggests that you can write programs like this:This program is similarly UB under Stacked Borrows, because moving the mutable reference retags it, invalidates all other pointers to its pointee. I don't know if this pattern is similarly unsound with respect to rustc's current use of LLVM
noalias
.Both
Rc
andArc
provide::as_ptr
, through which it is valid to do mutation. In my opinion, mutating through this pointer qualifies as "arbitrary &self methods or anything transitively accessible from &Self". But that permits mutating the referent of a&T
while it is active, which is unsound.The text was updated successfully, but these errors were encountered: