From 71dd2f075940ea9dd1b8f10260182a64a800e141 Mon Sep 17 00:00:00 2001 From: Johnson Ajibi Date: Sun, 30 Aug 2026 05:25:21 +0100 Subject: [PATCH] zeroize: avoid double-zeroizing Vec's initialized elements Vec::zeroize() zeroized the initialized elements via iter_mut(), then called clear() (which resets len to 0), then zeroized spare_capacity_mut(). Since spare_capacity_mut() covers everything beyond len, and len was already 0 at that point, it covered the entire allocation - re-zeroizing the elements that were already zeroized in the first step. Reorder so the spare (truly uninitialized) capacity is zeroed first, while len still reflects the real element count, so the two zeroing passes cover disjoint ranges. Behavior is unchanged (the full allocation is still zeroed) other than removing the redundant work; existing tests (including zeroize_vec_entire_capacity, which checks no partially-zeroized or uninitialized data survives) still pass. Fixes #1524 --- zeroize/src/lib.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/zeroize/src/lib.rs b/zeroize/src/lib.rs index d780af55..45fd42ca 100644 --- a/zeroize/src/lib.rs +++ b/zeroize/src/lib.rs @@ -526,14 +526,17 @@ where /// Ensures the entire capacity of the `Vec` is zeroed. Cannot ensure that /// previous reallocations did not leave values on the heap. fn zeroize(&mut self) { + // Zero the spare (uninitialized) capacity first, i.e. everything + // beyond `len`. This must happen before `clear()` resets `len` to 0, + // otherwise `spare_capacity_mut()` would cover the whole allocation + // and re-zero the initialized elements a second time below. + self.spare_capacity_mut().zeroize(); + // Zeroize all the initialized elements. self.iter_mut().zeroize(); - // Set the Vec's length to 0 and drop all the elements. + // Set the Vec's length to 0 and drop all the (already-zeroized) elements. self.clear(); - - // Zero the full capacity of `Vec`. - self.spare_capacity_mut().zeroize(); } }