To help protect against heap exploits and bugs in unsafe or third-party code, the Rust compiler should emit code to enable Windows' HeapEnableTerminationOnCorruption feature for all Windows Rust programs.
With HeapEnableTerminationOnCorruption enabled, if the Windows heap manager detects an error in any system heap used by the process, it terminates the process. After a process enables this feature, it cannot be disabled. This feature should not cause any compatibility problems for correct programs.
See MSDN for HeapSetInformation and HeapEnableTerminationOnCorruption:
https://docs.microsoft.com/en-us/windows/desktop/api/heapapi/nf-heapapi-heapsetinformation
Here is how Firefox enables HeapEnableTerminationOnCorruption for its processes:
I took a stab at implementing this, by adding HeapSetInformation to std::rt::lang_start_internal. But it turned out to be already enabled by default. See https://blogs.msdn.microsoft.com/oldnewthing/20131227-00/?p=2243.
On 64-bit it is already always enabled. On 32-bit it also is when the subsystem major version is 6 or higher. Which is the default, and I am not sure this can be changed to something lower for Rust binaries. We only support the subsystems console and windows, and not setting a version.
Tested with this snippid:
extern crate libc;
fn main() {
unsafe {
let ptr = libc::malloc(80);
libc::free(ptr);
libc::free(ptr);
}
}
with as result STATUS_HEAP_CORRUPTION for both 32- and 64-bit:
error: process didn't exit successfully: `target\i686-pc-windows-msvc\debug\windows_mitigations.exe` (exit code: 0xc0000374, STATUS_HEAP_CORRUPTION)
Seems like there is nothing to be done here?
Awesome! In that case, I'll close this issue then. Thanks for investigating.
Most helpful comment
I took a stab at implementing this, by adding
HeapSetInformationtostd::rt::lang_start_internal. But it turned out to be already enabled by default. See https://blogs.msdn.microsoft.com/oldnewthing/20131227-00/?p=2243.On 64-bit it is already always enabled. On 32-bit it also is when the subsystem major version is 6 or higher. Which is the default, and I am not sure this can be changed to something lower for Rust binaries. We only support the subsystems
consoleandwindows, and not setting a version.Tested with this snippid:
with as result
STATUS_HEAP_CORRUPTIONfor both 32- and 64-bit:Seems like there is nothing to be done here?