about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2021-12-11 23:31:54 +0100
committerGitHub <noreply@github.com>2021-12-11 23:31:54 +0100
commit9aade508d57d2e18bc1789fc02d5e7fc8dab2cf3 (patch)
tree1f406bb55e9134cf419507457edc0cc6fae7749f
parentbd46953f0b52063859ec5c276e93b7fd4f06aa2a (diff)
parent9063b64cff102c63f542452fa23d414c75a25ba7 (diff)
downloadrust-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.rs10
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