Skip to content

Commit

Permalink
Auto merge of rust-lang#2968 - RalfJung:memcpy, r=RalfJung
Browse files Browse the repository at this point in the history
C "memcpy" shim: ensure the pointers are valid

Also add tests for some other shims that already behave correctly

Fixes rust-lang/miri#2966
  • Loading branch information
bors committed Jul 6, 2023
2 parents 7591c51 + a811ada commit c8b3992
Show file tree
Hide file tree
Showing 9 changed files with 109 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/tools/miri/src/shims/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
10 changes: 10 additions & 0 deletions src/tools/miri/tests/fail/shims/memchr_null.rs
Original file line number Diff line number Diff line change
@@ -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
}
}
15 changes: 15 additions & 0 deletions src/tools/miri/tests/fail/shims/memchr_null.stderr
Original file line number Diff line number Diff line change
@@ -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

10 changes: 10 additions & 0 deletions src/tools/miri/tests/fail/shims/memcmp_null.rs
Original file line number Diff line number Diff line change
@@ -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
}
}
15 changes: 15 additions & 0 deletions src/tools/miri/tests/fail/shims/memcmp_null.stderr
Original file line number Diff line number Diff line change
@@ -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

12 changes: 12 additions & 0 deletions src/tools/miri/tests/fail/shims/memcpy_zero.rs
Original file line number Diff line number Diff line change
@@ -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
}
}
15 changes: 15 additions & 0 deletions src/tools/miri/tests/fail/shims/memcpy_zero.stderr
Original file line number Diff line number Diff line change
@@ -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

11 changes: 11 additions & 0 deletions src/tools/miri/tests/fail/shims/memrchr_null.rs
Original file line number Diff line number Diff line change
@@ -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
}
}
15 changes: 15 additions & 0 deletions src/tools/miri/tests/fail/shims/memrchr_null.stderr
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit c8b3992

Please sign in to comment.