Skip to content

ASLR on Windows breaks thread-local variables #17684

Closed
@thestinger

Description

@thestinger
Contributor

This appears to be a MinGW-w64 linker bug.

Activity

added
A-securityArea: Security (example: address space layout randomization).
on Oct 1, 2014
steveklabnik

steveklabnik commented on Dec 31, 2015

@steveklabnik
Member

Triage: I am not sure if there has been any change, nor steps to reproduce.

brson

brson commented on Feb 6, 2016

@brson
Contributor

If this was a mingw-specific bug, we may be able to reactivate it on the msvc builds.

retep998

retep998 commented on Feb 6, 2016

@retep998
Member

According to MSDN By default, /DYNAMICBASE is on. so we've already been effectively using ASLR with -msvc targets.

changed the title [-]ASLR on Windows breaks TLS[/-] [+]ASLR on Windows breaks thread-local variables[/+] on Jun 23, 2016
Mark-Simulacrum

Mark-Simulacrum commented on May 6, 2017

@Mark-Simulacrum
Member

Can someone comment on whether thread locals are broken on Windows MinGW-w64 today? What are the reproduction steps?

added
O-windows-gnuToolchain: GNU, Operating system: Windows
and removed
O-windowsOperating system: Windows
on May 6, 2017
sipsorcery

sipsorcery commented on Oct 2, 2017

@sipsorcery

I've done a cursory check of TLS with 64 bit binaries compiled with msvc and mingw32-g++ and both are working correctly.

// http://en.cppreference.com/w/cpp/language/storage_duration
// msvc on win64: cl tls.cpp /link
// mingw on linux64: x86_64-w64-mingw32-g++ tls.cpp -static -static-libstdc++

#include <iostream>
#include <string>
#include <thread>
#include <mutex>

thread_local unsigned int rage = 1;
std::mutex cout_mutex;

void increase_rage(const std::string& thread_name)
{
	++rage; // modifying outside a lock is okay; this is a thread-local variable
	std::lock_guard<std::mutex> lock(cout_mutex);
	std::cout << "Rage counter for " << thread_name << ": " << rage << '\n';
}

int main()
{
	std::thread a(increase_rage, "a"), b(increase_rage, "b");

	{
		std::lock_guard<std::mutex> lock(cout_mutex);
		std::cout << "Rage counter for main: " << rage << '\n';
	}

	a.join();
	b.join();

	getchar();
}

msvc output:

f:\Temp>tls
Rage counter for a: 2
Rage counter for b: 2
Rage counter for main: 1

mingw32-g++ output:

f:\Temp>tls_mingw.exe
Rage counter for main: 1
Rage counter for a: 2
Rage counter for b: 2

64 bit binaries on Windows use ASLR by default unless explicitly disabled with a linker option. Both binaries in this test had the NX Compatible flag set in the executable image header.

Happy to test further if anyone has a pointer to the problem code.

retep998

retep998 commented on Oct 2, 2017

@retep998
Member

@sipsorcery The key thing is #[thread_local] statics in Rust. The NX compatible bit does not indicate ASLR, rather it needs to have the Dynamic base bit.

added
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
on Jan 12, 2020

8 remaining items

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-securityArea: Security (example: address space layout randomization).A-thread-localsArea: Thread local storage (TLS)C-bugCategory: This is a bug.O-windows-gnuToolchain: GNU, Operating system: WindowsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @steveklabnik@brson@sipsorcery@retep998@mati865

      Issue actions

        ASLR on Windows breaks thread-local variables · Issue #17684 · rust-lang/rust