On Thu, 21 Jan 2016, Faraz Shahbazker wrote:
> +#ifdef EXEC_STACK_OVERRIDE
> + EXEC_STACK_OVERRIDE (&GL(dl_stack_flags));
> +#endif
We want to avoid #ifdef where possible. It's better to have a default
definition of this macro to expand to do nothing, in a header overridden
for MIPS.
> @@ -14,3 +14,9 @@ UNIQUE
> #
> # MIPS O32 FP64
> MIPS_O32_FP64 mips*-*-linux*
> +#
> +# MIPS IFUNC
> +IFUNC mips*-*-linux*
> +#
> +# Non-executable stack support
> +MIPS_GNU_STACK mips*-*-linux*
> \ No newline at end of file
Always end text files with a newline (exactly one newline, otherwise the
git hooks will complain).
@@ -77,6 +77,10 @@ _init (int argc, char **argv, char **envp)
/* First the initialization which normally would be done by the
dynamic linker. */
_dl_non_dynamic_init ();
+
+#ifdef EXEC_STACK_OVERRIDE
+ EXEC_STACK_OVERRIDE (&GL(dl_stack_flags));
+#endif
#endif
#ifdef VDSO_SETUP
@@ -31,7 +31,8 @@ routines = $(all-dl-routines) dl-support dl-iteratephdr \
dl-routines = $(addprefix dl-,load lookup object reloc deps hwcaps \
runtime error init fini debug misc \
version profile conflict tls origin scope \
- execstack caller open close trampoline)
+ execstack caller open close trampoline \
+ execstack-ovrd)
ifeq (yes,$(use-ldconfig))
dl-routines += dl-cache
endif
@@ -122,7 +123,8 @@ tests = tst-tls1 tst-tls2 tst-tls9 tst-leaks1 \
tests-static = tst-tls1-static tst-tls2-static tst-stackguard1-static \
tst-leaks1-static tst-array1-static tst-array5-static \
tst-ptrguard1-static tst-dl-iter-static \
- tst-tlsalign-static tst-tlsalign-extern-static
+ tst-tlsalign-static tst-tlsalign-extern-static \
+ tst-execstack-ovrd-static
ifeq (yes,$(build-shared))
tests-static += tst-tls9-static
tst-tls9-static-ENV = \
@@ -158,7 +160,8 @@ endif
test-srcs = tst-pathopt
selinux-enabled := $(shell cat /selinux/enforce 2> /dev/null)
ifneq ($(selinux-enabled),1)
-tests-execstack-yes = tst-execstack tst-execstack-needed tst-execstack-prog
+tests-execstack-yes = tst-execstack tst-execstack-needed tst-execstack-prog \
+ tst-execstack-ovrd
endif
endif
ifeq ($(run-built-tests),yes)
@@ -901,6 +904,8 @@ LDFLAGS-tst-execstack-needed = -Wl,-z,noexecstack
LDFLAGS-tst-execstack-prog = -Wl,-z,execstack
CFLAGS-tst-execstack-prog.c += -Wno-trampolines
CFLAGS-tst-execstack-mod.c += -Wno-trampolines
+LDFLAGS-tst-execstack-ovrd = -Wl,-z,noexecstack
+LDFLAGS-tst-execstack-ovrd-static = -Wl,-z,noexecstack
endif
LDFLAGS-tst-array2 = $(no-as-needed)
new file mode 100644
@@ -0,0 +1,25 @@
+/* Non-executable stack override for GNU dynamic linker. Stub version.
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+int
+internal_function
+_dl_exec_stack_override (void* flags)
+{
+ return 0;
+}
+rtld_hidden_def (_dl_exec_stack_override)
@@ -1278,6 +1278,14 @@ cannot allocate TLS data structures for initial thread");
/* Adjust the PT_PHDR value by the runtime load address. */
l->l_phdr = (ElfW(Phdr) *) ((ElfW(Addr)) l->l_phdr + l->l_addr);
+ /* Program requests a non-executable stack, but architecture does
+ not support it. */
+ if (__glibc_unlikely ((*GL(dl_exec_stack_override_hook)) (&stack_flags) != 0))
+ {
+ errstring = N_("cannot override stack memory protections");
+ goto call_lose_errno;
+ }
+
if (__glibc_unlikely ((stack_flags &~ GL(dl_stack_flags)) & PF_X))
{
if (__glibc_unlikely (__check_caller (RETURN_ADDRESS (0), allow_ldso) != 0))
@@ -182,6 +182,10 @@ ElfW(Word) _dl_stack_flags = DEFAULT_STACK_PERMS;
int (*_dl_make_stack_executable_hook) (void **) internal_function
= _dl_make_stack_executable;
+/* Check if architecture allows non-executable stack. */
+int (*_dl_exec_stack_override_hook) (void *) internal_function
+ = _dl_exec_stack_override;
+
/* Function in libpthread to wait for termination of lookups. */
void (*_dl_wait_lookup_done) (void);
@@ -768,6 +768,7 @@ dl_main (const ElfW(Phdr) *phdr,
/* The explicit initialization here is cheaper than processing the reloc
in the _rtld_local definition's initializer. */
GL(dl_make_stack_executable_hook) = &_dl_make_stack_executable;
+ GL(dl_exec_stack_override_hook) = &_dl_exec_stack_override;
/* Process the environment variable which control the behaviour. */
process_envvars (&mode);
new file mode 100644
@@ -0,0 +1 @@
+#include "tst-execstack-ovrd.c"
new file mode 100644
@@ -0,0 +1 @@
+#include "tst-execstack-prog.c"
@@ -366,6 +366,9 @@ struct rtld_global
It returns an errno code or zero on success. */
EXTERN int (*_dl_make_stack_executable_hook) (void **) internal_function;
+ /* Check if this architecture support non-executable stack segments. */
+ EXTERN int (*_dl_exec_stack_override_hook) (void *) internal_function;
+
/* Prevailing state of the stack, PF_X indicating it's executable. */
EXTERN ElfW(Word) _dl_stack_flags;
@@ -629,6 +632,11 @@ extern void **_dl_initial_error_catch_tsd (void) __attribute__ ((const))
extern int _dl_make_stack_executable (void **stack_endp) internal_function;
rtld_hidden_proto (_dl_make_stack_executable)
+/* This is the initial value of GL(dl_exec_stack_override_hook).
+ A threads library can change it. */
+extern int _dl_exec_stack_override (void *) internal_function;
+rtld_hidden_proto (_dl_exec_stack_override)
+
/* Variable pointing to the end of the stack (or close to it). This value
must be constant over the runtime of the application. Some programs
might use the variable which results in copy relocations on some
new file mode 100644
@@ -0,0 +1,50 @@
+/* Non-executable stack override for GNU dynamic linker. MIPS specific
+ version.
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <elf.h>
+#include <ldsodefs.h>
+#include <misc/sys/auxv.h>
+
+ /* Flag to indicate that non-executable stack supported by kernel.
+ Ref: arch/mips/include/asm/elf.h in kernel sources. */
+#define AV_FLAGS_MIPS_GNU_STACK (1 << 24)
+
+extern int __stack_prot attribute_relro attribute_hidden;
+
+int
+internal_function
+_dl_exec_stack_override (void* flags)
+{
+ if ((*(ElfW(Word) *)flags & PF_X) == 0
+ && (getauxval (AT_FLAGS) & AV_FLAGS_MIPS_GNU_STACK) == 0)
+ {
+#ifndef SHARED
+ /* For static executable, we need to set stack permission here. */
+ uintptr_t page = ((uintptr_t) __libc_stack_end
+ & -(intptr_t) GLRO(dl_pagesize));
+ if (__mprotect ((void *) page, GLRO(dl_pagesize),
+ PROT_READ | PROT_WRITE | PROT_EXEC | __stack_prot) < 0)
+ return errno;
+#endif /* !SHARED */
+ *(ElfW(Word) *)flags |= PF_X;
+ }
+
+ return 0;
+}
+rtld_hidden_def (_dl_exec_stack_override)
new file mode 100644
@@ -0,0 +1,26 @@
+/* Initialization code run first thing by the ELF startup code. Linux/ARM.
+ Copyright (C) 2016 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef SHARED
+#include <ldsodefs.h>
+
+# define EXEC_STACK_OVERRIDE GL(dl_exec_stack_override)
+#endif /* !SHARED */
+
+#include <csu/init-first.c>
@@ -34,7 +34,7 @@ extern void _dl_static_init (struct link_map *map);
#undef VALID_ELF_ABIVERSION
#define VALID_ELF_ABIVERSION(osabi,ver) \
(ver == 0 \
- || (osabi == ELFOSABI_SYSV && ver < 4) \
+ || (osabi == ELFOSABI_SYSV && ver < 6) \
|| (osabi == ELFOSABI_GNU && ver < LIBC_ABI_MAX))
#endif /* ldsodefs.h */
@@ -14,3 +14,9 @@ UNIQUE
#
# MIPS O32 FP64
MIPS_O32_FP64 mips*-*-linux*
+#
+# MIPS IFUNC
+IFUNC mips*-*-linux*
+#
+# Non-executable stack support
+MIPS_GNU_STACK mips*-*-linux*