From 521e77d712a4b633701f57dc8d404827db76518a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 17 Apr 2020 20:43:54 +0200 Subject: [PATCH 1/3] test that we properly check dynamic alignment --- .../unaligned_pointers/dyn_alignment.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 tests/compile-fail/unaligned_pointers/dyn_alignment.rs diff --git a/tests/compile-fail/unaligned_pointers/dyn_alignment.rs b/tests/compile-fail/unaligned_pointers/dyn_alignment.rs new file mode 100644 index 0000000000..a8cf54edc8 --- /dev/null +++ b/tests/compile-fail/unaligned_pointers/dyn_alignment.rs @@ -0,0 +1,19 @@ +// should find the bug even without these +// compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows + +#[repr(align(256))] +#[derive(Debug)] +struct MuchAlign; + +fn main() { + let buf = [0u32; 256]; + // `buf` is sufficiently aligned for `layout.align` on a `dyn Debug`, but not + // for the actual alignment required by `MuchAlign`. + // We craft a wide reference `&dyn Debug` with the vtable for `MuchAlign`. That should be UB, + // as the reference is not aligned to its dynamic alignment requirements. + let mut ptr = &MuchAlign as &dyn std::fmt::Debug; + // Overwrite the data part of `ptr`. + unsafe { (&mut ptr as *mut _ as *mut *const u8).write(&buf as *const _ as *const u8); } + // Re-borrow that. This should be UB. + let _ptr = &*ptr; //~ ERROR accessing memory with alignment 4, but alignment 256 is required +} From c6ab27577b3291036788735058194e9bb05dc70c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 18 Apr 2020 02:06:36 +0200 Subject: [PATCH 2/3] test that we check dynamic actual size of object --- tests/compile-fail/dangling_pointers/dyn_size.rs | 13 +++++++++++++ .../unaligned_pointers/dyn_alignment.rs | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 tests/compile-fail/dangling_pointers/dyn_size.rs diff --git a/tests/compile-fail/dangling_pointers/dyn_size.rs b/tests/compile-fail/dangling_pointers/dyn_size.rs new file mode 100644 index 0000000000..c8f1ee3113 --- /dev/null +++ b/tests/compile-fail/dangling_pointers/dyn_size.rs @@ -0,0 +1,13 @@ +// should find the bug even without these +// compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows + +struct SliceWithHead(u8, [u8]); + +fn main() { + let buf = [0u32; 1]; + // We craft a wide pointer `*const SliceWithHead` such that the unsized tail is only partially allocated. + // That should be UB, as the reference is not fully dereferencable. + let ptr: *const SliceWithHead = unsafe { std::mem::transmute((&buf, 4usize)) }; + // Re-borrow that. This should be UB. + let _ptr = unsafe { &*ptr }; //~ ERROR pointer must be in-bounds at offset 5 +} diff --git a/tests/compile-fail/unaligned_pointers/dyn_alignment.rs b/tests/compile-fail/unaligned_pointers/dyn_alignment.rs index a8cf54edc8..4d0b3af095 100644 --- a/tests/compile-fail/unaligned_pointers/dyn_alignment.rs +++ b/tests/compile-fail/unaligned_pointers/dyn_alignment.rs @@ -12,7 +12,7 @@ fn main() { // We craft a wide reference `&dyn Debug` with the vtable for `MuchAlign`. That should be UB, // as the reference is not aligned to its dynamic alignment requirements. let mut ptr = &MuchAlign as &dyn std::fmt::Debug; - // Overwrite the data part of `ptr`. + // Overwrite the data part of `ptr` so it points to `buf`. unsafe { (&mut ptr as *mut _ as *mut *const u8).write(&buf as *const _ as *const u8); } // Re-borrow that. This should be UB. let _ptr = &*ptr; //~ ERROR accessing memory with alignment 4, but alignment 256 is required From 0345ee42da3a206e92cecd42b0b472b82552af95 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 18 Apr 2020 09:15:59 +0200 Subject: [PATCH 3/3] some UB gets masked by optimizations --- tests/compile-fail/dangling_pointers/dyn_size.rs | 4 ++-- tests/compile-fail/unaligned_pointers/dyn_alignment.rs | 4 ++-- tests/compile-fail/validity/nonzero.rs | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/compile-fail/dangling_pointers/dyn_size.rs b/tests/compile-fail/dangling_pointers/dyn_size.rs index c8f1ee3113..39a091387c 100644 --- a/tests/compile-fail/dangling_pointers/dyn_size.rs +++ b/tests/compile-fail/dangling_pointers/dyn_size.rs @@ -1,5 +1,5 @@ -// should find the bug even without these -// compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows +// should find the bug even without these, but gets masked by optimizations +// compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -Zmir-opt-level=0 struct SliceWithHead(u8, [u8]); diff --git a/tests/compile-fail/unaligned_pointers/dyn_alignment.rs b/tests/compile-fail/unaligned_pointers/dyn_alignment.rs index 4d0b3af095..aa293a5d21 100644 --- a/tests/compile-fail/unaligned_pointers/dyn_alignment.rs +++ b/tests/compile-fail/unaligned_pointers/dyn_alignment.rs @@ -1,5 +1,5 @@ -// should find the bug even without these -// compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows +// should find the bug even without these, but gets masked by optimizations +// compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -Zmir-opt-level=0 #[repr(align(256))] #[derive(Debug)] diff --git a/tests/compile-fail/validity/nonzero.rs b/tests/compile-fail/validity/nonzero.rs index dbb31b3f17..8ff19a2b43 100644 --- a/tests/compile-fail/validity/nonzero.rs +++ b/tests/compile-fail/validity/nonzero.rs @@ -1,4 +1,5 @@ -// compile-flags: -Zmir-opt-level=1 +// gets masked by optimizations +// compile-flags: -Zmir-opt-level=0 #![feature(rustc_attrs)] #![allow(unused_attributes)]