[BZ,#17841] : Build failure if compiler defaults to PIE

Message ID 20150528130523.GA16533@gmail.com
State Committed
Headers

Commit Message

H.J. Lu May 28, 2015, 1:05 p.m. UTC
  To support building glibc with GCC 6 configured with --enable-default-pie,
which generates PIE by default, we need to build programs as PIE.  But
elf/tst-dlopen-aout must not be built as PIE since it tests dlopen on
ET_EXEC file and PIE is ET_DYN.

OK for master?

H.J.
---
	[BZ #17841]
	* Makeconfig (no-pie-ldflag): New.
	(+link): Set to $(+link-pie) if default to PIE.
	(+link-tests): Set to $(+link-pie-tests) if default to PIE.
	* config.make.in (build-pie-default): New.
	* configure.ac (libc_cv_pie_default): New.  Set to yes if -fPIE
	is default.  AC_SUBST.
	* configure: Regenerated.
	* elf/Makefile (LDFLAGS-tst-dlopen-aout): New.
---
 Makeconfig     |  6 ++++++
 config.make.in |  1 +
 configure      | 21 +++++++++++++++++++++
 configure.ac   | 13 +++++++++++++
 elf/Makefile   |  1 +
 5 files changed, 42 insertions(+)
  

Comments

Mike Frysinger May 28, 2015, 2:59 p.m. UTC | #1
On 28 May 2015 06:05, H.J. Lu wrote:
> To support building glibc with GCC 6 configured with --enable-default-pie,
> which generates PIE by default, we need to build programs as PIE.  But
> elf/tst-dlopen-aout must not be built as PIE since it tests dlopen on
> ET_EXEC file and PIE is ET_DYN.

i think you're going to need more patches than this to make it work.  Gentoo
has been building glibc this way for years though in our hardened project.
we currently have:
https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=f14f39cfd7b959c806d822a2f6863873151f0a83
https://sources.gentoo.org/sys-libs/glibc/files/2.20/glibc-2.20-hardened-inittls-nosysenter.patch

and also this one (which your patch partially covers):
https://sources.gentoo.org/sys-libs/glibc/files/2.17/glibc-2.17-hardened-pie.patch
although iirc, this one depends on changes in gcc itself related to producing 
pie by default.  it might need tweaking when aligning Gentoo's patches and the 
gcc-6 behavior.

> OK for master?

looks ok to me, but prob want to give time for others to comment
-mike
  
H.J. Lu May 28, 2015, 3:06 p.m. UTC | #2
On Thu, May 28, 2015 at 7:59 AM, Mike Frysinger <vapier@gentoo.org> wrote:
> On 28 May 2015 06:05, H.J. Lu wrote:
>> To support building glibc with GCC 6 configured with --enable-default-pie,
>> which generates PIE by default, we need to build programs as PIE.  But
>> elf/tst-dlopen-aout must not be built as PIE since it tests dlopen on
>> ET_EXEC file and PIE is ET_DYN.
>
> i think you're going to need more patches than this to make it work.  Gentoo

What did you mean by "make it work"? I successfully built glibc with GCC 6
default to PIE and there were no regressions.

> has been building glibc this way for years though in our hardened project.
> we currently have:
> https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=f14f39cfd7b959c806d822a2f6863873151f0a83
> https://sources.gentoo.org/sys-libs/glibc/files/2.20/glibc-2.20-hardened-inittls-nosysenter.patch
>
> and also this one (which your patch partially covers):
> https://sources.gentoo.org/sys-libs/glibc/files/2.17/glibc-2.17-hardened-pie.patch

I don't believe those changes are needed for GCC 6. I do have another
patch to build archives without PIE with GCC default to PIE.  But it
may be useful to have PIE archives so that people can build static
PIE with PIE achieves.

> although iirc, this one depends on changes in gcc itself related to producing
> pie by default.  it might need tweaking when aligning Gentoo's patches and the
> gcc-6 behavior.
>
>> OK for master?
>
> looks ok to me, but prob want to give time for others to comment
> -mike
  
Mike Frysinger May 28, 2015, 3:57 p.m. UTC | #3
On 28 May 2015 08:06, H.J. Lu wrote:
> On Thu, May 28, 2015 at 7:59 AM, Mike Frysinger wrote:
> > On 28 May 2015 06:05, H.J. Lu wrote:
> >> To support building glibc with GCC 6 configured with --enable-default-pie,
> >> which generates PIE by default, we need to build programs as PIE.  But
> >> elf/tst-dlopen-aout must not be built as PIE since it tests dlopen on
> >> ET_EXEC file and PIE is ET_DYN.
> >
> > i think you're going to need more patches than this to make it work.  Gentoo
> 
> What did you mean by "make it work"? I successfully built glibc with GCC 6
> default to PIE and there were no regressions.

did you do it for x86 ?  if you read the nosysenter patch below, it describes in 
detail the problems with x86 and building as PIE.
-mike
  
H.J. Lu May 28, 2015, 4:04 p.m. UTC | #4
On Thu, May 28, 2015 at 8:57 AM, Mike Frysinger <vapier@gentoo.org> wrote:
> On 28 May 2015 08:06, H.J. Lu wrote:
>> On Thu, May 28, 2015 at 7:59 AM, Mike Frysinger wrote:
>> > On 28 May 2015 06:05, H.J. Lu wrote:
>> >> To support building glibc with GCC 6 configured with --enable-default-pie,
>> >> which generates PIE by default, we need to build programs as PIE.  But
>> >> elf/tst-dlopen-aout must not be built as PIE since it tests dlopen on
>> >> ET_EXEC file and PIE is ET_DYN.
>> >
>> > i think you're going to need more patches than this to make it work.  Gentoo
>>
>> What did you mean by "make it work"? I successfully built glibc with GCC 6
>> default to PIE and there were no regressions.
>
> did you do it for x86 ?  if you read the nosysenter patch below, it describes in
> detail the problems with x86 and building as PIE.

That is a separate issue.  I am expecting some targets must be
updated to support PIE as default.
  
H.J. Lu May 29, 2015, 2:59 a.m. UTC | #5
On Thu, May 28, 2015 at 8:57 AM, Mike Frysinger <vapier@gentoo.org> wrote:
> On 28 May 2015 08:06, H.J. Lu wrote:
>> On Thu, May 28, 2015 at 7:59 AM, Mike Frysinger wrote:
>> > On 28 May 2015 06:05, H.J. Lu wrote:
>> >> To support building glibc with GCC 6 configured with --enable-default-pie,
>> >> which generates PIE by default, we need to build programs as PIE.  But
>> >> elf/tst-dlopen-aout must not be built as PIE since it tests dlopen on
>> >> ET_EXEC file and PIE is ET_DYN.
>> >
>> > i think you're going to need more patches than this to make it work.  Gentoo
>>
>> What did you mean by "make it work"? I successfully built glibc with GCC 6
>> default to PIE and there were no regressions.
>
> did you do it for x86 ?  if you read the nosysenter patch below, it describes in
> detail the problems with x86 and building as PIE.

I filed a GCC bug against cleanup block under PIE:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66334
  
Roland McGrath May 29, 2015, 3:29 a.m. UTC | #6
Is there any harm in just using "LDFLAGS-tst-dlopen-aout = -no-pie" without
the conditionalized variable?  Either way, that variable should be further
down in the file, where the details about other individual tests' builds are.

The configure check and the +link/+link-tests hack seem OK to me.
  
H.J. Lu May 29, 2015, 3:46 a.m. UTC | #7
On Thu, May 28, 2015 at 8:29 PM, Roland McGrath <roland@hack.frob.com> wrote:
> Is there any harm in just using "LDFLAGS-tst-dlopen-aout = -no-pie" without

-no-pie is new in GCC 6.  Older GCC doesn't support -no-pie.

> the conditionalized variable?  Either way, that variable should be further
> down in the file, where the details about other individual tests' builds are.
>
> The configure check and the +link/+link-tests hack seem OK to me.
  
Roland McGrath June 5, 2015, 8:41 p.m. UTC | #8
> On Thu, May 28, 2015 at 8:29 PM, Roland McGrath <roland@hack.frob.com> wrote:
> > Is there any harm in just using "LDFLAGS-tst-dlopen-aout = -no-pie" without
> 
> -no-pie is new in GCC 6.  Older GCC doesn't support -no-pie.

OK.
  

Patch

diff --git a/Makeconfig b/Makeconfig
index d32a0fd..831604a 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -442,6 +442,11 @@  endif
 # Commands for linking programs with the C library.
 ifndef +link
 ifeq (yes,$(build-shared))
+ifeq (yes,$(build-pie-default))
+no-pie-ldflag = -no-pie
++link = $(+link-pie)
++link-tests = $(+link-pie-tests)
+else
 +link-before-libc = $(CC) -nostdlib -nostartfiles -o $@ \
 	      $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \
 	      $(combreloc-LDFLAGS) $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \
@@ -462,6 +467,7 @@  $(+link-before-libc) $(rtld-tests-LDFLAGS) $(link-libc-tests) \
 		     $(+link-after-libc)
 $(call after-link,$@)
 endef
+endif
 else
 +link = $(+link-static)
 +link-tests = $(+link-static-tests)
diff --git a/config.make.in b/config.make.in
index 5a18dae..a9f5696 100644
--- a/config.make.in
+++ b/config.make.in
@@ -82,6 +82,7 @@  nss-crypt = @libc_cv_nss_crypt@
 # Configuration options.
 build-shared = @shared@
 build-pic-default= @libc_cv_pic_default@
+build-pie-default= @libc_cv_pie_default@
 build-profile = @profile@
 build-static-nss = @static_nss@
 add-ons = @add_ons@
diff --git a/configure b/configure
index 1e4138b..45cc7cb 100755
--- a/configure
+++ b/configure
@@ -596,6 +596,7 @@  mach_interface_list
 DEFINES
 static_nss
 profile
+libc_cv_pie_default
 libc_cv_pic_default
 shared
 static
@@ -7317,6 +7318,26 @@  fi
 $as_echo "$libc_cv_pic_default" >&6; }
 
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -fPIE is default" >&5
+$as_echo_n "checking whether -fPIE is default... " >&6; }
+if ${libc_cv_pie_default+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  libc_cv_pie_default=yes
+cat > conftest.c <<EOF
+#if defined __PIE__ || defined __pie__ || defined PIE || defined pie
+# error PIE is default.
+#endif
+EOF
+if eval "${CC-cc} -S conftest.c 2>&5 1>&5"; then
+  libc_cv_pie_default=no
+fi
+rm -f conftest.*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_pie_default" >&5
+$as_echo "$libc_cv_pie_default" >&6; }
+
+
 
 
 
