aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog72
-rw-r--r--INSTALL9
-rw-r--r--Makeconfig38
-rw-r--r--NEWS9
-rw-r--r--config.h.in3
-rwxr-xr-xconfigure79
-rw-r--r--configure.ac29
-rw-r--r--csu/Makefile24
-rw-r--r--csu/libc-start.c2
-rw-r--r--csu/libc-tls.c6
-rw-r--r--csu/static-reloc.c26
-rw-r--r--elf/Makefile7
-rw-r--r--elf/dl-reloc-static-pie.c52
-rw-r--r--elf/dl-support.c11
-rw-r--r--elf/dynamic-link.h2
-rw-r--r--elf/get-dynamic-info.h6
-rw-r--r--gmon/Makefile25
-rw-r--r--gmon/tst-gmon-static-pie.c1
-rw-r--r--manual/install.texi9
-rw-r--r--sysdeps/generic/ldsodefs.h11
-rw-r--r--sysdeps/i386/configure33
-rw-r--r--sysdeps/i386/configure.ac23
-rw-r--r--sysdeps/mips/Makefile3
-rw-r--r--sysdeps/x86_64/configure33
-rw-r--r--sysdeps/x86_64/configure.ac25
25 files changed, 521 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index 852043e521..e9f203fd37 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,75 @@
+2017-12-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ [BZ #19574]
+ * INSTALL: Regenerated.
+ * Makeconfig (real-static-start-installed-name): New.
+ (pic-default): Updated for --enable-static-pie.
+ (pie-default): New for --enable-static-pie.
+ (default-pie-ldflag): Likewise.
+ (+link-static-before-libc): Replace $(DEFAULT-LDFLAGS-$(@F))
+ with $(if $($(@F)-no-pie),$(no-pie-ldflag),$(default-pie-ldflag)).
+ Replace $(static-start-installed-name) with
+ $(real-static-start-installed-name).
+ (+prectorT): Updated for --enable-static-pie.
+ (+postctorT): Likewise.
+ (CFLAGS-.o): Add $(pie-default).
+ (CFLAGS-.op): Likewise.
+ * NEWS: Mention --enable-static-pie.
+ * config.h.in (ENABLE_STATIC_PIE): New.
+ * configure.ac (--enable-static-pie): New configure option.
+ (have-no-dynamic-linker): New LIBC_CONFIG_VAR.
+ (have-static-pie): Likewise.
+ Enable static PIE if linker supports --no-dynamic-linker.
+ (ENABLE_STATIC_PIE): New AC_DEFINE.
+ (enable-static-pie): New LIBC_CONFIG_VAR.
+ * configure: Regenerated.
+ * csu/Makefile (omit-deps): Add r$(start-installed-name) and
+ gr$(start-installed-name) for --enable-static-pie.
+ (extra-objs): Likewise.
+ (install-lib): Likewise.
+ (extra-objs): Add static-reloc.o and static-reloc.os
+ ($(objpfx)$(start-installed-name)): Also depend on
+ $(objpfx)static-reloc.o.
+ ($(objpfx)r$(start-installed-name)): New.
+ ($(objpfx)g$(start-installed-name)): Also depend on
+ $(objpfx)static-reloc.os.
+ ($(objpfx)gr$(start-installed-name)): New.
+ * csu/libc-start.c (LIBC_START_MAIN): Call _dl_relocate_static_pie
+ in libc.a.
+ * csu/libc-tls.c (__libc_setup_tls): Add main_map->l_addr to
+ initimage.
+ * csu/static-reloc.c: New file.
+ * elf/Makefile (routines): Add dl-reloc-static-pie.
+ (elide-routines.os): Likewise.
+ (DEFAULT-LDFLAGS-tst-tls1-static-non-pie): Removed.
+ (tst-tls1-static-non-pie-no-pie): New.
+ * elf/dl-reloc-static-pie.c: New file.
+ * elf/dl-support.c (_dl_get_dl_main_map): New function.
+ * elf/dynamic-link.h (ELF_DURING_STARTUP): Also check
+ STATIC_PIE_BOOTSTRAP.
+ * elf/get-dynamic-info.h (elf_get_dynamic_info): Likewise.
+ * gmon/Makefile (tests): Add tst-gmon-static-pie.
+ (tests-static): Likewise.
+ (DEFAULT-LDFLAGS-tst-gmon-static): Removed.
+ (tst-gmon-static-no-pie): New.
+ (CFLAGS-tst-gmon-static-pie.c): Likewise.
+ (CRT-tst-gmon-static-pie): Likewise.
+ (tst-gmon-static-pie-ENV): Likewise.
+ (tests-special): Likewise.
+ ($(objpfx)tst-gmon-static-pie.out): Likewise.
+ (clean-tst-gmon-static-pie-data): Likewise.
+ ($(objpfx)tst-gmon-static-pie-gprof.out): Likewise.
+ * gmon/tst-gmon-static-pie.c: New file.
+ * manual/install.texi: Document --enable-static-pie.
+ * sysdeps/generic/ldsodefs.h (_dl_relocate_static_pie): New.
+ (_dl_get_dl_main_map): Likewise.
+ * sysdeps/i386/configure.ac: Check if linker supports static PIE.
+ * sysdeps/x86_64/configure.ac: Likewise.
+ * sysdeps/i386/configure: Regenerated.
+ * sysdeps/x86_64/configure: Likewise.
+ * sysdeps/mips/Makefile (ASFLAGS-.o): Add $(pie-default).
+ (ASFLAGS-.op): Likewise.
+
2017-12-15 Joseph Myers <joseph@codesourcery.com>
* io/Makefile (tst-open-tmpfile-ARGS): New variable.
diff --git a/INSTALL b/INSTALL
index 80306de35c..9a1404bd3c 100644
--- a/INSTALL
+++ b/INSTALL
@@ -86,6 +86,15 @@ will be used, and CFLAGS sets optimization options for the compiler.
systems support shared libraries; you need ELF support and
(currently) the GNU linker.
+'--enable-static-pie'
+ Enable static position independent executable (static PIE) support.
+ Static PIE is similar to static executable, but can be loaded at
+ any address without help from a dynamic linker. All static
+ programs as well as static tests are built as static PIE, except
+ for those marked with no-pie. The resulting glibc can be used with
+ the GCC option, -static-pie, which is available with GCC 8 or
+ above, to create static PIE.
+
'--disable-profile'
Don't build libraries with profiling information. You may want to
use this option if you don't plan to do profiling.
diff --git a/Makeconfig b/Makeconfig
index 1346109ac0..99cc136bfa 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -352,6 +352,14 @@ ifndef static-start-installed-name
static-start-installed-name = $(start-installed-name)
endif
+ifeq (yes,$(enable-static-pie))
+# Link with rcrt1.o, instead of crt1.o, to call _dl_relocate_static_pie
+# to relocate static PIE.
+real-static-start-installed-name = r$(static-start-installed-name)
+else
+real-static-start-installed-name = $(static-start-installed-name)
+endif
+
ifeq (yesyes,$(build-shared)$(have-z-combreloc))
combreloc-LDFLAGS = -Wl,-z,combreloc
LDFLAGS.so += $(combreloc-LDFLAGS)
@@ -371,6 +379,20 @@ LDFLAGS.so += $(hashstyle-LDFLAGS)
LDFLAGS-rtld += $(hashstyle-LDFLAGS)
endif
+ifeq (yes,$(enable-static-pie))
+pic-default = -DPIC
+# Compile libc.a and libc_p.a with -fPIE/-fpie for static PIE.
+pie-default = $(pie-ccflag)
+ifeq (yes,$(have-static-pie))
+default-pie-ldflag = -static-pie
+else
+# Static PIE can't have dynamic relocations in read-only segments since
+# static PIE is mapped into memory by kernel. --eh-frame-hdr is needed
+# for PIE to support exception.
+default-pie-ldflag = -Wl,-pie,--no-dynamic-linker,--eh-frame-hdr,-z,text
+endif
+endif
+
# If lazy relocations are disabled, add the -z now flag. Use
# LDFLAGS-lib.so instead of LDFLAGS.so, to avoid adding the flag to
# test modules.
@@ -420,9 +442,9 @@ endif
# Command for statically linking programs with the C library.
ifndef +link-static
+link-static-before-libc = $(CC) -nostdlib -nostartfiles -static -o $@ \
- $(DEFAULT-LDFLAGS-$(@F)) \
+ $(if $($(@F)-no-pie),$(no-pie-ldflag),$(default-pie-ldflag)) \
$(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \
- $(firstword $(CRT-$(@F)) $(csu-objpfx)$(static-start-installed-name)) \
+ $(firstword $(CRT-$(@F)) $(csu-objpfx)$(real-static-start-installed-name)) \
$(+preinit) $(+prectorT) \
$(filter-out $(addprefix $(csu-objpfx),start.o \
$(start-installed-name))\
@@ -637,8 +659,14 @@ endif
+prectorS = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtbeginS.o`
+postctorS = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtendS.o`
# Variants of the two previous definitions for statically linking programs.
+ifeq (yes,$(enable-static-pie))
+# Static PIE must use PIE variants.
++prectorT = $(+prectorS)
++postctorT = $(+postctorS)
+else
+prectorT = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtbeginT.o`
+postctorT = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtend.o`
+endif
csu-objpfx = $(common-objpfx)csu/
elf-objpfx = $(common-objpfx)elf/
@@ -959,7 +987,8 @@ libtypes = $(foreach o,$(object-suffixes-for-libc),$(libtype$o))
all-object-suffixes := .o .os .oS
object-suffixes :=
CPPFLAGS-.o = $(pic-default)
-CFLAGS-.o = $(filter %frame-pointer,$(+cflags))
+# libc.a must be compiled with -fPIE/-fpie for static PIE.
+CFLAGS-.o = $(filter %frame-pointer,$(+cflags)) $(pie-default)
libtype.o := lib%.a
object-suffixes += .o
ifeq (yes,$(build-shared))
@@ -984,7 +1013,8 @@ ifeq (yes,$(build-profile))
all-object-suffixes += .op
object-suffixes += .op
CPPFLAGS-.op = -DPROF $(pic-default)
-CFLAGS-.op = -pg
+# libc_p.a must be compiled with -fPIE/-fpie for static PIE.
+CFLAGS-.op = -pg $(pie-default)
libtype.op = lib%_p.a
endif
diff --git a/NEWS b/NEWS
index c5607c855f..61fed654d8 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,15 @@ Version 2.27
Major new features:
+* The GNU C Library can now be compiled with support for building static
+ PIE executables (See --enable-static-pie in INSTALL). These static PIE
+ exectuables are like static executables but can be loaded at any address
+ and provide additional security hardening benefits at the cost of some
+ memory and performance. When the library is built with --enable-static-pie
+ the resulting libc.a is usable with GCC 8 and above to create static PIE
+ executables using the GCC option '-static-pie'. This feature is currently
+ supported on i386, x86_64 and x32.
+
* Optimized x86-64 asin, atan2, exp, expf, log, pow, atan, sin, cosf,
sinf and tan with FMA, contributed by Arjan van de Ven and H.J. Lu
from Intel.
diff --git a/config.h.in b/config.h.in
index 3c91d597ff..d928e7dd86 100644
--- a/config.h.in
+++ b/config.h.in
@@ -238,6 +238,9 @@
/* Build glibc with tunables support. */
#define HAVE_TUNABLES 0
+/* Define if static PIE is enabled. */
+#define ENABLE_STATIC_PIE 0
+
/* Some compiler options may now allow to use ebp in __asm__ (used mainly
in i386 6 argument syscall issue). */
#define CAN_USE_REGISTER_ASM_EBP 0
diff --git a/configure b/configure
index 4a85706862..9da9fb2736 100755
--- a/configure
+++ b/configure
@@ -763,6 +763,7 @@ with_default_link
enable_sanity_checks
enable_shared
enable_profile
+enable_static_pie
enable_timezone_tools
enable_hardcoded_path_in_tests
enable_stackguard_randomization
@@ -1417,6 +1418,8 @@ Optional Features:
in special situations) [default=yes]
--enable-shared build shared library [default=yes if GNU ld]
--enable-profile build profiled library [default=no]
+ --enable-static-pie enable static PIE support and use it in the
+ testsuite [default=no]
--disable-timezone-tools
do not install timezone tools [default=install]
--enable-hardcoded-path-in-tests
@@ -3350,6 +3353,13 @@ else
profile=no
fi
+# Check whether --enable-static-pie was given.
+if test "${enable_static_pie+set}" = set; then :
+ enableval=$enable_static_pie; static_pie=$enableval
+else
+ static_pie=no
+fi
+
# Check whether --enable-timezone-tools was given.
if test "${enable_timezone_tools+set}" = set; then :
enableval=$enable_timezone_tools; enable_timezone_tools=$enableval
@@ -5806,6 +5816,62 @@ fi
$as_echo "$libc_linker_feature" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for linker that supports --no-dynamic-linker" >&5
+$as_echo_n "checking for linker that supports --no-dynamic-linker... " >&6; }
+libc_linker_feature=no
+if test x"$gnu_ld" = x"yes"; then
+ libc_linker_check=`$LD -v --help 2>/dev/null | grep "\--no-dynamic-linker"`
+ if test -n "$libc_linker_check"; then
+ cat > conftest.c <<EOF
+int _start (void) { return 42; }
+EOF
+ if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp
+ -Wl,--no-dynamic-linker -nostdlib -nostartfiles
+ -fPIC -shared -o conftest.so conftest.c
+ 1>&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }
+ then
+ libc_linker_feature=yes
+ fi
+ rm -f conftest*
+ fi
+fi
+if test $libc_linker_feature = yes; then
+ libc_cv_no_dynamic_linker=yes
+else
+ libc_cv_no_dynamic_linker=no
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_linker_feature" >&5
+$as_echo "$libc_linker_feature" >&6; }
+config_vars="$config_vars
+have-no-dynamic-linker = $libc_cv_no_dynamic_linker"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -static-pie" >&5
+$as_echo_n "checking for -static-pie... " >&6; }
+if ${libc_cv_static_pie+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if { ac_try='${CC-cc} -static-pie -xc /dev/null -S -o /dev/null'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :
+ libc_cv_static_pie=yes
+else
+ libc_cv_static_pie=no
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_static_pie" >&5
+$as_echo "$libc_cv_static_pie" >&6; }
+config_vars="$config_vars
+have-static-pie = $libc_cv_static_pie"
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fpie" >&5
$as_echo_n "checking for -fpie... " >&6; }
if ${libc_cv_fpie+:} false; then :
@@ -6705,6 +6771,19 @@ $as_echo "$libc_cv_pie_default" >&6; }
libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory`
+if test "$static_pie" = yes; then
+ # The linker must support --no-dynamic-linker.
+ if test "$libc_cv_no_dynamic_linker" != yes; then
+ as_fn_error $? "linker support for --no-dynamic-linker needed" "$LINENO" 5
+ fi
+ # Default to PIE.
+ libc_cv_pie_default=yes
+ $as_echo "#define ENABLE_STATIC_PIE 1" >>confdefs.h
+
+fi
+config_vars="$config_vars
+enable-static-pie = $static_pie"
+
diff --git a/configure.ac b/configure.ac
index edf662715b..8e4006f0a9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -170,6 +170,11 @@ AC_ARG_ENABLE([profile],
[build profiled library @<:@default=no@:>@]),
[profile=$enableval],
[profile=no])
+AC_ARG_ENABLE([static-pie],
+ AC_HELP_STRING([--enable-static-pie],
+ [enable static PIE support and use it in the testsuite @<:@default=no@:>@]),
+ [static_pie=$enableval],
+ [static_pie=no])
AC_ARG_ENABLE([timezone-tools],
AC_HELP_STRING([--disable-timezone-tools],
[do not install timezone tools @<:@default=install@:>@]),
@@ -1287,6 +1292,19 @@ LIBC_LINKER_FEATURE([-z execstack], [-Wl,-z,execstack],
[libc_cv_z_execstack=yes], [libc_cv_z_execstack=no])
AC_SUBST(libc_cv_z_execstack)
+LIBC_LINKER_FEATURE([--no-dynamic-linker],
+ [-Wl,--no-dynamic-linker],
+ [libc_cv_no_dynamic_linker=yes],
+ [libc_cv_no_dynamic_linker=no])
+LIBC_CONFIG_VAR([have-no-dynamic-linker], [$libc_cv_no_dynamic_linker])
+
+AC_CACHE_CHECK(for -static-pie, libc_cv_static_pie, [dnl
+LIBC_TRY_CC_OPTION([-static-pie],
+ [libc_cv_static_pie=yes],
+ [libc_cv_static_pie=no])
+])
+LIBC_CONFIG_VAR([have-static-pie], [$libc_cv_static_pie])
+
AC_CACHE_CHECK(for -fpie, libc_cv_fpie, [dnl
LIBC_TRY_CC_OPTION([-fpie], [libc_cv_fpie=yes], [libc_cv_fpie=no])
])
@@ -1794,6 +1812,17 @@ AC_SUBST(libc_cv_pie_default)
libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory`
AC_SUBST(libc_cv_multidir)
+if test "$static_pie" = yes; then
+ # The linker must support --no-dynamic-linker.
+ if test "$libc_cv_no_dynamic_linker" != yes; then
+ AC_MSG_ERROR([linker support for --no-dynamic-linker needed])
+ fi
+ # Default to PIE.
+ libc_cv_pie_default=yes
+ AC_DEFINE(ENABLE_STATIC_PIE)
+fi
+LIBC_CONFIG_VAR([enable-static-pie], [$static_pie])
+
AC_SUBST(profile)
AC_SUBST(static_nss)
diff --git a/csu/Makefile b/csu/Makefile
index e42a32b3eb..86b95a9759 100644
--- a/csu/Makefile
+++ b/csu/Makefile
@@ -37,7 +37,9 @@ extra-objs = start.o \
S$(start-installed-name)
omit-deps = $(patsubst %.o,%,$(start-installed-name) g$(start-installed-name) \
b$(start-installed-name) $(csu-dummies) \
- S$(start-installed-name))
+ S$(start-installed-name) \
+ r$(start-installed-name) \
+ gr$(start-installed-name))
install-lib = $(start-installed-name) g$(start-installed-name) $(csu-dummies)
# No tests are allowed in the csu/ subdirectory because the startup
@@ -60,10 +62,17 @@ extra-objs += gmon-start.o
endif
ifneq ($(start-installed-name),$(static-start-installed-name))
+# FIXME: Only Hurd defines static-start-installed-name. Hurd needs to
+# provide special rules to support static PIE.
extra-objs += $(static-start-installed-name) g$(static-start-installed-name)
omit-deps += $(patsubst %.o,%,$(static-start-installed-name) \
g$(static-start-installed-name))
install-lib += $(static-start-installed-name) g$(static-start-installed-name)
+else
+ifeq (yes,$(enable-static-pie))
+extra-objs += r$(start-installed-name) gr$(start-installed-name)
+install-lib += r$(start-installed-name) gr$(start-installed-name)
+endif
endif
before-compile += $(objpfx)abi-tag.h
@@ -82,7 +91,10 @@ multilib-extra-objs = $(addprefix $(multidir)/, $(install-lib))
extra-objs += $(multilib-extra-objs)
endif
-extra-objs += abi-note.o init.o
+extra-objs += abi-note.o init.o static-reloc.o
+ifeq (yes,$(build-shared))
+extra-objs += static-reloc.os
+endif
asm-CPPFLAGS += -I$(objpfx).
# Enable unwinding so backtrace unwinds to __libc_start_main
@@ -101,6 +113,9 @@ ifndef start-installed-name-rule
# We link the ELF startfile along with a SHT_NOTE section indicating
# the kernel ABI the binaries linked with this library will require.
$(objpfx)$(start-installed-name): $(objpfx)start.o $(objpfx)abi-note.o \
+ $(objpfx)init.o $(objpfx)static-reloc.o
+ $(link-relocatable)
+$(objpfx)r$(start-installed-name): $(objpfx)start.o $(objpfx)abi-note.o \
$(objpfx)init.o
$(link-relocatable)
$(objpfx)S$(start-installed-name): $(objpfx)start.os $(objpfx)abi-note.o \
@@ -113,7 +128,10 @@ endif
# to turn on profiling code at startup.
ifeq (yes,$(build-shared))
$(objpfx)g$(start-installed-name): \
- $(objpfx)g%: $(objpfx)S% $(objpfx)gmon-start.os
+ $(objpfx)g%: $(objpfx)S% $(objpfx)gmon-start.os $(objpfx)static-reloc.os
+ $(link-relocatable)
+$(objpfx)gr$(start-installed-name): \
+ $(objpfx)gr%: $(objpfx)r% $(objpfx)gmon-start.o
$(link-relocatable)
ifneq ($(start-installed-name),$(static-start-installed-name))
$(objpfx)g$(static-start-installed-name): \
diff --git a/csu/libc-start.c b/csu/libc-start.c
index 24c63be02f..34dd125260 100644
--- a/csu/libc-start.c
+++ b/csu/libc-start.c
@@ -141,6 +141,8 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
__libc_multiple_libcs = &_dl_starting_up && !_dl_starting_up;
#ifndef SHARED
+ _dl_relocate_static_pie ();
+
char **ev = &argv[argc + 1];
__environ = ev;
diff --git a/csu/libc-tls.c b/csu/libc-tls.c
index 00138eb43a..1f8ddaf543 100644
--- a/csu/libc-tls.c
+++ b/csu/libc-tls.c
@@ -114,6 +114,8 @@ __libc_setup_tls (void)
size_t tcb_offset;
const ElfW(Phdr) *phdr;
+ struct link_map *main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
+
/* Look through the TLS segment if there is any. */
if (_dl_phdr != NULL)