mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-23 13:30:06 +00:00
52a01100ad
This looks like a post-exploitation hardening measure: If an attacker is able to redirect execution flow, they could use that to load a DSO which contains additional code (or perhaps make the stack executable). However, the checks are not in the correct place to be effective: If they are performed before the critical operation, an attacker with sufficient control over execution flow could simply jump directly to the code which performs the operation, bypassing the check. The check would have to be executed unconditionally after the operation and terminate the process in case a caller violation was detected. Furthermore, in _dl_check_caller, there was a fallback reading global writable data (GL(dl_rtld_map).l_map_start and GL(dl_rtld_map).l_text_end), which could conceivably be targeted by an attacker to disable the check, too. Other critical functions (such as system) remain completely unprotected, so the value of these additional checks does not appear that large. Therefore this commit removes this functionality.
60 lines
1.7 KiB
C
60 lines
1.7 KiB
C
/* Stack executability handling for GNU dynamic linker. Linux version.
|
|
Copyright (C) 2003-2018 Free Software Foundation, Inc.
|
|
This file is part of the GNU C Library.
|
|
|
|
The GNU C Library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2.1 of the License, or (at your option) any later version.
|
|
|
|
The GNU C Library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with the GNU C Library; if not, see
|
|
<http://www.gnu.org/licenses/>. */
|
|
|
|
#include <ldsodefs.h>
|
|
#include <sys/mman.h>
|
|
#include <errno.h>
|
|
#include <libintl.h>
|
|
#include <stdbool.h>
|
|
#include <stackinfo.h>
|
|
#include <sysdep.h>
|
|
|
|
|
|
extern int __stack_prot attribute_relro attribute_hidden;
|
|
|
|
|
|
int
|
|
_dl_make_stack_executable (void **stack_endp)
|
|
{
|
|
/* This gives us the highest/lowest page that needs to be changed. */
|
|
uintptr_t page = ((uintptr_t) *stack_endp
|
|
& -(intptr_t) GLRO(dl_pagesize));
|
|
int result = 0;
|
|
|
|
if (__builtin_expect (__mprotect ((void *) page, GLRO(dl_pagesize),
|
|
__stack_prot) == 0, 1))
|
|
goto return_success;
|
|
result = errno;
|
|
goto out;
|
|
|
|
return_success:
|
|
/* Clear the address. */
|
|
*stack_endp = NULL;
|
|
|
|
/* Remember that we changed the permission. */
|
|
GL(dl_stack_flags) |= PF_X;
|
|
|
|
out:
|
|
#ifdef check_consistency
|
|
check_consistency ();
|
|
#endif
|
|
|
|
return result;
|
|
}
|
|
rtld_hidden_def (_dl_make_stack_executable)
|