diff options
| author | The 8472 <git@infinite-source.de> | 2021-12-11 17:10:56 +0100 |
|---|---|---|
| committer | The 8472 <git@infinite-source.de> | 2021-12-11 17:10:56 +0100 |
| commit | 9063b64cff102c63f542452fa23d414c75a25ba7 (patch) | |
| tree | c1d94b34bc5ba00cb89c36301bc5c8998d764d01 | |
| parent | 4a66a704b2c3d30ff07d89380ebb9ba3de3b3182 (diff) | |
| download | rust-9063b64cff102c63f542452fa23d414c75a25ba7.tar.gz rust-9063b64cff102c63f542452fa23d414c75a25ba7.zip | |
Fix zero-sized reference to deallocated memory
fixes #91772
| -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 |
