From 08ddbd6ce024e1bee9a11d61f52dc0e3b753c616 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 21 May 2020 22:38:06 +0200 Subject: [PATCH 1/4] prepare Dlsym system for dynamic symbols on Windows --- src/shims/dlsym.rs | 19 ++++++++++++++----- src/shims/foreign_items/posix.rs | 4 +--- src/shims/foreign_items/windows.rs | 11 ++++++++--- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/shims/dlsym.rs b/src/shims/dlsym.rs index 3c4a942b596f..1416db346cd0 100644 --- a/src/shims/dlsym.rs +++ b/src/shims/dlsym.rs @@ -11,12 +11,21 @@ pub enum Dlsym { impl Dlsym { // Returns an error for unsupported symbols, and None if this symbol // should become a NULL pointer (pretend it does not exist). - pub fn from_str(name: &str) -> InterpResult<'static, Option> { + pub fn from_str(name: &[u8], target_os: &str) -> InterpResult<'static, Option> { use self::Dlsym::*; - Ok(match name { - "getentropy" => Some(GetEntropy), - "__pthread_get_minstack" => None, - _ => throw_unsup_format!("unsupported dlsym: {}", name), + let name = String::from_utf8_lossy(name); + Ok(match target_os { + "linux" | "macos" => match &*name { + "getentropy" => Some(GetEntropy), + "__pthread_get_minstack" => None, + _ => throw_unsup_format!("unsupported dlsym: {}", name), + } + "windows" => match &*name { + "SetThreadStackGuarantee" => None, + "AcquireSRWLockExclusive" => None, + _ => throw_unsup_format!("unsupported dlsym: {}", name), + } + os => bug!("dlsym not implemented for target_os {}", os), }) } } diff --git a/src/shims/foreign_items/posix.rs b/src/shims/foreign_items/posix.rs index 951a40293b72..39b00feec194 100644 --- a/src/shims/foreign_items/posix.rs +++ b/src/shims/foreign_items/posix.rs @@ -173,9 +173,7 @@ fn emulate_foreign_item_by_name( this.read_scalar(handle)?.not_undef()?; let symbol = this.read_scalar(symbol)?.not_undef()?; let symbol_name = this.memory.read_c_str(symbol)?; - let err = format!("bad c unicode symbol: {:?}", symbol_name); - let symbol_name = ::std::str::from_utf8(symbol_name).unwrap_or(&err); - if let Some(dlsym) = Dlsym::from_str(symbol_name)? { + if let Some(dlsym) = Dlsym::from_str(symbol_name, &this.tcx.sess.target.target.target_os)? { let ptr = this.memory.create_fn_alloc(FnVal::Other(dlsym)); this.write_scalar(Scalar::from(ptr), dest)?; } else { diff --git a/src/shims/foreign_items/windows.rs b/src/shims/foreign_items/windows.rs index 7f3cd03cd2d3..a11e3b8aa6a0 100644 --- a/src/shims/foreign_items/windows.rs +++ b/src/shims/foreign_items/windows.rs @@ -260,9 +260,14 @@ fn emulate_foreign_item_by_name( } "GetProcAddress" if this.frame().instance.to_string().starts_with("std::sys::windows::") => { #[allow(non_snake_case)] - let &[_hModule, _lpProcName] = check_arg_count(args)?; - // Pretend this does not exist / nothing happened, by returning zero. - this.write_null(dest)?; + let &[_hModule, lpProcName] = check_arg_count(args)?; + let name = this.memory.read_c_str(this.read_scalar(lpProcName)?.not_undef()?)?; + if let Some(dlsym) = Dlsym::from_str(name, &this.tcx.sess.target.target.target_os)? { + let ptr = this.memory.create_fn_alloc(FnVal::Other(dlsym)); + this.write_scalar(Scalar::from(ptr), dest)?; + } else { + this.write_null(dest)?; + } } "SetConsoleTextAttribute" if this.frame().instance.to_string().starts_with("std::sys::windows::") => { #[allow(non_snake_case)] From f09decb398f86ebfb7938b5aca39202acb50d45e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 21 May 2020 23:00:59 +0200 Subject: [PATCH 2/4] disentangle macos and linux dlsyms --- src/shims/dlsym.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/shims/dlsym.rs b/src/shims/dlsym.rs index 1416db346cd0..301687092813 100644 --- a/src/shims/dlsym.rs +++ b/src/shims/dlsym.rs @@ -15,15 +15,18 @@ pub fn from_str(name: &[u8], target_os: &str) -> InterpResult<'static, Option
match &*name { - "getentropy" => Some(GetEntropy), + "linux" => match &*name { "__pthread_get_minstack" => None, - _ => throw_unsup_format!("unsupported dlsym: {}", name), + _ => throw_unsup_format!("unsupported Linux dlsym: {}", name), + } + "macos" => match &*name { + "getentropy" => Some(GetEntropy), + _ => throw_unsup_format!("unsupported macOS dlsym: {}", name), } "windows" => match &*name { "SetThreadStackGuarantee" => None, "AcquireSRWLockExclusive" => None, - _ => throw_unsup_format!("unsupported dlsym: {}", name), + _ => throw_unsup_format!("unsupported Windows dlsym: {}", name), } os => bug!("dlsym not implemented for target_os {}", os), }) From 526fae75413392dcfd05256145c5503011d9c89a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 21 May 2020 23:06:31 +0200 Subject: [PATCH 3/4] GetProcAddress: basic validation for hModule argument --- src/shims/foreign_items/windows.rs | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/shims/foreign_items/windows.rs b/src/shims/foreign_items/windows.rs index a11e3b8aa6a0..60448406a67d 100644 --- a/src/shims/foreign_items/windows.rs +++ b/src/shims/foreign_items/windows.rs @@ -206,6 +206,20 @@ fn emulate_foreign_item_by_name( this.write_scalar(Scalar::from_i32(result), dest)?; } + // Dynamic symbol loading + "GetProcAddress" => { + #[allow(non_snake_case)] + let &[hModule, lpProcName] = check_arg_count(args)?; + this.read_scalar(hModule)?.not_undef()?; + let name = this.memory.read_c_str(this.read_scalar(lpProcName)?.not_undef()?)?; + if let Some(dlsym) = Dlsym::from_str(name, &this.tcx.sess.target.target.target_os)? { + let ptr = this.memory.create_fn_alloc(FnVal::Other(dlsym)); + this.write_scalar(Scalar::from(ptr), dest)?; + } else { + this.write_null(dest)?; + } + } + // Miscellaneous "SystemFunction036" => { // The actual name of 'RtlGenRandom' @@ -258,17 +272,6 @@ fn emulate_foreign_item_by_name( // Pretend this does not exist / nothing happened, by returning zero. this.write_null(dest)?; } - "GetProcAddress" if this.frame().instance.to_string().starts_with("std::sys::windows::") => { - #[allow(non_snake_case)] - let &[_hModule, lpProcName] = check_arg_count(args)?; - let name = this.memory.read_c_str(this.read_scalar(lpProcName)?.not_undef()?)?; - if let Some(dlsym) = Dlsym::from_str(name, &this.tcx.sess.target.target.target_os)? { - let ptr = this.memory.create_fn_alloc(FnVal::Other(dlsym)); - this.write_scalar(Scalar::from(ptr), dest)?; - } else { - this.write_null(dest)?; - } - } "SetConsoleTextAttribute" if this.frame().instance.to_string().starts_with("std::sys::windows::") => { #[allow(non_snake_case)] let &[_hConsoleOutput, _wAttribute] = check_arg_count(args)?; From 402535ef8639b4ba42ad4c1be7ff50542f8104d1 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 21 May 2020 23:24:37 +0200 Subject: [PATCH 4/4] also pretend GetSystemTimePreciseAsFileTime does not exist --- src/shims/dlsym.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/shims/dlsym.rs b/src/shims/dlsym.rs index 301687092813..87c7f447ac03 100644 --- a/src/shims/dlsym.rs +++ b/src/shims/dlsym.rs @@ -26,6 +26,7 @@ pub fn from_str(name: &[u8], target_os: &str) -> InterpResult<'static, Option
match &*name { "SetThreadStackGuarantee" => None, "AcquireSRWLockExclusive" => None, + "GetSystemTimePreciseAsFileTime" => None, _ => throw_unsup_format!("unsupported Windows dlsym: {}", name), } os => bug!("dlsym not implemented for target_os {}", os),