public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Nix <nix@esperi.org.uk>
To: libc-alpha@sourceware.org
Cc: fweimer@redhat.com
Subject: [PATCH 03/15] Do not stack-protect ifunc resolvers.
Date: Mon, 19 Dec 2016 11:27:00 -0000	[thread overview]
Message-ID: <20161219111528.14969-4-nix@esperi.org.uk> (raw)
In-Reply-To: <20161219111528.14969-1-nix@esperi.org.uk>

From: Nick Alcock <nick.alcock@oracle.com>

When dynamically linking, ifunc resolvers are called before TLS is
initialized, so they cannot be safely stack-protected.

We avoid disabling stack-protection on large numbers of files by
using __attribute__ ((__optimize__ ("-fno-stack-protector")))
to turn it off just for the resolvers themselves.  (We provide
the attribute even when statically linking, because we will later
use it elsewhere too.)

v4: New.
v5: Comment fix.
v6: Don't check for __attribute__((__optimize__)).
v7: Tiny context adjustments for revisions in earlier patches.
v9: Rebase atop new ifunc_resolver work.
v10: Spacing change in comment.

	* config.h.in (HAVE_CC_NO_STACK_PROTECTOR): New macro.
	* include/libc-symbols.h (inhibit_stack_protector): New macro.
	(__ifunc_resolver): Use it.
	* elf/ifuncdep2.c (foo1_ifunc): Add inhibit_stack_protector.
	(foo2_ifunc): Likewise.
	(foo3_ifunc): Likewise.
	* elf/ifuncmain6pie.c (foo_ifunc): Likewise.
	* elf/ifuncmain7.c (foo_ifunc): Likewise.
	* elf/ifuncmod1.c (foo_ifunc): Likewise.
	(foo_hidden_ifunc): Likewise.
	(foo_protected_ifunc): Likewise.
	* elf/ifuncmod5.c (foo_ifunc): Likewise.
	(foo_hidden_ifunc): Likewise.
	(foo_protected_ifunc): Likewise.
	* sysdeps/x86_64/ifuncmod8.c (foo_ifunc): Likewise.
	* sysdeps/generic/ifunc-sel.h (ifunc_sel): Likewise.
	(ifunc_one): Likewise.
	* sysdeps/nacl/nacl_interface_query.c [SHARED]
	(nacl_interface_query_ifunc): Likewise.
	* sysdeps/powerpc/ifunc-sel.h (ifunc_sel): Likewise.
	(ifunc_one): Likewise.
	* sysdeps/unix/make-syscalls.sh: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
	(gettimeofday_ifunc): Likewise.
	* sysdeps/unix/sysv/linux/x86/gettimeofday.c (gettimeofday_ifunc):
	Likewise.
	* sysdeps/unix/sysv/linux/x86_64/x32/getcpu.c (getcpu_ifunc):
	Likewise.
---
 config.h.in                                    |  4 ++++
 configure.ac                                   |  1 +
 elf/ifuncdep2.c                                |  3 +++
 elf/ifuncmain6pie.c                            |  1 +
 elf/ifuncmain7.c                               |  1 +
 elf/ifuncmod1.c                                |  3 +++
 elf/ifuncmod5.c                                |  3 +++
 include/libc-symbols.h                         | 12 +++++++++++-
 sysdeps/generic/ifunc-sel.h                    |  2 ++
 sysdeps/nacl/nacl_interface_query.c            |  1 +
 sysdeps/powerpc/ifunc-sel.h                    |  2 ++
 sysdeps/unix/make-syscalls.sh                  |  1 +
 sysdeps/unix/sysv/linux/powerpc/gettimeofday.c |  1 +
 sysdeps/unix/sysv/linux/x86/gettimeofday.c     |  1 +
 sysdeps/unix/sysv/linux/x86_64/x32/getcpu.c    |  1 +
 sysdeps/x86_64/ifuncmod8.c                     |  1 +
 16 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/config.h.in b/config.h.in
index d96ce0f..82f95a6 100644
--- a/config.h.in
+++ b/config.h.in
@@ -48,6 +48,10 @@
 /* Define if compiler accepts -ftree-loop-distribute-patterns.  */
 #undef  HAVE_CC_INHIBIT_LOOP_TO_LIBCALL
 
+/* Define if compiler accepts -fno-stack-protector in an
+   __attribute__ ((__optimize__)).  */
+#undef	HAVE_CC_NO_STACK_PROTECTOR
+
 /* The level of stack protection in use for glibc as a whole.
    May be overridden on a file-by-file basis.  */
 #ifndef STACK_PROTECTOR_LEVEL
