-
Notifications
You must be signed in to change notification settings - Fork 13.1k
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
The ref to *const implicit conversion has become a footgun with e.g. Rc::from_raw #112337
Comments
I think at least the It's less clear if the equivalent "release" code should work: pub unsafe extern "C" fn release(f: &Foo) {
let _ = Rc::from_raw(f);
} since you could argue that |
Even just the I don't know how this should best be addressed. Even #111229 doesn't help here, because |
It's not necessarily about owning, though, more about interior mutability. |
@Nilstrieb |
yes, but having an
So even if it's not language level UB, it's still breaking a safety invariant. |
How so? That's the whole point of
The pointer might be valid for the
I don't see how the code in the OP breaks that invariant. |
|
The pointer doesn't have write access to the field, that's expected. But it also does not have write access to the reference counter, which is the problem: See Miri on https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=bcc0acaa89f36841786b0cc10f626968 |
Sure, I get it, I just don't think it's reasonable behavior. As in, it seems silly (to me) that this code is fine: let rc = Rc::new(0);
let r = Rc::into_raw(rc);
unsafe {
Rc::increment_strong_count(r);
Rc::decrement_strong_count(r);
} But this is UB in a way that it can cause security issues: let rc = Rc::new(0);
let r = Rc::into_raw(rc);
unsafe {
Rc::increment_strong_count(&*r);
Rc::decrement_strong_count(&*r);
} In particular, it seems reasonable to have types that are effectively "always-refcounted" in your program, in a way that calling Or at the very least there should be a warning / lint of sorts. Because it seems like an extremely easy mistake to make. |
It's completely reasonable behaviour. Creating a reference Optimizing the fn takes_reference(t: &i32) {
// Some operation
}
fn create_rc() {
let rc = Rc::new(0);
takes_reference(&*rc);
} This optimization would become invalid if |
…tions. r=glandium Even tho rust-lang/rust#112337 is IMO a rust bug, it's easy to work around in our code and it doesn't really affect expressiveness. Differential Revision: https://phabricator.services.mozilla.com/D180065
…tions. r=glandium, a=dmeehan Even tho rust-lang/rust#112337 is IMO a rust bug, it's easy to work around in our code and it doesn't really affect expressiveness. Differential Revision: https://phabricator.services.mozilla.com/D180065
…tions. r=glandium Even tho rust-lang/rust#112337 is IMO a rust bug, it's easy to work around in our code and it doesn't really affect expressiveness. Differential Revision: https://phabricator.services.mozilla.com/D180065
…tions. r=glandium, a=dmeehan Even tho rust-lang/rust#112337 is IMO a rust bug, it's easy to work around in our code and it doesn't really affect expressiveness. Differential Revision: https://phabricator.services.mozilla.com/D180065
There are reasonable use-cases for casting references and transmute to a container. Seems reasonable to have stuff like C-style inheritance:
Casting from |
That's an interesting variation of rust-lang/unsafe-code-guidelines#256, you should leave a comment there. |
For any such tricks, you'll have to use raw pointers throughout. Making Depending on how rust-lang/unsafe-code-guidelines#236 is resolved, something like |
If |
Currently it looks like |
I tried that in #114559 and it's not looking good. |
Even tho rust-lang/rust#112337 is IMO a rust bug, it's easy to work around in our code and it doesn't really affect expressiveness. Differential Revision: https://phabricator.services.mozilla.com/D180065
Even tho rust-lang/rust#112337 is IMO a rust bug, it's easy to work around in our code and it doesn't really affect expressiveness. Differential Revision: https://phabricator.services.mozilla.com/D180065
Even tho rust-lang/rust#112337 is IMO a rust bug, it's easy to work around in our code and it doesn't really affect expressiveness. Differential Revision: https://phabricator.services.mozilla.com/D180065
Even tho rust-lang/rust#112337 is IMO a rust bug, it's easy to work around in our code and it doesn't really affect expressiveness. Differential Revision: https://phabricator.services.mozilla.com/D180065
The following code does nothing in practice (no strong reference added to the Rc) with 1.70 or earlier versions compiled against LLVM 16.
The corresponding (release) IR, per the playground:
Changing the ref to a *const "fixes" the problem.
IR looks like this:
Here, the Rc is updated with a new strong reference.
This is another footgun that comes from llvm/llvm-project@01859da, along with #111229.
The text was updated successfully, but these errors were encountered: