From 9063b64cff102c63f542452fa23d414c75a25ba7 Mon Sep 17 00:00:00 2001 From: The 8472 Date: Sat, 11 Dec 2021 17:10:56 +0100 Subject: [PATCH] Fix zero-sized reference to deallocated memory fixes #91772 --- library/alloc/src/vec/drain.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/library/alloc/src/vec/drain.rs b/library/alloc/src/vec/drain.rs index 089cd4db64c1d..1bff19d05c10d 100644 --- a/library/alloc/src/vec/drain.rs +++ b/library/alloc/src/vec/drain.rs @@ -128,10 +128,6 @@ impl 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 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