Auto merge of #2067 - RalfJung:strerror_r, r=RalfJung
implement strerror_r
This isn't perfect; we end up using [this match](https://github.com/rust-lang/rust/blob/72a25d05bf1a4b155d74139ef700ff93af6d8e22/library/std/src/io/error.rs#L380) rather than the platform-specific messages, but at least we show something -- this is mostly informational anyway.
Auto merge of #2061 - RalfJung:edition, r=RalfJung
port Miri to edition 2021
`cargo fix --edition` didn't change anything for either of these crates, so this looks like a very simple port. And then we can remove a bunch of annoying imports. :)
I thought this also unlocks the named format string stuff, but it seems that works on all editions except for that problem around `panic!`. Whatever. ;)
Auto merge of #2058 - RalfJung:variadic, r=RalfJung
For variadic functions, accept arbitrary trailing arguments
However, make sure that if we use argument N we check the size of all arguments before that, because otherwise this might not work properly depending on how varargs are implemented. This caught bugs in our futex tests. ;)
I couldn't find a good way to systematically ensure this, so it is just something we have to be on the look for during review. (This generally applies also for fixed-arg shims: we should check the size of each parameter.)
Also treat prctl like a variadic function, Cc `@saethlin.`
Auto merge of #2054 - m-ou-se:futex-wait-bitset, r=RalfJung
Add support for FUTEX_{WAIT,WAKE}_BITSET
FUTEX_WAIT_BITSET and FUTEX_WAKE_BITSET are extensions of FUTEX_WAIT and FUTEX_WAKE that allow tagging each waiting thread with up to 32 'labels', and then only wake up threads that match certain labels. The non-bitset operations behave like their bitset was fully set (u32::MAX), meaning that they'll wait for anything, and wake up anything.
The only other difference is that FUTEX_WAIT_BITSET uses an absolute timeout instead of an relative timeout like FUTEX_WAIT.
Often, FUTEX_WAIT_BITSET is used not for its bitset functionality, but only for its absolute timeout functionality. It is then used with a bitset of u32::MAX.
~~This adds support for only that use case to Miri, as that's all `std` currently needs. Any other bitset is still unsupported.~~
Update: This adds full support for both these syscalls.
Auto merge of #2046 - RalfJung:very-strict, r=RalfJung
make strict-provenance imply check-number-validity
I feel like Miri not catching [this example](https://github.com/rust-lang/unsafe-code-guidelines/issues/286#issuecomment-1085144431) with strict provenance checking enabled is surprising.
OTOH, Miri suddenly complaining about uninit data in integers with `-Zmiri-strict-provenance` also might be surprising. Which one is more surprising? I don't know. We *could* go out of our way and have a mode where uninit integers are okay but provenance is not, but I am not sure if that is truly worth it. It'd be quite annoying to implement.
Auto merge of #2045 - RalfJung:strict-provenance, r=RalfJung
add -Zmiri-strict-provenance
This implements [strict provenance](https://github.com/rust-lang/rust/issues/95228) in Miri. The only change is that casting an integer to a pointer does not even attempt to produce a good provenance for the given address; instead, it always uses the invalid provenance. This stricter than even `-Zmiri-tag-raw-pointers` in that it also rejects the following example (which does not even involve Stacked Borrows):
```rust
fn main() {
let x = 22;
let ptr = &x as *const _ as *const u8;
let roundtrip = ptr as usize as *const u8;
let _ = unsafe { roundtrip.offset(1) };
}
```
The new flag also implies `-Zmiri-tag-raw-pointers` since the only reason one would *not* want to tag raw pointers is to support ptr-int-ptr roundtrips.
Note that the flag does *not* check against ptr-to-int *transmutes*; that still requires `-Zmiri-check-number-validity`. You can also check for strict provenance *without* Stacked Borrows by adding `-Zmiri-disable-stacked-borrows`.
The new "Miri hard mode" flags for maximal checking are `-Zmiri-strict-provenance -Zmiri-check-number-validity`. (Add `-Zmiri-symbolic-alignment-check` if you feel extra spicy today.)
bors [Sat, 26 Mar 2022 15:08:43 +0000 (15:08 +0000)]
Auto merge of #2039 - RalfJung:too-big, r=RalfJung
another test for too big type
The existing test covers "slice is bigger than largest supported object" but we had no test covering "total size is bigger than largest supported object", which happens when the unsized tail itself is okay in terms of size, but together with the sized prefix it becomes too big.
bors [Sun, 20 Mar 2022 02:37:09 +0000 (02:37 +0000)]
Auto merge of #1975 - DrMeepster:backtrace_fix, r=RalfJung
Make backtraces work with #[global_allocator]
Currently, backtraces break when the global allocator is overridden because the allocator will attempt to deallocate memory allocated directly by Miri.
~~This PR fixes that by using a new memory kind and providing a function to deallocate it. We can't call the custom allocator to allocate because it's not possible to call a function in the middle of a shim.~~
This PR fixes that by adding a new version of the backtrace API accessible by setting `flags` to 1. Existing code still functions.
bors [Fri, 18 Mar 2022 20:38:37 +0000 (20:38 +0000)]
Auto merge of #2024 - saethlin:better-local-check, r=RalfJung
Consider the cargo workspace when checking if a frame is local
`DefId::is_local` returns a result which is technically correct, but doesn't match the user's intuition when running integration tests or doctests. This incorporates the workspace crates mentioned in `cargo metadata` into the check for whether a frame is local to match user intuition.
For example, here is the backtrace you get from `MIRIFLAGS=-Zmiri-tag-raw-pointers cargo miri test` in `bytes` 1.1.0:
```
--> /home/ben/.rustup/toolchains/miri/lib/rustlib/src/rust/library/core/src/slice/raw.rs:131:14
|
131 | unsafe { &mut *ptr::slice_from_raw_parts_mut(data, len) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trying to reborrow for Unique at alloc67158, but parent tag <untagged> does not have an appropriate item in the borrow stack
|
= 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::slice::from_raw_parts_mut::<u8>` at /home/ben/.rustup/toolchains/miri/lib/rustlib/src/rust/library/core/src/slice/raw.rs:131:14
= note: inside `bytes::bytes::rebuild_boxed_slice` at /tmp/bytes-1.1.0/src/bytes.rs:938:19
= note: inside closure at /tmp/bytes-1.1.0/src/bytes.rs:904:18
= note: inside `<std::sync::atomic::AtomicPtr<()> as bytes::loom::sync::atomic::AtomicMut<()>>::with_mut::<[closure@bytes::bytes::promotable_even_drop::{closure#0}], ()>` at /tmp/bytes-1.1.0/src/loom.rs:17:17
= note: inside `bytes::bytes::promotable_even_drop` at /tmp/bytes-1.1.0/src/bytes.rs:895:5
= note: inside `<bytes::Bytes as std::ops::Drop>::drop` at /tmp/bytes-1.1.0/src/bytes.rs:515:18
= note: inside `std::ptr::drop_in_place::<bytes::Bytes> - shim(Some(bytes::Bytes))` at /home/ben/.rustup/toolchains/miri/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:188:1
note: inside `copy_to_bytes_less` at tests/test_buf.rs:112:1
--> tests/test_buf.rs:112:1
|
112 | }
| ^
note: inside closure at tests/test_buf.rs:106:1
--> tests/test_buf.rs:106:1
|
105 | #[test]
| ------- in this procedural macro expansion
106 | / fn copy_to_bytes_less() {
107 | | let mut buf = &b"hello world"[..];
108 | |
109 | | let bytes = buf.copy_to_bytes(5);
110 | | assert_eq!(bytes, &b"hello"[..]);
111 | | assert_eq!(buf, &b" world"[..])
112 | | }
| |_^
= note: this error originates in the attribute macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
```
We get these because the integration tests are occurring in a crate called `test`, not the actual `bytes` crate. With this PR, we get this:
```
= note: inside `std::slice::from_raw_parts_mut::<u8>` at /home/ben/.rustup/toolchains/miri/lib/rustlib/src/rust/library/core/src/slice/raw.rs:131:14
note: inside `bytes::bytes::rebuild_boxed_slice` at /tmp/bytes-1.1.0/src/bytes.rs:938:19
--> /tmp/bytes-1.1.0/src/bytes.rs:938:19
|
938 | Box::from_raw(slice::from_raw_parts_mut(buf, cap))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside closure at /tmp/bytes-1.1.0/src/bytes.rs:904:18
--> /tmp/bytes-1.1.0/src/bytes.rs:904:18
|
904 | drop(rebuild_boxed_slice(buf, ptr, len));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside `<std::sync::atomic::AtomicPtr<()> as bytes::loom::sync::atomic::AtomicMut<()>>::with_mut::<[closure@bytes::bytes::promotable_even_drop::{closure#0}], ()>` at /tmp/bytes-1.1.0/src/loom.rs:17:17
--> /tmp/bytes-1.1.0/src/loom.rs:17:17
|
17 | f(self.get_mut())
| ^^^^^^^^^^^^^^^^^
note: inside `bytes::bytes::promotable_even_drop` at /tmp/bytes-1.1.0/src/bytes.rs:895:5
--> /tmp/bytes-1.1.0/src/bytes.rs:895:5
|
895 | / data.with_mut(|shared| {
896 | | let shared = *shared;
897 | | let kind = shared as usize & KIND_MASK;
898 | |
... |
905 | | }
906 | | });
| |______^
note: inside `<bytes::Bytes as std::ops::Drop>::drop` at /tmp/bytes-1.1.0/src/bytes.rs:515:18
--> /tmp/bytes-1.1.0/src/bytes.rs:515:18
|
515 | unsafe { (self.vtable.drop)(&mut self.data, self.ptr, self.len) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: inside `std::ptr::drop_in_place::<bytes::Bytes> - shim(Some(bytes::Bytes))` at /home/ben/.rustup/toolchains/miri/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:188:1
note: inside `copy_to_bytes_less` at tests/test_buf.rs:112:1
--> tests/test_buf.rs:112:1
|
112 | }
| ^
note: inside closure at tests/test_buf.rs:106:1
--> tests/test_buf.rs:106:1
|
105 | #[test]
| ------- in this procedural macro expansion
106 | / fn copy_to_bytes_less() {
107 | | let mut buf = &b"hello world"[..];
108 | |
109 | | let bytes = buf.copy_to_bytes(5);
110 | | assert_eq!(bytes, &b"hello"[..]);
111 | | assert_eq!(buf, &b" world"[..])
112 | | }
| |_^
= note: this error originates in the attribute macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
```
Note that this kind of inflation is rather rare to see. Most backtraces change not at all or only a tiny bit.
I originally implemented this to support another improvement to Miri diagnostics, but I think this is hairy enough to deserve its own PR, if somewhat poorly-motivated.
bors [Thu, 17 Mar 2022 13:26:29 +0000 (13:26 +0000)]
Auto merge of #1971 - saethlin:sb-details, r=RalfJung
Add a lot more information to SB fatal errors
In fatal errors, this clarifies the difference between a tag not being present in the borrow stack at all, and the tag being present but granting SRO. It also introduces a little notation for memory ranges so we can mention to the user that the span may point to code that operates on multiple memory locations, but we are reporting an error at a particular offset.
This also gets rid of the unqualified phrase "the borrow stack" in errors, and clarifies that it is the borrow stack _for some location_.
The crate `pdqselect` v0.1.1:
Before:
```
2103 | unsafe { copy_nonoverlapping(src, dst, count) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no item granting read access to tag <2357> at alloc1029 found in borrow stack.
```
After:
```
2103 | unsafe { copy_nonoverlapping(src, dst, count) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| attempting a read access using <2357> at alloc1029[0x0], but that tag does not exist in the borrow stack for this location
| this error occurs as part of an access at alloc1029[0x0..0x4]
```
And the crate `half` v1.8.2
Before:
```
131 | unsafe { &mut *ptr::slice_from_raw_parts_mut(data, len) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trying to reborrow for Unique at alloc1051, but parent tag <2091> does not have an appropriate item in the borrow stack
```
After:
```
131 | unsafe { &mut *ptr::slice_from_raw_parts_mut(data, len) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| trying to reborrow <2091> for Unique permission at alloc1051[0x0], but that tag only grants SharedReadOnly permission for this location
| this error occurs as part of a reborrow at alloc1051[0x0..0x6]
```
Ben Kimock [Sun, 6 Feb 2022 00:44:56 +0000 (19:44 -0500)]
Print more in SB error diagnostics
This tries to clarify exactly why an access is not valid by printing
what memory range the access was over, which in combination with
tag-tracking may help a user figure out the source of the problem.