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.