From a52eaaa996a7edeb699a756f755ad4b8c23dc9df Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 24 Sep 2014 15:35:44 -0700 Subject: [PATCH] Disable runtime split stack support on Windows --- src/librustrt/stack.rs | 19 ++++----------- src/libstd/rand/os.rs | 40 +------------------------------ src/test/run-pass/out-of-stack.rs | 10 ++++++-- 3 files changed, 13 insertions(+), 56 deletions(-) diff --git a/src/librustrt/stack.rs b/src/librustrt/stack.rs index 3190e9f78414..a4cbbf248113 100644 --- a/src/librustrt/stack.rs +++ b/src/librustrt/stack.rs @@ -200,11 +200,7 @@ pub unsafe fn record_sp_limit(limit: uint) { asm!("movq $0, %fs:112" :: "r"(limit) :: "volatile") } #[cfg(target_arch = "x86_64", target_os = "windows")] #[inline(always)] - unsafe fn target_record_sp_limit(limit: uint) { - // see: http://en.wikipedia.org/wiki/Win32_Thread_Information_Block - // store this inside of the "arbitrary data slot", but double the size - // because this is 64 bit instead of 32 bit - asm!("movq $0, %gs:0x28" :: "r"(limit) :: "volatile") + unsafe fn target_record_sp_limit(_: uint) { } #[cfg(target_arch = "x86_64", target_os = "freebsd")] #[inline(always)] unsafe fn target_record_sp_limit(limit: uint) { @@ -228,10 +224,7 @@ pub unsafe fn record_sp_limit(limit: uint) { asm!("movl $0, %gs:48" :: "r"(limit) :: "volatile") } #[cfg(target_arch = "x86", target_os = "windows")] #[inline(always)] - unsafe fn target_record_sp_limit(limit: uint) { - // see: http://en.wikipedia.org/wiki/Win32_Thread_Information_Block - // store this inside of the "arbitrary data slot" - asm!("movl $0, %fs:0x14" :: "r"(limit) :: "volatile") + unsafe fn target_record_sp_limit(_: uint) { } // mips, arm - Some brave soul can port these to inline asm, but it's over @@ -282,9 +275,7 @@ pub unsafe fn get_sp_limit() -> uint { } #[cfg(target_arch = "x86_64", target_os = "windows")] #[inline(always)] unsafe fn target_get_sp_limit() -> uint { - let limit; - asm!("movq %gs:0x28, $0" : "=r"(limit) ::: "volatile"); - return limit; + return 1024; } #[cfg(target_arch = "x86_64", target_os = "freebsd")] #[inline(always)] unsafe fn target_get_sp_limit() -> uint { @@ -318,9 +309,7 @@ pub unsafe fn get_sp_limit() -> uint { } #[cfg(target_arch = "x86", target_os = "windows")] #[inline(always)] unsafe fn target_get_sp_limit() -> uint { - let limit; - asm!("movl %fs:0x14, $0" : "=r"(limit) ::: "volatile"); - return limit; + return 1024; } // mips, arm - Some brave soul can port these to inline asm, but it's over diff --git a/src/libstd/rand/os.rs b/src/libstd/rand/os.rs index 95be3191bab4..120ace1c36a5 100644 --- a/src/libstd/rand/os.rs +++ b/src/libstd/rand/os.rs @@ -136,7 +136,6 @@ mod imp { use os; use rand::Rng; use result::{Ok, Err}; - use rt::stack; use self::libc::{DWORD, BYTE, LPCSTR, BOOL}; use self::libc::types::os::arch::extra::{LONG_PTR}; use slice::MutableSlice; @@ -159,7 +158,6 @@ mod imp { static PROV_RSA_FULL: DWORD = 1; static CRYPT_SILENT: DWORD = 64; static CRYPT_VERIFYCONTEXT: DWORD = 0xF0000000; - static NTE_BAD_SIGNATURE: DWORD = 0x80090006; #[allow(non_snake_case)] extern "system" { @@ -178,48 +176,12 @@ mod imp { /// Create a new `OsRng`. pub fn new() -> IoResult { let mut hcp = 0; - let mut ret = unsafe { + let ret = unsafe { CryptAcquireContextA(&mut hcp, 0 as LPCSTR, 0 as LPCSTR, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT) }; - // FIXME #13259: - // It turns out that if we can't acquire a context with the - // NTE_BAD_SIGNATURE error code, the documentation states: - // - // The provider DLL signature could not be verified. Either the - // DLL or the digital signature has been tampered with. - // - // Sounds fishy, no? As it turns out, our signature can be bad - // because our Thread Information Block (TIB) isn't exactly what it - // expects. As to why, I have no idea. The only data we store in the - // TIB is the stack limit for each thread, but apparently that's - // enough to make the signature valid. - // - // Furthermore, this error only happens the *first* time we call - // CryptAcquireContext, so we don't have to worry about future - // calls. - // - // Anyway, the fix employed here is that if we see this error, we - // pray that we're not close to the end of the stack, temporarily - // set the stack limit to 0 (what the TIB originally was), acquire a - // context, and then reset the stack limit. - // - // Again, I'm not sure why this is the fix, nor why we're getting - // this error. All I can say is that this seems to allow libnative - // to progress where it otherwise would be hindered. Who knew? - if ret == 0 && os::errno() as DWORD == NTE_BAD_SIGNATURE { - unsafe { - let limit = stack::get_sp_limit(); - stack::record_sp_limit(0); - ret = CryptAcquireContextA(&mut hcp, 0 as LPCSTR, 0 as LPCSTR, - PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT | CRYPT_SILENT); - stack::record_sp_limit(limit); - } - } - if ret == 0 { Err(IoError::last_error()) } else { diff --git a/src/test/run-pass/out-of-stack.rs b/src/test/run-pass/out-of-stack.rs index 7f2f9f9ece83..bbaa09bfac31 100644 --- a/src/test/run-pass/out-of-stack.rs +++ b/src/test/run-pass/out-of-stack.rs @@ -42,11 +42,17 @@ fn main() { let silent = Command::new(args[0].as_slice()).arg("silent").output().unwrap(); assert!(!silent.status.success()); let error = String::from_utf8_lossy(silent.error.as_slice()); - assert!(error.as_slice().contains("has overflowed its stack")); + // FIXME #17562: Windows is using stack probes and isn't wired up to print an error + if !cfg!(windows) { + assert!(error.as_slice().contains("has overflowed its stack")); + } let loud = Command::new(args[0].as_slice()).arg("loud").output().unwrap(); assert!(!loud.status.success()); let error = String::from_utf8_lossy(silent.error.as_slice()); - assert!(error.as_slice().contains("has overflowed its stack")); + // FIXME #17562: Windows is using stack probes and isn't wired up to print an error + if !cfg!(windows) { + assert!(error.as_slice().contains("has overflowed its stack")); + } } }