1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 02:37:36 +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:
Ben Wiederhake 2021-11-06 12:49:26 +01:00 committed by Andreas Kling
parent 2801323236
commit 2158e1a6b9
3 changed files with 15 additions and 3 deletions

View file

@ -39,6 +39,7 @@ int _entry(int argc, char** argv, char** env)
environ = env;
__environ_is_malloced = false;
__begin_atexit_locking();
_init();

View file

@ -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");

View file

@ -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;