Patchwork [2/3,MIPS] Define USE_DL_EXEC_STACK_OVERRIDE on Mips

login
register
mail settings
Submitter Dragan Mladjenovic
Date June 27, 2019, 9:50 p.m.
Message ID <1561672142-5907-3-git-send-email-dmladjenovic@wavecomp.com>
Download mbox | patch
Permalink /patch/33467/
State New
Headers show

Comments

Dragan Mladjenovic - June 27, 2019, 9:50 p.m.
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

Patch

diff --git a/sysdeps/unix/sysv/linux/mips/Makefile b/sysdeps/unix/sysv/linux/mips/Makefile

index 8217f42..4f2f422 100644

--- a/sysdeps/unix/sysv/linux/mips/Makefile

+++ b/sysdeps/unix/sysv/linux/mips/Makefile

@@ -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)
diff --git a/sysdeps/unix/sysv/linux/mips/configure.ac b/sysdeps/unix/sysv/linux/mips/configure.ac

index 9147aa4..bf2c6a9 100644

--- a/sysdeps/unix/sysv/linux/mips/configure.ac

+++ b/sysdeps/unix/sysv/linux/mips/configure.ac

@@ -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])
diff --git a/sysdeps/unix/sysv/linux/mips/dl-execstack-ovrd.c b/sysdeps/unix/sysv/linux/mips/dl-execstack-ovrd.c

new file mode 100644
index 0000000..408186d

--- /dev/null

+++ b/sysdeps/unix/sysv/linux/mips/dl-execstack-ovrd.c

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

diff --git a/sysdeps/unix/sysv/linux/mips/dl-sysdep.h b/sysdeps/unix/sysv/linux/mips/dl-sysdep.h

new file mode 100644
index 0000000..6ac36b6

--- /dev/null

+++ b/sysdeps/unix/sysv/linux/mips/dl-sysdep.h

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

+

diff --git a/sysdeps/unix/sysv/linux/mips/tst-execstack-ovrd-static.c b/sysdeps/unix/sysv/linux/mips/tst-execstack-ovrd-static.c

new file mode 100644
index 0000000..0e5e61b

--- /dev/null

+++ b/sysdeps/unix/sysv/linux/mips/tst-execstack-ovrd-static.c

@@ -0,0 +1 @@ 

+#include "tst-execstack-ovrd.c"

diff --git a/sysdeps/unix/sysv/linux/mips/tst-execstack-ovrd.c b/sysdeps/unix/sysv/linux/mips/tst-execstack-ovrd.c

new file mode 100644
index 0000000..9d2f4ef

--- /dev/null

+++ b/sysdeps/unix/sysv/linux/mips/tst-execstack-ovrd.c

@@ -0,0 +1,2 @@ 

+#include "tst-execstack-prog.c"

+

diff --git a/sysdeps/unix/sysv/linux/mips/tst-execstack-ovrd1-static.c b/sysdeps/unix/sysv/linux/mips/tst-execstack-ovrd1-static.c

new file mode 100644
index 0000000..e45ac94

--- /dev/null

+++ b/sysdeps/unix/sysv/linux/mips/tst-execstack-ovrd1-static.c

@@ -0,0 +1 @@ 

+#include "tst-execstack-ovrd1.c"

diff --git a/sysdeps/unix/sysv/linux/mips/tst-execstack-ovrd1.c b/sysdeps/unix/sysv/linux/mips/tst-execstack-ovrd1.c

new file mode 100644
index 0000000..7e6252d

--- /dev/null

+++ b/sysdeps/unix/sysv/linux/mips/tst-execstack-ovrd1.c

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

+