Bug 19011 - Issues with ld on mingw-w64 and bad defaults
Summary: Issues with ld on mingw-w64 and bad defaults
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.25
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
Depends on:
Reported: 2015-09-27 16:49 UTC by Alex Smith
Modified: 2020-01-11 13:40 UTC (History)
5 users (show)

See Also:
Last reconfirmed:

Don't strip reloc sections when building with dynamicbase (1.17 KB, patch)
2018-07-25 09:39 UTC, hugo@beauzee.fr
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Alex Smith 2015-09-27 16:49:13 UTC
There are a number of issues that ld has on mingw-w64 (or otherwise targeting mingw-w64).  Most of them stem from the fact that ld's defaults for mingw-w64 targets are terrible and unfortunately most or all of these settings have security implications.  I would like this thread to be a consolidation of any previous threads that may have reported a subset of these issues.

Put simply, for mingw-w64 targets (32 and 64-bit) binutil's ld should do the following:
 - Default to enabling dynamicbase and nxcompat.
 - Never strip the reloc section.
 - Default to enabling HEASLR (high-entropy-va)
 - Use a base address > 4GB for 64-bit binaries.
 - Default to disable-auto-image-base

All of the above will bring binaries created with gcc/ld in line with what's produced by msvc (visual studio/Microsoft's compiler/linker).  Any compatibility issues caused by these changes should be acceptably small and msvc has been defaulting to all of these since they were brought about in VS2008 (yes 2008 for dynamicbase and nxcompat).

Going through the list in a little more detail, dynamicbase and nxcompat is universally safe for mingw-w64 targets (and only mingw-w64 targets on windows) and should cause no compatibility issues at all.  Furthermore if you specify dynamicbase it should automatically cause the linker to output a reloc section (or not strip it or however it works internally).  Otherwise you get weird stuff like this[1] where another option is being invented for the wrong reasons.  There's no reason for this option because ld should never be stripping the reloc section from executables in the first place (or perhaps better logic should be if you specify dynamicbase it should just have the reloc section, no reason to split this into another option).

Defaulting to HEASLR is also a no brainer.  It's ignored on targets which don't support it.  Specifying a base address > 4GB is a compatibility single to the loader that there are no "latent pointer truncation issues" and it can use extra entropy (8 -> 17 bits) for the base address randomization[2].
Executables should have a base address of 0x140000000 and dll's should use 

All of the above ties into my last point of switching the default to --disable-auto-image-base.  Thanks to ASLR there's no reason to be generating random image base's anymore for mingw-w64 binaries.

The above should bring binaries produced with ld in line with what Microsoft's linker uses and is way more sane than what's currently used so we don't have to use a million workarounds in order to get something sane[3][4][5].  [3] is especially hilarious.

[1] https://sourceware.org/bugzilla/show_bug.cgi?id=17321
[2] http://blogs.technet.com/b/srd/archive/2013/12/11/software-defense-mitigating-common-exploitation-techniques.aspx
[3] https://github.com/TheRyuu/FFmpeg/commit/91b668acd6decec0a6f8d20bf56e2644f96adcb9
[4] https://github.com/TheRyuu/FFmpeg/commit/f2b805d02ee12af5593130ef06f0924422e8622e
[5] https://github.com/TheRyuu/FFmpeg/commit/ae4e2e6cc32541ce19a716136995d605a723ac5e
Comment 1 Nick Clifton 2015-09-29 10:59:48 UTC
Hi Alex,

  Is it possible for you to produce a consolidated patch that addresses all of these issues ?

  I am all in favour of these changes unless someone has strenuous objections - and I seriously doubt that anyone will.  But it will make my life easier if I only have one patch to test instead of 5.

Comment 2 Alex Smith 2015-09-29 17:27:49 UTC
I don't mind having a go but I'm unfamiliar with the binutils/ld source so I'll have to figure out where everything is first.

On that note are you (or anyone who might be able to help) on irc?
Comment 3 Nick Clifton 2015-09-30 12:40:48 UTC
Sorry - I am not on IRC, but do feel free to email me direct.

Comment 4 hugo@beauzee.fr 2018-07-25 09:39:19 UTC
Created attachment 11152 [details]
Don't strip reloc sections when building with dynamicbase

This should address the "- Never strip the reloc section." part.
Comment 5 hugo@beauzee.fr 2018-07-25 09:42:31 UTC
The attached patch fixes the IMAGE_FILE_RELOCS_STRIPPED bit to be set in the headers when no symbol is exported, when building with -Wl,--dynamicbase.

Please let me know if some corrections are to be made!

AFAIU I need to explicitly state that I'm ok with the copyright being assigned to the FSF, so I'm ok with it.

Comment 6 hugo@beauzee.fr 2018-07-25 14:59:53 UTC
Well, apparently the attached fixes the header, but makes windows fail to run the resulting executable, so I guess something's missing.

Any help would be appreciated!
Comment 7 Tom Ritter 2018-10-11 15:20:32 UTC
This is a big drive-by, as I don't have much understanding on the details of the problem; but Tor uses the following patch to add a relocation section so Windows builds of Tor Browser can have ASLR: https://gitweb.torproject.org/builders/tor-browser-build.git/tree/projects/binutils/enable-reloc-section-ld.patch
Comment 8 gerald@wireshark.org 2018-10-11 17:16:16 UTC
Googling for "mingw-w64 aslr" turned up a CERT vulnerability note[1] for this issue along with CVE-2018-5392. It wasn't apparent from the VN or the CVE whether or not Sourceware had been notified of the CVE assignment.

[1] https://www.kb.cert.org/vuls/id/307144
Comment 9 Hannes Domani 2020-01-11 13:40:09 UTC
(In reply to Alex Smith from comment #0)
> Furthermore if you specify dynamicbase it should automatically cause the
> linker to output a reloc section (or not strip it or however it works
> internally).

This is now done since https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commit;h=dc9bd8c92af67947db44b3cb428c050259b15cd0.
--enable-reloc-section was implemented, but it is also automatically enabled with -dynamicbase.