mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 07:37:46 +00:00
LibC: Avoid unnecessary mprotect during program initialization
For 'true', this shaves off about 69 syscalls, as measured by strace.
This commit is contained in:
parent
2801323236
commit
2158e1a6b9
3 changed files with 15 additions and 3 deletions
|
@ -39,6 +39,7 @@ int _entry(int argc, char** argv, char** env)
|
|||
|
||||
environ = env;
|
||||
__environ_is_malloced = false;
|
||||
__begin_atexit_locking();
|
||||
|
||||
_init();
|
||||
|
||||
|
|
|
@ -32,9 +32,13 @@ static AtExitEntry* atexit_entries;
|
|||
static size_t atexit_entry_count = 0;
|
||||
static pthread_mutex_t atexit_mutex = __PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
// During startup, it is sufficiently unlikely that the attacker can exploit any write primitive.
|
||||
// We use this to avoid unnecessary syscalls to mprotect.
|
||||
static bool atexit_region_should_lock = false;
|
||||
|
||||
static void lock_atexit_handlers()
|
||||
{
|
||||
if (mprotect(atexit_entries, atexit_entry_region_size, PROT_READ) < 0) {
|
||||
if (atexit_region_should_lock && mprotect(atexit_entries, atexit_entry_region_size, PROT_READ) < 0) {
|
||||
perror("lock_atexit_handlers");
|
||||
_exit(1);
|
||||
}
|
||||
|
@ -42,19 +46,25 @@ static void lock_atexit_handlers()
|
|||
|
||||
static void unlock_atexit_handlers()
|
||||
{
|
||||
if (mprotect(atexit_entries, atexit_entry_region_size, PROT_READ | PROT_WRITE) < 0) {
|
||||
if (atexit_region_should_lock && mprotect(atexit_entries, atexit_entry_region_size, PROT_READ | PROT_WRITE) < 0) {
|
||||
perror("unlock_atexit_handlers");
|
||||
_exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void __begin_atexit_locking()
|
||||
{
|
||||
atexit_region_should_lock = true;
|
||||
lock_atexit_handlers();
|
||||
}
|
||||
|
||||
int __cxa_atexit(AtExitFunction exit_function, void* parameter, void* dso_handle)
|
||||
{
|
||||
__pthread_mutex_lock(&atexit_mutex);
|
||||
|
||||
// allocate initial atexit region
|
||||
if (!atexit_entries) {
|
||||
atexit_entries = (AtExitEntry*)mmap(nullptr, atexit_entry_region_size, PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
|
||||
atexit_entries = (AtExitEntry*)mmap(nullptr, atexit_entry_region_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
|
||||
if (atexit_entries == MAP_FAILED) {
|
||||
__pthread_mutex_unlock(&atexit_mutex);
|
||||
perror("__cxa_atexit mmap");
|
||||
|
|
|
@ -15,6 +15,7 @@ typedef void (*AtExitFunction)(void*);
|
|||
extern void __libc_init();
|
||||
extern void __malloc_init();
|
||||
extern void __stdio_init();
|
||||
extern void __begin_atexit_locking();
|
||||
extern void _init();
|
||||
extern bool __environ_is_malloced;
|
||||
extern bool __stdio_is_initialized;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue