cygwin + binutils 2.36 + ASLR/dynamicbase defaults

Jeremy Drake cygwin@jdrake.com
Mon Mar 1 04:16:56 GMT 2021


On Sun, 28 Feb 2021, ASSI wrote:

> > Is this still problematic for cygwin?
>
> Yes it is and I'm currently figuring out how to best get rid of it in
> order to be able to update binutils (why this was ever allowed in
> without an accompanying configure option is a mystery to me).

Well, Microsoft's LINK.EXE and LLVM's LLD have already been using these
new defaults for some time.  But I was surprised how quickly my patch was
accepted/merged.

> I've
> already nixed it for Cygwin, but I'm not yet sure what to do for the
> cross compilation toolchain.  While it should in principle work there,
> I'm pretty sure that there will be problems when it comes to the nitty
> gritty details.  It's already transpired that some of the linker scripts
> can't deal with the larger base addresses this change does generate
> eventually.

To clarify, default base addresses should not have changed for cygwin
targets, they were already above 4GB.

I have a prelimiary patch that I plan to send upstream once I get some
testing done on it, which reverts the default dll characteristics for
cygwin targets.  I don't know if what you've done to 'nix it' for Cygwin
was similar.

I have not seen anything one way or the other on the NXCOMPAT flag.  Does
that also needs to be reverted for Cygwin?

> > The reason I'm asking is because we updated to 2.36 in MSYS2 and are
> > wondering if we need to patch this out (or change the defaults) It
> > seems to work as is right now, but maybe we are just lucky(?).
>
> You are just lucky and need to test more. :-)

I have seen the issues you described on 32-bit, but my understanding of
how ASLR works suggested that it should be very rare on 64-bit.

> Note that the change does not only affect DLL as the commit message
> would want you to believe and you will eventually end up with a
> situation where ASLR tries moves the stack of an executable, at which
> point you can no longer fork.

... but now that you mention the stack moving, yes, I could see that
being an issue.

Yes, the specific field where these flags are stored is called "DLL
Characteristics" so that is how it was referred to, but they do not
exclusively apply to DLLs.

https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#dll-characteristics
-------------- next part --------------
From 39bde2f11a1eb97503bae9cf15f5fc05640e5251 Mon Sep 17 00:00:00 2001
From: Jeremy Drake <sourceware-bugzilla@jdrake.com>
Date: Sun, 28 Feb 2021 15:49:08 -0800
Subject: [PATCH] ld: revert default dll characteristics for Cygwin.

Mail thread from
https://cygwin.com/pipermail/cygwin/2021-February/247922.html suggests
these flags will NOT work for Cygwin, which relies on stable address
layouts for their fork() emulation.

In the process, renamed move_default_addr_high shell variable to
cygwin_beahior, as the old name wasn't quite accurate anymore and I
wanted to use it choose which dll characteristics flags to use by
default.

Also copied that switch to pe.em, as it was only in pep.em before but
32-bit also needed to switch defaults for Cygwin.
---
 ld/emultempl/pe.em  | 13 ++++++++++++-
 ld/emultempl/pep.em | 40 +++++++++++++++++++++-------------------
 2 files changed, 33 insertions(+), 20 deletions(-)

diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em
index 748a6b49412..9f757cc31dc 100644
--- a/ld/emultempl/pe.em
+++ b/ld/emultempl/pe.em
@@ -5,6 +5,16 @@ if [ -z "$MACHINE" ]; then
 else
   OUTPUT_ARCH=${ARCH}:${MACHINE}
 fi
+
+case ${target} in
+  *-*-cygwin*)
+    cygwin_behavior=1
+    ;;
+  *)
+    cygwin_behavior=0;
+    ;;
+esac
+
 rm -f e${EMULATION_NAME}.c
 (echo;echo;echo;echo;echo)>e${EMULATION_NAME}.c # there, now line numbers match ;-)
 fragment <<EOF
@@ -104,7 +114,8 @@ fragment <<EOF
 #define DEFAULT_PSEUDO_RELOC_VERSION 1
 #endif
 
-#define DEFAULT_DLL_CHARACTERISTICS	(IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE \
+#define DEFAULT_DLL_CHARACTERISTICS	(${cygwin_behavior} ? 0 : \
+					   IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE \
 					 | IMAGE_DLL_CHARACTERISTICS_NX_COMPAT)
 
 #if defined(TARGET_IS_i386pe) || ! defined(DLL_SUPPORT)
diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em
index ff49c15c002..69f5bd04655 100644
--- a/ld/emultempl/pep.em
+++ b/ld/emultempl/pep.em
@@ -8,10 +8,10 @@ fi
 
 case ${target} in
   *-*-cygwin*)
-    move_default_addr_high=1
+    cygwin_behavior=1
     ;;
   *)
-    move_default_addr_high=0;
+    cygwin_behavior=0;
     ;;
 esac
 
@@ -99,45 +99,47 @@ fragment <<EOF
 #define DLL_SUPPORT
 #endif
 
-#define DEFAULT_DLL_CHARACTERISTICS	(IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE \
+#define DEFAULT_DLL_CHARACTERISTICS	(${cygwin_behavior} ? 0 : \
+					   IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE \
 					 | IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA \
 					 | IMAGE_DLL_CHARACTERISTICS_NX_COMPAT)
 
+
 #if defined(TARGET_IS_i386pep) || ! defined(DLL_SUPPORT)
 #define	PE_DEF_SUBSYSTEM		3
 #undef NT_EXE_IMAGE_BASE
 #define NT_EXE_IMAGE_BASE \
-  ((bfd_vma) (${move_default_addr_high} ? 0x100400000LL \
-					: 0x140000000LL))
+  ((bfd_vma) (${cygwin_behavior} ? 0x100400000LL \
+				 : 0x140000000LL))
 #undef NT_DLL_IMAGE_BASE
 #define NT_DLL_IMAGE_BASE \
-  ((bfd_vma) (${move_default_addr_high} ? 0x400000000LL \
-					: 0x180000000LL))
+  ((bfd_vma) (${cygwin_behavior} ? 0x400000000LL \
+				 : 0x180000000LL))
 #undef NT_DLL_AUTO_IMAGE_BASE
 #define NT_DLL_AUTO_IMAGE_BASE \
-  ((bfd_vma) (${move_default_addr_high} ? 0x400000000LL \
-					: 0x1C0000000LL))
+  ((bfd_vma) (${cygwin_behavior} ? 0x400000000LL \
+				 : 0x1C0000000LL))
 #undef NT_DLL_AUTO_IMAGE_MASK
 #define NT_DLL_AUTO_IMAGE_MASK \
-  ((bfd_vma) (${move_default_addr_high} ? 0x1ffff0000LL \
-					: 0x1ffff0000LL))
+  ((bfd_vma) (${cygwin_behavior} ? 0x1ffff0000LL \
+				 : 0x1ffff0000LL))
 #else
 #undef  NT_EXE_IMAGE_BASE
 #define NT_EXE_IMAGE_BASE \
-  ((bfd_vma) (${move_default_addr_high} ? 0x100010000LL \
-					: 0x10000LL))
+  ((bfd_vma) (${cygwin_behavior} ? 0x100010000LL \
+				 : 0x10000LL))
 #undef NT_DLL_IMAGE_BASE
 #define NT_DLL_IMAGE_BASE \
-  ((bfd_vma) (${move_default_addr_high} ? 0x110000000LL \
-					: 0x10000000LL))
+  ((bfd_vma) (${cygwin_behavior} ? 0x110000000LL \
+				 : 0x10000000LL))
 #undef NT_DLL_AUTO_IMAGE_BASE
 #define NT_DLL_AUTO_IMAGE_BASE \
-  ((bfd_vma) (${move_default_addr_high} ? 0x120000000LL \
-					: 0x61300000LL))
+  ((bfd_vma) (${cygwin_behavior} ? 0x120000000LL \
+				 : 0x61300000LL))
 #undef NT_DLL_AUTO_IMAGE_MASK
 #define NT_DLL_AUTO_IMAGE_MASK \
-  ((bfd_vma) (${move_default_addr_high} ? 0x0ffff0000LL \
-					: 0x0ffc0000LL))
+  ((bfd_vma) (${cygwin_behavior} ? 0x0ffff0000LL \
+				 : 0x0ffc0000LL))
 #undef  PE_DEF_SECTION_ALIGNMENT
 #define	PE_DEF_SUBSYSTEM		2
 #undef  PE_DEF_FILE_ALIGNMENT
-- 
2.30.1.windows.1



More information about the Cygwin mailing list