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

windows: always use RtlGenRandom on pre-1.78 Rust versions #610

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ libc = { version = "0.2.154", default-features = false }
wasi = { version = "0.14", default-features = false }

# windows7
[target.'cfg(all(windows, not(target_vendor = "win7")))'.dependencies]
[target.'cfg(all(windows, not(target_vendor = "win7"), not(getrandom_windows_legacy)))'.dependencies]
windows-targets = "0.53"

# wasm_js
Expand All @@ -83,6 +83,7 @@ level = "warn"
check-cfg = [
'cfg(getrandom_backend, values("custom", "rdrand", "rndr", "linux_getrandom", "wasm_js"))',
'cfg(getrandom_msan)',
'cfg(getrandom_windows_legacy)',
'cfg(getrandom_test_linux_fallback)',
'cfg(getrandom_test_linux_without_fallback)',
'cfg(getrandom_test_netbsd_fallback)',
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ fn get_random_u128() -> Result<u128, getrandom::Error> {
| Target | Target Triple | Implementation
| ------------------ | ------------------ | --------------
| Linux, Android | `*‑linux‑*` | [`getrandom`][1] system call if available, otherwise [`/dev/urandom`][2] after successfully polling `/dev/random`
| Windows 10+ | `*‑windows‑*` | [`ProcessPrng`]
| Windows 10+ | `*‑windows‑*` | [`ProcessPrng`] on Rust 1.78+, [`RtlGenRandom`] otherwise
| Windows 7, 8 | `*-win7‑windows‑*` | [`RtlGenRandom`]
| macOS | `*‑apple‑darwin` | [`getentropy`][3]
| iOS, tvOS, watchOS | `*‑apple‑{ios,tvos,watchos}` | [`CCRandomGenerateBytes`]
Expand Down
52 changes: 50 additions & 2 deletions build.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,57 @@
// Automatically detect cfg(sanitize = "memory") even if cfg(sanitize) isn't
// supported. Build scripts get cfg() info, even if the cfg is unstable.
use std::{env, ffi::OsString, process::Command};

/// Tries to get the minor version of the Rust compiler in use.
/// If it fails for any reason, returns `None`.
///
/// Based on the `rustc_version` crate.
fn rustc_minor_version() -> Option<u64> {
let rustc = env::var_os("RUSTC").unwrap_or_else(|| OsString::from("rustc"));
let mut cmd = if let Some(wrapper) = env::var_os("RUSTC_WRAPPER").filter(|w| !w.is_empty()) {
let mut cmd = Command::new(wrapper);
cmd.arg(rustc);
cmd
} else {
Command::new(rustc)
};

let out = cmd.arg("-vV").output().ok()?;

if !out.status.success() {
return None;
}

let stdout = std::str::from_utf8(&out.stdout).ok()?;

// Assumes that the first line contains "rustc 1.xx.0-channel (abcdef 2025-01-01)"
// where "xx" is the minor version which we want to extract
let mut lines = stdout.lines();
let first_line = lines.next()?;
let minor_ver_str = first_line.split(".").nth(1)?;
minor_ver_str.parse().ok()
}

fn main() {
// Automatically detect cfg(sanitize = "memory") even if cfg(sanitize) isn't
// supported. Build scripts get cfg() info, even if the cfg is unstable.
println!("cargo:rerun-if-changed=build.rs");
let santizers = std::env::var("CARGO_CFG_SANITIZE").unwrap_or_default();
if santizers.contains("memory") {
println!("cargo:rustc-cfg=getrandom_msan");
}

// Use `RtlGenRandom` on older compiler versions since win7 targets
// were introduced only in Rust 1.78
let target_family = env::var_os("CARGO_CFG_TARGET_FAMILY").and_then(|f| f.into_string().ok());
if target_family.as_deref() == Some("windows") {
/// Minor version of the Rust compiler in which win7 targets were inroduced
const WIN7_INTRODUCED_MINOR_VER: u64 = 78;

match rustc_minor_version() {
Some(minor_ver) if minor_ver < WIN7_INTRODUCED_MINOR_VER => {
println!("cargo:rustc-cfg=getrandom_windows_legacy");
}
None => println!("cargo:warning=Couldn't detect minor version of the Rust compiler"),
_ => {}
}
}
}
2 changes: 1 addition & 1 deletion src/backends.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ cfg_if! {
} else if #[cfg(target_os = "solid_asp3")] {
mod solid;
pub use solid::*;
} else if #[cfg(all(windows, target_vendor = "win7"))] {
} else if #[cfg(all(windows, any(target_vendor = "win7", getrandom_windows_legacy)))] {
mod windows7;
pub use windows7::*;
} else if #[cfg(windows)] {
Expand Down