Skip to content

Commit 6454be8

Browse files
committed
fixup rebase
1 parent 4369f70 commit 6454be8

File tree

9 files changed

+125
-16
lines changed

9 files changed

+125
-16
lines changed

src/shims/native_lib/mod.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -226,8 +226,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
226226
let this = self.eval_context_mut();
227227

228228
for evt in events.acc_events {
229+
//eprintln!("evt: {evt:?}");
229230
let evt_rg = evt.get_range();
230-
231231
// LLVM at least permits vectorising accesses to adjacent allocations,
232232
// so we cannot assume 1 access = 1 allocation. :(
233233
let mut rg = evt_rg.addr..evt_rg.end();
@@ -239,12 +239,14 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
239239
let alloc_addr = alloc.get_bytes_unchecked_raw().addr();
240240

241241
// Skip forward however many bytes of the access are contained in the current allocation.
242-
let overlap_size = alloc.len().strict_sub(evt_rg.addr.saturating_sub(alloc_addr));
243-
let _ = rg.advance_by(overlap_size);
242+
let overlap = std::cmp::max(alloc_addr, curr).strict_sub(alloc_addr)
243+
..std::cmp::min(alloc_addr.strict_add(alloc.len()), rg.end)
244+
.strict_sub(alloc_addr);
245+
let _ = rg.advance_by(overlap.len());
246+
//eprintln!("overlap: {overlap:?}");
244247

245248
// Get an overlap range as an offset from the allocation base addr.
246-
let overlap_start = evt_rg.addr.strict_sub(alloc_addr);
247-
let overlap = overlap_start..overlap_start.strict_add(overlap_size);
249+
//let overlap = unshifted_overlap.start..unshifted_overlap.start.strict_add(unshifted_overlap.len());
248250

249251
// Reads are infallible, writes might not be.
250252
if evt.is_read() {
@@ -256,8 +258,14 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
256258
}
257259
}
258260
} else if evt.definitely_happened() || alloc.mutability.is_mut() {
259-
//let (alloc, cx) = this.get_alloc_raw_mut(alloc_id)?;
260-
//alloc.process_native_write(AllocRange { start: overlap.start, size: overlap.len() })
261+
let (alloc, cx) = this.get_alloc_raw_mut(alloc_id)?;
262+
alloc.process_native_write(
263+
&cx.tcx,
264+
Some(AllocRange {
265+
start: Size::from_bytes(overlap.start),
266+
size: Size::from_bytes(overlap.len()),
267+
}),
268+
)
261269
}
262270
}
263271
}
@@ -349,7 +357,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
349357
// Prepare for possible write from native code if mutable.
350358
if info.mutbl.is_mut() {
351359
let (alloc, cx) = this.get_alloc_raw_mut(alloc_id)?;
352-
alloc.process_native_write(&cx.tcx, None);
360+
if !tracing {
361+
alloc.process_native_write(&cx.tcx, None);
362+
}
353363
// Also expose *mutable* provenance for the interpreter-level allocation.
354364
std::hint::black_box(alloc.get_bytes_unchecked_raw_mut().expose_provenance());
355365
}

