diff options
author | Andreas Kling <kling@serenityos.org> | 2021-02-02 19:59:15 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-02-02 20:13:44 +0100 |
commit | df7ddfb8035ed133e01edb3ed3aba0cf2088e8b0 (patch) | |
tree | bdf8d3ba40531ca40469bfef45ac7cae676e74a7 | |
parent | 47d0ca85e8da188be0d829192008a4eee9d92e39 (diff) | |
download | serenity-df7ddfb8035ed133e01edb3ed3aba0cf2088e8b0.zip |
LibELF: Mark libc.so and libpthread.so as syscall regions
Also, before calling the main program entry function, inform the kernel
that no more syscall regions can be registered.
This effectively bans syscalls from everywhere except LibC and
LibPthread. Pretty neat! :^)
-rw-r--r-- | Userland/Libraries/LibELF/DynamicLinker.cpp | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/Userland/Libraries/LibELF/DynamicLinker.cpp b/Userland/Libraries/LibELF/DynamicLinker.cpp index f3273ea87c..746adbc3ee 100644 --- a/Userland/Libraries/LibELF/DynamicLinker.cpp +++ b/Userland/Libraries/LibELF/DynamicLinker.cpp @@ -31,6 +31,7 @@ #include <AK/LexicalPath.h> #include <AK/LogStream.h> #include <AK/ScopeGuard.h> +#include <Kernel/API/Syscall.h> #include <LibC/mman.h> #include <LibC/stdio.h> #include <LibC/sys/internals.h> @@ -214,6 +215,14 @@ static NonnullRefPtr<DynamicLoader> commit_elf(const String& name) auto object = loader->load_stage_3(RTLD_GLOBAL | RTLD_LAZY, g_total_tls_size); ASSERT(object); + + + if (name.is_one_of("libc.so", "libpthread.so")) { + if (syscall(SC_msyscall, object->base_address().as_ptr())) { + ASSERT_NOT_REACHED(); + } + } + if (name == "libc.so") { initialize_libc(*object); } @@ -263,7 +272,13 @@ void ELF::DynamicLinker::linker_main(String&& main_program_name, int main_progra if (g_do_breakpoint_trap_before_entry) { asm("int3"); } - int rc = main_function(argc, argv, envp); + + int rc = syscall(SC_msyscall, nullptr); + if (rc < 0) { + ASSERT_NOT_REACHED(); + } + + rc = main_function(argc, argv, envp); dbgln<DYNAMIC_LOAD_DEBUG>("rc: {}", rc); if (g_libc_exit != nullptr) { g_libc_exit(rc); |