[PATCH v2] elf: early conversion of elf p_flags to mprotect flags

Cupertino Miranda cupertino.miranda@oracle.com
Thu Jul 3 11:36:17 GMT 2025


Hi everyone,

New version after Adhmervals review.
Adhmerval: Thank you for the suggested solution.

Looking for your feedback.

Best regards,
Cupertino

This patch replaces _dl_stack_flags global variable by
_dl_stack_prot_flags.
The advantage is that any convertion from p_flags to final used mprotect
flags occurs at loading of p_flags. It avoids repeated spurious
convertions of _dl_stack_flags, for example in allocate_thread_stack.

This modification was suggested in:
  https://sourceware.org/pipermail/libc-alpha/2025-March/165537.html
---
 elf/Makefile                           |  2 +-
 elf/dl-execstack-tunable.c             |  2 +-
 elf/dl-load.c                          | 19 +++-----------
 elf/dl-support.c                       |  7 +++---
 elf/rtld.c                             | 12 ++++-----
 include/alloca.h                       |  2 --
 include/stackinfo.h                    | 34 ++++++++++++++++++++++++++
 nptl/allocatestack.c                   | 12 +++------
 support/support_stack_alloc.c          |  9 +++----
 sysdeps/alpha/stackinfo.h              |  6 ++---
 sysdeps/arm/stackinfo.h                |  6 ++---
 sysdeps/generic/ldsodefs.h             |  2 +-
 sysdeps/generic/stackinfo.h            |  2 +-
 sysdeps/hppa/stackinfo.h               |  6 ++---
 sysdeps/i386/stackinfo.h               |  6 ++---
 sysdeps/m68k/stackinfo.h               |  6 ++---
 sysdeps/mach/htl/pt-stack-alloc.c      |  2 +-
 sysdeps/mach/hurd/dl-execstack.c       |  2 +-
 sysdeps/microblaze/stackinfo.h         |  6 ++---
 sysdeps/mips/stackinfo.h               |  6 ++---
 sysdeps/or1k/stackinfo.h               |  6 ++---
 sysdeps/powerpc/powerpc32/stackinfo.h  |  4 +--
 sysdeps/s390/stackinfo.h               |  6 ++---
 sysdeps/sh/stackinfo.h                 |  6 ++---
 sysdeps/sparc/stackinfo.h              |  6 ++---
 sysdeps/unix/sysv/linux/dl-execstack.c |  3 ++-
 sysdeps/unix/sysv/linux/machine-sp.h   |  2 ++
 sysdeps/unix/sysv/linux/spawni.c       |  5 +---
 sysdeps/x86_64/stackinfo.h             |  6 ++---
 29 files changed, 102 insertions(+), 91 deletions(-)

