about summary refs log tree commit diff
path: root/elf
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2004-09-19 02:48:59 +0000
committerUlrich Drepper <drepper@redhat.com>2004-09-19 02:48:59 +0000
commitdcca3fe25f4a57f351ce95253f32e191dfe1167d (patch)
tree47ed6fa14ac4ec6b14b20e06ffe69e424622ba4f /elf
parentd72433621f75bce7281adb7060459f6918287926 (diff)
downloadglibc-dcca3fe25f4a57f351ce95253f32e191dfe1167d.tar.gz
glibc-dcca3fe25f4a57f351ce95253f32e191dfe1167d.tar.xz
glibc-dcca3fe25f4a57f351ce95253f32e191dfe1167d.zip
Update.
	* sysdeps/unisx/sysv/linux/dl-execstack.c: Get protection flag
	from memory.
	* elf/dl-load.c (_dl_map_object_from_fd): Add PROT_EXEC flag to
	__stack_flags.
Diffstat (limited to 'elf')
-rw-r--r--elf/dl-load.c45
1 files changed, 32 insertions, 13 deletions
diff --git a/elf/dl-load.c b/elf/dl-load.c
index cb0642a6d2..059be4eacf 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -101,6 +101,9 @@ ELF_PREFERRED_ADDRESS_DATA;
 # define ELF_FIXED_ADDRESS(loader, mapstart) ((void) 0)
 #endif
 
+
+extern int __stack_prot attribute_relro attribute_hidden;
+
 /* Type for the buffer we put the ELF header and hopefully the program
    header.  This buffer does not really have to be too large.  In most
    cases the program header follows the ELF header directly.  If this
@@ -1302,6 +1305,35 @@ cannot allocate TLS data structures for initial thread");
       goto call_lose;
     }
 
+  if (__builtin_expect ((stack_flags &~ GL(dl_stack_flags)) & PF_X, 0))
+    {
+      /* The stack is presently not executable, but this module
+	 requires that it be executable.  We must change the
+	 protection of the variable which contains the flags used in
+	 the mprotect calls.  */
+#ifdef HAVE_Z_RELRO
+      if (mode & __RTLD_DLOPEN)
+	{
+	  uintptr_t p = ((uintptr_t) &__stack_prot) & ~(GLRO(dl_pagesize) - 1);
+	  size_t s = (uintptr_t) &__stack_prot - p + sizeof (int);
+
+	  __mprotect ((void *) p, s, PROT_READ|PROT_WRITE);
+	  __stack_prot |= PROT_EXEC;
+	  __mprotect ((void *) p, s, PROT_READ);
+	}
+      else
+#endif
+	__stack_prot |= PROT_EXEC;
+
+      errval = (*GL(dl_make_stack_executable_hook)) (stack_endp);
+      if (errval)
+	{
+	  errstring = N_("\
+cannot enable executable stack as shared object requires");
+	  goto call_lose;
+	}
+    }
+
   if (l->l_info[DT_HASH])
     _dl_setup_hash (l);
 
@@ -1344,19 +1376,6 @@ cannot allocate TLS data structures for initial thread");
   l->l_dev = st.st_dev;
   l->l_ino = st.st_ino;
 
-  if (__builtin_expect ((stack_flags &~ GL(dl_stack_flags)) & PF_X, 0))
-    {
-      /* The stack is presently not executable, but this module
-	 requires that it be executable.  */
-      errval = (*GL(dl_make_stack_executable_hook)) (stack_endp);
-      if (errval)
-	{
-	  errstring = N_("\
-cannot enable executable stack as shared object requires");
-	  goto call_lose;
-	}
-    }
-
   /* When we profile the SONAME might be needed for something else but
      loading.  Add it right away.  */
   if (__builtin_expect (GLRO(dl_profile) != NULL, 0)