I want to use Rust raw pointer like *const
to reproduce the security problem of use after free, but when I use the raw pointer to access fields or call the function of a freed struct variable, there's no panic occurred.
Here's my codes:
new
method is used to create the struct more conveniently. as_ptr
method is used to return the raw pointer of the struct itself.
pub struct Foo{
data: Vec<u8>,
}
impl Foo{
pub fn new(data: &[u8]) -> Foo{
Foo{ data: data.to_vec() }
}
pub fn as_ptr(&self) -> *const Foo{
// return a raw pointer of this struct
self as *const Foo
}
pub fn test(&self){
println!("test");
}
}
test
method above and use_raw_ptr
method below are intended to reproduce the use after free problem.
pub unsafe fn use_raw_ptr(ptr: *const Foo){
println!("{:?}", (*ptr).data);
}
When testing, I create a Foo
struct variable foo
in match
blocks, which I suppose should be the scope of the foo
variable. Then the raw pointer of foo
is passed to p
if data
is legal. After match
block, I try to use p
to call the function test
of Foo
and access data
field of foo
, where I suppose use after free problem should appear because foo
should be freed already.
fn main(){
let data: Option<&[u8]> = Some(b"abc");
let p = match data{
Some(data) => {
let foo = Foo::new(data);
foo.as_ptr();
}
None => std::ptr::null(),
};
unsafe {(*p).test()};
println!("{:?}", data);
unsafe{ use_raw_ptr(p) };
}
However, no panic occurrs when executing the codes and here's the output:
test
Some([97, 98, 99])
[192, 230, 41]
It also should be mentioned that the result of use_raw_ptr
differs everytime I run the codes, but the length of printed result always match the input data. I wonder if this is because when foo
is freed, some information like the length of data
is still remained?
fn main(){
let data: Option<&[u8]> = Some(b"abcde");
// ... same as above
}
// output
test
Some([97, 98, 99, 100, 101])
[192, 230, 5, 252, 49]
Besides, I think that the reason of the succecc call of unsafe{(*p).test()}
is that it calls the function of Foo
struct instead of foo
variable. I don't know if this is corrent and I'm wondering if I can make program panic here using raw pointer to access freed memory.