Skip to content

Commit 5730f12

Browse files
authored
Rollup merge of #99371 - ChrisDenton:simplify-gen-random-keys, r=thomcc
Remove synchronization from Windows `hashmap_random_keys` Unfortunately using synchronization when generating hashmap keys can prevent it being used in `DllMain`. ~~Fixes #99341~~
2 parents e141246 + 46673bb commit 5730f12

File tree

1 file changed

+8
-60
lines changed

1 file changed

+8
-60
lines changed

Diff for: library/std/src/sys/windows/rand.rs

+8-60
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,9 @@
11
use crate::io;
22
use crate::mem;
3-
use crate::sync;
3+
use crate::ptr;
44
use crate::sys::c;
55

6-
/// The kinds of HashMap RNG that may be available
7-
#[derive(Clone, Copy, Debug, PartialEq)]
8-
enum HashMapRng {
9-
Preferred,
10-
Fallback,
11-
}
12-
136
pub fn hashmap_random_keys() -> (u64, u64) {
14-
match get_hashmap_rng() {
15-
HashMapRng::Preferred => {
16-
preferred_rng().expect("couldn't generate random bytes with preferred RNG")
17-
}
18-
HashMapRng::Fallback => {
19-
fallback_rng().expect("couldn't generate random bytes with fallback RNG")
20-
}
21-
}
22-
}
23-
24-
/// Returns the HashMap RNG that should be used
25-
///
26-
/// Panics if they are both broken
27-
fn get_hashmap_rng() -> HashMapRng {
28-
// Assume that if the preferred RNG is broken the first time we use it, it likely means
29-
// that: the DLL has failed to load, there is no point to calling it over-and-over again,
30-
// and we should cache the result
31-
static VALUE: sync::OnceLock<HashMapRng> = sync::OnceLock::new();
32-
*VALUE.get_or_init(choose_hashmap_rng)
33-
}
34-
35-
/// Test whether we should use the preferred or fallback RNG
36-
///
37-
/// If the preferred RNG is successful, we choose it. Otherwise, if the fallback RNG is successful,
38-
/// we choose that
39-
///
40-
/// Panics if both the preferred and the fallback RNG are both non-functional
41-
fn choose_hashmap_rng() -> HashMapRng {
42-
let preferred_error = match preferred_rng() {
43-
Ok(_) => return HashMapRng::Preferred,
44-
Err(e) => e,
45-
};
46-
47-
match fallback_rng() {
48-
Ok(_) => return HashMapRng::Fallback,
49-
Err(fallback_error) => panic!(
50-
"preferred RNG broken: `{}`, fallback RNG broken: `{}`",
51-
preferred_error, fallback_error
52-
),
53-
}
54-
}
55-
56-
/// Generate random numbers using the preferred RNG function (BCryptGenRandom)
57-
fn preferred_rng() -> Result<(u64, u64), io::Error> {
58-
use crate::ptr;
59-
607
let mut v = (0, 0);
618
let ret = unsafe {
629
c::BCryptGenRandom(
@@ -66,22 +13,23 @@ fn preferred_rng() -> Result<(u64, u64), io::Error> {
6613
c::BCRYPT_USE_SYSTEM_PREFERRED_RNG,
6714
)
6815
};
69-
70-
if ret == 0 { Ok(v) } else { Err(io::Error::last_os_error()) }
16+
if ret != 0 { fallback_rng() } else { v }
7117
}
7218

7319
/// Generate random numbers using the fallback RNG function (RtlGenRandom)
7420
#[cfg(not(target_vendor = "uwp"))]
75-
fn fallback_rng() -> Result<(u64, u64), io::Error> {
21+
#[inline(never)]
22+
fn fallback_rng() -> (u64, u64) {
7623
let mut v = (0, 0);
7724
let ret =
7825
unsafe { c::RtlGenRandom(&mut v as *mut _ as *mut u8, mem::size_of_val(&v) as c::ULONG) };
7926

80-
if ret != 0 { Ok(v) } else { Err(io::Error::last_os_error()) }
27+
if ret != 0 { v } else { panic!("fallback RNG broken: {}", io::Error::last_os_error()) }
8128
}
8229

8330
/// We can't use RtlGenRandom with UWP, so there is no fallback
8431
#[cfg(target_vendor = "uwp")]
85-
fn fallback_rng() -> Result<(u64, u64), io::Error> {
86-
Err(io::const_io_error!(io::ErrorKind::Unsupported, "RtlGenRandom() not supported on UWP"))
32+
#[inline(never)]
33+
fn fallback_rng() -> (u64, u64) {
34+
panic!("fallback RNG broken: RtlGenRandom() not supported on UWP");
8735
}

0 commit comments

Comments
 (0)