Skip to content

Commit a4b7e14

Browse files
committed
C "memcpy" shim: ensure the pointers are valid
Also add tests for some other shims that already behave correctly
1 parent 7591c51 commit a4b7e14

9 files changed

+108
-0
lines changed

src/tools/miri/src/shims/foreign_items.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
763763
let ptr_dest = this.read_pointer(ptr_dest)?;
764764
let ptr_src = this.read_pointer(ptr_src)?;
765765
let n = this.read_target_usize(n)?;
766+
767+
// C requires that this must always be a valid pointer, even if `n` is zero, so we better check that.
768+
// (This is more than Rust requires, so `mem_copy` is not sufficient.)
769+
this.ptr_get_alloc_id(ptr_dest)?;
770+
this.ptr_get_alloc_id(ptr_src)?;
771+
766772
this.mem_copy(
767773
ptr_src,
768774
Align::ONE,
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//@ignore-target-windows: No libc on Windows
2+
3+
use std::ptr;
4+
5+
// null is explicitly called out as UB in the C docs.
6+
fn main() {
7+
unsafe {
8+
libc::memchr(ptr::null(), 0, 0); //~ERROR: dangling
9+
}
10+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error: Undefined Behavior: memory access failed: null pointer is a dangling pointer (it has no provenance)
2+
--> $DIR/memchr_null.rs:LL:CC
3+
|
4+
LL | libc::memchr(ptr::null(), 0, 0);
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: null pointer is a dangling pointer (it has no provenance)
6+
|
7+
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
8+
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
9+
= note: BACKTRACE:
10+
= note: inside `main` at $DIR/memchr_null.rs:LL:CC
11+
12+
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
13+
14+
error: aborting due to previous error
15+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//@ignore-target-windows: No libc on Windows
2+
3+
use std::ptr;
4+
5+
// null is explicitly called out as UB in the C docs.
6+
fn main() {
7+
unsafe {
8+
libc::memcmp(ptr::null(), ptr::null(), 0); //~ERROR: dangling
9+
}
10+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error: Undefined Behavior: memory access failed: null pointer is a dangling pointer (it has no provenance)
2+
--> $DIR/memcmp_null.rs:LL:CC
3+
|
4+
LL | libc::memcmp(ptr::null(), ptr::null(), 0);
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: null pointer is a dangling pointer (it has no provenance)
6+
|
7+
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
8+
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
9+
= note: BACKTRACE:
10+
= note: inside `main` at $DIR/memcmp_null.rs:LL:CC
11+
12+
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
13+
14+
error: aborting due to previous error
15+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//@ignore-target-windows: No libc on Windows
2+
//@compile-flags: -Zmiri-permissive-provenance
3+
// C's memcpy is 0 bytes is UB for some pointers that are allowed in Rust's `copy_nonoverlapping`.
4+
5+
fn main() {
6+
let from = 42 as *const u8;
7+
let to = 23 as *mut u8;
8+
unsafe {
9+
to.copy_from(from, 0); // this is fine
10+
libc::memcpy(to.cast(), from.cast(), 0); //~ERROR: dangling
11+
}
12+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error: Undefined Behavior: out-of-bounds pointer use: 0x17[noalloc] is a dangling pointer (it has no provenance)
2+
--> $DIR/memcpy_zero.rs:LL:CC
3+
|
4+
LL | libc::memcpy(to.cast(), from.cast(), 0);
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: 0x17[noalloc] is a dangling pointer (it has no provenance)
6+
|
7+
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
8+
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
9+
= note: BACKTRACE:
10+
= note: inside `main` at $DIR/memcpy_zero.rs:LL:CC
11+
12+
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
13+
14+
error: aborting due to previous error
15+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//@ignore-target-windows: No libc on Windows
2+
3+
use std::ptr;
4+
5+
// null is explicitly called out as UB in the C docs.
6+
fn main() {
7+
unsafe {
8+
libc::memrchr(ptr::null(), 0, 0); //~ERROR: dangling
9+
}
10+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error: Undefined Behavior: memory access failed: null pointer is a dangling pointer (it has no provenance)
2+
--> $DIR/memrchr_null.rs:LL:CC
3+
|
4+
LL | libc::memrchr(ptr::null(), 0, 0);
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: null pointer is a dangling pointer (it has no provenance)
6+
|
7+
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
8+
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
9+
= note: BACKTRACE:
10+
= note: inside `main` at $DIR/memrchr_null.rs:LL:CC
11+
12+
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
13+
14+
error: aborting due to previous error
15+

0 commit comments

Comments
 (0)