about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-07-06 08:00:34 +0000
committerbors <bors@rust-lang.org>2023-07-06 08:00:34 +0000
commitc8b3992da82d973031ed56630765f947fe7fe394 (patch)
tree155059be3374e418ee5943c20107dc8da1092f12
parent7591c514368ff53207714cdf7c702addb1366cb5 (diff)
parenta811adab348464dc9e00bf424632cb0efa53e815 (diff)
downloadrust-c8b3992da82d973031ed56630765f947fe7fe394.tar.gz
rust-c8b3992da82d973031ed56630765f947fe7fe394.zip
Auto merge of #2968 - RalfJung:memcpy, r=RalfJung
C "memcpy" shim: ensure the pointers are valid

Also add tests for some other shims that already behave correctly

Fixes https://github.com/rust-lang/miri/issues/2966
-rw-r--r--src/tools/miri/src/shims/foreign_items.rs6
-rw-r--r--src/tools/miri/tests/fail/shims/memchr_null.rs10
-rw-r--r--src/tools/miri/tests/fail/shims/memchr_null.stderr15
-rw-r--r--src/tools/miri/tests/fail/shims/memcmp_null.rs10
-rw-r--r--src/tools/miri/tests/fail/shims/memcmp_null.stderr15
-rw-r--r--src/tools/miri/tests/fail/shims/memcpy_zero.rs12
-rw-r--r--src/tools/miri/tests/fail/shims/memcpy_zero.stderr15
-rw-r--r--src/tools/miri/tests/fail/shims/memrchr_null.rs11
-rw-r--r--src/tools/miri/tests/fail/shims/memrchr_null.stderr15
9 files changed, 109 insertions, 0 deletions
diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs
index f4e91c30d9f..6915c396d61 100644
--- a/src/tools/miri/src/shims/foreign_items.rs
+++ b/src/tools/miri/src/shims/foreign_items.rs
@@ -763,6 +763,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 let ptr_dest = this.read_pointer(ptr_dest)?;
                 let ptr_src = this.read_pointer(ptr_src)?;
                 let n = this.read_target_usize(n)?;
+
+                // C requires that this must always be a valid pointer, even if `n` is zero, so we better check that.
+                // (This is more than Rust requires, so `mem_copy` is not sufficient.)
+                this.ptr_get_alloc_id(ptr_dest)?;
+                this.ptr_get_alloc_id(ptr_src)?;
+
                 this.mem_copy(
                     ptr_src,
                     Align::ONE,
diff --git a/src/tools/miri/tests/fail/shims/memchr_null.rs b/src/tools/miri/tests/fail/shims/memchr_null.rs
new file mode 100644
index 00000000000..6bc7af7e6bf
--- /dev/null
+++ b/src/tools/miri/tests/fail/shims/memchr_null.rs
@@ -0,0 +1,10 @@
+//@ignore-target-windows: No libc on Windows
+
+use std::ptr;
+
+// null is explicitly called out as UB in the C docs.
+fn main() {
+    unsafe {
+        libc::memchr(ptr::null(), 0, 0); //~ERROR: dangling
+    }
+}
diff --git a/src/tools/miri/tests/fail/shims/memchr_null.stderr b/src/tools/miri/tests/fail/shims/memchr_null.stderr
new file mode 100644
index 00000000000..d48606f34ad
--- /dev/null
+++ b/src/tools/miri/tests/fail/shims/memchr_null.stderr
@@ -0,0 +1,15 @@
+error: Undefined Behavior: memory access failed: null pointer is a dangling pointer (it has no provenance)
+  --> $DIR/memchr_null.rs:LL:CC
+   |
+LL |         libc::memchr(ptr::null(), 0, 0);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: null pointer is a dangling pointer (it has no provenance)
+   |
+   = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
+   = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
+   = note: BACKTRACE:
+   = note: inside `main` at $DIR/memchr_null.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to previous error
+
diff --git a/src/tools/miri/tests/fail/shims/memcmp_null.rs b/src/tools/miri/tests/fail/shims/memcmp_null.rs
new file mode 100644
index 00000000000..a4e0034c40b
--- /dev/null
+++ b/src/tools/miri/tests/fail/shims/memcmp_null.rs
@@ -0,0 +1,10 @@
+//@ignore-target-windows: No libc on Windows
+
+use std::ptr;
+
+// null is explicitly called out as UB in the C docs.
+fn main() {
+    unsafe {
+        libc::memcmp(ptr::null(), ptr::null(), 0); //~ERROR: dangling
+    }
+}
diff --git a/src/tools/miri/tests/fail/shims/memcmp_null.stderr b/src/tools/miri/tests/fail/shims/memcmp_null.stderr
new file mode 100644
index 00000000000..7a09c779894
--- /dev/null
+++ b/src/tools/miri/tests/fail/shims/memcmp_null.stderr
@@ -0,0 +1,15 @@
+error: Undefined Behavior: memory access failed: null pointer is a dangling pointer (it has no provenance)
+  --> $DIR/memcmp_null.rs:LL:CC
+   |
+LL |         libc::memcmp(ptr::null(), ptr::null(), 0);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: null pointer is a dangling pointer (it has no provenance)
+   |
+   = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
+   = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
+   = note: BACKTRACE:
+   = note: inside `main` at $DIR/memcmp_null.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to previous error
+
diff --git a/src/tools/miri/tests/fail/shims/memcpy_zero.rs b/src/tools/miri/tests/fail/shims/memcpy_zero.rs
new file mode 100644
index 00000000000..5283fea4cb9
--- /dev/null
+++ b/src/tools/miri/tests/fail/shims/memcpy_zero.rs
@@ -0,0 +1,12 @@
+//@ignore-target-windows: No libc on Windows
+//@compile-flags: -Zmiri-permissive-provenance
+// C's memcpy is 0 bytes is UB for some pointers that are allowed in Rust's `copy_nonoverlapping`.
+
+fn main() {
+    let from = 42 as *const u8;
+    let to = 23 as *mut u8;
+    unsafe {
+        to.copy_from(from, 0); // this is fine
+        libc::memcpy(to.cast(), from.cast(), 0); //~ERROR: dangling
+    }
+}
diff --git a/src/tools/miri/tests/fail/shims/memcpy_zero.stderr b/src/tools/miri/tests/fail/shims/memcpy_zero.stderr
new file mode 100644
index 00000000000..7c1c3fe20c4
--- /dev/null
+++ b/src/tools/miri/tests/fail/shims/memcpy_zero.stderr
@@ -0,0 +1,15 @@
+error: Undefined Behavior: out-of-bounds pointer use: 0x17[noalloc] is a dangling pointer (it has no provenance)
+  --> $DIR/memcpy_zero.rs:LL:CC
+   |
+LL |         libc::memcpy(to.cast(), from.cast(), 0);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: 0x17[noalloc] is a dangling pointer (it has no provenance)
+   |
+   = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
+   = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
+   = note: BACKTRACE:
+   = note: inside `main` at $DIR/memcpy_zero.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to previous error
+
diff --git a/src/tools/miri/tests/fail/shims/memrchr_null.rs b/src/tools/miri/tests/fail/shims/memrchr_null.rs
new file mode 100644
index 00000000000..b6707d558d8
--- /dev/null
+++ b/src/tools/miri/tests/fail/shims/memrchr_null.rs
@@ -0,0 +1,11 @@
+//@ignore-target-windows: No libc on Windows
+//@ignore-target-apple: No `memrchr` on some apple targets
+
+use std::ptr;
+
+// null is explicitly called out as UB in the C docs.
+fn main() {
+    unsafe {
+        libc::memrchr(ptr::null(), 0, 0); //~ERROR: dangling
+    }
+}
diff --git a/src/tools/miri/tests/fail/shims/memrchr_null.stderr b/src/tools/miri/tests/fail/shims/memrchr_null.stderr
new file mode 100644
index 00000000000..b5b7630e7fd
--- /dev/null
+++ b/src/tools/miri/tests/fail/shims/memrchr_null.stderr
@@ -0,0 +1,15 @@
+error: Undefined Behavior: memory access failed: null pointer is a dangling pointer (it has no provenance)
+  --> $DIR/memrchr_null.rs:LL:CC
+   |
+LL |         libc::memrchr(ptr::null(), 0, 0);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: null pointer is a dangling pointer (it has no provenance)
+   |
+   = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
+   = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
+   = note: BACKTRACE:
+   = note: inside `main` at $DIR/memrchr_null.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to previous error
+