| Age | Commit message (Collapse) | Author | Lines |
|
Tested through x86 avx512vpopcntdq and avx512bitalg functions.
|
|
|
|
Issue discovered in TB: spurious reads are not (yet) possible in a concurrent setting
We discovered a week ago that in general, the current model of TB does not allow spurious reads because although reads provably never invalidate other reads, they migh invalidate writes.
Consider the code
```rs
fn f1(x: &u8) {}
fn f2(y: &mut u8) -> &mut u8 { &mut *y }
let mut data = 0;
let _ = thread::spawn(|| {
f1(&mut data)
};
let _ = thread::spawn(|| {
let y = f2(&mut data);
*y = 42;
});
```
of which one possible interleaving is
```rs
1: retag x (&, protect) // x: [P]Frozen
2: retag y (&mut, protect) // y: [P]Reserved, x: [P]Frozen
1: return f1 // x: [P]Frozen -> Frozen, y: [P]Reserved
2: return f2 // x: Frozen, y: [P]Reserved -> Reserved
2: write y // x: Disabled, y: Active
```
that does not have UB.
Assume enough barriers to force this specific interleaving, and consider that the compiler could choose to insert a spurious read throug `x` during the call to `f1` which would produce
```rs
1: retag x (&, protect) // x: [P]Frozen
2: retag y (&mut, protect) // y: [P]Reserved, x: [P]Frozen
1: spurious read x // x: [P]Frozen, y: [P]Reserved -> [P]Frozen
1: return f1 // x: [P]Frozen -> Frozen, y: [P]Frozen
2: return f2 // x: Frozen, y: [P]Frozen -> Frozen
2: write y // UB
```
Thus the target of the optimization (with a spurious read) has UB when the source did not.
This is bad.
SB is not affected because the code would be UB as early as `retag y`, this happens because we're trying to be a bit more subtle than that, and because the effects of a foreign read on a protected `&mut` bleed outside of the boundaries of the protector. Fortunately we have a fix planned, but in the meantime here are some `#[should_panic]` exhaustive tests to illustrate the issue.
The error message printed by the `#[should_panic]` tests flags the present issue in slightly more general terms: it says that the sequence `retag x (&, protect); retag y (&mut, protect);` produces the configuration `C_source := x: [P]Frozen, x: [P]Reserved`, and that inserting a spurious read through `x` turns it into `C_target := x: [P]Frozen, y: [P]Reserved`.
It then says that `C_source` is distinguishable from `C_target`, which means that there exists a sequence of instructions applied to both that triggers UB in `C_target` but not in `C_source`.
It happens that one such sequence is `1: return f1; 2: return f2; 2: write y;` as shown above, but it is not the only one, as for example the interleaving `1: return f1; 2: write y;` is also problematic.
|
|
This occurs because in some interleavings, inserting
a spurious read turns a Reserved into Frozen.
We show here an exhaustive test (including arbitrary unknown
code in two different threads) that makes this issue
observable.
|
|
also share the code that emits the actual error
|
|
Implement some `llvm.x86.sse2.*` intrinsics and add tests
Continuation of https://github.com/rust-lang/miri/pull/2989 with SSE2 intrinsics.
Thankfully, a significant amount of SSE2 functions use `simd_*` intrinsics, which are already implemented in Miri.
|
|
Implements LLVM intrisics needed to run most SSE2 functions from `core::arch::x86{,_64}`.
Also adds miri tests for those functions (mostly copied from core_arch tests).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
consistent across targets
|
|
value callee-invalid
|
|
feat(std): Stabilize 'os_str_bytes' feature
Closes #111544
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
also we were missing the case for Vector arguments, so handle those as well
|
|
|
|
argument passing
this entirely avoids even creating unsized locals in Immediate::Uninitialized state
|
|
new invariant: Place::Local never refers to something unsized
|
|
|
|
|
|
miri ABI compatibility check: accept u32 and i32
If only the sign differs, then surely these types are compatible. (We do still check that `arg_ext` is the same, just in case.)
Also I made it so that the ABI check must *imply* that size and alignment are the same, but it doesn't actively check that itself. With how crazy ABI constraints get, having equal size and align really shouldn't be used as a signal for anything I think...
|
|
|
|
|
|
tests/catch_panic: make output easier to interpret
|
|
|
|
avoid triple-backtrace due to panic-during-cleanup
Supersedes https://github.com/rust-lang/rust/pull/115020
Cc https://github.com/rust-lang/rust/issues/114954
r? ``@Amanieu``
|
|
|
|
|
|
Record allocation spans inside force_allocation
This expands https://github.com/rust-lang/miri/pull/2940 to cover locals
r? `@RalfJung`
|
|
|
|
|
|
|
|
|
|
|
|
direct abort
|
|
the same message
|
|
|
|
|
|
When reporting a heap use-after-free, say where the allocation was allocated and deallocated
This is a partial solution to: https://github.com/rust-lang/miri/issues/2917
Currently in the interpreter, we only have accurate information for where heap allocations are allocated and deallocated (see https://github.com/rust-lang/miri/pull/2940#discussion_r1243559711). So this just implements support for allocations where the information is already available, and the full support will require more interpreter tweaks.
|