Skip to content

Commit 71dd2f0

Browse files
committed
zeroize: avoid double-zeroizing Vec's initialized elements
Vec<Z>::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
1 parent 03a330e commit 71dd2f0

1 file changed

Lines changed: 7 additions & 4 deletions

File tree

‎zeroize/src/lib.rs‎

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -526,14 +526,17 @@ where
526526
/// Ensures the entire capacity of the `Vec` is zeroed. Cannot ensure that
527527
/// previous reallocations did not leave values on the heap.
528528
fn zeroize(&mut self) {
529+
// Zero the spare (uninitialized) capacity first, i.e. everything
530+
// beyond `len`. This must happen before `clear()` resets `len` to 0,
531+
// otherwise `spare_capacity_mut()` would cover the whole allocation
532+
// and re-zero the initialized elements a second time below.
533+
self.spare_capacity_mut().zeroize();
534+
529535
// Zeroize all the initialized elements.
530536
self.iter_mut().zeroize();
531537

532-
// Set the Vec's length to 0 and drop all the elements.
538+
// Set the Vec's length to 0 and drop all the (already-zeroized) elements.
533539
self.clear();
534-
535-
// Zero the full capacity of `Vec`.
536-
self.spare_capacity_mut().zeroize();
537540
}
538541
}
539542

0 commit comments

Comments
 (0)