diff --git a/elf/Makefile b/elf/Makefile
index 362523ff11..95da4229b6 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -2156,7 +2156,7 @@ $(objpfx)execstack-default: $(first-word $(wildcard $(sysdirs:%=%/stackinfo.h)))
 	$(make-target-directory)
 	{ echo '#include <elf.h>'; \
 	  echo '#include <stackinfo.h>'; \
-	  echo '#if (DEFAULT_STACK_PERMS & PF_X) == 0'; \
+	  echo '#if (DEFAULT_STACK_PROT_PERMS & PROT_EXEC) == 0'; \
 	  echo '@@@execstack-no@@@'; \
 	  echo '#else'; \
 	  echo '@@@execstack-yes@@@'; \
diff --git a/elf/dl-execstack-tunable.c b/elf/dl-execstack-tunable.c
index e3b638aeaa..b2511ea031 100644
--- a/elf/dl-execstack-tunable.c
+++ b/elf/dl-execstack-tunable.c
@@ -25,7 +25,7 @@ _dl_handle_execstack_tunable (void)
   switch (TUNABLE_GET (glibc, rtld, execstack, int32_t, NULL))
     {
     case stack_tunable_mode_disable:
-      if ((__glibc_unlikely (GL(dl_stack_flags)) & PF_X))
+      if ((__glibc_unlikely (GL(dl_stack_prot_flags)) & PROT_EXEC))
 	_dl_fatal_printf (
 "Fatal glibc error: executable stack is not allowed\n");
       break;
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 6e26ef0583..1d7ec9c047 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -1096,7 +1096,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
    /* On most platforms presume that PT_GNU_STACK is absent and the stack is
     * executable.  Other platforms default to a nonexecutable stack and don't
     * need PT_GNU_STACK to do so.  */
-   unsigned int stack_flags = DEFAULT_STACK_PERMS;
+   unsigned int stack_flags = DEFAULT_STACK_PROT_PERMS;
 
   {
     /* Scan the program header table, collecting its load commands.  */
@@ -1171,18 +1171,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
 	  DIAG_POP_NEEDS_COMMENT;
 
 	  /* Optimize a common case.  */
-#if (PF_R | PF_W | PF_X) == 7 && (PROT_READ | PROT_WRITE | PROT_EXEC) == 7
-	  c->prot = (PF_TO_PROT
-		     >> ((ph->p_flags & (PF_R | PF_W | PF_X)) * 4)) & 0xf;
-#else
-	  c->prot = 0;
-	  if (ph->p_flags & PF_R)
-	    c->prot |= PROT_READ;
-	  if (ph->p_flags & PF_W)
-	    c->prot |= PROT_WRITE;
-	  if (ph->p_flags & PF_X)
-	    c->prot |= PROT_EXEC;
-#endif
+	  c->prot = pf_to_prot (ph->p_flags);
 	  break;
 
 	case PT_TLS:
@@ -1219,7 +1208,7 @@ _dl_map_object_from_fd (const char *name, const char */origname, int fd,
 	  break;
 
 	case PT_GNU_STACK:
-	  stack_flags = ph->p_flags;
+	  stack_flags = pf_to_prot (ph->p_flags);
 	  break;
 
 	case PT_GNU_RELRO:
@@ -1319,7 +1308,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
     /* Adjust the PT_PHDR value by the runtime load address.  */
     l->l_phdr = (ElfW(Phdr) *) ((ElfW(Addr)) l->l_phdr + l->l_addr);
 
-  if (__glibc_unlikely ((stack_flags &~ GL(dl_stack_flags)) & PF_X))
+  if (__glibc_unlikely ((stack_flags &~ GL(dl_stack_prot_flags)) & PROT_EXEC))
     {
       /* The stack is presently not executable, but this module
 	 requires that it be executable.  Only tries to change the
diff --git a/elf/dl-support.c b/elf/dl-support.c
index 7b2a1c35d5..bbef3ab6b6 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -166,9 +166,8 @@ enum dso_sort_algorithm _dl_dso_sort_algo;
 /* The value of the FPU control word the kernel will preset in hardware.  */
 fpu_control_t _dl_fpu_control = _FPU_DEFAULT;
 
-/* Prevailing state of the stack.  Generally this includes PF_X, indicating it's
- * executable but this isn't true for all platforms.  */
-ElfW(Word) _dl_stack_flags = DEFAULT_STACK_PERMS;
+/* Required flags used for stack allocation.  */
+int _dl_stack_prot_flags = DEFAULT_STACK_PROT_PERMS;
 
 #if PTHREAD_IN_LIBC
 list_t _dl_stack_used;
@@ -322,7 +321,7 @@ _dl_non_dynamic_init (void)
       {
       /* Check if the stack is nonexecutable.  */
       case PT_GNU_STACK:
-	_dl_stack_flags = ph->p_flags;
+	_dl_stack_prot_flags = pf_to_prot (ph->p_flags);
 	break;
 
       case PT_GNU_RELRO:
diff --git a/elf/rtld.c b/elf/rtld.c
index e6a181dc31..74364bc8ed 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -322,7 +322,7 @@ struct rtld_global _rtld_global =
 #include <dl-procruntime.c>
     /* Generally the default presumption without further information is an
      * executable stack but this is not true for all platforms.  */
-    ._dl_stack_flags = DEFAULT_STACK_PERMS,
+    ._dl_stack_prot_flags = DEFAULT_STACK_PROT_PERMS,
 #ifdef _LIBC_REENTRANT
     ._dl_load_lock = _RTLD_LOCK_RECURSIVE_INITIALIZER,
     ._dl_load_write_lock = _RTLD_LOCK_RECURSIVE_INITIALIZER,
@@ -1198,7 +1198,7 @@ rtld_setup_main_map (struct link_map *main_map)
 	break;
 
       case PT_GNU_STACK:
-	GL(dl_stack_flags) = ph->p_flags;
+	GL(dl_stack_prot_flags) = pf_to_prot (ph->p_flags);
 	break;
 
       case PT_GNU_RELRO:
@@ -1488,12 +1488,12 @@ dl_main (const ElfW(Phdr) *phdr,
       --_dl_argc;
       ++_dl_argv;
 
-      /* The initialization of _dl_stack_flags done below assumes the
+      /* The initialization of dl_stack_prot_flags done below assumes the
 	 executable's PT_GNU_STACK may have been honored by the kernel, and
 	 so a PT_GNU_STACK with PF_X set means the stack started out with
 	 execute permission.  However, this is not really true if the
 	 dynamic linker is the executable the kernel loaded.  For this
-	 case, we must reinitialize _dl_stack_flags to match the dynamic
+	 case, we must reinitialize dl_stack_prot_flags to match the dynamic
 	 linker itself.  If the dynamic linker was built with a
 	 PT_GNU_STACK, then the kernel may have loaded us with a
 	 nonexecutable stack that we will have to make executable when we
@@ -1503,7 +1503,7 @@ dl_main (const ElfW(Phdr) *phdr,
       for (const ElfW(Phdr) *ph = phdr; ph < &phdr[phnum]; ++ph)
 	if (ph->p_type == PT_GNU_STACK)
 	  {
-	    GL(dl_stack_flags) = ph->p_flags;
+	    GL(dl_stack_prot_flags) = pf_to_prot (ph->p_flags);
 	    break;
 	  }
 
@@ -1624,8 +1624,6 @@ dl_main (const ElfW(Phdr) *phdr,
 
   bool has_interp = rtld_setup_main_map (main_map);
 
-  /* Handle this after PT_GNU_STACK parse, because it updates dl_stack_flags
-     if required.  */
   _dl_handle_execstack_tunable ();
 
   /* If the current libname is different from the SONAME, add the
diff --git a/include/alloca.h b/include/alloca.h
index c0b8395443..1bd3af3e27 100644
--- a/include/alloca.h
+++ b/include/alloca.h
@@ -4,8 +4,6 @@
 
 # ifndef _ISOMAC
 
-#include <stackinfo.h>
-
 #undef	__alloca
 
 /* Now define the internal interfaces.  */
diff --git a/include/stackinfo.h b/include/stackinfo.h
index 3c1541b42d..b2d9ed174f 100644
--- a/include/stackinfo.h
+++ b/include/stackinfo.h
@@ -39,4 +39,38 @@
 # error "stackinfo.h must define _STACK_GROWS_UP or _STACK_GROWS_DOWN!"
 #endif
 
+#include <sys/mman.h>
+#include <link.h>
+
+/* ELF uses the PF_x macros to specify the segment permissions, mmap
+   uses PROT_xxx.  In most cases the three macros have the values 1, 2,
+   and 3 but not in a matching order.  The following macros allows
+   converting from the PF_x values to PROT_xxx values.  */
+#define PF_TO_PROT \
+  ((PROT_READ << (PF_R * 4))						      \
+   | (PROT_WRITE << (PF_W * 4))						      \
+   | (PROT_EXEC << (PF_X * 4))						      \
+   | ((PROT_READ | PROT_WRITE) << ((PF_R | PF_W) * 4))			      \
+   | ((PROT_READ | PROT_EXEC) << ((PF_R | PF_X) * 4))			      \
+   | ((PROT_WRITE | PROT_EXEC) << (PF_W | PF_X) * 4)			      \
+   | ((PROT_READ | PROT_WRITE | PROT_EXEC) << ((PF_R | PF_W | PF_X) * 4)))
+
+static inline int
+pf_to_prot (ElfW(Word) value)
+{
+#if (PF_R | PF_W | PF_X) == 7 && (PROT_READ | PROT_WRITE | PROT_EXEC) == 7
+  return (PF_TO_PROT >> ((value & (PF_R | PF_W | PF_X)) * 4)) & 0xf;
+#else
+  ElfW(Word) ret = 0;
+  if (value & PF_R)
+    ret |= PROT_READ;
+  if (value & PF_W)
+    ret |= PROT_WRITE;
+  if (value & PF_X)
+    ret |= PROT_EXEC;
+  return ret;
+#endif
+
+}
+
 #endif  /* include/stackinfo.h */
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
index 800ca89720..4c2aacdd10 100644
--- a/nptl/allocatestack.c
+++ b/nptl/allocatestack.c
@@ -150,17 +150,11 @@ get_cached_stack (size_t *sizep, void **memp)
    and fallback to ALLOCATE_GUARD_PROT_NONE if the madvise call fails.  */
 static int allocate_stack_mode = ALLOCATE_GUARD_MADV_GUARD;
 
-static inline int stack_prot (void)
-{
-  return (PROT_READ | PROT_WRITE
-	  | ((GL(dl_stack_flags) & PF_X) ? PROT_EXEC : 0));
-}
-
 static void *
 allocate_thread_stack (size_t size, size_t guardsize)
 {
   /* MADV_ADVISE_GUARD does not require an additional PROT_NONE mapping.  */
-  int prot = stack_prot ();
+  int prot = GL(dl_stack_prot_flags);
 
   if (atomic_load_relaxed (&allocate_stack_mode) == ALLOCATE_GUARD_PROT_NONE)
     /* If a guard page is required, avoid committing memory by first allocate
@@ -216,7 +210,7 @@ setup_stack_prot (char *mem, size_t size, struct pthread *pd,
     }
   else
     {
-      const int prot = stack_prot ();
+      const int prot = GL(dl_stack_prot_flags);
       char *guardend = guard + guardsize;
 #if _STACK_GROWS_DOWN
       /* As defined at guard_position, for architectures with downward stack
@@ -294,7 +288,7 @@ adjust_stack_prot (char *mem, size_t size, const struct pthread *pd,
 	}
       else if (pd->stack_mode == ALLOCATE_GUARD_PROT_NONE)
 	{
-	  const int prot = stack_prot ();
+	  const int prot = GL(dl_stack_prot_flags);
 #if _STACK_GROWS_DOWN
 	  return __mprotect (mem + guardsize, slacksize, prot) == 0;
 #else
diff --git a/support/support_stack_alloc.c b/support/support_stack_alloc.c
index 5e576bea74..132e7b4f70 100644
--- a/support/support_stack_alloc.c
+++ b/support/support_stack_alloc.c
@@ -64,11 +64,10 @@ support_stack_alloc (size_t size)
                             MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE|MAP_STACK,
                             -1);
   /* Some architecture still requires executable stack for the signal return
-     trampoline, although PF_X could be overridden if PT_GNU_STACK is present.
-     However since glibc does not export such information with a proper ABI,
-     it uses the historical permissions.  */
-  int prot = PROT_READ | PROT_WRITE
-	     | (DEFAULT_STACK_PERMS & PF_X ? PROT_EXEC : 0);
+     trampoline, although PROT_EXEC could be overridden if PT_GNU_STACK is
+     present.  However since glibc does not export such information with a
+     proper ABI, it uses the historical permissions.  */
+  int prot = DEFAULT_STACK_PROT_PERMS;
   xmprotect (alloc_base + guardsize, stacksize, prot);
   memset (alloc_base + guardsize, 0xA5, stacksize);
   return (struct support_stack) { alloc_base + guardsize, stacksize, guardsize };
diff --git a/sysdeps/alpha/stackinfo.h b/sysdeps/alpha/stackinfo.h
index a469964c10..d69647756b 100644
--- a/sysdeps/alpha/stackinfo.h
+++ b/sysdeps/alpha/stackinfo.h
@@ -26,8 +26,8 @@
 /* On Alpha the stack grows down.  */
 #define _STACK_GROWS_DOWN	1
 
-/* Default to an executable stack.  PF_X can be overridden if PT_GNU_STACK is
- * present, but it is presumed absent.  */
-#define DEFAULT_STACK_PERMS (PF_R|PF_W|PF_X)
+/* Default to an executable stack.  PROT_EXEC can be overridden if PT_GNU_STACK
+ * is present, but it is presumed absent.  */
+#define DEFAULT_STACK_PROT_PERMS (PROT_READ|PROT_WRITE|PROT_EXEC)
 
 #endif	/* stackinfo.h */
diff --git a/sysdeps/arm/stackinfo.h b/sysdeps/arm/stackinfo.h
index 3068352eab..30608f7062 100644
--- a/sysdeps/arm/stackinfo.h
+++ b/sysdeps/arm/stackinfo.h
@@ -26,8 +26,8 @@
 /* On Arm the stack grows down.  */
 #define _STACK_GROWS_DOWN	1
 
-/* Default to an executable stack.  PF_X can be overridden if PT_GNU_STACK is
- * present, but it is presumed absent.  */
-#define DEFAULT_STACK_PERMS (PF_R|PF_W|PF_X)
+/* Default to an executable stack.  PROT_EXEC can be overridden if PT_GNU_STACK
+ * is present, but it is presumed absent.  */
+#define DEFAULT_STACK_PROT_PERMS (PROT_READ|PROT_WRITE|PROT_EXEC)
 
 #endif	/* stackinfo.h */
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index fc4a3de767..bcf9582df4 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -418,7 +418,7 @@ struct rtld_global
 #include <dl-procruntime.c>
 
   /* Prevailing state of the stack, PF_X indicating it's executable.  */
-  EXTERN ElfW(Word) _dl_stack_flags;
+  EXTERN int _dl_stack_prot_flags;
 
   /* Flag signalling whether there are gaps in the module ID allocation.  */
   EXTERN bool _dl_tls_dtv_gaps;
diff --git a/sysdeps/generic/stackinfo.h b/sysdeps/generic/stackinfo.h
index 8abbb3dff7..ab3e72e5c2 100644
--- a/sysdeps/generic/stackinfo.h
+++ b/sysdeps/generic/stackinfo.h
@@ -24,6 +24,6 @@
 #include <elf.h>
 
 #define _STACK_GROWS_DOWN	1
-#define DEFAULT_STACK_PERMS	(PF_R|PF_W)
+#define DEFAULT_STACK_PROT_PERMS (PROT_READ|PROT_WRITE)
 
 #endif
diff --git a/sysdeps/hppa/stackinfo.h b/sysdeps/hppa/stackinfo.h
index 53bb11fde0..22920d20a9 100644
--- a/sysdeps/hppa/stackinfo.h
+++ b/sysdeps/hppa/stackinfo.h
@@ -23,9 +23,9 @@
 
 #include <elf.h>
 
-/* Default to an executable stack.  PF_X can be overridden if PT_GNU_STACK is
- * present, but it is presumed absent.  */
-#define DEFAULT_STACK_PERMS (PF_R|PF_W|PF_X)
+/* Default to an executable stack.  PROT_EXEC can be overridden if PT_GNU_STACK
+ * is present, but it is presumed absent.  */
+#define DEFAULT_STACK_PROT_PERMS (PROT_READ|PROT_WRITE|PROT_EXEC)
 
 /* On PA the stack grows up.  */
 #define _STACK_GROWS_UP	1
diff --git a/sysdeps/i386/stackinfo.h b/sysdeps/i386/stackinfo.h
index 74e82278d3..8d7a46c405 100644
--- a/sysdeps/i386/stackinfo.h
+++ b/sysdeps/i386/stackinfo.h
@@ -26,9 +26,9 @@
 /* On x86 the stack grows down.  */
 #define _STACK_GROWS_DOWN	1
 
-/* Default to an executable stack.  PF_X can be overridden if PT_GNU_STACK is
- * present, but it is presumed absent.  */
-#define DEFAULT_STACK_PERMS (PF_R|PF_W|PF_X)
+/* Default to an executable stack.  PROT_EXEC can be overridden if PT_GNU_STACK
+ * is present, but it is presumed absent.  */
+#define DEFAULT_STACK_PROT_PERMS (PROT_READ|PROT_WRITE|PROT_EXEC)
 
 /* Access to the stack pointer.  The macros are used in alloca_account
    for which they need to act as barriers as well, hence the additional
diff --git a/sysdeps/m68k/stackinfo.h b/sysdeps/m68k/stackinfo.h
index 7a757df147..77672c71c4 100644
--- a/sysdeps/m68k/stackinfo.h
+++ b/sysdeps/m68k/stackinfo.h
@@ -26,9 +26,9 @@
 /* On m68k the stack grows down.  */
 #define _STACK_GROWS_DOWN	1
 
-/* Default to an executable stack.  PF_X can be overridden if PT_GNU_STACK
-   is present, but it is presumed absent.  */
-#define DEFAULT_STACK_PERMS (PF_R|PF_W|PF_X)
+/* Default to an executable stack.  PROT_EXEC can be overridden if PT_GNU_STACK is
+ * present, but it is presumed absent.  */
+#define DEFAULT_STACK_PROT_PERMS (PROT_READ|PROT_WRITE|PROT_EXEC)
 
 /* Access to the stack pointer.  */
 #define stackinfo_get_sp() \
diff --git a/sysdeps/mach/htl/pt-stack-alloc.c b/sysdeps/mach/htl/pt-stack-alloc.c
index 3e196f8ca7..42762bc0ad 100644
--- a/sysdeps/mach/htl/pt-stack-alloc.c
+++ b/sysdeps/mach/htl/pt-stack-alloc.c
@@ -33,7 +33,7 @@ __pthread_stack_alloc (void **stackaddr, size_t stacksize)
   error_t err;
   vm_prot_t prot = VM_PROT_READ | VM_PROT_WRITE;
 
-  if (GL(dl_stack_flags) & PF_X)
+  if (GL(dl_stack_prot_flags) & PROT_EXEC)
     prot |= VM_PROT_EXECUTE;
 
   err = __vm_map (__mach_task_self (), (vm_offset_t *) stackaddr,
diff --git a/sysdeps/mach/hurd/dl-execstack.c b/sysdeps/mach/hurd/dl-execstack.c
index dc4719bd38..9e69169367 100644
--- a/sysdeps/mach/hurd/dl-execstack.c
+++ b/sysdeps/mach/hurd/dl-execstack.c
@@ -38,7 +38,7 @@ _dl_make_stack_executable (const void *stack_endp)
     return errno;
 
   /* Remember that we changed the permission.  */
-  GL(dl_stack_flags) |= PF_X;
+  GL(dl_stack_prot_flags) |= PROT_EXEC;
 
   return 0;
 #else
diff --git a/sysdeps/microblaze/stackinfo.h b/sysdeps/microblaze/stackinfo.h
index 8960bd3d25..51d40a7732 100644
--- a/sysdeps/microblaze/stackinfo.h
+++ b/sysdeps/microblaze/stackinfo.h
@@ -27,8 +27,8 @@
 /* On MicroBlaze the stack grows down.  */
 # define _STACK_GROWS_DOWN	1
 
-/* Default to an executable stack.  PF_X can be overridden if PT_GNU_STACK is
- * present, but it is presumed absent.  */
-# define DEFAULT_STACK_PERMS (PF_R|PF_W|PF_X)
+/* Default to an executable stack.  PROT_EXEC can be overridden if PT_GNU_STACK
+ * is present, but it is presumed absent.  */
+#define DEFAULT_STACK_PROT_PERMS (PROT_READ|PROT_WRITE|PROT_EXEC)
 
 #endif	/* stackinfo.h.  */
diff --git a/sysdeps/mips/stackinfo.h b/sysdeps/mips/stackinfo.h
index 6cce9386d6..107a8ea7c9 100644
--- a/sysdeps/mips/stackinfo.h
+++ b/sysdeps/mips/stackinfo.h
@@ -26,8 +26,8 @@
 /* On MIPS the stack grows down.  */
 #define _STACK_GROWS_DOWN	1
 
-/* Default to an executable stack.  PF_X can be overridden if PT_GNU_STACK is
- * present, but it is presumed absent.  */
-#define DEFAULT_STACK_PERMS (PF_R|PF_W|PF_X)
+/* Default to an executable stack.  PROT_EXEC can be overridden if PT_GNU_STACK
+ * is present, but it is presumed absent.  */
+#define DEFAULT_STACK_PROT_PERMS (PROT_READ|PROT_WRITE|PROT_EXEC)
 
 #endif	/* stackinfo.h */
diff --git a/sysdeps/or1k/stackinfo.h b/sysdeps/or1k/stackinfo.h
index 39cf5c2456..d93a795c51 100644
--- a/sysdeps/or1k/stackinfo.h
+++ b/sysdeps/or1k/stackinfo.h
@@ -27,8 +27,8 @@
 /* On or1k the stack grows down.  */
 #define _STACK_GROWS_DOWN	1
 
-/* Default to an executable stack.  PF_X can be overridden if PT_GNU_STACK is
-   present, but it is presumed absent.  */
-#define DEFAULT_STACK_PERMS (PF_R | PF_W | PF_X)
+/* Default to an executable stack.  PROT_EXEC can be overridden if PT_GNU_STACK
+ * is present, but it is presumed absent.  */
+#define DEFAULT_STACK_PROT_PERMS (PROT_READ|PROT_WRITE|PROT_EXEC)
 
 #endif /* stackinfo.h */
diff --git a/sysdeps/powerpc/powerpc32/stackinfo.h b/sysdeps/powerpc/powerpc32/stackinfo.h
index 31cba55805..50a3b367c6 100644
--- a/sysdeps/powerpc/powerpc32/stackinfo.h
+++ b/sysdeps/powerpc/powerpc32/stackinfo.h
@@ -26,7 +26,7 @@
 /* On PPC the stack grows down.  */
 #define _STACK_GROWS_DOWN	1
 
-/* PF_X can be overridden if PT_GNU_STACK is present but is presumed absent.  */
-#define DEFAULT_STACK_PERMS (PF_R|PF_W|PF_X)
+/* PROT_EXEC can be overridden if PT_GNU_STACK is present but is presumed absent.  */
+#define DEFAULT_STACK_PROT_PERMS (PROT_READ|PROT_WRITE|PROT_EXEC)
 
 #endif	/* stackinfo.h */
diff --git a/sysdeps/s390/stackinfo.h b/sysdeps/s390/stackinfo.h
index 657ab3487f..9be764495a 100644
--- a/sysdeps/s390/stackinfo.h
+++ b/sysdeps/s390/stackinfo.h
@@ -26,8 +26,8 @@
 /* On s390 the stack grows down.  */
 #define _STACK_GROWS_DOWN	1
 
-/* Default to an executable stack.  PF_X can be overridden if PT_GNU_STACK is
- * present, but it is presumed absent.  */
-#define DEFAULT_STACK_PERMS (PF_R|PF_W|PF_X)
+/* Default to an executable stack.  PROT_EXEC can be overridden if PT_GNU_STACK
+ * is present, but it is presumed absent.  */
+#define DEFAULT_STACK_PROT_PERMS (PROT_READ|PROT_WRITE|PROT_EXEC)
 
 #endif	/* stackinfo.h */
diff --git a/sysdeps/sh/stackinfo.h b/sysdeps/sh/stackinfo.h
index 8f7bf163be..e502993d24 100644
--- a/sysdeps/sh/stackinfo.h
+++ b/sysdeps/sh/stackinfo.h
@@ -26,8 +26,8 @@
 /* On SH the stack grows down.  */
 #define _STACK_GROWS_DOWN	1
 
-/* Default to an executable stack.  PF_X can be overridden if PT_GNU_STACK is
- * present, but it is presumed absent.  */
-#define DEFAULT_STACK_PERMS (PF_R|PF_W|PF_X)
+/* Default to an executable stack.  PROT_EXEC can be overridden if PT_GNU_STACK
+ * is present, but it is presumed absent.  */
+#define DEFAULT_STACK_PROT_PERMS (PROT_READ|PROT_WRITE|PROT_EXEC)
 
 #endif	/* stackinfo.h */
diff --git a/sysdeps/sparc/stackinfo.h b/sysdeps/sparc/stackinfo.h
index 23a74ed7fe..a4a0eb15c9 100644
--- a/sysdeps/sparc/stackinfo.h
+++ b/sysdeps/sparc/stackinfo.h
@@ -26,8 +26,8 @@
 /* On sparc the stack grows down.  */
 #define _STACK_GROWS_DOWN	1
 
-/* Default to an executable stack.  PF_X can be overridden if PT_GNU_STACK is
- * present, but it is presumed absent.  */
-#define DEFAULT_STACK_PERMS (PF_R|PF_W|PF_X)
+/* Default to an executable stack.  PROT_EXEC can be overridden if PT_GNU_STACK
+ * is present, but it is presumed absent.  */
+#define DEFAULT_STACK_PROT_PERMS (PROT_READ|PROT_WRITE|PROT_EXEC)
 
 #endif	/* stackinfo.h */
diff --git a/sysdeps/unix/sysv/linux/dl-execstack.c b/sysdeps/unix/sysv/linux/dl-execstack.c
index 6db9601656..a59bd5632a 100644
--- a/sysdeps/unix/sysv/linux/dl-execstack.c
+++ b/sysdeps/unix/sysv/linux/dl-execstack.c
@@ -17,6 +17,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <ldsodefs.h>
+#include <stackinfo.h>
 
 int
 _dl_make_stack_executable (const void *stack_endp)
@@ -36,7 +37,7 @@ _dl_make_stack_executable (const void *stack_endp)
     return errno;
 
   /* Remember that we changed the permission.  */
-  GL(dl_stack_flags) |= PF_X;
+  GL(dl_stack_prot_flags) |= PROT_EXEC;
 
   return 0;
 }
diff --git a/sysdeps/unix/sysv/linux/machine-sp.h b/sysdeps/unix/sysv/linux/machine-sp.h
index 6ab3ca6d50..bda90fe801 100644
--- a/sysdeps/unix/sysv/linux/machine-sp.h
+++ b/sysdeps/unix/sysv/linux/machine-sp.h
@@ -19,6 +19,8 @@
 #ifndef _MACHINE_SP_H
 #define _MACHINE_SP_H
 
+#include <stackinfo.h>
+
 /* Return the current stack pointer.  */
 static inline uintptr_t
 __thread_stack_pointer (void)
diff --git a/sysdeps/unix/sysv/linux/spawni.c b/sysdeps/unix/sysv/linux/spawni.c
index eca1a84254..bc8476ff11 100644
--- a/sysdeps/unix/sysv/linux/spawni.c
+++ b/sysdeps/unix/sysv/linux/spawni.c
@@ -348,9 +348,6 @@ __spawnix (int *pid, const char *file,
 	return errno;
       }
 
-  int prot = (PROT_READ | PROT_WRITE
-	     | ((GL (dl_stack_flags) & PF_X) ? PROT_EXEC : 0));
-
   /* Add a slack area for child's stack.  */
   size_t argv_size = (argc * sizeof (void *)) + 512;
   /* We need at least a few pages in case the compiler's stack checking is
@@ -361,7 +358,7 @@ __spawnix (int *pid, const char *file,
      where it might use about 1k extra stack space).  */
   argv_size += (32 * 1024);
   size_t stack_size = ALIGN_UP (argv_size, GLRO(dl_pagesize));
-  void *stack = __mmap (NULL, stack_size, prot,
+  void *stack = __mmap (NULL, stack_size, GL (dl_stack_prot_flags),
 			MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
   if (__glibc_unlikely (stack == MAP_FAILED))
     return errno;
diff --git a/sysdeps/x86_64/stackinfo.h b/sysdeps/x86_64/stackinfo.h
index 416d687869..0e88e6d94e 100644
--- a/sysdeps/x86_64/stackinfo.h
+++ b/sysdeps/x86_64/stackinfo.h
@@ -32,9 +32,9 @@
 /* On x86_64 the stack grows down.  */
 #define _STACK_GROWS_DOWN	1
 
-/* Default to an executable stack.  PF_X can be overridden if PT_GNU_STACK is
- * present, but it is presumed absent.  */
-#define DEFAULT_STACK_PERMS (PF_R|PF_W|PF_X)
+/* Default to an executable stack.  PROT_EXEC can be overridden if PT_GNU_STACK
+ * is present, but it is presumed absent.  */
+#define DEFAULT_STACK_PROT_PERMS (PROT_READ|PROT_WRITE|PROT_EXEC)
 
 /* Access to the stack pointer.  The macros are used in alloca_account
    for which they need to act as barriers as well, hence the additional
-- 
2.39.5



More information about the Libc-alpha mailing list