In the rush to get the Windows builds working correctly, we may have disabled hardening options that we shouldn't have. I experienced crashes on Windows 7 with a few options as well. We should get to the bottom of those issues and if they persist, we should ping the mingw-w64 people and find out what the issue is.
I played around with this a bit today and here is a tiny bit of progress and some rabid fangirling of objdump.
I enabled ASLR and DEP for tor.exe and libevent (nothing else automatically picks up LDFLAGS, so I need to look into that) and so far nothing is crashing for me on Win7.
Relatedly, I've been using objdump lately to look at the results of builds from #9444 (closed) and decided to see if it's possible to glean information about ASLR and DEP from the Windows binaries without having to check them in ProcessHacker or some other Windows app. For DLLs and EXEs (both PE), there is something called DllCharacteristics in the header which will tell you which, if any, of those are enabled. For ASLR it is 0x40 and for DEP it's 0x100, so all of our DLLs and EXEs should be showing something like: DllCharacteristics 00000140. The main reason this is cool is that you can use objdump from Linux to investigate this, you don't need to use some Microsoft tool, and it can be automated post-build as a QA measure to make sure nothing funky happens accidentally to disable these measures.
pefile is a multi-platform Python module to read and work with Portable Executable (aka PE) files. Most of the information in the PE Header is accessible, as well as all the sections, section's information and data.
I'm going to continue to tighten up the hardening options and try to reproduce the crashing. I'll also test further with the Microsoft tools mentioned above.
-pie is definitely the culprit. I built two TBBs: one with DEP/ASLR and no -pie and another with DEP/ASLR and -pie. The latter crashes and the former doesn't. I also get the same wrong AddressOfEntryPoint (00001000) in the build with -pie whereas in the non-pie build I get the correct one (000014b0).
It took a little wrangling but I eventually got all of the libs we build building with DEP/ASLR (this is including the Firefox libs). I think we should consider extending that to the libssp we build in mingw-64, but I didn't look into how to do that yet.
I will break it up further before I ask for any real merging, but I wanted to link it here because I won't be able to get to that before Monday and thought people should have a chance to look it over or at least test it if they felt like doing so. This enables DEP/ASLR and SSP on all binaries and DLLs we build. I also built a new libssp and am shipping the bundle with that instead of the MinGW one we were using before.
Issues:
None of the PT stuff is hardened at all. Is this a blocker for getting it into a beta?
skruffy's got two patches in here: one for binutils that creates a proper reloc section so we can have working ASLR, and one for gcc that prevents the use of /dev/urandom on Windows. nickm and zwol have reviewd the gcc (SSP) patch and deemed it okay, but both said someone with more binutils knowledge needs to check the ld patch. For reference they are here:
Only the libssp-0.dll is different (apart from the different tor-browser-bundle commit). I uploaded mine: https://people.torproject.org/~gk/misc/hardened_libssp-0.dll 36f7c2434e0e65ca9b6065c97a42de98992e434d80236e3619140c88ca7dfcdc. I built from commit 17425dec3a13de51b717efeb8bdde1a4460d31fa.
gk -- it turned out to be a one line patch to make libssp build reproducibly. I've updated my branch.
As for next steps, the branch needs to be rebased... I tried it today but it looks quite messy with all the meek changes that have happened in the intervening period. I either need more sleep or to sit with someone and work on fixing the conflicts, because my first glance at it made me worry I might screw it up.
Some issues remain, namely that none of the pluggable transports are hardened. The python dll we're distributing only has DEP and not ASLR. As I understand it, the default options have changed in the distributions of Python 3.x, but it seems like no small task to switch from one to the other. I looked into crosscompiling Python and while it seems possible (in the sense that there is some python-mingw port by some random person on the internet), it also might be quite a time consuming project.
As for the PTs written in Go, I refer to this thread where Russ Cox says:
Address space randomization is an OS-level workaround for a language-level problem, namely that simple C programs tend to be full of exploitable buffer overflows. Go fixes this at the language level, with bounds-checked arrays and slices and no dangling pointers, which makes the OS-level workaround much less important. In return, we receive the incredible debuggability of deterministic address space layout. I would not give that up lightly.
Anyway, feedback welcome. Putting this into needs_review. I should note that skruffy's binutils patch remains mostly unreviewed, and I still need to send it upstream, but if anyone feels like digging into it before I do, I would appreciate it (and so would he).
Edit: And Tom, since you were part of the iSEC review, can you double check that I got the hardening right? I reviewed the binaries with objdump and in procexp and Process Hacker on a Win7 VM but would love a second set of eyes.