From a29f86b512a0a6a353c11f44af768da6bdc5c782 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 20 Jun 2020 14:28:55 +0200 Subject: [PATCH 1/3] make sure '&raw *' on a dangling raw ptr is UB --- .../dangling_pointers/dangling_pointer_addr_of.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 tests/compile-fail/dangling_pointers/dangling_pointer_addr_of.rs diff --git a/tests/compile-fail/dangling_pointers/dangling_pointer_addr_of.rs b/tests/compile-fail/dangling_pointers/dangling_pointer_addr_of.rs new file mode 100644 index 00000000000..5df5b324f45 --- /dev/null +++ b/tests/compile-fail/dangling_pointers/dangling_pointer_addr_of.rs @@ -0,0 +1,13 @@ +// Make sure we find these even with many checks disabled. +// compile-flags: -Zmiri-disable-alignment-check -Zmiri-disable-stacked-borrows -Zmiri-disable-validation +#![feature(raw_ref_macros)] +use std::ptr; + +fn main() { + let p = { + let b = Box::new(42); + &*b as *const i32 + }; + let x = unsafe { ptr::raw_const!(*p) }; //~ ERROR dereferenced after this allocation got freed + panic!("this should never print: {:?}", x); +} From 03fe3772a8a6859b2aa890f5a002e7cc3707e326 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 20 Jun 2020 14:31:47 +0200 Subject: [PATCH 2/3] make sure the raw_ptr macros also avoid UB --- tests/run-pass/packed_struct.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/run-pass/packed_struct.rs b/tests/run-pass/packed_struct.rs index 5582caaf37e..43419695ba0 100644 --- a/tests/run-pass/packed_struct.rs +++ b/tests/run-pass/packed_struct.rs @@ -1,7 +1,8 @@ -#![feature(unsize, coerce_unsized, raw_ref_op)] +#![feature(unsize, coerce_unsized, raw_ref_op, raw_ref_macros)] use std::collections::hash_map::DefaultHasher; use std::hash::Hash; +use std::ptr; fn test_basic() { #[repr(packed)] @@ -45,7 +46,9 @@ fn test(t: Test2) { assert_eq!({x.b}, 99); // but we *can* take a raw pointer! assert_eq!(unsafe { (&raw const x.a).read_unaligned() }, 42); + assert_eq!(unsafe { ptr::raw_const!(x.a).read_unaligned() }, 42); assert_eq!(unsafe { (&raw const x.b).read_unaligned() }, 99); + assert_eq!(unsafe { ptr::raw_const!(x.b).read_unaligned() }, 99); x.b = 77; assert_eq!({x.b}, 77); From 8d1d5724727ee5a6862881bc97da86b9c90f9b21 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 20 Jun 2020 14:34:57 +0200 Subject: [PATCH 3/3] unaligned-raw-deref is always UB --- .../unaligned_pointers/unaligned_ptr_addr_of.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 tests/compile-fail/unaligned_pointers/unaligned_ptr_addr_of.rs diff --git a/tests/compile-fail/unaligned_pointers/unaligned_ptr_addr_of.rs b/tests/compile-fail/unaligned_pointers/unaligned_ptr_addr_of.rs new file mode 100644 index 00000000000..cd52cd44c2b --- /dev/null +++ b/tests/compile-fail/unaligned_pointers/unaligned_ptr_addr_of.rs @@ -0,0 +1,12 @@ +// This should fail even without validation or Stacked Borrows. +// compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows +#![feature(raw_ref_macros)] +use std::ptr; + +fn main() { + let x = [2u16, 3, 4]; // Make it big enough so we don't get an out-of-bounds error. + let x = &x[0] as *const _ as *const u32; + // This must fail because alignment is violated: the allocation's base is not sufficiently aligned. + // The deref is UB even if we just put the result into a raw pointer. + let _x = unsafe { ptr::raw_const!(*x) }; //~ ERROR memory with alignment 2, but alignment 4 is required +}