Does Rust's owenship paradigm guaranties full data deletation from stack/heap?

Hi everyone,
during my development process using Rust I've missing one thing about data security and data flow - how I can be sure that after leaving function data that was generated inside that function is truly deleted from stack/heap? I understand that according to borrowing paradigm data is "attached" to the scope where it was created and destroyed after execution leaves the scope, but could it be possible that Rust just deletes references to objects and not data itself? Or it's mandatory for Rust to delete data from memory after leaving scope?
Thanks in advance

Depends on what you mean by "delete".

The memory is not "deleted" in the sense that its contents are destroyed. For example, if you store an encryption key in memory (heap or stack), then when dropped the memory will be released so that it can be re-used later on, but the encryption key stored in that memory will persist until something else overwrites it.

But if by "deleted" you mean "released such that it can be reused", then yes, all memory is released automatically.

An exception to this "all memory is released" rule are leaks. These can happen by accident or on purpose. For example, if you create a cycle using Rc or Arc pointers, that cycle will not be released. Or, you can deliberately call Box::leak to leak an allocation, ensuring it is never released.

However, even leaks are released to the operating system when the process ends.

In short: unless you are writing something like Box yourself, or creating cyclic structures using reference counting, you shouldn't need to worry about manually freeing memory. If you're storing secrets, then you really, really need to know what you're doing, and should ask someone who knows more than I do.

6 Likes

Thank you Daniel for swift response. I've chosen Rust because it's native (unlike Java) and it's much easier to interact directly with memory (easier than C/C++). I'm planing to use it for cryptography and mobile app protection. So for me it's mandatory to be sure that crpyto keys, encryption and decryption, etc won't leave any data evidences after execution or use. For now I'm using clear_on_drop::clear::Clear::clear(). While debugging in Rust Rover I see in memory view that it deletes start of object (reference?) but I'm not sure as for the rest of the object (especially in heap). Maybe there is other and better approach for zeroing memory of objects that is in heap, maybe something like pointer arithmetic but without that awkward syntax like in C/C++?

Have you seen the zeroize crate before?

1 Like

Yes, but I think clear_on_drop is more developer friendly as it doesn't require manual implementation of ZeroizeOnDrop trait.

ZeroizeOnDrop can be derived as well. I find zeroizes guarantees quite compelling, which is why I asked if you had considered using it before.

There's also the secrecy::Secret wrapper (build on top of zeroize) you could store your keys in. It makes accidentally leaking your keys harder because you have to explicitly expose them every time you need to access them.

5 Likes

It's possible to intentionally leak memory in safe code.[1] Rust not calling the destructor of a value going out of scope which was not intentionally leaked would be a compiler bug.


  1. E.g. ↩︎

3 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.