Commit Graph

2843 Commits

Author SHA1 Message Date
Ralf Jung
63625b0397 adjust for better provenance control 2022-06-06 11:43:25 -04:00
infrandomness
d0a0369a24 Refactor POSIX to UNIX
This renames the directory containing posix to unix; where applicable,
it also rename functions with the word "posix" to "unix"
2022-06-05 22:46:34 +02:00
bors
2eae474673 Auto merge of #2197 - RalfJung:round-robin, r=RalfJung
make Miri's scheduler proper round-robin

When thread N blocks or yields, we activate thread N+1 next, rather than always activating thread 0. This should guarantee that as long as all threads regularly yield, each thread eventually takes a step again.

Fixes the "multiple loops that yield playing ping-pong" part of https://github.com/rust-lang/miri/issues/1388.
`@cbeuw` I hope this doesn't screw up the scheduler-dependent tests you are adding in your PR.
2022-06-05 18:37:07 +00:00
Ralf Jung
47745380cd make Miri's scheduler proper round-robin 2022-06-05 14:22:00 -04:00
bors
5f988ab553 Auto merge of #2189 - RalfJung:clippy, r=RalfJung
run Clippy on CI

and fix some things it complains about. Also use `rustup-toolchain` script on CI (reduces code duplication, and good thing to make sure it keeps working, since we recommend it in the docs).

I left `ui_test` out for now; I'll leave those nits to `@oli-obk.` ;)
2022-06-05 15:18:39 +00:00
Ralf Jung
32c03080f1 rustup 2022-06-04 19:43:46 -04:00
Ralf Jung
151b6b13e0 clippy: main crate 2022-06-04 13:29:00 -04:00
Matthias Krüger
bcc491a6ba clippy fixes
clippy::redundant_closure
clippy::unnecessary_mut_passed
clippy::single_char_pattern
clippy::clone_on_copy
clippy::into_iter_on_ref
clippy::extra_unused_lifetimes
2022-06-04 17:10:32 +02:00
Ralf Jung
e79a331fea do not pass TyCtxt by reference 2022-06-02 15:11:22 -04:00
Oli Scherer
4b100a1b58 Check that diagnostics happen in the line that they are annotated for 2022-06-01 11:47:54 +00:00
Ralf Jung
62c48b2998 fix some lifetime names 2022-05-31 08:45:01 -04:00
Ralf Jung
eb6d4cdac0 reduce some code duplication 2022-05-31 08:43:17 -04:00
bors
aa589d3dc7 Auto merge of #2145 - saethlin:zero-size-creation, r=RalfJung
Save a created event for zero-size reborrows

Currently, we don't save a created event for zero-sized reborrows. Attempting to use something from a zero-sized reborrow is surprisingly common, for example on `minimal-lexical==0.2.1` we previously just emit this:
```
Undefined Behavior: attempting a write access using <187021> at alloc72933[0x0], but that tag does not exist in the borrow stack for this location
    --> /root/rust/library/core/src/ptr/mod.rs:1287:9
     |
1287 |         copy_nonoverlapping(&src as *const T, dst, 1);
     |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     |         |
     |         attempting a write access using <187021> at alloc72933[0x0], but that tag does not exist in the borrow stack for this location
     |         this error occurs as part of an access at alloc72933[0x0..0x8]
     |
     = help: this indicates a potential bug in the program: it performed an invalid operation, but the rules it violated are still experimental
     = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information

     = note: inside `std::ptr::write::<u64>` at /root/rust/library/core/src/ptr/mod.rs:1287:9
note: inside `minimal_lexical::stackvec::StackVec::push_unchecked` at /root/build/src/stackvec.rs:82:13
    --> /root/build/src/stackvec.rs:82:13
     |
82   |             ptr::write(self.as_mut_ptr().add(self.len()), value);
     |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

... backtrace continues...
```
Which leaves us with the question "where did we make this pointer?" because for every other diagnostic you get a "was created by" note, so I suspect people might be tempted to think there is a Miri bug here. I certainly was.

---
This code duplication is so awful, I'm going to take a look at cleaning it up later. The fact that `ptr_get_alloc_id` can fail in this situation makes things annoying.
2022-05-30 23:43:51 +00:00
Ben Kimock
ba9391334e Add support for _COARSE clocks, spruce up comments 2022-05-30 11:26:10 -04:00
Ben Kimock
9a1475dbe2 Save a created event for zero-size reborrows 2022-05-29 16:45:26 -04:00
Ralf Jung
7cd5fc3de3 rustup 2022-05-29 14:06:35 +02:00
Ralf Jung
8c42ef1dee enable number validity checking and ptr::invalid checking by default 2022-05-25 16:17:41 +02:00
Oli Scherer
f1756c3ddd Add a custom ui test runner and move all tests to it 2022-05-25 13:31:26 +00:00
Jakob Degen
168c83a0b7 Adjust Miri to also require return places everywhere 2022-05-24 17:16:36 +02:00
Ralf Jung
697dca2e0e clean up int2ptr code a bit 2022-05-23 10:03:33 +02:00
bors
ab03d32622 Auto merge of #2059 - carbotaniuman:master, r=RalfJung
Initial work on Miri permissive-exposed-provenance

