[v2,1/3,ELF] Allow the machine support to enforce executable stack

Message ID 1563275697-30825-1-git-send-email-dmladjenovic@wavecomp.com
State Superseded
Headers

Commit Message

Dragan Mladjenovic July 16, 2019, 11:15 a.m. UTC
  This patch allows the machine-dependent code to override non-executable
stack permissions by defining DL_EXEC_STACK_OVERRIDE to the condition under
which the stack should be made executable.

	* elf/dl-exec-stack-override.h: New file.
	* elf/dl-support.c (_dl_non_dynamic_init): Call _dl_exec_stack_override.
	* elf/rtld.c (dl_main): Likewise.
	* sysdeps/generic/ldsodefs.h: Default DL_EXEC_STACK_OVERRIDE to false.
---
 elf/dl-exec-stack-override.h | 36 ++++++++++++++++++++++++++++++++++++
 elf/dl-support.c             |  3 +++
 elf/rtld.c                   |  3 +++
 sysdeps/generic/ldsodefs.h   |  4 ++++
 4 files changed, 46 insertions(+)
 create mode 100644 elf/dl-exec-stack-override.h
  

Patch

diff --git a/elf/dl-exec-stack-override.h b/elf/dl-exec-stack-override.h
new file mode 100644
index 0000000..10401a8
--- /dev/null
+++ b/elf/dl-exec-stack-override.h
@@ -0,0 +1,36 @@ 
+/* Make stack executable if the machine requires it.  Generic 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 <ldsodefs.h>
+
+extern int __stack_prot attribute_relro attribute_hidden;
+
+static __always_inline void
+_dl_exec_stack_override (void)
+{
+  if (__glibc_unlikely ((GL(dl_stack_flags) & PF_X) == 0
+                         && DL_EXEC_STACK_OVERRIDE))
+  {
+    __stack_prot |= PROT_READ|PROT_WRITE|PROT_EXEC;
+
+    void *stack_end = __libc_stack_end;
+    int err = _dl_make_stack_executable (&stack_end);
+    if (__glibc_unlikely (err))
+      _dl_fatal_printf ("cannot enable executable stack as machine requires\n");
+  }
+}
diff --git a/elf/dl-support.c b/elf/dl-support.c
index 0a8b636..923aa4c 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -29,6 +29,7 @@ 
 #include <dl-machine.h>
 #include <libc-lock.h>
 #include <dl-cache.h>
+#include <dl-exec-stack-override.h>
 #include <dl-librecon.h>
 #include <dl-procinfo.h>
 #include <unsecvars.h>
@@ -375,6 +376,8 @@  _dl_non_dynamic_init (void)
 	  _dl_stack_flags = _dl_phdr[i].p_flags;
 	  break;
 	}
+
+  _dl_exec_stack_override ();
 }
 
 #ifdef DL_SYSINFO_IMPLEMENTATION
diff --git a/elf/rtld.c b/elf/rtld.c
index c9490ff..f3e00f9 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -36,6 +36,7 @@ 
 #include <dl-librecon.h>
 #include <unsecvars.h>
 #include <dl-cache.h>
+#include <dl-exec-stack-override.h>
 #include <dl-osinfo.h>
 #include <dl-procinfo.h>
 #include <dl-prop.h>
@@ -1542,6 +1543,8 @@  ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
   DL_SYSDEP_OSCHECK (_dl_fatal_printf);
 #endif
 
+  _dl_exec_stack_override ();
+
   /* Initialize the data structures for the search paths for shared
      objects.  */
   _dl_init_paths (library_path);
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index b1fc5c3..70e96c0 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -119,6 +119,10 @@  dl_symbol_visibility_binds_local_p (const ElfW(Sym) *sym)
 # define DL_STATIC_INIT(map)
 #endif
 
+#ifndef DL_EXEC_STACK_OVERRIDE
+# define DL_EXEC_STACK_OVERRIDE false
+#endif
+
 /* Reloc type classes as returned by elf_machine_type_class().
    ELF_RTYPE_CLASS_PLT means this reloc should not be satisfied by
    some PLT symbol, ELF_RTYPE_CLASS_COPY means this reloc should not be