@@ -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"
+