Miri portions of the changes for portions of a permissive ptr-to-int model for Miri. This is more restrictive than what we currently have so it will probably need a flag once I figure out how to hook that up.

> This implements a form of permissive exposed-address provenance, wherein the only way to expose the address is with a cast to usize (ideally expose_addr). This is more restrictive than C in that stuff like reading the representation bytes (via unions, type-punning, transmute) does not expose the address, only expose_addr. This is less restrictive than C in that a pointer casted from an integer has union provenance of all exposed pointers, not any udi stuff.

There's a few TODOs here, namely related to `fn memory_read` and friends. We pass it the maybe/unreified provenance before `ptr_get_alloc` reifies it into a concrete one, so it doesn't have the `AllocId` (or the SB tag, but that's getting ahead of ourselves). One way this could be fixed is changing `ptr_get_alloc` and (`ptr_try_get_alloc_id` on the rustc side) to return a pointer with the tag fixed up. We could also take in different arguments, but I'm not sure what works best.

The other TODOs here are how permissive this model could be. This currently does not enforce that a ptr-to-int cast happens before the corresponding int-to-ptr (colloquial meaning of happens before, not atomic meaning). Example:

```
let ptr = 0x2000 as *const i32;
let a: i32 = 5;
let a_ptr = &a as *const i32;

// value is 0x2000;
a_ptr as usize;

println!("{}", unsafe { *ptr }); // this is valid
```

We also allow the resulting pointer to dereference different non-contiguous allocations (the "not any udi stuff" mentioned above), which I'm not sure if is allowed by LLVM.

This is the Miri side of https://github.com/rust-lang/rust/pull/95826.
2022-05-23 07:24:33 +00:00
carbotaniuman
f7bc441fd3 Initial work on permissive provenance 2022-05-23 09:07:31 +02:00
bors
72e11d370a Auto merge of #2105 - thomcc:flip-failure-rate, r=RalfJung
Fix backwards `cmpxchg_weak_failure_rate` check

Uh, I guess I got this backwards a long time ago 😓.
2022-05-23 07:03:49 +00:00
Thom Chiovoloni
fdfbd7a658
Fix backwards cmpxchg_weak_failure_rate check 2022-05-22 20:24:08 -07:00
Ben Kimock
b20c6cfd81 Factor current-span logic into a lazy caching handle 2022-05-22 18:23:01 -04:00
Matthias Krüger
89da571b5d shims: fs: silence stderr instead of stdout.
Fixes #2143
2022-05-22 21:54:00 +02:00
Matthias Krüger
d7d7a9a162 [NFC] shims: fs: fmt 2022-05-22 21:47:44 +02:00
bors
e3227cfc7e Auto merge of #2141 - saethlin:early-diagnostics-ice, r=RalfJung
Adjust diagnostics assertion so we don't ICE in setup

Fixes https://github.com/rust-lang/miri/issues/2076 just by handling diagnostics produced during setup. The tracking notes don't have any spans but it's better than an ICE.

It looks like we leak allocations 1..20, and allocations 13..19 don't have any creation notes, and 14 only has a `FreedAlloc` alloc tracking diagnostic.
2022-05-22 16:17:17 +00:00
Ralf Jung
73534a678d
tweak comment 2022-05-22 18:16:59 +02:00
Ben Kimock
486a769935 Handle diagnotics emitted in runtime initialization 2022-05-22 11:28:40 -04:00
bors
d58abab2e7 Auto merge of #2142 - saethlin:cleanup-data-race-ice, r=oli-obk
Make allow_data_races_* public and use it during EnvVars::cleanup

Fixes https://github.com/rust-lang/miri/issues/2020

I've tried for hours now to come up with a test case for this ICE with no luck. I suspect there's something about the way the data race detection works under these conditions that I just don't understand 😩.

But I tried this change out on a handful of crates and I don't see any more ICEs of this form. For whatever reason it seems like `bastion==0.4.5` is a good way to run into this, with the flags
```
MIRIFLAGS="-Zmiri-tag-raw-pointers -Zmiri-panic-on-unsupported -Zmiri-disable-isolation" cargo +miri miri test --no-fail-fast --doc
```
I think all the cases I've run into with this involve both `-Zmiri-panic-on-unsupported` and `-Zmiri-tag-raw-pointers`, so it could be that the combination of an unexpected panic and a machine halt is required.
2022-05-22 06:18:29 +00:00
Mateusz Gienieczko
bd731508d4
Use precomputed layouts. 2022-05-22 01:01:12 +02:00
Mateusz Gienieczko
a40ff562a0
Add i16 and u16 primitive layout. 2022-05-22 01:00:59 +02:00
Mateusz Gienieczko
2fa53c0385
Dynamic offset calculation in GetSystemInfo. 2022-05-21 21:42:25 +02:00
Ben Kimock
3cfce6ffb2 Make allow_data_races_* public to silence data races during cleanup 2022-05-21 15:16:15 -04:00
Mateusz Gienieczko
63e98aee0c
Change GetSystemInfo to explicit offset. 2022-05-21 19:44:12 +02:00
Mateusz Gienieczko
c4ee368acb
Set page size in GetSystemInfo. 2022-05-21 18:17:25 +02:00
Ralf Jung
8b4d613cc8 rustup 2022-05-20 18:37:57 +02:00
bors
9230b92cf2 Auto merge of #2128 - saethlin:fix-creation-range, r=RalfJung
Pass the correct size to the AllocRange for log_creation

Fixes https://github.com/rust-lang/miri/issues/2127

I guess all I needed was a bit of sleep and reassurance that this diagnostic is the wrong part of that situation.
2022-05-19 15:08:22 +00:00
Ben Kimock
ada864f387 Pass the correct size to the AllocRange for log_creation 2022-05-19 09:29:08 -04:00
Ralf Jung
ea63a695c8 rustup 2022-05-15 12:58:28 +02:00
Ralf Jung
90a190e03b don't ICE when libcore is missing 2022-05-15 10:26:47 +02:00
bors
90d28eada1 Auto merge of #2116 - carbotaniuman:minimal-miri-changes, r=RalfJung
Minimal miri changes for rustc permissive provenance

Simple no-op changes to adapt to new API surface.
2022-05-15 07:11:51 +00:00
bors
98c8c8f9b5 Auto merge of #2030 - saethlin:track-alloc-history, r=oli-obk
Print spans where tags are created and invalidated

5225225 called this "automatic tag tracking" and I think that may be a reasonable description, but I would like to kill tag tracking as a primary use of Miri if possible. Tag tracking isn't always possible; for example if the UB is only detected with isolation off and the failing tag is made unstable by removing isolation. (also it's bad UX to run the tool twice)

