On 12/19/2016 12:15 PM, Nix wrote:
> 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);
These are functions *returned* by IFUNC resolvers, and therefore can be
compiled with stack protector enabled. I will drop those.
Thanks,
Florian
On 21 Dec 2016, Florian Weimer outgrape:
> On 12/19/2016 12:15 PM, Nix wrote:
>> 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);
>
> These are functions *returned* by IFUNC resolvers, and therefore can
> be compiled with stack protector enabled. I will drop those.
I think I was a bit gettimeofday-trigger-happy when I wrote this.
If it still works on x86-32 with -fstack-protector-all, you're clearly
right :)
@@ -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
@@ -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
@@ -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);
@@ -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);
@@ -20,6 +20,7 @@ __asm__(".type foo, %gnu_indirect_function");
static void *
__attribute__ ((used))
+inhibit_stack_protector
foo_ifunc (void)
{
return ifunc_one (one);
@@ -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);
@@ -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);
@@ -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; \
@@ -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;
@@ -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;
@@ -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");
@@ -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});'; \\
@@ -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);
@@ -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);
@@ -21,6 +21,7 @@
void *getcpu_ifunc (void) __asm__ ("__getcpu");
void *
+inhibit_stack_protector
getcpu_ifunc (void)
{
PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
@@ -28,6 +28,7 @@ foo_impl (float x)
}
void *
+inhibit_stack_protector
foo_ifunc (void)
{
__m128i xmm = _mm_set1_epi32 (-1);