Erase RAM footprint of data in Rust

Suppose I have a data structure

struct SuperSecret {
...
}

which is created in a function and only used inside of that function. So when the function terminates, system storage (most likely RAM, but might also be on a SWAP partition) is freed.

However since that chunk of RAM is not erased by default the data is still there, which is a well know security risk.

What is Rust's way to ensure that the date is destroyed for real after use? This must include two things. First the eraser needs to know all copies of that data (if its stored in more then one place), then it needs to overwrite it after freeing with garbage or zero or something like that.

There is std::ptr::write_volatile which makes sure, that the write isn't opimized away (like the good ol' memset would).

I would implement Drop for that struct, that will, when called, write zeros to all fields.

Be warned, that this will likely cause UB, because if you write all zeros to a String, for example, the string will be dropped afterwards. There is the ManuallyDrop wrapper for it. Maybe you can give it a try.

Be warned, that this is the unsafe land and you should be cautious.

Thanks for the hind. What does UB stands for?

Undefined Behavior

Zeroing memory on impl Drop doesn't cause any UB since it's not dropped yet - you still have &mut T of it. Problem is that the compiler optimization would likely wipe out the zeroing instructions, since nobody would read it again normally.

Anyway, why don't you try existing solution instead? https://docs.rs/secrets/1.1.0/secrets/

3 Likes

Great! That is exactly what I was looking for.

With the write_volatile you could make sure the zeroes are written there. To avoid the UB, you could use MaybeUninit, then it is fine for the instance to contain zeroes even if the type itself does not allow them.

Nevertheless, I still think this is not enough. Usually, rust is allowed to memcpy whatever whereever, so it could make more byte copies of that thing under the hood, even if semantically there was always just one copy, ever.

2 Likes

See also, zeroize

1 Like