Description
Description
Explicitly dropping any stack variable (e.g. ZeroizeHash
) by calling drop(self)
could lead to memory not being correctly zeroized.
Version
master
Present Behaviour
The following program prints out
use zeroize::Zeroize;
#[derive(Zeroize)]
#[zeroize(drop)]
pub struct DerivedKey([u8; 32 as usize]);
impl DerivedKey {
/// Returns a reference to the underlying byte array.
pub fn as_bytes(&self) -> &[u8] {
&self.0
}
}
impl Drop for DerivedKey {
fn drop(&mut self) {
println!("Pointer in zeroize: {:?}", self.0.as_ptr());
self.0.zeroize();
}
}
fn my_func() -> *const u8 {
let zeroized_key = DerivedKey([42; 32]);
let ptr = zeroized_key.0.as_ptr();
println!("Pointer in func: {:?}", ptr);
println!("Memory in func: {:?}", unsafe {
core::slice::from_raw_parts(ptr, 32)
});
drop(zeroized_key);
ptr
}
fn main() {
let ptr: *const u8 = my_func();
println!("Pointer in main: {:?}", ptr);
println!("Memory in main: {:?}", unsafe {
core::slice::from_raw_parts(ptr, 32)
});
}
Pointer in func: 0x7ffe801ca2a0
Memory in func: [42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42]
Pointer in zeroize: 0x7ffe801ca230
Pointer in main: 0x7ffe801ca2a0
Memory in main: [48, 162, 28, 128, 254, 127, 0, 0, 208, 37, 148, 4, 136, 85, 0, 0, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42]
The issue is when we explicitly do the drop(zeroized_key)
in my_func
, there's an implicit copy (I'm not sure why, since DerivedKey
does not implement copy) of derived_key
which is passed to drop. So the original memory ends up not being zeroized properly.
The memory is zeroized correctly if we don't explicitly call drop and let the variable go out of scope.
I couldn't find any code in our Lighthouse that drops a zeroize struct explicitly, but could be a potential issue if improperly used.
Steps to resolve
Potentially use heap memory like
pub struct DerivedKey(Box<[u8; 32 as usize]>);
for newtype wrappers as described in https://benma.github.io/2020/10/16/rust-zeroize-move.html