Skip to content

Commit

Permalink
Merge pull request #341 from aticu/develop
Browse files Browse the repository at this point in the history
zeroize: zeroize entire capacity of `Vec`
  • Loading branch information
tony-iqlusion committed Jan 30, 2020
2 parents a8b673d + 78aa2f5 commit 9a2610e
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 0 deletions.
1 change: 1 addition & 0 deletions AUTHORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ contributions under the terms of the [Apache License, Version 2.0]
* David Tolnay ([@dtolnay](https://github.com/dtolnay))
* Kai Ren ([@tyranron](https://github.com/tyranron))
* Murarth ([@murarth](https://github.com/murarth))
* Niclas Schwarzlose ([@aticu](https://github.com/aticu))
* Yin Guanhao ([@sopium](https://github.com/sopium))
* Will Speak ([@iwillspeak](https://github.com/iwillspeak))
63 changes: 63 additions & 0 deletions zeroize/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,32 @@ where
/// previous reallocations did not leave values on the heap.
fn zeroize(&mut self) {
self.iter_mut().zeroize();

// Zero the capacity of the `Vec` that is not initialized.
{
// Safety:
//
// This is safe, because `Vec` never allocates more than `isize::MAX` bytes.
// This exact use case is even mentioned in the documentation of `pointer::add`.
let extra_capacity_start = unsafe { self.as_mut_ptr().add(self.len()) as *mut u8 };
let extra_capacity_len = self.capacity().saturating_sub(self.len());

for i in 0..(extra_capacity_len * core::mem::size_of::<Z>()) {
// Safety:
//
// This is safe, because `Vec` never allocates more than `isize::MAX` bytes.
let current_ptr = unsafe { extra_capacity_start.add(i) };
// Safety:
//
// `current_ptr` is valid, because it lies within the allocation of the `Vec`.
// It is also properly aligned, because we write a `u8`, which has an alignment of
// 1.
unsafe { ptr::write_volatile(current_ptr, 0) };
}

atomic_fence();
}

self.clear();
}
}
Expand Down Expand Up @@ -458,6 +484,43 @@ mod tests {
assert!(vec.is_empty());
}

#[cfg(feature = "alloc")]
#[test]
fn zeroize_vec_entire_capacity() {
#[derive(Clone)]
struct PanicOnNonZeroDrop(u64);

impl Zeroize for PanicOnNonZeroDrop {
fn zeroize(&mut self) {
self.0 = 0;
}
}

impl Drop for PanicOnNonZeroDrop {
fn drop(&mut self) {
if self.0 != 0 {
panic!("dropped non-zeroized data");
}
}
}

// Ensure that the entire capacity of the vec is zeroized and that no unitinialized data
// is ever interpreted as initialized
let mut vec = vec![PanicOnNonZeroDrop(42); 2];

unsafe {
vec.set_len(1);
}

vec.zeroize();

unsafe {
vec.set_len(2);
}

drop(vec);
}

#[cfg(feature = "alloc")]
#[test]
fn zeroize_string() {
Expand Down

0 comments on commit 9a2610e

Please sign in to comment.