Auto merge of #121337 - ChrisDenton:ProcessPrng, r=Mark-Simulacrum · rust-lang/rust@34aab62 (original) (raw)

File tree

6 files changed

lines changed

6 files changed

lines changed

Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
1 +From 9f65e742ba3e41474e6126c6c4469c48eaa6ca7e Mon Sep 17 00:00:00 2001
2 +From: Chris Denton chris@chrisdenton.dev
3 +Date: Tue, 20 Feb 2024 16:01:40 -0300
4 +Subject: [PATCH] Don't use raw-dylib in std
5 +
6 +---
7 + library/std/src/sys/pal/windows/c.rs | 2 +-
8 + library/std/src/sys/pal/windows/rand.rs | 3 +--
9 + 2 files changed, 2 insertions(+), 3 deletions(-)
10 +
11 +diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs
12 +index ad8e01bfa9b..9ca8e4c16ce 100644
13 +--- a/library/std/src/sys/pal/windows/c.rs
14 ++++ b/library/std/src/sys/pal/windows/c.rs
15 +@@ -323,7 +323,7 @@ pub unsafe fn NtWriteFile(
16 +
17 + // Use raw-dylib to import ProcessPrng as we can't rely on there being an import library.
18 + cfg_if::cfg_if! {
19 +-if #[cfg(not(target_vendor = "win7"))] {
20 ++if #[cfg(any())] {
21 + #[cfg(target_arch = "x86")]
22 + #[link(name = "bcryptprimitives", kind = "raw-dylib", import_name_type = "undecorated")]
23 + extern "system" {
24 +diff --git a/library/std/src/sys/pal/windows/rand.rs b/library/std/src/sys/pal/windows/rand.rs
25 +index e427546222a..f2fe42a4d51 100644
26 +--- a/library/std/src/sys/pal/windows/rand.rs
27 ++++ b/library/std/src/sys/pal/windows/rand.rs
28 +@@ -2,7 +2,7 @@
29 + use core::mem;
30 + use core::ptr;
31 +
32 +-#[cfg(not(target_vendor = "win7"))]
33 ++#[cfg(any())]
34 + #[inline]
35 + pub fn hashmap_random_keys() -> (u64, u64) {
36 + let mut v = (0, 0);
37 +@@ -13,7 +13,6 @@ pub fn hashmap_random_keys() -> (u64, u64) {
38 + v
39 + }
40 +
41 +-#[cfg(target_vendor = "win7")]
42 + pub fn hashmap_random_keys() -> (u64, u64) {
43 + use crate::ffi::c_void;
44 + use crate::io;
45 +--
46 +2.42.0.windows.2
47 +
Original file line number Diff line number Diff line change
@@ -321,6 +321,21 @@ pub unsafe fn NtWriteFile(
321 321 }
322 322 }
323 323
324 +// Use raw-dylib to import ProcessPrng as we can't rely on there being an import library.
325 +cfg_if::cfg_if! {
326 +if #[cfg(not(target_vendor = "win7"))] {
327 + #[cfg(target_arch = "x86")]
328 + #[link(name = "bcryptprimitives", kind = "raw-dylib", import_name_type = "undecorated")]
329 + extern "system" {
330 +pub fn ProcessPrng(pbdata: *mut u8, cbdata: usize) -> BOOL;
331 +}
332 + #[cfg(not(target_arch = "x86"))]
333 + #[link(name = "bcryptprimitives", kind = "raw-dylib")]
334 + extern "system" {
335 +pub fn ProcessPrng(pbdata: *mut u8, cbdata: usize) -> BOOL;
336 +}
337 +}}
338 +
324 339 // Functions that aren't available on every version of Windows that we support,
325 340 // but we still use them and just provide some form of a fallback implementation.
326 341 compat_fn_with_fallback! {
Original file line number Diff line number Diff line change
@@ -2180,10 +2180,6 @@ Windows.Win32.Networking.WinSock.WSATRY_AGAIN
2180 2180 Windows.Win32.Networking.WinSock.WSATYPE_NOT_FOUND
2181 2181 Windows.Win32.Networking.WinSock.WSAVERNOTSUPPORTED
2182 2182 Windows.Win32.Security.Authentication.Identity.RtlGenRandom
2183 -Windows.Win32.Security.Cryptography.BCRYPT_ALG_HANDLE
2184 -Windows.Win32.Security.Cryptography.BCRYPT_USE_SYSTEM_PREFERRED_RNG
2185 -Windows.Win32.Security.Cryptography.BCryptGenRandom
2186 -Windows.Win32.Security.Cryptography.BCRYPTGENRANDOM_FLAGS
2187 2183 Windows.Win32.Security.SECURITY_ATTRIBUTES
2188 2184 Windows.Win32.Security.TOKEN_ACCESS_MASK
2189 2185 Windows.Win32.Security.TOKEN_ACCESS_PSEUDO_HANDLE
Original file line number Diff line number Diff line change
@@ -15,15 +15,6 @@ extern "system" {
15 15 pub fn RtlGenRandom(randombuffer: *mut ::core::ffi::c_void, randombufferlength: u32)
16 16 -> BOOLEAN;
17 17 }
18 -#[link(name = "bcrypt")]
19 -extern "system" {
20 -pub fn BCryptGenRandom(
21 -halgorithm: BCRYPT_ALG_HANDLE,
22 -pbbuffer: *mut u8,
23 -cbbuffer: u32,
24 -dwflags: BCRYPTGENRANDOM_FLAGS,
25 -) -> NTSTATUS;
26 -}
27 18 #[link(name = "kernel32")]
28 19 extern "system" {
29 20 pub fn AcquireSRWLockExclusive(srwlock: *mut SRWLOCK) -> ();
@@ -889,9 +880,6 @@ impl ::core::clone::Clone for ARM64_NT_NEON128_0 {
889 880 *self
890 881 }
891 882 }
892 -pub type BCRYPTGENRANDOM_FLAGS = u32;
893 -pub type BCRYPT_ALG_HANDLE = *mut ::core::ffi::c_void;
894 -pub const BCRYPT_USE_SYSTEM_PREFERRED_RNG: BCRYPTGENRANDOM_FLAGS = 2u32;
895 883 pub const BELOW_NORMAL_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 16384u32;
896 884 pub type BOOL = i32;
897 885 pub type BOOLEAN = u8;
Original file line number Diff line number Diff line change
@@ -1,42 +1,27 @@
1 -use crate::mem;
2 -use crate::ptr;
3 1 use crate::sys::c;
2 +use core::mem;
3 +use core::ptr;
4 4
5 +#[cfg(not(target_vendor = "win7"))]
6 +#[inline]
5 7 pub fn hashmap_random_keys() -> (u64, u64) {
6 8 let mut v = (0, 0);
7 -let ret = unsafe {
8 - c::BCryptGenRandom(
9 - ptr::null_mut(),
10 - core::ptr::addr_of_mut!(v) as *mut u8,
11 - mem::size_of_val(&v) as c::ULONG,
12 - c::BCRYPT_USE_SYSTEM_PREFERRED_RNG,
13 -)
14 -};
15 -if c::nt_success(ret) { v } else { fallback_rng() }
9 +let ret = unsafe { c::ProcessPrng(ptr::addr_of_mut!(v).cast::<u8>(), mem::size_of_val(&v)) };
10 +// ProcessPrng is documented as always returning `TRUE`.
11 +// https://learn.microsoft.com/en-us/windows/win32/seccng/processprng#return-value
12 +debug_assert_eq!(ret, c::TRUE);
13 + v
16 14 }
17 15
18 -/// Generate random numbers using the fallback RNG function (RtlGenRandom)
19 -///
20 -/// This is necessary because of a failure to load the SysWOW64 variant of the
21 -/// bcryptprimitives.dll library from code that lives in bcrypt.dll
22 -/// See https://bugzilla.mozilla.org/show\_bug.cgi?id=1788004#c9
23 -#[cfg(not(target_vendor = "uwp"))]
24 -#[inline(never)]
25 -fn fallback_rng() -> (u64, u64) {
16 +#[cfg(target_vendor = "win7")]
17 +pub fn hashmap_random_keys() -> (u64, u64) {
26 18 use crate::ffi::c_void;
27 19 use crate::io;
28 20
29 21 let mut v = (0, 0);
30 22 let ret = unsafe {
31 - c::RtlGenRandom(core::ptr::addr_of_mut!(v) as *mut c_void, mem::size_of_val(&v) as c::ULONG)
23 + c::RtlGenRandom(ptr::addr_of_mut!(v).cast::<c_void>(), mem::size_of_val(&v) as c::ULONG)
32 24 };
33 25
34 -if ret != 0 { v } else { panic!("fallback RNG broken: {}", io::Error::last_os_error()) }
35 -}
36 -
37 -/// We can't use RtlGenRandom with UWP, so there is no fallback
38 -#[cfg(target_vendor = "uwp")]
39 -#[inline(never)]
40 -fn fallback_rng() -> (u64, u64) {
41 -panic!("fallback RNG broken: RtlGenRandom() not supported on UWP");
26 +if ret != 0 { v } else { panic!("RNG broken: {}", io::Error::last_os_error()) }
42 27 }
Original file line number Diff line number Diff line change
@@ -427,6 +427,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
427 427 this.gen_random(ptr, len.into())?;
428 428 this.write_scalar(Scalar::from_bool(true), dest)?;
429 429 }
430 +"ProcessPrng" => {
431 +let [ptr, len] =
432 + this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
433 +let ptr = this.read_pointer(ptr)?;
434 +let len = this.read_target_usize(len)?;
435 + this.gen_random(ptr, len.into())?;
436 + this.write_scalar(Scalar::from_i32(1), dest)?;
437 +}
430 438 "BCryptGenRandom" => {
431 439 let [algorithm, ptr, len, flags] =
432 440 this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;