Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sanitize memory and CPU registers for sensitive data #17046

Closed
l0kod opened this issue Sep 6, 2014 · 6 comments
Closed

Sanitize memory and CPU registers for sensitive data #17046

l0kod opened this issue Sep 6, 2014 · 6 comments
Labels

Comments

@l0kod
Copy link
Contributor

@l0kod l0kod commented Sep 6, 2014

As part as exploit mitigation (#15179), it's important for sensitive data like cryptographic keys (especially for perfect forward secrecy) to be able to securely wipe them as soon as they are not needed. This avoid data to leak because of unsafe code with memory leak (e.g. Heartbleed), arbitrary code execution, suspend to disk, cold boot attack…
This imply memory (data copies) that should be cleaned with a function like the C11 memset_s or OpenBSD explicit_bzero (guaranteeing that the compiler will not optimize and do nothing) and declared variable like with the C volatile to avoid side effect. The memory should also be marked as not swappable. Processor registers who manipulates sensitive data should be explicitly cleaned as well.

Good article on the subject: http://benpfaff.org/papers/shredding.html/index.html
Nice post explaining the problem with CPU registers: http://www.daemonology.net/blog/2014-09-06-zeroing-buffers-is-insufficient.html

It would be handy to be able to annotate types (e.g. PrivateKey) with an attribute like #[sensitive]. Rust's runtime could then take care of cleaning data footprints after variable end of life, explicit drop call and all CPU registers used. This could be tricky…

cc @DaGenix

@thestinger

This comment has been minimized.

Copy link
Contributor

@thestinger thestinger commented Sep 6, 2014

Memory exploit mitigations (#15179) aren't really related to this. I don't think there's any additional compiler feature that's necessary.

This imply memory (data copies) that should be cleaned with a function like the C11 memset_s or OpenBSD explicit_bzero (guaranteeing that the compiler will not optimize and do nothing) and declared variable like with the C volatile to avoid side effect.

Rust already has volatile versions of memcpy, memset and memmove.

The memory should also be marked as not swappable.

This isn't something that could be done automatically for types in Rust. The standard library could provide a good module for memory mappings in the future, but that's an independent feature request.

Processor registers who manipulates sensitive data should be explicitly cleaned as well.

It's not possible to implement this in the Rust compiler. It might be in the scope of the LLVM project, and then it could be exposed here, but I doubt there's enough interest to get it done.

It would be handy to be able to annotate types (e.g. PrivateKey) with an attribute like #[sensitive]. Rust's runtime could then take care of cleaning data footprints after variable end of life, explicit drop call and all CPU registers used. This could be tricky…

The tools to do this don't exist in LLVM. Rust also leaves far too much up to unsafe code in libraries for something like this to be implemented at a compiler level. It doesn't really make sense to leave issues open for incredibly niche features that aren't actionable. Is there anything specific that we can actually expose from LLVM or implement in the Rust compiler / libraries?

You can already implement a destructor zeroing a type, and it could be done via a custom deriving attribute if desired. Implement it as a syntax extension outside of the standard library first, and then file a feature request if it's being used by enough projects to show that it's not a very small niche. It's not going to be anywhere close to a full solution though, because types like Vec<T> don't zero the old location when they move it.

@thestinger

This comment has been minimized.

Copy link
Contributor

@thestinger thestinger commented Sep 6, 2014

#17047 filed to cover the mmap/mprotect/mlock functionality

@thestinger thestinger closed this Sep 6, 2014
@thestinger

This comment has been minimized.

Copy link
Contributor

@thestinger thestinger commented Sep 6, 2014

I don't think there's another specific feature request or bug report here. Open-ended discussion is more suited to http://discuss.rust-lang.org/ now.

@l0kod

This comment has been minimized.

Copy link
Contributor Author

@l0kod l0kod commented Feb 25, 2015

For reference, there is TARS for memory protection and a presentation given at the Bay Area Rust Meetup. However, it doesn't handle CPU registers.

cc @seb-m, @DaGenix, @klutzy

@klutzy

This comment has been minimized.

Copy link
Contributor

@klutzy klutzy commented Feb 25, 2015

discussion on clang side: [cfe-dev] Zero'ing Registers on Function Return (2014-09)

@idupree

This comment has been minimized.

Copy link
Contributor

@idupree idupree commented May 4, 2016

non-bitrotted version of [cfe-dev] archive link: http://lists.llvm.org/pipermail/cfe-dev/2014-September/039044.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.