This is just one of the things we can do with https://github.com/rust-lang/miri/pull/2024

The memory usage of this is _shockingly_ low, I think because the memory usage of Miri is driven by allocations where each byte ends up with its own very large stack. The memory usage in this change is linear with the number of tags, not tags * bytes. If memory usage gets out of control we can cap the number of events we save per allocation, from experience we tend to only use the most recent few in diagnostics but of course there's no guarantee of that so if we can manage to keep everything that would be best.

In many cases now I can tell exactly what these codebases are doing wrong just from the new outputs here, which I think is extremely cool.

New helps generated with plain old `cargo miri test` on `rust-argon2` v1.0.0:
```
test argon2::tests::single_thread_verification_multi_lane_hash ... error: Undefined Behavior: trying to reborrow <1485898> for Unique permission at alloc110523[0x0], but that tag does not exist in the borrow stack for this location
   --> /home/ben/.rustup/toolchains/miri/lib/rustlib/src/rust/library/core/src/mem/manually_drop.rs:89:9
    |
89  |         slot.value
    |         ^^^^^^^^^^
    |         |
    |         trying to reborrow <1485898> for Unique permission at alloc110523[0x0], but that tag does not exist in the borrow stack for this location
    |         this error occurs as part of a reborrow at alloc110523[0x0..0x20]
    |
    = help: this indicates a potential bug in the program: it performed an invalid operation, but the rules it violated are still experimental
    = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
help: <1485898> was created by a retag at offsets [0x0..0x20]
   --> src/memory.rs:42:13
    |
42  |             vec.push(unsafe { &mut (*ptr) });
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: <1485898> was later invalidated at offsets [0x0..0x20]
   --> src/memory.rs:42:31
    |
42  |             vec.push(unsafe { &mut (*ptr) });
    |                               ^^^^^^^^^^^
```

