about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-10-21 12:48:54 +0000
committerbors <bors@rust-lang.org>2022-10-21 12:48:54 +0000
commit233542bf424af3153f031cdc54c010959e1bb403 (patch)
tree46b861bb8cab3171ea6d7325aa684c6022d0d3dc
parent9670a3092fa3402cea95c38931f93c6235158d21 (diff)
parentf554ebbc77b850a83ecd479a0409080e27507dd0 (diff)
downloadrust-233542bf424af3153f031cdc54c010959e1bb403.tar.gz
rust-233542bf424af3153f031cdc54c010959e1bb403.zip
Auto merge of #2610 - RalfJung:issue-1909, r=RalfJung
add test for #1909

Fixes https://github.com/rust-lang/miri/issues/1909
-rw-r--r--src/tools/miri/tests/pass/issues/issue-miri-1909.rs57
1 files changed, 57 insertions, 0 deletions
diff --git a/src/tools/miri/tests/pass/issues/issue-miri-1909.rs b/src/tools/miri/tests/pass/issues/issue-miri-1909.rs
new file mode 100644
index 00000000000..ce2114e760a
--- /dev/null
+++ b/src/tools/miri/tests/pass/issues/issue-miri-1909.rs
@@ -0,0 +1,57 @@
+//@compile-flags: -Zmiri-permissive-provenance
+#![deny(unsafe_op_in_unsafe_fn)]
+//! This does some tricky ptr-int-casting.
+
+use core::alloc::{GlobalAlloc, Layout};
+use std::alloc::System;
+
+/// # Safety
+/// `ptr` must be valid for writes of `len` bytes
+unsafe fn volatile_write_zeroize_mem(ptr: *mut u8, len: usize) {
+    for i in 0..len {
+        // ptr as usize + i can't overlow because `ptr` is valid for writes of `len`
+        let ptr_new: *mut u8 = ((ptr as usize) + i) as *mut u8;
+        // SAFETY: `ptr` is valid for writes of `len` bytes, so `ptr_new` is valid for a
+        // byte write
+        unsafe {
+            core::ptr::write_volatile(ptr_new, 0u8);
+        }
+    }
+}
+
+pub struct ZeroizeAlloc;
+
+unsafe impl GlobalAlloc for ZeroizeAlloc {
+    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
+        // SAFETY: uphold by caller
+        unsafe { System.alloc(layout) }
+    }
+
+    unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
+        // securely wipe the deallocated memory
+        // SAFETY: `ptr` is valid for writes of `layout.size()` bytes since it was
+        // previously successfully allocated (by the safety assumption on this function)
+        // and not yet deallocated
+        unsafe {
+            volatile_write_zeroize_mem(ptr, layout.size());
+        }
+        // SAFETY: uphold by caller
+        unsafe { System.dealloc(ptr, layout) }
+    }
+
+    unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
+        // SAFETY: uphold by caller
+        unsafe { System.alloc_zeroed(layout) }
+    }
+}
+
+#[global_allocator]
+static GLOBAL: ZeroizeAlloc = ZeroizeAlloc;
+
+fn main() {
+    let layout = Layout::new::<[u8; 16]>();
+    let ptr = unsafe { std::alloc::alloc_zeroed(layout) };
+    unsafe {
+        std::alloc::dealloc(ptr, layout);
+    }
+}