mirror of
git://sourceware.org/git/glibc.git
synced 2024-11-27 03:41:23 +08:00
2003-09-25 Roland McGrath <roland@redhat.com>
* sysdeps/unix/sysv/linux/dl-execstack.c (_dl_make_stack_executable): Don't check for zero __libc_stack_end, it should be initialized. [_STACK_GROWS_DOWN] [PROT_GROWSDOWN]: Try using PROT_GROWSDOWN flag and fall back if it fails with EINVAL. [_STACK_GROWS_UP] [PROT_GROWSUP]: Likewise for PROT_GROWSUP.
This commit is contained in:
parent
55715bfca6
commit
e95dc10c40
@ -29,16 +29,24 @@ int
|
||||
internal_function
|
||||
_dl_make_stack_executable (void)
|
||||
{
|
||||
if (__libc_stack_end == 0)
|
||||
/* XXX for a DT_NEEDED library that requires the change,
|
||||
this is not initialized yet!
|
||||
*/
|
||||
return ENOSYS;
|
||||
|
||||
#if _STACK_GROWS_DOWN
|
||||
/* This gives us the highest page that needs to be changed. */
|
||||
uintptr_t page = (uintptr_t) __libc_stack_end & -(intptr_t) GL(dl_pagesize);
|
||||
|
||||
/* Newer Linux kernels support a flag to make our job easy. */
|
||||
# ifdef PROT_GROWSDOWN
|
||||
static bool no_growsdown;
|
||||
if (! no_growsdown)
|
||||
{
|
||||
if (__mprotect ((void *) page, GL(dl_pagesize),
|
||||
PROT_READ|PROT_WRITE|PROT_EXEC|PROT_GROWSDOWN) == 0)
|
||||
return 0;
|
||||
if (errno != EINVAL)
|
||||
return errno;
|
||||
no_growsdown = true;
|
||||
}
|
||||
# endif
|
||||
|
||||
/* There is always a hole in the address space below the bottom of the
|
||||
stack. So when we make an mprotect call that starts below the bottom
|
||||
of the stack, it will include the hole and fail with ENOMEM.
|
||||
@ -76,6 +84,20 @@ _dl_make_stack_executable (void)
|
||||
/* This gives us the lowest page that needs to be changed. */
|
||||
uintptr_t page = (uintptr_t) __libc_stack_end & -(intptr_t) GL(dl_pagesize);
|
||||
|
||||
/* Newer Linux kernels support a flag to make our job easy. */
|
||||
# ifdef PROT_GROWSUP
|
||||
static bool no_growsup;
|
||||
if (! no_growsup)
|
||||
{
|
||||
if (__mprotect ((void *) page, GL(dl_pagesize),
|
||||
PROT_READ|PROT_WRITE|PROT_EXEC|PROT_GROWSUP) == 0)
|
||||
return 0;
|
||||
if (errno != EINVAL)
|
||||
return errno;
|
||||
no_growsup = true;
|
||||
}
|
||||
# endif
|
||||
|
||||
/* There is always a hole in the address space above the top of the
|
||||
stack. So when we make an mprotect call that spans past the top
|
||||
of the stack, it will include the hole and fail with ENOMEM.
|
||||
|
Loading…
Reference in New Issue
Block a user