mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-21 12:30:06 +00:00
Do not stack-protect ifunc resolvers [BZ #7065]
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.)
This commit is contained in:
parent
003a27e819
commit
de6591238b
25
ChangeLog
25
ChangeLog
@ -1,3 +1,28 @@
|
|||||||
|
2016-12-26 Nick Alcock <nick.alcock@oracle.com>
|
||||||
|
|
||||||
|
[BZ #7065]
|
||||||
|
* configure.ac (HAVE_CC_NO_STACK_PROTECTOR): Define.
|
||||||
|
* 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, foo2_ifunc, foo3_ifunc): Apply
|
||||||
|
inhibit_stack_protector.
|
||||||
|
* elf/ifuncmain6pie.c (foo_ifunc): Likewise.
|
||||||
|
* elf/ifuncmain7.c (foo_ifunc): Likewise.
|
||||||
|
* elf/ifuncmod1.c (foo_ifunc, foo_hidden_ifunc)
|
||||||
|
(foo_protected_ifunc): Likewise.
|
||||||
|
* elf/ifuncmod5.c (foo_ifunc, foo_hidden_ifunc)
|
||||||
|
(foo_protected_ifunc): Likewise.
|
||||||
|
* sysdeps/generic/ifunc-sel.h (ifunc_sel, ifunc_one): Likewise.
|
||||||
|
* sysdeps/nacl/nacl_interface_query.c
|
||||||
|
(nacl_interface_query_ifunc): Likewise.
|
||||||
|
* sysdeps/powerpc/ifunc-sel.h (ifunc_sel, ifunc_one): Likewise.
|
||||||
|
* sysdeps/unix/sysv/linux/x86_64/x32/getcpu.c (getcpu_ifunc):
|
||||||
|
Likewise.
|
||||||
|
* sysdeps/x86_64/ifuncmod8.c (foo_ifunc): Likewise.
|
||||||
|
* sysdeps/unix/make-syscalls.sh: Apply inhibit_stack_protector to
|
||||||
|
the generated vDSO syscall resolver.
|
||||||
|
|
||||||
2016-12-26 Nick Alcock <nick.alcock@oracle.com>
|
2016-12-26 Nick Alcock <nick.alcock@oracle.com>
|
||||||
Florian Weimer <fweimer@redhat.com>
|
Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
@ -48,6 +48,10 @@
|
|||||||
/* Define if compiler accepts -ftree-loop-distribute-patterns. */
|
/* Define if compiler accepts -ftree-loop-distribute-patterns. */
|
||||||
#undef HAVE_CC_INHIBIT_LOOP_TO_LIBCALL
|
#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.
|
/* The level of stack protection in use for glibc as a whole.
|
||||||
May be overridden on a file-by-file basis. */
|
May be overridden on a file-by-file basis. */
|
||||||
#ifndef STACK_PROTECTOR_LEVEL
|
#ifndef STACK_PROTECTOR_LEVEL
|
||||||
|
2
configure
vendored
2
configure
vendored
@ -3994,6 +3994,8 @@ stack_protector=
|
|||||||
no_stack_protector=
|
no_stack_protector=
|
||||||
if test "$libc_cv_ssp" = yes; then
|
if test "$libc_cv_ssp" = yes; then
|
||||||
no_stack_protector="-fno-stack-protector -DSTACK_PROTECTOR_LEVEL=0"
|
no_stack_protector="-fno-stack-protector -DSTACK_PROTECTOR_LEVEL=0"
|
||||||
|
$as_echo "#define HAVE_CC_NO_STACK_PROTECTOR 1" >>confdefs.h
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$enable_stack_protector" = yes && test "$libc_cv_ssp" = yes; then
|
if test "$enable_stack_protector" = yes && test "$libc_cv_ssp" = yes; then
|
||||||
|
@ -653,6 +653,7 @@ stack_protector=
|
|||||||
no_stack_protector=
|
no_stack_protector=
|
||||||
if test "$libc_cv_ssp" = yes; then
|
if test "$libc_cv_ssp" = yes; then
|
||||||
no_stack_protector="-fno-stack-protector -DSTACK_PROTECTOR_LEVEL=0"
|
no_stack_protector="-fno-stack-protector -DSTACK_PROTECTOR_LEVEL=0"
|
||||||
|
AC_DEFINE(HAVE_CC_NO_STACK_PROTECTOR)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$enable_stack_protector" = yes && test "$libc_cv_ssp" = yes; then
|
if test "$enable_stack_protector" = yes && test "$libc_cv_ssp" = yes; then
|
||||||
|
@ -32,6 +32,7 @@ void * foo1_ifunc (void) __asm__ ("foo1");
|
|||||||
__asm__(".type foo1, %gnu_indirect_function");
|
__asm__(".type foo1, %gnu_indirect_function");
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
inhibit_stack_protector
|
||||||
foo1_ifunc (void)
|
foo1_ifunc (void)
|
||||||
{
|
{
|
||||||
return ifunc_sel (one, minus_one, zero);
|
return ifunc_sel (one, minus_one, zero);
|
||||||
@ -41,6 +42,7 @@ void * foo2_ifunc (void) __asm__ ("foo2");
|
|||||||
__asm__(".type foo2, %gnu_indirect_function");
|
__asm__(".type foo2, %gnu_indirect_function");
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
inhibit_stack_protector
|
||||||
foo2_ifunc (void)
|
foo2_ifunc (void)
|
||||||
{
|
{
|
||||||
return ifunc_sel (minus_one, one, zero);
|
return ifunc_sel (minus_one, one, zero);
|
||||||
@ -50,6 +52,7 @@ void * foo3_ifunc (void) __asm__ ("foo3");
|
|||||||
__asm__(".type foo3, %gnu_indirect_function");
|
__asm__(".type foo3, %gnu_indirect_function");
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
inhibit_stack_protector
|
||||||
foo3_ifunc (void)
|
foo3_ifunc (void)
|
||||||
{
|
{
|
||||||
return ifunc_sel (one, zero, minus_one);
|
return ifunc_sel (one, zero, minus_one);
|
||||||
|
@ -21,6 +21,7 @@ void * foo_ifunc (void) __asm__ ("foo");
|
|||||||
__asm__(".type foo, %gnu_indirect_function");
|
__asm__(".type foo, %gnu_indirect_function");
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
inhibit_stack_protector
|
||||||
foo_ifunc (void)
|
foo_ifunc (void)
|
||||||
{
|
{
|
||||||
return ifunc_one (one);
|
return ifunc_one (one);
|
||||||
|
@ -20,6 +20,7 @@ __asm__(".type foo, %gnu_indirect_function");
|
|||||||
|
|
||||||
static void *
|
static void *
|
||||||
__attribute__ ((used))
|
__attribute__ ((used))
|
||||||
|
inhibit_stack_protector
|
||||||
foo_ifunc (void)
|
foo_ifunc (void)
|
||||||
{
|
{
|
||||||
return ifunc_one (one);
|
return ifunc_one (one);
|
||||||
|
@ -36,6 +36,7 @@ void * foo_ifunc (void) __asm__ ("foo");
|
|||||||
__asm__(".type foo, %gnu_indirect_function");
|
__asm__(".type foo, %gnu_indirect_function");
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
inhibit_stack_protector
|
||||||
foo_ifunc (void)
|
foo_ifunc (void)
|
||||||
{
|
{
|
||||||
return ifunc_sel (one, minus_one, zero);
|
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");
|
__asm__(".type foo_hidden, %gnu_indirect_function");
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
inhibit_stack_protector
|
||||||
foo_hidden_ifunc (void)
|
foo_hidden_ifunc (void)
|
||||||
{
|
{
|
||||||
return ifunc_sel (minus_one, one, zero);
|
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");
|
__asm__(".type foo_protected, %gnu_indirect_function");
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
inhibit_stack_protector
|
||||||
foo_protected_ifunc (void)
|
foo_protected_ifunc (void)
|
||||||
{
|
{
|
||||||
return ifunc_sel (one, zero, minus_one);
|
return ifunc_sel (one, zero, minus_one);
|
||||||
|
@ -31,6 +31,7 @@ void * foo_ifunc (void) __asm__ ("foo");
|
|||||||
__asm__(".type foo, %gnu_indirect_function");
|
__asm__(".type foo, %gnu_indirect_function");
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
inhibit_stack_protector
|
||||||
foo_ifunc (void)
|
foo_ifunc (void)
|
||||||
{
|
{
|
||||||
return ifunc_sel (one, minus_one, zero);
|
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");
|
__asm__(".type foo_hidden, %gnu_indirect_function");
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
inhibit_stack_protector
|
||||||
foo_hidden_ifunc (void)
|
foo_hidden_ifunc (void)
|
||||||
{
|
{
|
||||||
return ifunc_sel (minus_one, one, zero);
|
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");
|
__asm__(".type foo_protected, %gnu_indirect_function");
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
inhibit_stack_protector
|
||||||
foo_protected_ifunc (void)
|
foo_protected_ifunc (void)
|
||||||
{
|
{
|
||||||
return ifunc_sel (one, zero, minus_one);
|
return ifunc_sel (one, zero, minus_one);
|
||||||
|
@ -336,6 +336,16 @@ for linking")
|
|||||||
|
|
||||||
#define attribute_relro __attribute__ ((section (".data.rel.ro")))
|
#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
|
/* The following macros are used for PLT bypassing within libc.so
|
||||||
(and if needed other libraries similarly).
|
(and if needed other libraries similarly).
|
||||||
First of all, you need to have the function prototyped somewhere,
|
First of all, you need to have the function prototyped somewhere,
|
||||||
@ -737,7 +747,7 @@ for linking")
|
|||||||
|
|
||||||
/* Helper / base macros for indirect function symbols. */
|
/* Helper / base macros for indirect function symbols. */
|
||||||
#define __ifunc_resolver(type_name, name, expr, arg, init, classifier) \
|
#define __ifunc_resolver(type_name, name, expr, arg, init, classifier) \
|
||||||
classifier void *name##_ifunc (arg) \
|
classifier inhibit_stack_protector void *name##_ifunc (arg) \
|
||||||
{ \
|
{ \
|
||||||
init (); \
|
init (); \
|
||||||
__typeof (type_name) *res = expr; \
|
__typeof (type_name) *res = expr; \
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
extern int global;
|
extern int global;
|
||||||
|
|
||||||
static inline void *
|
static inline void *
|
||||||
|
inhibit_stack_protector
|
||||||
ifunc_sel (int (*f1) (void), int (*f2) (void), int (*f3) (void))
|
ifunc_sel (int (*f1) (void), int (*f2) (void), int (*f3) (void))
|
||||||
{
|
{
|
||||||
switch (global)
|
switch (global)
|
||||||
@ -19,6 +20,7 @@ ifunc_sel (int (*f1) (void), int (*f2) (void), int (*f3) (void))
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void *
|
static inline void *
|
||||||
|
inhibit_stack_protector
|
||||||
ifunc_one (int (*f1) (void))
|
ifunc_one (int (*f1) (void))
|
||||||
{
|
{
|
||||||
return f1;
|
return f1;
|
||||||
|
@ -29,6 +29,7 @@ extern TYPE_nacl_irt_query nacl_interface_query_ifunc (void)
|
|||||||
asm ("nacl_interface_query");
|
asm ("nacl_interface_query");
|
||||||
|
|
||||||
TYPE_nacl_irt_query
|
TYPE_nacl_irt_query
|
||||||
|
inhibit_stack_protector
|
||||||
nacl_interface_query_ifunc (void)
|
nacl_interface_query_ifunc (void)
|
||||||
{
|
{
|
||||||
return &__nacl_irt_query;
|
return &__nacl_irt_query;
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
extern int global;
|
extern int global;
|
||||||
|
|
||||||
static inline void *
|
static inline void *
|
||||||
|
inhibit_stack_protector
|
||||||
ifunc_sel (int (*f1) (void), int (*f2) (void), int (*f3) (void))
|
ifunc_sel (int (*f1) (void), int (*f2) (void), int (*f3) (void))
|
||||||
{
|
{
|
||||||
register void *ret __asm__ ("r3");
|
register void *ret __asm__ ("r3");
|
||||||
@ -32,6 +33,7 @@ ifunc_sel (int (*f1) (void), int (*f2) (void), int (*f3) (void))
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void *
|
static inline void *
|
||||||
|
inhibit_stack_protector
|
||||||
ifunc_one (int (*f1) (void))
|
ifunc_one (int (*f1) (void))
|
||||||
{
|
{
|
||||||
register void *ret __asm__ ("r3");
|
register void *ret __asm__ ("r3");
|
||||||
|
@ -287,6 +287,7 @@ while read file srcfile caller syscall args strong weak; do
|
|||||||
(echo '#include <dl-vdso.h>'; \\
|
(echo '#include <dl-vdso.h>'; \\
|
||||||
echo 'extern void *${strong}_ifunc (void) __asm ("${strong}");'; \\
|
echo 'extern void *${strong}_ifunc (void) __asm ("${strong}");'; \\
|
||||||
echo 'void *'; \\
|
echo 'void *'; \\
|
||||||
|
echo 'inhibit_stack_protector'; \\
|
||||||
echo '${strong}_ifunc (void)'; \\
|
echo '${strong}_ifunc (void)'; \\
|
||||||
echo '{'; \\
|
echo '{'; \\
|
||||||
echo ' PREPARE_VERSION_KNOWN (symver, ${vdso_symver});'; \\
|
echo ' PREPARE_VERSION_KNOWN (symver, ${vdso_symver});'; \\
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
void *getcpu_ifunc (void) __asm__ ("__getcpu");
|
void *getcpu_ifunc (void) __asm__ ("__getcpu");
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
inhibit_stack_protector
|
||||||
getcpu_ifunc (void)
|
getcpu_ifunc (void)
|
||||||
{
|
{
|
||||||
PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
|
PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
|
||||||
|
@ -28,6 +28,7 @@ foo_impl (float x)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
inhibit_stack_protector
|
||||||
foo_ifunc (void)
|
foo_ifunc (void)
|
||||||
{
|
{
|
||||||
__m128i xmm = _mm_set1_epi32 (-1);
|
__m128i xmm = _mm_set1_epi32 (-1);
|
||||||
|
Loading…
Reference in New Issue
Block a user