mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-28 00:21:52 +03: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:
@ -29,16 +29,24 @@ int
|
|||||||
internal_function
|
internal_function
|
||||||
_dl_make_stack_executable (void)
|
_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
|
#if _STACK_GROWS_DOWN
|
||||||
/* This gives us the highest page that needs to be changed. */
|
/* This gives us the highest page that needs to be changed. */
|
||||||
uintptr_t page = (uintptr_t) __libc_stack_end & -(intptr_t) GL(dl_pagesize);
|
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
|
/* 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
|
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.
|
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. */
|
/* This gives us the lowest page that needs to be changed. */
|
||||||
uintptr_t page = (uintptr_t) __libc_stack_end & -(intptr_t) GL(dl_pagesize);
|
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
|
/* 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
|
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.
|
of the stack, it will include the hole and fail with ENOMEM.
|
||||||
|
Reference in New Issue
Block a user