diff options
author | Cupertino Miranda <cupertino.miranda@oracle.com> | 2025-08-22 11:37:00 +0100 |
---|---|---|
committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2025-08-27 10:45:45 -0300 |
commit | 3b2b88cceeb79f73a72367800d91599e2af4bb39 (patch) | |
tree | a4f7c0efe8d6c2a49ac448c977a639e609c3f45c | |
parent | 921e251e8f364d00fc753274095007275381ae65 (diff) | |
download | glibc-3b2b88cceeb79f73a72367800d91599e2af4bb39.zip glibc-3b2b88cceeb79f73a72367800d91599e2af4bb39.tar.gz glibc-3b2b88cceeb79f73a72367800d91599e2af4bb39.tar.bz2 |
elf: early conversion of elf p_flags to mprotect flags
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
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
30 files changed, 104 insertions, 102 deletions
diff --git a/elf/Makefile b/elf/Makefile index 3a5596e..5a676f8 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -2167,7 +2167,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 e3b638a..b2511ea 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 00b9da9..891b449 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1095,7 +1095,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. */ @@ -1170,18 +1170,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: @@ -1218,7 +1207,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: @@ -1318,7 +1307,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 7b2a1c3..bbef3ab 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: @@ -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, @@ -1197,7 +1197,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: @@ -1541,12 +1541,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 @@ -1556,7 +1556,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; } @@ -1677,8 +1677,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 c0b8395..5f2df32 100644 --- a/include/alloca.h +++ b/include/alloca.h @@ -4,7 +4,7 @@ # ifndef _ISOMAC -#include <stackinfo.h> +#include <elf.h> #undef __alloca diff --git a/include/stackinfo.h b/include/stackinfo.h index 3c1541b..3cf36c9 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 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 */ diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c index 800ca89..4c2aacd 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 5e576be..132e7b4 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 a469964..d696477 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 3068352..30608f7 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 74025f1..31e9a6b 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -171,19 +171,6 @@ dl_symbol_visibility_binds_local_p (const ElfW(Sym) *sym) # 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>")) @@ -416,7 +403,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 8abbb3d..ab3e72e 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 53bb11f..22920d2 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 74e8227..8d7a46c 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 7a757df..74c0af5 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 +/* 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() \ diff --git a/sysdeps/mach/htl/pt-stack-alloc.c b/sysdeps/mach/htl/pt-stack-alloc.c index 64cc186..d9f3e24 100644 --- a/sysdeps/mach/htl/pt-stack-alloc.c +++ b/sysdeps/mach/htl/pt-stack-alloc.c @@ -34,7 +34,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 dc4719b..9e69169 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/mach/hurd/htl/pt-sysdep.c b/sysdeps/mach/hurd/htl/pt-sysdep.c index 3505d31..735dc5b 100644 --- a/sysdeps/mach/hurd/htl/pt-sysdep.c +++ b/sysdeps/mach/hurd/htl/pt-sysdep.c @@ -25,6 +25,7 @@ #include <pt-internal.h> #include <pthreadP.h> +#include <stackinfo.h> static void reset_pthread_total (void) diff --git a/sysdeps/microblaze/stackinfo.h b/sysdeps/microblaze/stackinfo.h index 8960bd3..51d40a7 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 6cce938..107a8ea 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 39cf5c2..10a56c5 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 31cba55..327e614 100644 --- a/sysdeps/powerpc/powerpc32/stackinfo.h +++ b/sysdeps/powerpc/powerpc32/stackinfo.h @@ -26,7 +26,8 @@ /* 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 657ab34..9be7644 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 8f7bf16..e502993 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 23a74ed..a4a0eb1 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 6db9601..a59bd56 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 6ab3ca6..bda90fe 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 eca1a84..bc8476f 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 416d687..0e88e6d 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 |