tests/native-lib/fail/trace_read.stderr

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,27 @@
1+
warning: integer-to-pointer cast
2+
--> tests/native-lib/fail/trace_read.rs:LL:CC
3+
|
4+
LL | let invalid: *const i32 = std::ptr::with_exposed_provenance(intermediate.addr());
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ integer-to-pointer cast
6+
|
7+
= help: this program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`, which means that Miri might miss pointer bugs in this program
8+
= help: see https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation
9+
= help: to ensure that Miri does not miss bugs in your program, use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead
10+
= help: you can then set `MIRIFLAGS=-Zmiri-strict-provenance` to ensure you are not relying on `with_exposed_provenance` semantics
11+
= help: alternatively, `MIRIFLAGS=-Zmiri-permissive-provenance` disables this warning
12+
= note: BACKTRACE:
13+
= note: inside `unexposed_reachable_alloc` at tests/native-lib/fail/trace_read.rs:LL:CC
14+
note: inside `main`
15+
--> tests/native-lib/fail/trace_read.rs:LL:CC
16+
|
17+
LL | unexposed_reachable_alloc();
18+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
19+
120
error: Undefined Behavior: pointer not dereferenceable: pointer must be dereferenceable for 4 bytes, but got $HEX[noalloc] which is a dangling pointer (it has no provenance)
221
--> tests/native-lib/fail/trace_read.rs:LL:CC
322
|
4-
LL | println!("{}", *invalid);
5-
| ^^^^^^^^ Undefined Behavior occurred here
23+
LL | ... println!("{}", *invalid);
24+
| ^^^^^^^^ Undefined Behavior occurred here
625
|
726
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
827
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
@@ -17,5 +36,5 @@ LL | unexposed_reachable_alloc();
1736

1837
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
1938

20-
error: aborting due to 1 previous error
39+
error: aborting due to 1 previous error; 1 warning emitted
2140

tests/native-lib/fail/trace_write.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@ fn main() {
1313
}
1414

1515
fn partial_init() {
16-
let mut slice: [u8; 10];
16+
let mut slice = std::mem::MaybeUninit::<[u8; 3]>::uninit();
17+
let slice_ptr = slice.as_mut_ptr().cast::<u8>();
1718
unsafe {
18-
init_n(5, (&raw mut slice).cast());
19-
assert!(slice[3] == 0);
20-
println!("{}", slice[6]);
19+
init_n(2, slice_ptr);
20+
assert!(*slice_ptr == 0);
21+
assert!(*slice_ptr.offset(1) == 0);
22+
let _val = *slice_ptr.offset(2); //~ ERROR: Undefined Behavior: using uninitialized data
2123
}
2224
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
warning: sharing memory with a native function called via FFI
2+
--> tests/native-lib/fail/trace_write.rs:LL:CC
3+
|
4+
LL | init_n(2, slice_ptr);
5+
| ^^^^^^^^^^^^^^^^^^^^ sharing memory with a native function
6+
|
7+
= help: when memory is shared with a native function call, Miri can only track initialisation and provenance on a best-effort basis
8+
= help: in particular, Miri assumes that the native call initializes all memory it has written to
9+
= help: Miri also assumes that any part of this memory may be a pointer that is permitted to point to arbitrary exposed memory
10+
= help: what this means is that Miri will easily miss Undefined Behavior related to incorrect usage of this shared memory, so you should not take a clean Miri run as a signal that your FFI code is UB-free
11+
= help: tracing memory accesses in native code is not yet fully implemented, so there can be further imprecisions beyond what is documented here
12+
= note: BACKTRACE:
13+
= note: inside `partial_init` at tests/native-lib/fail/trace_write.rs:LL:CC
14+
note: inside `main`
15+
--> tests/native-lib/fail/trace_write.rs:LL:CC
16+
|
17+
LL | partial_init();
18+
| ^^^^^^^^^^^^^^
19+
20+
error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory
21+
--> tests/native-lib/fail/trace_write.rs:LL:CC
22+
|
23+
LL | let _val = *slice_ptr.offset(2);
24+
| ^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
25+
|
26+
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
27+
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
28+
= note: BACKTRACE:
29+
= note: inside `partial_init` at tests/native-lib/fail/trace_write.rs:LL:CC
30+
note: inside `main`
31+
--> tests/native-lib/fail/trace_write.rs:LL:CC
32+
|
33+
LL | partial_init();
34+
| ^^^^^^^^^^^^^^
35+
36+
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
37+
38+
error: aborting due to 1 previous error; 1 warning emitted
39+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
warning: sharing memory with a native function called via FFI
2+
--> tests/native-lib/pass/ptr_read_access.rs:LL:CC
3+
|
4+
LL | unsafe { print_pointer(&x) };
5+
| ^^^^^^^^^^^^^^^^^ sharing memory with a native function
6+
|
7+
= help: when memory is shared with a native function call, Miri can only track initialisation and provenance on a best-effort basis
8+
= help: in particular, Miri assumes that the native call initializes all memory it has written to
9+
= help: Miri also assumes that any part of this memory may be a pointer that is permitted to point to arbitrary exposed memory
10+
= help: what this means is that Miri will easily miss Undefined Behavior related to incorrect usage of this shared memory, so you should not take a clean Miri run as a signal that your FFI code is UB-free
11+
= help: tracing memory accesses in native code is not yet fully implemented, so there can be further imprecisions beyond what is documented here
12+
= note: BACKTRACE:
13+
= note: inside `test_access_pointer` at tests/native-lib/pass/ptr_read_access.rs:LL:CC
14+
note: inside `main`
15+
--> tests/native-lib/pass/ptr_read_access.rs:LL:CC
16+
|
17+
LL | test_access_pointer();
18+
| ^^^^^^^^^^^^^^^^^^^^^
19+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
printing pointer dereference from C: 42
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
warning: sharing memory with a native function called via FFI
2+
--> tests/native-lib/pass/ptr_write_access.rs:LL:CC
3+
|
4+
LL | unsafe { increment_int(&mut x) };
5+
| ^^^^^^^^^^^^^^^^^^^^^ sharing memory with a native function
6+
|
7+
= help: when memory is shared with a native function call, Miri can only track initialisation and provenance on a best-effort basis
8+
= help: in particular, Miri assumes that the native call initializes all memory it has written to
9+
= help: Miri also assumes that any part of this memory may be a pointer that is permitted to point to arbitrary exposed memory
10+
= help: what this means is that Miri will easily miss Undefined Behavior related to incorrect usage of this shared memory, so you should not take a clean Miri run as a signal that your FFI code is UB-free
11+
= help: tracing memory accesses in native code is not yet fully implemented, so there can be further imprecisions beyond what is documented here
12+
= note: BACKTRACE:
13+
= note: inside `test_increment_int` at tests/native-lib/pass/ptr_write_access.rs:LL:CC
14+
note: inside `main`
15+
--> tests/native-lib/pass/ptr_write_access.rs:LL:CC
16+
|
17+
LL | test_increment_int();
18+
| ^^^^^^^^^^^^^^^^^^^^
19+

tests/native-lib/ptr_write_access.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,6 @@ EXPORT void init_ptr_stored_in_shared_mem(int32_t val) {
112112

113113
EXPORT void init_n(int32_t n, char* ptr) {
114114
for (int i=0; i<n; i++) {
115-
*ptr = 0;
115+
*(ptr+i) = 0;
116116
}
117117
}

0 commit comments

Comments
 (0)