Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ASLR on Windows breaks thread-local variables #17684

Open
thestinger opened this Issue Oct 1, 2014 · 6 comments

Comments

Projects
None yet
6 participants
@thestinger
Copy link
Contributor

thestinger commented Oct 1, 2014

This appears to be a MinGW-w64 linker bug.

@steveklabnik

This comment has been minimized.

Copy link
Member

steveklabnik commented Dec 31, 2015

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

@brson

This comment has been minimized.

Copy link
Contributor

brson commented Feb 6, 2016

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

@retep998

This comment has been minimized.

Copy link
Member

retep998 commented Feb 6, 2016

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

@thestinger thestinger changed the title ASLR on Windows breaks TLS ASLR on Windows breaks thread-local variables Jun 23, 2016

@Mark-Simulacrum

This comment has been minimized.

Copy link
Member

Mark-Simulacrum commented May 6, 2017

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

@retep998 retep998 added O-windows-gnu and removed O-windows labels May 6, 2017

@sipsorcery

This comment has been minimized.

Copy link

sipsorcery commented Oct 2, 2017

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

This comment has been minimized.

Copy link
Member

retep998 commented Oct 2, 2017

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.