Skip to content

Commit 98d49ed

Browse files
zeroize: avoid double-zeroizing Vec's initialized elements (#1525)
Fixes #1524. `Vec<Z>::zeroize()` previously: 1. Zeroizes the initialized elements via `iter_mut()` 2. Calls `clear()`, which resets `len` to 0 3. Zeroizes `spare_capacity_mut()` Since `spare_capacity_mut()` covers everything beyond `len`, and `len` is already 0 by step 3, it covers the *entire* allocation - re-zeroizing the elements that were already zeroized in step 1. This PR reorders the operations so the spare (truly uninitialized) capacity is zeroed first, while `len` still reflects the real element count. The two zeroing passes then cover disjoint ranges instead of overlapping. Behavior is unchanged - the full allocation is still zeroed - only the redundant work is removed. Verified locally with `cargo test --features alloc`: all existing tests pass, including `zeroize_vec_entire_capacity`, which specifically checks that no partially-zeroized or uninitialized data survives (this test's ordering-sensitive assertions still hold under the new order - traced through manually and confirmed via the test run). --------- Co-authored-by: Tony Arcieri <bascule@gmail.com>
1 parent 03a330e commit 98d49ed

1 file changed

Lines changed: 8 additions & 5 deletions

File tree

‎zeroize/src/lib.rs‎

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -523,17 +523,20 @@ where
523523
{
524524
/// "Best effort" zeroization for `Vec`.
525525
///
526-
/// Ensures the entire capacity of the `Vec` is zeroed. Cannot ensure that
526+
/// Call `Zeroize` on all `Vec` elements and spare capacity. 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)