Uh oh!
There was an error while loading. Please reload this page.
Fix invalid slice access in String::retain - #82554
Conversation
rust-highfive
commented
Feb 26, 2021
r? @m-ou-se (rust-highfive has picked a reviewer for you, use r? to override) |
eddyb
commented
Feb 26, 2021
cc @RalfJung |
RalfJung
commented
Feb 27, 2021
Yeah, that seems potentially problematic. Until we have a better idea of what the aliasing model will be long-term, it's better to be conservative and always remain in-bounds even for dynamically sized references. I haven't carefully checked the code here, but a set-len-on-drop guard is a common approach elsewhere in the stdlib. Is this function covered by a liballoc test case? If yes, any idea why Miri is not complaining about this? If it is possible to cause a Miri error with the current implementation of that function, it'd be good to add that as a testcase. |
SkiFire13
commented
Feb 27, 2021
The function was covered by this test, but it contains a rust/library/alloc/tests/string.rs Lines 368 to 400 in 8e863eb However even when run without the fnmain(){unsafe{letmut v = vec![1,2,3];
v.set_len(0);assert_eq!(*v.get_unchecked(1),2);let a = [1,2,3];let s = &a[0..0];assert_eq!(s.len(),0);assert_eq!(*s.get_unchecked(1),2);}}I guess miri doesn't correctly track slices bounds but only the allocation ones? |
Miri has supported unwinding for more than a year at this point. ;)
Interesting... I first thought this was just a missing fnmain(){unsafe{let a = [1,2,3];let s = &a[0..1];assert_eq!(s.len(),1);assert_eq!(*s.get_unchecked(1),2);}}Something strange is going on with zero-sized references here. |
SkiFire13
commented
Feb 27, 2021
Oops, I copypasted the test without importing the |
fix reborrowing of tagged ZST references `@SkiFire13` [pointed out](rust-lang/rust#82554 (comment)) that Miri fails to detect illegal use of empty slices. This PR fixes that. In so doing, it uncovers a flaw of Stacked Borrows: it is incompatible with how the formatting machinery uses `extern type`, so for now we skip reborrowing when we cannot determine the exact size of the pointee.
RalfJung
commented
Mar 1, 2021
This is fixed now in latest Miri, but you need to pass |
m-ou-se
commented
Mar 3, 2021
I'm a bit worried that the resulting code here is worse with a drop guard. Did you check? It might be better to keep the Alternatively, you could keep use |
DJMcNab
commented
Mar 3, 2021
I do already have most of an impl of the I think the safety comments are correct, although the actual reasons that I think |
SkiFire13
commented
Mar 3, 2021
The difference looks pretty minimal, it adds just a couple of methods and some instructions outside the main loop. https://godbolt.org/z/4rqM9P |
SkiFire13
commented
Mar 10, 2021
I forgot to update the labels Also, I correct my previous statement, it doesn't add code to the function, it just moves the return label. |
m-ou-se
commented
Mar 21, 2021
@bors r+ |
bors
commented
Mar 21, 2021
📌 Commit c89e643 has been approved by |
…ness, r=m-ou-se Fix invalid slice access in String::retain As noted in rust-lang#78499, the previous fix was technically still unsound because it accessed elements of a slice outside its bounds (even though they were still inside the same allocation). This PR addresses that concern by switching to a dropguard approach.
Rollup of 9 pull requests Successful merges: - rust-lang#80193 (stabilize `feature(osstring_ascii)`) - rust-lang#80771 (Make NonNull::as_ref (and friends) return refs with unbound lifetimes) - rust-lang#81607 (Implement TrustedLen and TrustedRandomAccess for Range<integer>, array::IntoIter, VecDequeue's iterators) - rust-lang#82554 (Fix invalid slice access in String::retain) - rust-lang#82686 (Move `std::sys::unix::platform` to `std::sys::unix::ext`) - rust-lang#82771 (slice: Stabilize IterMut::as_slice.) - rust-lang#83329 (Cleanup LLVM debuginfo module docs) - rust-lang#83336 (Fix ICE with `use clippy::a::b;`) - rust-lang#83350 (Download a more recent LLVM version if `src/version` is modified) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
As noted in #78499, the previous fix was technically still unsound because it accessed elements of a slice outside its bounds (even though they were still inside the same allocation). This PR addresses that concern by switching to a dropguard approach.