Skip to content

Commit d7864d2

Browse files
committed
Auto merge of rust-lang#3388 - RalfJung:exposed, r=RalfJung
add exposed-provenance example where we miss UB Example by `@saethlin`
2 parents dd5b4f5 + c99c314 commit d7864d2

File tree

1 file changed

+26
-0
lines changed

1 file changed

+26
-0
lines changed

src/tools/miri/tests/pass/intptrcast.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,31 @@ fn functions() {
149149
}
150150
}
151151

152+
/// Example that should be UB but due to wildcard pointers being too permissive
153+
/// we don't notice.
154+
fn should_be_ub() {
155+
let alloc1 = 1u8;
156+
let alloc2 = 2u8;
157+
// Expose both allocations
158+
let addr1: usize = &alloc1 as *const u8 as usize;
159+
let addr2: usize = &alloc2 as *const u8 as usize;
160+
161+
// Cast addr1 back to a pointer. In Miri, this gives it Wildcard provenance.
162+
let wildcard = addr1 as *const u8;
163+
unsafe {
164+
// Read through the wildcard
165+
assert_eq!(*wildcard, 1);
166+
// Offset the pointer to another allocation.
167+
// Note that we are doing this arithmetic that does not require we stay within bounds of the allocation.
168+
let wildcard = wildcard.wrapping_offset(addr2 as isize - addr1 as isize);
169+
// This should report UB:
170+
assert_eq!(*wildcard, 2);
171+
// ... but it doesn't. A pointer's provenance specifies a single allocation that it is allowed to read from.
172+
// And wrapping_offset only modifies the address, not the provenance.
173+
// So which allocation is wildcard allowed to access? It cannot be both.
174+
}
175+
}
176+
152177
fn main() {
153178
cast();
154179
cast_dangling();
@@ -162,4 +187,5 @@ fn main() {
162187
ptr_eq_integer();
163188
zst_deref_of_dangling();
164189
functions();
190+
should_be_ub();
165191
}

0 commit comments

Comments
 (0)