From 60a0688185b1412147a5b5f235597bc7618b104a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 27 Jul 2019 11:03:12 +0200 Subject: [PATCH 1/4] adjust tests for eager pointer checks on deref --- tests/compile-fail/deref-invalid-ptr.rs | 7 +++++++ tests/compile-fail/deref-partially-dangling.rs | 8 ++++++++ tests/compile-fail/intptrcast_alignment_check.rs | 12 +++--------- tests/compile-fail/storage_dead_dangling.rs | 4 ++-- tests/run-pass/ref-invalid-ptr.rs | 12 ------------ tests/run-pass/stacked-borrows/stacked-borrows.rs | 11 ----------- 6 files changed, 20 insertions(+), 34 deletions(-) create mode 100644 tests/compile-fail/deref-invalid-ptr.rs create mode 100644 tests/compile-fail/deref-partially-dangling.rs delete mode 100644 tests/run-pass/ref-invalid-ptr.rs diff --git a/tests/compile-fail/deref-invalid-ptr.rs b/tests/compile-fail/deref-invalid-ptr.rs new file mode 100644 index 0000000000..2a8be87e12 --- /dev/null +++ b/tests/compile-fail/deref-invalid-ptr.rs @@ -0,0 +1,7 @@ +// This should fail even without validation. +// compile-flags: -Zmiri-disable-validation + +fn main() { + let x = 2usize as *const u32; + let _y = unsafe { &*x as *const u32 }; //~ ERROR dangling pointer was dereferenced +} diff --git a/tests/compile-fail/deref-partially-dangling.rs b/tests/compile-fail/deref-partially-dangling.rs new file mode 100644 index 0000000000..221e585c5f --- /dev/null +++ b/tests/compile-fail/deref-partially-dangling.rs @@ -0,0 +1,8 @@ +// Deref a raw ptr to access a field of a large struct, where the field +// is allocated but not the entire struct is. +fn main() { + let x = (1, 13); + let xptr = &x as *const _ as *const (i32, i32, i32); + let val = unsafe { (*xptr).1 }; //~ ERROR pointer must be in-bounds at offset 12, but is outside bounds of allocation + assert_eq!(val, 13); +} diff --git a/tests/compile-fail/intptrcast_alignment_check.rs b/tests/compile-fail/intptrcast_alignment_check.rs index 4e12a8a9e2..fcf613ace4 100644 --- a/tests/compile-fail/intptrcast_alignment_check.rs +++ b/tests/compile-fail/intptrcast_alignment_check.rs @@ -1,6 +1,3 @@ -// Validation makes this fail in the wrong place -// compile-flags: -Zmiri-disable-validation - // Even with intptrcast and without validation, we want to be *sure* to catch bugs // that arise from pointers being insufficiently aligned. The only way to achieve // that is not not let programs exploit integer information for alignment, so here @@ -8,11 +5,8 @@ fn main() { let x = &mut [0u8; 3]; let base_addr = x as *mut _ as usize; - let u16_ref = unsafe { if base_addr % 2 == 0 { - &mut *(base_addr as *mut u16) - } else { - &mut *((base_addr+1) as *mut u16) - } }; - *u16_ref = 2; //~ ERROR tried to access memory with alignment 1, but alignment 2 is required + let base_addr_aligned = if base_addr % 2 == 0 { base_addr } else { base_addr+1 }; + let u16_ptr = base_addr_aligned as *mut u16; + unsafe { *u16_ptr = 2; } //~ ERROR tried to access memory with alignment 1, but alignment 2 is required println!("{:?}", x); } diff --git a/tests/compile-fail/storage_dead_dangling.rs b/tests/compile-fail/storage_dead_dangling.rs index 85c76f6f41..5a5d79f158 100644 --- a/tests/compile-fail/storage_dead_dangling.rs +++ b/tests/compile-fail/storage_dead_dangling.rs @@ -8,8 +8,8 @@ fn fill(v: &mut i32) { } fn evil() { - let v = unsafe { &mut *(LEAK as *mut i32) }; - let _x = *v; //~ ERROR dangling pointer was dereferenced + let v = unsafe { &mut *(LEAK as *mut i32) }; //~ ERROR dangling pointer was dereferenced + let _x = *v; } fn main() { diff --git a/tests/run-pass/ref-invalid-ptr.rs b/tests/run-pass/ref-invalid-ptr.rs deleted file mode 100644 index e0e7d2afef..0000000000 --- a/tests/run-pass/ref-invalid-ptr.rs +++ /dev/null @@ -1,12 +0,0 @@ -// FIXME: validation disabled because it checks these references too eagerly. -// compile-flags: -Zmiri-disable-validation - -fn main() { - let x = 2usize as *const u32; - // This is not aligned, but we immediately cast it to a raw ptr so that must be ok. - let _y = unsafe { &*x as *const u32 }; - - let x = 0usize as *const u32; - // This is NULL, but we immediately cast it to a raw ptr so that must be ok. - let _y = unsafe { &*x as *const u32 }; -} diff --git a/tests/run-pass/stacked-borrows/stacked-borrows.rs b/tests/run-pass/stacked-borrows/stacked-borrows.rs index 7d84e33b3d..afa364e856 100644 --- a/tests/run-pass/stacked-borrows/stacked-borrows.rs +++ b/tests/run-pass/stacked-borrows/stacked-borrows.rs @@ -1,6 +1,5 @@ // Test various stacked-borrows-related things. fn main() { - deref_partially_dangling_raw(); read_does_not_invalidate1(); read_does_not_invalidate2(); ref_raw_int_raw(); @@ -14,16 +13,6 @@ fn main() { shr_and_raw(); } -// Deref a raw ptr to access a field of a large struct, where the field -// is allocated but not the entire struct is. -// For now, we want to allow this. -fn deref_partially_dangling_raw() { - let x = (1, 13); - let xptr = &x as *const _ as *const (i32, i32, i32); - let val = unsafe { (*xptr).1 }; - assert_eq!(val, 13); -} - // Make sure that reading from an `&mut` does, like reborrowing to `&`, // NOT invalidate other reborrows. fn read_does_not_invalidate1() { From a801b0ba3f8f16aa9ded9d28af4279b4b0b4509b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 28 Jul 2019 14:55:55 +0200 Subject: [PATCH 2/4] adjust for fn rename --- src/operator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/operator.rs b/src/operator.rs index f047f4f4fa..acf1db2977 100644 --- a/src/operator.rs +++ b/src/operator.rs @@ -35,7 +35,7 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> { #[inline] fn pointer_inbounds(&self, ptr: Pointer) -> InterpResult<'tcx> { let (size, _align) = self.memory().get_size_and_align(ptr.alloc_id, AllocCheck::Live)?; - ptr.check_in_alloc(size, CheckInAllocMsg::InboundsTest) + ptr.check_inbounds_alloc(size, CheckInAllocMsg::InboundsTest) } fn binary_ptr_op( From 2f95d4d50cbf28de90d01a01e36197872f3a55f6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 28 Jul 2019 18:08:39 +0200 Subject: [PATCH 3/4] remove dead code --- tests/compile-fail/storage_dead_dangling.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/compile-fail/storage_dead_dangling.rs b/tests/compile-fail/storage_dead_dangling.rs index 5a5d79f158..3047f086bd 100644 --- a/tests/compile-fail/storage_dead_dangling.rs +++ b/tests/compile-fail/storage_dead_dangling.rs @@ -8,8 +8,7 @@ fn fill(v: &mut i32) { } fn evil() { - let v = unsafe { &mut *(LEAK as *mut i32) }; //~ ERROR dangling pointer was dereferenced - let _x = *v; + unsafe { &mut *(LEAK as *mut i32) }; //~ ERROR dangling pointer was dereferenced } fn main() { From 8a103cfdd99b258560c1c3c88c1e49108fb87c7d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 15 Aug 2019 11:06:27 +0200 Subject: [PATCH 4/4] bump Rust --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index 6a1f1c81bd..f7f2a4e20f 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -00ee1b47f42129a0a6e33510578fbcf07c1e5382 +1cdcea920e56a5d0587307a4c9cf8fff5c77c4bc