$(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@@@'; \
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;
/* 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. */
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:
break;
case PT_GNU_STACK:
- stack_flags = ph->p_flags;
+ stack_flags = pf_to_prot (ph->p_flags);
break;
case PT_GNU_RELRO:
/* 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
/* 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;
{
/* 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:
#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,
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:
--_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
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;
}
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
# ifndef _ISOMAC
-#include <stackinfo.h>
+#include <elf.h>
#undef __alloca
# 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 4 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 */
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
}
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
}
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
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 };
/* 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 */
/* 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 */
# define ELF_RTYPE_CLASS_COPY 0
#endif
-/* 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)))
-
/* The filename itself, or the main program name, if available. */
#define DSO_FILENAME(name) ((name)[0] ? (name) \
: (rtld_progname ?: "<main program>"))
#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;
#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
#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
/* 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
/* 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
+/* Default to an executable stack. PROT_EXEC can be overridden if PT_GNU_STACK
is present, but it is presumed absent. */
-#define DEFAULT_STACK_PERMS (PF_R|PF_W|PF_X)
+#define DEFAULT_STACK_PROT_PERMS (PROT_READ|PROT_WRITE|PROT_EXEC)
/* Access to the stack pointer. */
#define stackinfo_get_sp() \
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,
return errno;
/* Remember that we changed the permission. */
- GL(dl_stack_flags) |= PF_X;
+ GL(dl_stack_prot_flags) |= PROT_EXEC;
return 0;
#else
#include <pt-internal.h>
#include <pthreadP.h>
+#include <stackinfo.h>
static void
reset_pthread_total (void)
/* 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. */
/* 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 */
/* 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 */
/* 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 */
/* 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 */
/* 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 */
/* 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 */
<https://www.gnu.org/licenses/>. */
#include <ldsodefs.h>
+#include <stackinfo.h>
int
_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;
}
#ifndef _MACHINE_SP_H
#define _MACHINE_SP_H
+#include <stackinfo.h>
+
/* Return the current stack pointer. */
static inline uintptr_t
__thread_stack_pointer (void)
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
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;
/* 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