Skip to content

Possible Pointer Aliasing Violation in slice_from_mut_bytes_len: mutable slice built from as_ptr() #10

Description

@Koukyosyumei

Hi, I found a possible aliasing/provenance issue in plain-0.2.3 at:

plain/src/methods.rs

Lines 170 to 173 in d9c463e

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].

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions