linux: Remove __stack_prot

The __stack_prot is used by Linux to make the stack executable if
a modules requires it.  It is also marked as RELRO, which requires
to change the segment permission to RW to update it.

Also, there is no need to keep track of the flags: either the stack
will have the default permission of the ABI or should be change to
PROT_READ | PROT_WRITE | PROT_EXEC.  The only additional flag,
PROT_GROWSDOWN or PROT_GROWSUP, is Linux only and can be deducted
from _STACK_GROWS_DOWN/_STACK_GROWS_UP.

Also, the check_consistency function was already removed some time
ago.

Checked on x86_64-linux-gnu and i686-linux-gnu.
Reviewed-by: Florian Weimer <fweimer@redhat.com>
This commit is contained in:
Adhemerval Zanella 2024-06-11 12:27:04 -03:00
parent e7ac92e6ca
commit 7edd3814b0
2 changed files with 11 additions and 60 deletions

View File

@ -88,16 +88,6 @@ struct filebuf
#define STRING(x) __STRING (x) #define STRING(x) __STRING (x)
int __stack_prot attribute_hidden attribute_relro
#if _STACK_GROWS_DOWN && defined PROT_GROWSDOWN
= PROT_GROWSDOWN;
#elif _STACK_GROWS_UP && defined PROT_GROWSUP
= PROT_GROWSUP;
#else
= 0;
#endif
/* This is the decomposed LD_LIBRARY_PATH search path. */ /* This is the decomposed LD_LIBRARY_PATH search path. */
struct r_search_path_struct __rtld_env_path_list attribute_relro; struct r_search_path_struct __rtld_env_path_list attribute_relro;
@ -1308,41 +1298,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
if (__glibc_unlikely ((stack_flags &~ GL(dl_stack_flags)) & PF_X)) if (__glibc_unlikely ((stack_flags &~ GL(dl_stack_flags)) & PF_X))
{ {
/* The stack is presently not executable, but this module /* The stack is presently not executable, but this module
requires that it be executable. We must change the requires that it be executable. */
protection of the variable which contains the flags used in
the mprotect calls. */
#ifdef SHARED
if ((mode & (__RTLD_DLOPEN | __RTLD_AUDIT)) == __RTLD_DLOPEN)
{
const uintptr_t p = (uintptr_t) &__stack_prot & -GLRO(dl_pagesize);
const size_t s = (uintptr_t) (&__stack_prot + 1) - p;
struct link_map *const m = &GL(dl_rtld_map);
const uintptr_t relro_end = ((m->l_addr + m->l_relro_addr
+ m->l_relro_size)
& -GLRO(dl_pagesize));
if (__glibc_likely (p + s <= relro_end))
{
/* The variable lies in the region protected by RELRO. */
if (__mprotect ((void *) p, s, PROT_READ|PROT_WRITE) < 0)
{
errstring = N_("cannot change memory protections");
goto lose_errno;
}
__stack_prot |= PROT_READ|PROT_WRITE|PROT_EXEC;
__mprotect ((void *) p, s, PROT_READ);
}
else
__stack_prot |= PROT_READ|PROT_WRITE|PROT_EXEC;
}
else
#endif
__stack_prot |= PROT_READ|PROT_WRITE|PROT_EXEC;
#ifdef check_consistency
check_consistency ();
#endif
#if PTHREAD_IN_LIBC #if PTHREAD_IN_LIBC
errval = _dl_make_stacks_executable (stack_endp); errval = _dl_make_stacks_executable (stack_endp);
#else #else

View File

@ -27,35 +27,30 @@
#include <sysdep.h> #include <sysdep.h>
#include <unistd.h> #include <unistd.h>
extern int __stack_prot attribute_relro attribute_hidden;
static int static int
make_main_stack_executable (void **stack_endp) make_main_stack_executable (void **stack_endp)
{ {
/* This gives us the highest/lowest page that needs to be changed. */ /* This gives us the highest/lowest page that needs to be changed. */
uintptr_t page = ((uintptr_t) *stack_endp uintptr_t page = ((uintptr_t) *stack_endp
& -(intptr_t) GLRO(dl_pagesize)); & -(intptr_t) GLRO(dl_pagesize));
int result = 0;
if (__builtin_expect (__mprotect ((void *) page, GLRO(dl_pagesize), if (__mprotect ((void *) page, GLRO(dl_pagesize),
__stack_prot) == 0, 1)) PROT_READ | PROT_WRITE | PROT_EXEC
goto return_success; #if _STACK_GROWS_DOWN
result = errno; | PROT_GROWSDOWN
goto out; #elif _STACK_GROWS_UP
| PROT_GROWSUP
#endif
) != 0)
return errno;
return_success:
/* Clear the address. */ /* Clear the address. */
*stack_endp = NULL; *stack_endp = NULL;
/* Remember that we changed the permission. */ /* Remember that we changed the permission. */
GL(dl_stack_flags) |= PF_X; GL(dl_stack_flags) |= PF_X;
out: return 0;
#ifdef check_consistency
check_consistency ();
#endif
return result;
} }
int int