diff --git a/configure.ac b/configure.ac
index ff66b87..7e9383a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2075,6 +2075,19 @@  fi
 rm -f conftest.*])
 AC_SUBST(libc_cv_pic_default)
 
+AC_CACHE_CHECK([whether -fPIE is default], libc_cv_pie_default,
+[libc_cv_pie_default=yes
+cat > conftest.c <<EOF
+#if defined __PIE__ || defined __pie__ || defined PIE || defined pie
+# error PIE is default.
+#endif
+EOF
+if eval "${CC-cc} -S conftest.c 2>&AS_MESSAGE_LOG_FD 1>&AS_MESSAGE_LOG_FD"; then
+  libc_cv_pie_default=no
+fi
+rm -f conftest.*])
+AC_SUBST(libc_cv_pie_default)
+
 AC_SUBST(profile)
 AC_SUBST(static_nss)
 
diff --git a/elf/Makefile b/elf/Makefile
index dedf3c7..d4421e9 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -150,6 +150,7 @@  tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
 #	 reldep9
 ifeq ($(build-hardcoded-path-in-tests),yes)
 tests += tst-dlopen-aout
+LDFLAGS-tst-dlopen-aout = $(no-pie-ldflag)
 endif
 test-srcs = tst-pathopt
 selinux-enabled := $(shell cat /selinux/enforce 2> /dev/null)