Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this `unsafe` code Undefined Behavior in Rust?

Tags:

rust

I wanted to get a reference to structure from member references. So, I wrote the following code.

#[repr(C)]
struct Data {
    x: i32,
    y: u32,
}

fn compose<'a>(x: &'a i32, y: &'a u32) -> Option<&'a Data> {
    use memoffset::offset_of;

    let x_address = x as *const i32 as usize;
    let y_address = y as *const u32 as usize;

    if x_address + offset_of!(Data, y) != y_address {
        return None;
    }

    return Some(unsafe { &*(x_address as *const Data) });
}

It seems to work correctly but I don't know if it is safe or not. Is this undefined behavior or is there a good crate for solving this problem?

like image 394
いわんこ Avatar asked Mar 02 '26 12:03

いわんこ


1 Answers

Yes. This is undefined behavior. It is not reported by Miri (although a similar code is) because it doesn't track ptr-to-int-to-ptr roundtrips, but it is still undefined behavior to access a reference past its bounds, not to mention that even if this was fine compose() would still be unsound because two references can happen to have adjacent addresses but come from different allocations.

It may not be undefined behavior if UCG#134/UCG#256 will be decided to not be undefined behavior (you'll be allowed to read past the bounds of a reference). However, even in that case I'm not sure, because you have an active reference for y (although it is unlikely to matter). In the meantime, it is best to avoid this.

like image 163
Chayim Friedman Avatar answered Mar 05 '26 02:03

Chayim Friedman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!