-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Stable counterpart for core::intrinsics::volatile_set_memory
#76892
Comments
That is exactly what volatile is for, though... wanting volatile and wanting optimizations is somewhat of a contradiction. In UCG discussions around volatile (rust-lang/unsafe-code-guidelines#33, rust-lang/unsafe-code-guidelines#152) the general consensus was that the language itself should only offer volatile operations that cannot be teared -- currently you can do If we also offer "volatile accesses that are allowed to tear", then this is basically a whole new class of memory accesses, with guarantees and use-cases rather distinct from regular volatile accesses. Currently, it is all mixed up though. |
|
FYI if the size is preknown you can do something like this: pub unsafe fn volatile_set_memory(slice: &mut [u8; 32], n: u8) {
let ptr = slice as *mut [u8; 32];
ptr.write_volatile([n; 32]);
} Trying to do this generically over struct PrivateKey([u8; 32]);
impl PrivateKey {
pub unsafe fn volatile_zero(&mut self) {
let ptr = self as *mut Self as *mut [u8; size_of::<PrivateKey>()];
ptr.write_volatile([0u8; size_of::<PrivateKey>()]);
}
} |
Now that inline assembly is in stable, it can used to preventing “memset” from being optimized out, right? pub fn zeroize(x: &mut [u8]) {
x.fill(0);
unsafe {
core::arch::asm!(
"/* {ptr} */",
ptr = in(reg) x.as_ptr(),
options(nostack, readonly, preserves_flags),
);
}
} This wastes a register, but generates optimal code for the “memset”, especially when inlined and the size of the buffer is known and a multiple of e.g. xmm register size. |
A volatile memset function would be useful for efficiently zeroing sensitive data before dropping it so it's less likely to be exposed by bugs like Heartbleed. It's already possible to explicitly zero bytes in Rust by using
core::ptr::write_volatile
in a loop, but because the writes are volatile, the compiler is forced to emit them exactly as written (one byte at a time in simple implementations) rather than using an optimized memset routine.The text was updated successfully, but these errors were encountered: