-
Notifications
You must be signed in to change notification settings - Fork 13.4k
HashMap::new()
panics inside UEFI environments that don't support RNG protocol
#138252
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
Comments
HashMap::new()
panics inside UEFI environments that don't support RNG protocol
More specifically, the issue is that |
Unfortunately, you can't really do that nicely if a crate is doing the construction. In the specific case where this came up, I was attempting to parse a TOML file using the |
Hi, so this happens because the random implementation only works when the protocol is present (here). I remember having a discussion regarding this in the initial implementation, but maybe there is a way to use some register to get random values when the protocol is missing. On a sidenote, you can get rng to work in QEMU by passing the following argument: I tested your example program with my run script, it does work:
|
On x86 we could try rdrand as fallback and I think aarch64 has something similar? |
So, I did some testing and well, it seems that when It might be that if the hardware can do random number generation, the protocol will be present, at least for all implementations based on edk2 (which is most of them). |
Then it seems like it's just a bad qemu configuration. Is there any reason to support such a setup? |
I don't think so. Unless there is real world hardware example, I don't see any use in providing a backup like this. Fix for qemu: add I did find something interesting. Caching the handle using a static atomic pointer is slower than just calling locate handles every time. So I guess, I don't need to do any optimization there. |
Yeah, I ended up figuring that out shortly afterwards. That's on me for not thinking hard enough about where that RNG would come from 😅 I guess if this is merely a result of bad QEMU configuration and there aren't any actual physical devices that have features like this, there isn't really a problem and we can close this. |
@ifd3f Unfortunately, this is not limited to QEMU vms. |
Would a |
@seijikun can you check if |
If there are (fixable) problems with other protocols please file separate issues. This one is just about the random source used by hashmaps. |
Hi, do you want to create a PR for this? I did implement this fallback in the past, but well, I guess I never uploaded to github, so it's lost. You basically need to add the fallback here: rust/library/std/src/sys/random/uefi.rs Line 26 in 7068c8b
Alternatively, I can create a PR and ping you for testing by the weekend. |
@Ayush1325 I wrote a working --- a/rust/library/std/src/sys/random/uefi.rs
+++ b/rust/library/std/src/sys/random/uefi.rs
@@ -19,5 +19,21 @@ pub fn fill_bytes(bytes: &mut [u8]) {
}
}
+ // on x86, try using rdrand directly as a fallback
+ if is_x86_feature_detected!("rdrand") {
+ for chunk in bytes.chunks_mut(core::mem::size_of::<u64>()) {
+ let mut rand_val: u64 = 0;
+ unsafe {
+ if core::arch::x86_64::_rdrand64_step(&mut rand_val) == 0 {
+ panic!("failed to generate random data using rdrand");
+ }
+ }
+
+ let bytes = rand_val.to_le_bytes();
+ chunk.copy_from_slice(&bytes[..chunk.len()]);
+ }
+ return;
+ }
+
panic!("failed to generate random data");
}
I tested the block I added in isolation (outside of the |
Some UEFI systems based on American Megatrends Inc. v3.3 do not provide RNG support [1]. So fallback to rdrand in such cases. [1]: rust-lang#138252 (comment) Signed-off-by: Ayush Singh <[email protected]>
Some UEFI systems based on American Megatrends Inc. v3.3 do not provide RNG support [1]. So fallback to rdrand in such cases. [1]: rust-lang#138252 (comment) Signed-off-by: Ayush Singh <[email protected]>
Some UEFI systems based on American Megatrends Inc. v3.3 do not provide RNG support [1]. So fallback to rdrand in such cases. [1]: rust-lang#138252 (comment) Signed-off-by: Ayush Singh <[email protected]>
Some UEFI systems based on American Megatrends Inc. v3.3 do not provide RNG support [1]. So fallback to rdrand in such cases. [1]: rust-lang#138252 (comment) Signed-off-by: Ayush Singh <[email protected]>
Uh oh!
There was an error while loading. Please reload this page.
When you construct a HashMap inside a UEFI environment that does not support the RNG protocol, there will be a panic.
Here is a repo containing a minimal working repro of this issue: https://github.com/ifd3f/uefi-hashmap-panic-repro
I modified the uefi-std-example from the uefi-rs repo to construct a hashmap:
Running this in QEMU with OVMF firmware, instead of constructing the HashMap and printing it, it produces the following output:
Based on the panic, my understanding is that this happens because:
OVMF (or perhaps the way I set up QEMU) does not provide an RNG protocolThe VM does not have an RNG, so the EFI environment does not advertise any RNG protocols. Adding-device virtio-rng-pci
to the QEMU invocation does allow this code to work.This is the set of commands used to set up ESP using a virtual VFAT partition, and to launch QEMU with that ESP:
Meta
rustc --version --verbose
:Backtrace: I could not produce a backtrace. Setting
RUST_BACKTRACE=1
doesn't exactly work the same way in UEFI after all :)The text was updated successfully, but these errors were encountered: