Skip to content

Commit

Permalink
Improve delayload comments
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisDenton committed Oct 1, 2023
1 parent 11fe59d commit 5e04541
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 27 deletions.
58 changes: 32 additions & 26 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,35 +28,41 @@ fn main() {
let target = env::var("TARGET").unwrap();
println!("cargo:rustc-env=TARGET={target}");

// Set linker options specific to Windows MSVC.
let target_os = env::var("CARGO_CFG_TARGET_OS");
let target_env = env::var("CARGO_CFG_TARGET_ENV");
if Ok("windows") == target_os.as_deref() && Ok("msvc") == target_env.as_deref() {
// # Only search system32 for DLLs
//
// This applies to DLLs loaded at load time. However, this setting is ignored
// before Windows 10 RS1.
println!("cargo:cargo:rustc-link-arg-bin=rustup-init=/DEPENDENTLOADFLAG:0x800");
if target_os.as_deref() != Ok("windows") && target_env.as_deref() != Ok("msvc") {
return;
}

// # Delay load
//
// Delay load dlls that are not "known DLLs".
// Known DLLs are always loaded from the system directory whereas other DLLs
// are loaded from the application directory. By delay loading the latter
// we can ensure they are instead loaded from the system directory.
//
// This will work on all supported Windows versions but it relies on
// using `SetDefaultDllDirectories` before any libraries are loaded.
let delay_load_dlls = ["bcrypt", "powrprof", "secur32"];
for dll in delay_load_dlls {
println!("cargo:rustc-link-arg-bin=rustup-init=/delayload:{dll}.dll");
}
println!("cargo:rustc-link-arg-bin=rustup-init=delayimp.lib");
// # Only search system32 for DLLs
//
// This applies to DLLs loaded at load time. However, this setting is ignored
// before Windows 10 RS1 (aka 1601).
// https://learn.microsoft.com/en-us/cpp/build/reference/dependentloadflag?view=msvc-170
println!("cargo:cargo:rustc-link-arg-bin=rustup-init=/DEPENDENTLOADFLAG:0x800");

// # Turn linker warnings into errors
//
// Rust hides linker warnings meaning mistakes may go unnoticed.
// Turning them into errors forces them to be displayed (and the build to fail).
// If we do want to ignore specific warnings then `/IGNORE:` should be used.
println!("cargo:cargo:rustc-link-arg-bin=rustup-init=/WX");
// # Delay load
//
// Delay load dlls that are not "known DLLs"[1].
// Known DLLs are always loaded from the system directory whereas other DLLs
// are loaded from the application directory. By delay loading the latter
// we can ensure they are instead loaded from the system directory.
// [1]: https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order#factors-that-affect-searching
//
// This will work on all supported Windows versions but it relies on
// us using `SetDefaultDllDirectories` before any libraries are loaded.
// See also: src/bin/rustup-init.rs
let delay_load_dlls = ["bcrypt", "powrprof", "secur32"];
for dll in delay_load_dlls {
println!("cargo:rustc-link-arg-bin=rustup-init=/delayload:{dll}.dll");
}
println!("cargo:rustc-link-arg-bin=rustup-init=delayimp.lib");

// # Turn linker warnings into errors
//
// Rust hides linker warnings meaning mistakes may go unnoticed.
// Turning them into errors forces them to be displayed (and the build to fail).
// If we do want to ignore specific warnings then `/IGNORE:` should be used.
println!("cargo:cargo:rustc-link-arg-bin=rustup-init=/WX");
}
4 changes: 3 additions & 1 deletion src/bin/rustup-init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,12 +169,14 @@ fn do_recursion_guard() -> Result<()> {

/// Windows pre-main security mitigations.
///
/// This is attempts to defend against malicious DLLs that may sit alongside
/// This attempts to defend against malicious DLLs that may sit alongside
/// rustup-init in the user's download folder.
#[cfg(windows)]
pub fn pre_rustup_main_init() {
use winapi::um::libloaderapi::{SetDefaultDllDirectories, LOAD_LIBRARY_SEARCH_SYSTEM32};
// Default to loading delay loaded DLLs from the system directory.
// For DLLs loaded at load time, this relies on the `delayload` linker flag.
// This is only necessary prior to Windows 10 RS1. See build.rs for details.
unsafe {
let result = SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32);
// SetDefaultDllDirectories should never fail if given valid arguments.
Expand Down

0 comments on commit 5e04541

Please sign in to comment.