diff --git a/configure.ac b/configure.ac
index f131e97..2b58aa7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -639,6 +639,7 @@ stack_protector=
 no_stack_protector=
 if test "$libc_cv_ssp" = yes; then
   no_stack_protector="-fno-stack-protector -DSTACK_PROTECTOR_LEVEL=0"
+  AC_DEFINE(HAVE_CC_NO_STACK_PROTECTOR)
 fi
 
 if test "$enable_stack_protector" = yes && test "$libc_cv_ssp" = yes; then
diff --git a/elf/ifuncdep2.c b/elf/ifuncdep2.c
index 6e66d31..d87d61d 100644
--- a/elf/ifuncdep2.c
+++ b/elf/ifuncdep2.c
@@ -32,6 +32,7 @@ void * foo1_ifunc (void) __asm__ ("foo1");
 __asm__(".type foo1, %gnu_indirect_function");
 
 void *
+inhibit_stack_protector
 foo1_ifunc (void)
 {
   return ifunc_sel (one, minus_one, zero);
@@ -41,6 +42,7 @@ void * foo2_ifunc (void) __asm__ ("foo2");
 __asm__(".type foo2, %gnu_indirect_function");
 
 void *
+inhibit_stack_protector
 foo2_ifunc (void)
 {
   return ifunc_sel (minus_one, one, zero);
@@ -50,6 +52,7 @@ void * foo3_ifunc (void) __asm__ ("foo3");
 __asm__(".type foo3, %gnu_indirect_function");
 
 void *
+inhibit_stack_protector
 foo3_ifunc (void)
 {
   return ifunc_sel (one, zero, minus_one);
diff --git a/elf/ifuncmain6pie.c b/elf/ifuncmain6pie.c
index 8478d4c..04faeb8 100644
--- a/elf/ifuncmain6pie.c
+++ b/elf/ifuncmain6pie.c
@@ -21,6 +21,7 @@ void * foo_ifunc (void) __asm__ ("foo");
 __asm__(".type foo, %gnu_indirect_function");
 
 void *
+inhibit_stack_protector
 foo_ifunc (void)
 {
   return ifunc_one (one);
diff --git a/elf/ifuncmain7.c b/elf/ifuncmain7.c
index 617a596..1e8f7ea 100644
--- a/elf/ifuncmain7.c
+++ b/elf/ifuncmain7.c
@@ -20,6 +20,7 @@ __asm__(".type foo, %gnu_indirect_function");
 
 static void *
 __attribute__ ((used))
+inhibit_stack_protector
 foo_ifunc (void)
 {
   return ifunc_one (one);
diff --git a/elf/ifuncmod1.c b/elf/ifuncmod1.c
index 0b61380..f0bf5fb 100644
--- a/elf/ifuncmod1.c
+++ b/elf/ifuncmod1.c
@@ -36,6 +36,7 @@ void * foo_ifunc (void) __asm__ ("foo");
 __asm__(".type foo, %gnu_indirect_function");
 
 void *
+inhibit_stack_protector
 foo_ifunc (void)
 {
   return ifunc_sel (one, minus_one, zero);
@@ -45,6 +46,7 @@ void * foo_hidden_ifunc (void) __asm__ ("foo_hidden");
 __asm__(".type foo_hidden, %gnu_indirect_function");
 
 void *
+inhibit_stack_protector
 foo_hidden_ifunc (void)
 {
   return ifunc_sel (minus_one, one, zero);
@@ -54,6 +56,7 @@ void * foo_protected_ifunc (void) __asm__ ("foo_protected");
 __asm__(".type foo_protected, %gnu_indirect_function");
 
 void *
+inhibit_stack_protector
 foo_protected_ifunc (void)
 {
   return ifunc_sel (one, zero, minus_one);
diff --git a/elf/ifuncmod5.c b/elf/ifuncmod5.c
index 0e65a63..5a95780 100644
--- a/elf/ifuncmod5.c
+++ b/elf/ifuncmod5.c
@@ -31,6 +31,7 @@ void * foo_ifunc (void) __asm__ ("foo");
 __asm__(".type foo, %gnu_indirect_function");
 
 void *
+inhibit_stack_protector
 foo_ifunc (void)
 {
   return ifunc_sel (one, minus_one, zero);
@@ -40,6 +41,7 @@ void * foo_hidden_ifunc (void) __asm__ ("foo_hidden");
 __asm__(".type foo_hidden, %gnu_indirect_function");
 
 void *
+inhibit_stack_protector
 foo_hidden_ifunc (void)
 {
   return ifunc_sel (minus_one, one, zero);
@@ -49,6 +51,7 @@ void * foo_protected_ifunc (void) __asm__ ("foo_protected");
 __asm__(".type foo_protected, %gnu_indirect_function");
 
 void *
+inhibit_stack_protector
 foo_protected_ifunc (void)
 {
   return ifunc_sel (one, zero, minus_one);
diff --git a/include/libc-symbols.h b/include/libc-symbols.h
index 1c91f2e..d2f3d3a 100644
--- a/include/libc-symbols.h
+++ b/include/libc-symbols.h
@@ -338,6 +338,16 @@ for linking")
 
 #define attribute_relro __attribute__ ((section (".data.rel.ro")))
 
+
+/* Used to disable stack protection in sensitive places, like ifunc
+   resolvers and early static TLS init.  */
+#ifdef HAVE_CC_NO_STACK_PROTECTOR
+# define inhibit_stack_protector \
+    __attribute__ ((__optimize__ ("-fno-stack-protector")))
+#else
+# define inhibit_stack_protector
+#endif
+
 /* The following macros are used for PLT bypassing within libc.so
    (and if needed other libraries similarly).
    First of all, you need to have the function prototyped somewhere,
@@ -739,7 +749,7 @@ for linking")
 
 /* Helper / base  macros for indirect function symbols.  */
 #define __ifunc_resolver(type_name, name, expr, arg, init, classifier)	\
-  classifier void *name##_ifunc (arg)					\
+  classifier inhibit_stack_protector void *name##_ifunc (arg)					\
   {									\
     init ();								\
     __typeof (type_name) *res = expr;					\
diff --git a/sysdeps/generic/ifunc-sel.h b/sysdeps/generic/ifunc-sel.h
index 6a27b69..1fff405 100644
--- a/sysdeps/generic/ifunc-sel.h
+++ b/sysdeps/generic/ifunc-sel.h
@@ -5,6 +5,7 @@
 extern int global;
 
 static inline void *
+inhibit_stack_protector
 ifunc_sel (int (*f1) (void), int (*f2) (void), int (*f3) (void))
 {
  switch (global)
@@ -19,6 +20,7 @@ ifunc_sel (int (*f1) (void), int (*f2) (void), int (*f3) (void))
 }
 
 static inline void *
+inhibit_stack_protector
 ifunc_one (int (*f1) (void))
 {
   return f1;
diff --git a/sysdeps/nacl/nacl_interface_query.c b/sysdeps/nacl/nacl_interface_query.c
index adf1dd4..dbaa88b 100644
--- a/sysdeps/nacl/nacl_interface_query.c
+++ b/sysdeps/nacl/nacl_interface_query.c
@@ -29,6 +29,7 @@ extern TYPE_nacl_irt_query nacl_interface_query_ifunc (void)
   asm ("nacl_interface_query");
 
 TYPE_nacl_irt_query
+inhibit_stack_protector
 nacl_interface_query_ifunc (void)
 {
   return &__nacl_irt_query;
diff --git a/sysdeps/powerpc/ifunc-sel.h b/sysdeps/powerpc/ifunc-sel.h
index ac589bd..bdb00bf 100644
--- a/sysdeps/powerpc/ifunc-sel.h
+++ b/sysdeps/powerpc/ifunc-sel.h
@@ -5,6 +5,7 @@
 extern int global;
 
 static inline void *
+inhibit_stack_protector
 ifunc_sel (int (*f1) (void), int (*f2) (void), int (*f3) (void))
 {
   register void *ret __asm__ ("r3");
@@ -32,6 +33,7 @@ ifunc_sel (int (*f1) (void), int (*f2) (void), int (*f3) (void))
 }
 
 static inline void *
+inhibit_stack_protector
 ifunc_one (int (*f1) (void))
 {
   register void *ret __asm__ ("r3");
diff --git a/sysdeps/unix/make-syscalls.sh b/sysdeps/unix/make-syscalls.sh
index 58d165e..123553c 100644
--- a/sysdeps/unix/make-syscalls.sh
+++ b/sysdeps/unix/make-syscalls.sh
@@ -287,6 +287,7 @@ while read file srcfile caller syscall args strong weak; do
 	(echo '#include <dl-vdso.h>'; \\
 	 echo 'extern void *${strong}_ifunc (void) __asm ("${strong}");'; \\
 	 echo 'void *'; \\
+	 echo 'inhibit_stack_protector'; \\
 	 echo '${strong}_ifunc (void)'; \\
 	 echo '{'; \\
 	 echo '  PREPARE_VERSION_KNOWN (symver, ${vdso_symver});'; \\
diff --git a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
index 16c00d7..46608ee 100644
--- a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
@@ -33,6 +33,7 @@
 #  undef __gettimeofday
 
 int
+inhibit_stack_protector
 __gettimeofday_vsyscall (struct timeval *tv, struct timezone *tz)
 {
   return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
diff --git a/sysdeps/unix/sysv/linux/x86/gettimeofday.c b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
index c82452f..a419c4d 100644
--- a/sysdeps/unix/sysv/linux/x86/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
@@ -24,6 +24,7 @@
 # include <errno.h>
 
 static int
+inhibit_stack_protector
 __gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
 {
   return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/getcpu.c b/sysdeps/unix/sysv/linux/x86_64/x32/getcpu.c
index cbac4b3..8436f9d 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/getcpu.c
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/getcpu.c
@@ -21,6 +21,7 @@
 void *getcpu_ifunc (void) __asm__ ("__getcpu");
 
 void *
+inhibit_stack_protector
 getcpu_ifunc (void)
 {
   PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
diff --git a/sysdeps/x86_64/ifuncmod8.c b/sysdeps/x86_64/ifuncmod8.c
index c004367..7c06562 100644
--- a/sysdeps/x86_64/ifuncmod8.c
+++ b/sysdeps/x86_64/ifuncmod8.c
@@ -28,6 +28,7 @@ foo_impl (float x)
 }
 
 void *
+inhibit_stack_protector
 foo_ifunc (void)
 {
   __m128i xmm = _mm_set1_epi32 (-1);
-- 
2.10.1.208.gbec66bc

  parent reply	other threads:[~2016-12-19 11:27 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-12-19 11:15 --enable-stack-protector for glibc, v10 Nix
2016-12-19 11:15 ` [PATCH 06/15] Prevent the rtld mapfile computation from dragging in __stack_chk_fail* Nix
2016-12-19 11:15 ` [PATCH 04/15] Mark all machinery needed in early static-link init as -fno-stack-protector Nix
2016-12-21 14:18   ` Florian Weimer
2016-12-19 11:15 ` [PATCH 08/15] Add a hidden __stack_chk_fail_local alias to libc.so Nix
2016-12-19 11:25 ` [PATCH 09/15] De-PLTize __stack_chk_fail internal calls within libc.so Nix
2016-12-21 15:05   ` Florian Weimer
2016-12-22 22:41     ` Nix
2016-12-19 11:25 ` [PATCH 14/15] tst-quad1pie, tst-quad2pie: compile with -fPIE Nix
2016-12-21 13:36   ` Florian Weimer
2016-12-19 11:25 ` [PATCH 11/15] Drop explicit stack-protection of pieces of the system Nix
2016-12-19 11:25 ` [PATCH 10/15] Link a non-libc-using test with -fno-stack-protector Nix
2016-12-19 11:25 ` [PATCH 15/15] Enable -fstack-protector=* when requested by configure Nix
2016-12-19 11:26 ` [PATCH 01/15] Configury support for --enable-stack-protector Nix
2016-12-19 11:26 ` [PATCH 13/15] Move all tests out of csu Nix
2016-12-21 13:36   ` Florian Weimer
2016-12-19 11:26 ` [PATCH 12/15] Do not stack-protect sigreturn stubs Nix
2016-12-19 11:26 ` [PATCH 02/15] Initialize the stack guard earlier when linking statically Nix
2016-12-21 14:16   ` Florian Weimer
2016-12-21 20:15     ` Florian Weimer
2016-12-22 22:38       ` Nix
2016-12-19 11:26 ` [PATCH 05/15] Compile the entire dynamic linker with -fno-stack-protector Nix
2016-12-21 14:18   ` Florian Weimer
2016-12-21 14:25     ` Szabolcs Nagy
2016-12-21 14:57       ` Florian Weimer
2016-12-19 11:27 ` [PATCH 07/15] Work even with compilers hacked to enable -fstack-protector by default Nix
2016-12-19 11:27 ` Nix [this message]
2016-12-21 14:17   ` [PATCH 03/15] Do not stack-protect ifunc resolvers Florian Weimer
2016-12-22 22:40     ` Nix
2016-12-19 15:15 ` --enable-stack-protector for glibc, v10 Florian Weimer
2016-12-19 15:18   ` Chris Metcalf
2016-12-19 15:54   ` Nix
2016-12-20  8:30 ` Florian Weimer
2016-12-20 19:04   ` Nix
2016-12-21 17:26 ` Florian Weimer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20161219111528.14969-4-nix@esperi.org.uk \
    --to=nix@esperi.org.uk \
    --cc=fweimer@redhat.com \
    --cc=libc-alpha@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).