[2/3,MIPS] Define USE_DL_EXEC_STACK_OVERRIDE on Mips
Commit Message
This patch conditionally defines USE_DL_EXEC_STACK_OVERRIDE for hard-float builds
targeting minimum Linux kernel version lower than 4.8. In that case _dl_exec_stack_override
performs run-time check of kernel version and enforces executable stack on pre-4.8 kernels.
We now detect when glibc is built with toolchain that uses GNU.stack notes and xfail the
check-execstack only if one isn't used.
* sysdeps/unix/sysv/linux/mips/Makefile[$(subdir) == elf] (sysdep-dl-routines):
Add dl-execstack-ovrd.
(tests): Add tst-execstack-ovrd and tst-execstack-ovrd1.
(tests-static): Add tst-execstack-ovrd-static and tst-execstack-ovrd1-static.
(LDFLAGS-tst-execstack-ovrd*, tst-execstack-ovrd*-ENV ...): New.
(test-xfail-check-execstack): Enable when mips-has-gnustack is false.
(test-xfail-tst-execstack-ovrd1, test-xfail-tst-execstack-ovrd1-static): New.
Likewise enabled.
* sysdeps/unix/sysv/linux/mips/configure.ac (mips-has-gnustack): New var.
Set to value of libc_cv_as_noexecstack.
* sysdeps/unix/sysv/linux/mips/configure: Regenerated.
* sysdeps/unix/sysv/linux/mips/dl-execstack-ovrd.c: New file.
* sysdeps/unix/sysv/linux/mips/dl-sysdep.h: New file.
* sysdeps/unix/sysv/linux/mips/tst-execstack-ovrd-static.c: New file.
* sysdeps/unix/sysv/linux/mips/tst-execstack-ovrd.c: New file.
* sysdeps/unix/sysv/linux/mips/tst-execstack-ovrd1-static.c: New file.
* sysdeps/unix/sysv/linux/mips/tst-execstack-ovrd1.c: New file.
---
sysdeps/unix/sysv/linux/mips/Makefile | 28 +++++++++++--
sysdeps/unix/sysv/linux/mips/configure.ac | 2 +
sysdeps/unix/sysv/linux/mips/dl-execstack-ovrd.c | 48 ++++++++++++++++++++++
sysdeps/unix/sysv/linux/mips/dl-sysdep.h | 28 +++++++++++++
.../sysv/linux/mips/tst-execstack-ovrd-static.c | 1 +
sysdeps/unix/sysv/linux/mips/tst-execstack-ovrd.c | 2 +
.../sysv/linux/mips/tst-execstack-ovrd1-static.c | 1 +
sysdeps/unix/sysv/linux/mips/tst-execstack-ovrd1.c | 11 +++++
8 files changed, 117 insertions(+), 4 deletions(-)
create mode 100644 sysdeps/unix/sysv/linux/mips/dl-execstack-ovrd.c
create mode 100644 sysdeps/unix/sysv/linux/mips/dl-sysdep.h
create mode 100644 sysdeps/unix/sysv/linux/mips/tst-execstack-ovrd-static.c
create mode 100644 sysdeps/unix/sysv/linux/mips/tst-execstack-ovrd.c
create mode 100644 sysdeps/unix/sysv/linux/mips/tst-execstack-ovrd1-static.c
create mode 100644 sysdeps/unix/sysv/linux/mips/tst-execstack-ovrd1.c
--
1.9.1
@@ -57,6 +57,8 @@ abi-n64_hard_2008-condition := defined(__mips_nan2008) \
&& (_MIPS_SIM == _MIPS_SIM_ABI64)
ifeq ($(subdir),elf)
+sysdep-dl-routines += dl-execstack-ovrd
+
ifeq ($(build-shared),yes)
# This is needed for DSO loading from static binaries.
sysdep-dl-routines += dl-static
@@ -64,11 +66,29 @@ sysdep-dl-routines += dl-static
sysdep_routines += dl-vdso
endif
-# Supporting non-executable stacks on MIPS requires changes to both
-# the Linux kernel and glibc. See
-# <https://sourceware.org/ml/libc-alpha/2016-01/msg00567.html> and
-# <https://sourceware.org/ml/libc-alpha/2016-01/msg00719.html>.
+tests-static += tst-execstack-ovrd-static
+tests += tst-execstack-ovrd-static
+tests += tst-execstack-ovrd
+tests-static += tst-execstack-ovrd1-static
+tests += tst-execstack-ovrd1-static
+tests += tst-execstack-ovrd1
+LDFLAGS-tst-execstack-ovrd = -Wl,-z,noexecstack
+LDFLAGS-tst-execstack-ovrd-static = -Wl,-z,noexecstack
+LDFLAGS-tst-execstack-ovrd1 = -Wl,-z,noexecstack
+LDFLAGS-tst-execstack-ovrd1-static = -Wl,-z,noexecstack
+tst-execstack-ovrd-ENV = LD_ASSUME_KERNEL=4.5.0
+tst-execstack-ovrd-static-ENV = LD_ASSUME_KERNEL=4.5.0
+tst-execstack-ovrd1-ENV = LD_ASSUME_KERNEL=4.8.0
+tst-execstack-ovrd1-static-ENV = LD_ASSUME_KERNEL=4.8.0
+
+# If the compiler doesn't use GNU.stack note,
+# thease tests are expected to fail.
+ifneq ($(mips-has-gnustack),yes)
test-xfail-check-execstack = yes
+test-xfail-tst-execstack-ovrd1 = yes
+test-xfail-tst-execstack-ovrd1-static = yes
+endif
+
endif
ifeq ($(subdir),stdlib)
@@ -118,6 +118,8 @@ fi
LIBC_CONFIG_VAR([default-abi],
[${libc_mips_abi}_${libc_mips_float}${libc_mips_nan}])
+LIBC_CONFIG_VAR([mips-has-gnustack],[${libc_cv_as_noexecstack}])
+
case $machine in
mips/mips64/n64/*)
LIBC_SLIBDIR_RTLDDIR([lib64], [lib64])
new file mode 100644
@@ -0,0 +1,48 @@
+/* Non-executable stack override for GNU dynamic linker. MIPS/Linux version.
+ Copyright (C) 2019 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 <dl-sysdep.h>
+
+
+#ifdef USE_DL_EXEC_STACK_OVERRIDE
+
+extern int __stack_prot attribute_relro attribute_hidden;
+
+int
+_dl_exec_stack_override (void* flags)
+{
+ if ((*(ElfW(Word) *)flags & PF_X) == 0
+ && (GLRO(dl_osversion) > 0)
+ && (GLRO(dl_osversion) < __NOEXECSTACK_MIN_KERNEL_VERSION))
+ {
+#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
+ *(ElfW(Word) *)flags |= PF_X;
+ }
+ return 0;
+}
+rtld_hidden_def (_dl_exec_stack_override)
+#endif
new file mode 100644
@@ -0,0 +1,28 @@
+/* System-specific settings for dynamic linker code. Linux version.
+ Copyright (C) 2019 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_next <dl-sysdep.h>
+
+#define __NOEXECSTACK_MIN_KERNEL_VERSION (0x040800)
+
+#ifdef __mips_hard_float
+# if (__LINUX_KERNEL_VERSION < __NOEXECSTACK_MIN_KERNEL_VERSION)
+# define USE_DL_EXEC_STACK_OVERRIDE 1
+# endif
+#endif
+
new file mode 100644
@@ -0,0 +1 @@
+#include "tst-execstack-ovrd.c"
new file mode 100644
@@ -0,0 +1,2 @@
+#include "tst-execstack-prog.c"
+
new file mode 100644
@@ -0,0 +1 @@
+#include "tst-execstack-ovrd1.c"
new file mode 100644
@@ -0,0 +1,11 @@
+#include <signal.h>
+
+/* This test may fail (not produce a SIGSEGV) either because
+ DL_SYSDEP_OSCHECK detects that we are running on older kernel
+ than what we specify with LD_ASSUME_KERNEL and thus uses that
+ or the execution environment doesn't have NX semantics
+ (no RIXI support). */
+#define EXPECTED_SIGNAL SIGSEGV
+
+#include "tst-execstack-prog.c"
+