Hi, I found a possible aliasing/provenance issue in plain-0.2.3 at:
|
Ok(unsafe { |
|
slice::from_raw_parts_mut(bytes.as_ptr() as *mut T, len) |
|
}) |
|
} |
bytes has type &mut [u8], but the raw pointer used to create the returned &mut [T] is derived from bytes.as_ptr(), i.e. a const/shared raw pointer. Under Miri Tree Borrows, writing through a mutable reference constructed from that pointer can be rejected because the pointer is derived through the shared/frozen access path.
A likely fix is to use as_mut_ptr() instead:
Ok(unsafe {
slice::from_raw_parts_mut(bytes.as_mut_ptr() as *mut T, len)
})
I minimized the pattern to this reproducer:
use std::slice;
fn from_mut_bytes_bad(bytes: &mut [u8]) -> &mut [u32] {
assert_eq!(bytes.as_ptr().align_offset(std::mem::align_of::<u32>()), 0);
assert!(bytes.len() >= 4);
unsafe { slice::from_raw_parts_mut(bytes.as_ptr() as *mut u32, 1) }
}
fn main() {
let mut value = 0_u32;
let bytes = unsafe {
slice::from_raw_parts_mut((&mut value as *mut u32).cast::<u8>(), 4)
};
let words = from_mut_bytes_bad(bytes);
words[0] = 1;
}
Running with Tree Borrows:
MIRIFLAGS=-Zmiri-tree-borrows cargo +nightly miri run
reports UB on the write through words[0].
Hi, I found a possible aliasing/provenance issue in
plain-0.2.3at:plain/src/methods.rs
Lines 170 to 173 in d9c463e
bytes has type &mut [u8], but the raw pointer used to create the returned &mut [T] is derived from bytes.as_ptr(), i.e. a const/shared raw pointer. Under Miri Tree Borrows, writing through a mutable reference constructed from that pointer can be rejected because the pointer is derived through the shared/frozen access path.
A likely fix is to use as_mut_ptr() instead:
I minimized the pattern to this reproducer:
Running with Tree Borrows:
reports UB on the write through words[0].