And with `-Zmiri-tag-raw-pointers` on `slab` v0.4.5
```
error: Undefined Behavior: trying to reborrow <2915> for Unique permission at alloc1418[0x0], but that tag does not exist in the borrow stack for this location
   --> /tmp/slab-0.4.5/src/lib.rs:835:16
    |
835 |         match (&mut *ptr1, &mut *ptr2) {
    |                ^^^^^^^^^^
    |                |
    |                trying to reborrow <2915> for Unique permission at alloc1418[0x0], but that tag does not exist in the borrow stack for this location
    |                this error occurs as part of a reborrow at alloc1418[0x0..0x10]
    |
    = help: this indicates a potential bug in the program: it performed an invalid operation, but the rules it violated are still experimental
    = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
help: <2915> was created by a retag at offsets [0x0..0x10]
   --> /tmp/slab-0.4.5/src/lib.rs:833:20
    |
833 |         let ptr1 = self.entries.get_unchecked_mut(key1) as *mut Entry<T>;
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: <2915> was later invalidated at offsets [0x0..0x20]
   --> /tmp/slab-0.4.5/src/lib.rs:834:20
    |
834 |         let ptr2 = self.entries.get_unchecked_mut(key2) as *mut Entry<T>;
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```

And without raw pointer tagging, `cargo miri test` on `half` v1.8.2
```
error: Undefined Behavior: trying to reborrow <untagged> for Unique permission at alloc1340[0x0], but that tag only grants SharedReadOnly permission for this location
   --> /home/ben/.rustup/toolchains/miri/lib/rustlib/src/rust/library/core/src/slice/raw.rs:141:9
    |
141 |         &mut *ptr::slice_from_raw_parts_mut(data, len)
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |         |
    |         trying to reborrow <untagged> for Unique permission at alloc1340[0x0], but that tag only grants SharedReadOnly permission for this location
    |         this error occurs as part of a reborrow at alloc1340[0x0..0x6]
    |
    = help: this indicates a potential bug in the program: it performed an invalid operation, but the rules it violated are still experimental
    = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
help: tag was most recently created at offsets [0x0..0x6]
   --> /tmp/half-1.8.2/src/slice.rs:309:22
    |
309 |         let length = self.len();
    |                      ^^^^^^^^^^
help: this tag was also created here at offsets [0x0..0x6]
   --> /tmp/half-1.8.2/src/slice.rs:308:23
    |
308 |         let pointer = self.as_ptr() as *mut u16;
    |                       ^^^^^^^^^^^^^
```
The second suggestion is close to guesswork, but from experience it tends to be correct (as in, it tends to locate the pointer the user wanted) more often that it doesn't.
2022-05-14 19:27:04 +00:00
carbotaniuman
f8478df6dc Bump rustc for permissive provenance 2022-05-14 13:03:47 -05:00
Ben Kimock
8ff0aac06c More review feedback
* Store the local crates in an Rc<[CrateNum]>
* Move all the allocation history into Stacks
* Clean up the implementation of get_logs_relevant_to a bit
2022-05-13 19:04:51 -04:00
Ralf Jung
fde022007b data_race: use glob import like most files 2022-05-13 23:19:17 +02:00
bors
3f111c166a Auto merge of #2114 - cbeuw:shim-rmw, r=RalfJung
Use atomic RMW for `{mutex, rwlock, cond, srwlock}_get_or_create_id` functions

This is required for #1963

`{mutex, rwlock, cond, srwlock}_get_or_create_id()` currently checks whether an ID field is 0 using an atomic read, allocate one and get a new ID if it is, then write it in a separate atomic write. This is fine without weak memory. For instance, in `pthread_mutex_lock` which may be called by two threads concurrently, only one thread can read 0, create and then write a new ID, the later-run thread will always see the newly created ID and never 0.
```rust
    fn pthread_mutex_lock(&mut self, mutex_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
        let this = self.eval_context_mut();

        let kind = mutex_get_kind(this, mutex_op)?.check_init()?;
        let id = mutex_get_or_create_id(this, mutex_op)?;
        let active_thread = this.get_active_thread();
```

However, with weak memory behaviour, both threads may read 0: the first thread has to see 0 because nothing else was written to it, and the second thread is not guaranteed to observe the latest value, causing a duplicate mutex to be created and both threads "successfully" acquiring the lock at the same time.

This is a pretty typical pattern requiring the use of atomic RMWs. RMW *always* reads the latest value in a location, so only one thread can create the new mutex and ID, all others scheduled later will see the new ID.
2022-05-13 19:04:59 +00:00
Andy Wang
9e38dc4d49
Move and rename offset_and_layout_to_place to deref_operand_and_offset 2022-05-13 18:42:53 +01:00
Andy Wang
10d978c180
Inline _create() calls and add assertions 2022-05-12 21:06:17 +01:00