Provenance of pointer fields of structs obtained from `std::ptr::read` over a buffer coming from the C FFI
15:53 13 Mar 2026

I think I've kind of understood provenance (maybe not), but all the documentation I find talks about going from/to pointers and usize. But what about [u8; N] ?

Specifically, suppose I have this code:

#[repr(C)]
struct MyStruct {
    pub ptr: *const u32
}

#[repr(C)]
struct RawData {
    pub data: [u8; std::mem::size_of::()]
}

unsafe extern "C" {
    pub fn foreign() -> RawData;
}

pub fn does_this_work() -> MyStruct {
    unsafe {
        let data = foreign();
    
        std::ptr::read_unaligned((&raw data) as *const MyStruct)
    }
}

Why I'm doing that is beyond this question, but this is somewhat similar to what the Zngur C++ interop tool does under the hood.

From what I've understood about provenance, if the C API was returning a uintptr_t, aka usize, I would need to call std::ptr::with_exposed_provenance(). But here there is no such usize, and I cannot find documentation about provenance dealing with [u8; N] and std::ptr::read().

So what I cannot understand is the following:

  1. does the raw pointer inside the resulting MyStruct have provenance?

  2. is it valid to dereference (assuming it was on the C side)?

  3. if not, why?

  4. what to do to fix the situation?

rust unsafe