Miri reports UB if Arc::from_raw()'s input is a reconstructed fat pointer

I have to store a fat pointer obtained by Arc::into_raw in two separate struct fields. I'm building something similar to bytes, which has its focus on image buffers.

let raw = Arc::<[u8]>::from([0u8, 64u8, 128u8, 192u8]);
let len = raw.len();
let raw = Arc::into_raw(raw);

unsafe {
    let ptr = { (&*raw).as_ptr() };
    let data = std::slice::from_raw_parts(ptr, len);
    // Arc::from_raw(data);  // Miri errors if this lines is used instead of the last
    Arc::from_raw(raw);
};

Miri shows the following error:

trying to retag from <359913> for SharedReadWrite permission at alloc135114[0x0], but that tag does not exist in the borrow stack for this location
| this error occurs as part of retag at alloc135114[0x0..0x18]

My workaround would be Boxing the obtained fat-pointer raw and thereby ad another level of indirection. Any Ideas how I can split raw into len and ptr and recombine them to reconstruct the Arc?

The pointer returned by Arc::into_raw and required by Arc::from_raw have write permissions too (that doesn't mean you can freely write through it though!). The pointer you're passing however has gone through a shared reference, which means it only has read permissions.

1 Like

Thank you for looking into it. Do you have an Idea how to overcome this?

Don't get the pointer passed to Arc::from_raw from a reference. In your simple example above (&*raw).as_ptr() is the issue, change it to something like raw.cast::<u8>() instead.

2 Likes

Thank you very much! This put me in the right direction. There was another conversion into references, which i had to resolve. This is what I ended up with:

let raw = Arc::<[u8]>::from([0u8, 64u8, 128u8, 192u8]);
let len = raw.len();
let raw = Arc::into_raw(raw);

unsafe {
    let ptr = raw.cast::<u8>();
    let data = core::ptr::slice_from_raw_parts(ptr, len);
    Arc::from_raw(data);
};

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.