Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upborrowck is unsound in the presence of `&'static mut`s #27616
Comments
alexcrichton
added
the
I-nominated
label
Aug 10, 2015
alexcrichton
referenced this issue
Aug 10, 2015
Closed
RFC: Add Box::leak to leak Box<T> to &'static mut T #1233
This comment has been minimized.
This comment has been minimized.
|
Maybe there should be a "strict outlives" requirement for reborrows for |
This comment has been minimized.
This comment has been minimized.
|
I think there are two ways of looking at this issue:
@eddyb's suggestions seems reasonable as a general rule, but in this case, isn't the borrow happening from an unsafe pointer, which doesn't have a lifetime? How would it prevent @arielb1's attack? |
This comment has been minimized.
This comment has been minimized.
|
You can basically do that with every It doesn't matter how you get them. |
This comment has been minimized.
This comment has been minimized.
|
@arielb1 Can you mount the attack on a variable that's actually statically allocated? i.e.: static mut FOO : MyType = ...Isn't this the reason static variables can't have |
This comment has been minimized.
This comment has been minimized.
|
Note that this would also make a |
This comment has been minimized.
This comment has been minimized.
|
A counter example to my question/claim that @arielb1 came up with on IRC: use std::cell::Cell;
use std::fmt::Debug;
fn transmute<X, Y: Debug>(a: Y, dummy: X, x: &'static mut Result<X, Y>,
y: &'static mut Result<X, Y>) -> &'static mut X {
*x = Ok(dummy);
let foo = x.as_mut().unwrap();
*y = Err(a);
return foo;
}
static mut FOO : Result<Option<&'static Cell<usize>>, usize> = Err(123);
fn main() {
let baz : usize = 0xdeadbeef;
let myfoo = unsafe { &mut FOO };
let addr = &baz as *const usize as usize;
let oops = transmute(addr, None, myfoo, myfoo);
println!("Trying to print at address 0x{0:x}", addr);
oops.map(|o| {
println!("0x{0:x}", o.get());
o.set(0xabcdef);
println!("0x{0:x}", baz);
});
}So aliasing 'static references is just plain problematic, and clearly |
This comment has been minimized.
This comment has been minimized.
|
My intuition (and I suspect that of other people) was that global
I believe |
This comment has been minimized.
This comment has been minimized.
|
I agree with @eddyb that it's the re-borrow of |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
There is no
|
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
@arielb1 My intuition was that the resulting |
This comment has been minimized.
This comment has been minimized.
|
You can always borrow for the outermost function's lifetime - all borrows must intersect it. |
alexcrichton
added
the
T-lang
label
Aug 12, 2015
nikomatsakis
self-assigned this
Aug 13, 2015
This comment has been minimized.
This comment has been minimized.
|
A example of the core problem is: fn foo(x: &'static mut i32) -> (&'static mut i32, &'static mut i32) {
(x, x)
}i.e. |
This comment has been minimized.
This comment has been minimized.
|
So the reason for this is clear enough. There is this code in ty::ReStatic => {
// If we get here, an error must have been
// reported in
// `lifetime::guarantee_lifetime()`, because
// the only legal ways to have a borrow with a
// static lifetime should not require
// restrictions. To avoid reporting derived
// errors, we just return here without adding
// any loans.
return;
}I think the assumption here was that |
This comment has been minimized.
This comment has been minimized.
|
@nikomatsakis I'm curious what the effects of removing that early return would be. |
nikomatsakis
added a commit
to nikomatsakis/rust
that referenced
this issue
Sep 9, 2015
This comment has been minimized.
This comment has been minimized.
|
@eddyb sorry for being slow to respond. The answer is that I think the resulting restrictions are enough, as long as we extend the loan out to the borders of the fn. I have a patch that does just this. |
arielb1 commentedAug 9, 2015
STR
Actual Result
memory corruption - 0wned is printed.
Thanks for alevy on IRC for reporting this.