diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2021-12-11 23:31:54 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-12-11 23:31:54 +0100 |
| commit | 9aade508d57d2e18bc1789fc02d5e7fc8dab2cf3 (patch) | |
| tree | 1f406bb55e9134cf419507457edc0cc6fae7749f | |
| parent | bd46953f0b52063859ec5c276e93b7fd4f06aa2a (diff) | |
| parent | 9063b64cff102c63f542452fa23d414c75a25ba7 (diff) | |
| download | rust-9aade508d57d2e18bc1789fc02d5e7fc8dab2cf3.tar.gz rust-9aade508d57d2e18bc1789fc02d5e7fc8dab2cf3.zip | |
Rollup merge of #91797 - the8472:fix-invalid-deref, r=Mark-Simulacrum
Fix zero-sized reference to deallocated memory fixes #91772 r? `@camelid`
| -rw-r--r-- | library/alloc/src/vec/drain.rs | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/library/alloc/src/vec/drain.rs b/library/alloc/src/vec/drain.rs index 089cd4db64c..1bff19d05c1 100644 --- a/library/alloc/src/vec/drain.rs +++ b/library/alloc/src/vec/drain.rs @@ -128,10 +128,6 @@ impl<T, A: Allocator> Drop for Drain<'_, T, A> { let iter = mem::replace(&mut self.iter, (&mut []).iter()); let drop_len = iter.len(); - let drop_ptr = iter.as_slice().as_ptr(); - - // forget iter so there's no aliasing reference - drop(iter); let mut vec = self.vec; @@ -155,6 +151,12 @@ impl<T, A: Allocator> Drop for Drain<'_, T, A> { return; } + // as_slice() must only be called when iter.len() is > 0 because + // vec::Splice modifies vec::Drain fields and may grow the vec which would invalidate + // the iterator's internal pointers. Creating a reference to deallocated memory + // is invalid even when it is zero-length + let drop_ptr = iter.as_slice().as_ptr(); + unsafe { // drop_ptr comes from a slice::Iter which only gives us a &[T] but for drop_in_place // a pointer with mutable provenance is necessary. Therefore we must reconstruct |
