Skip to content

Incorrect zeroizing of newtype structs #1789

Open
@pawanjay176

Description

@pawanjay176

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions