diff options
author | Gunnar Beutner <gunnar@beutner.name> | 2021-04-16 21:50:17 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-04-18 10:55:25 +0200 |
commit | cf13fa57cde216b489f6ca1d88e38151151e7c6a (patch) | |
tree | 3e0df434c0beb7f7253d00db11d713e6a88f307b /Kernel | |
parent | 8dc375da96ea3c15445ea03978d48894c5816e88 (diff) | |
download | serenity-cf13fa57cde216b489f6ca1d88e38151151e7c6a.zip |
Kernel: Allow system calls from the dynamic loader
Previously the dynamic loader would become unused after it had invoked
the program's entry function. However, in order to support exceptions
and - at a later point - dlfcn functionality we need to call back
into the dynamic loader at runtime.
Because the dynamic loader has a static copy of LibC it'll attempt to
invoke syscalls directly from its text segment. For this to work the
executable region for the dynamic loader needs to have syscalls enabled.
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/Syscalls/execve.cpp | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/Kernel/Syscalls/execve.cpp b/Kernel/Syscalls/execve.cpp index d0effba3f3..6b440cf755 100644 --- a/Kernel/Syscalls/execve.cpp +++ b/Kernel/Syscalls/execve.cpp @@ -255,7 +255,13 @@ enum class ShouldAllocateTls { Yes, }; -static KResultOr<LoadResult> load_elf_object(NonnullOwnPtr<Space> new_space, FileDescription& object_description, FlatPtr load_offset, ShouldAllocateTls should_allocate_tls) +enum class ShouldAllowSyscalls { + No, + Yes, +}; + +static KResultOr<LoadResult> load_elf_object(NonnullOwnPtr<Space> new_space, FileDescription& object_description, + FlatPtr load_offset, ShouldAllocateTls should_allocate_tls, ShouldAllowSyscalls should_allow_syscalls) { auto& inode = *(object_description.inode()); auto vmobject = SharedInodeVMObject::create_with_inode(inode); @@ -392,6 +398,8 @@ static KResultOr<LoadResult> load_elf_object(NonnullOwnPtr<Space> new_space, Fil ph_load_result = region_or_error.error(); return IterationDecision::Break; } + if (should_allow_syscalls == ShouldAllowSyscalls::Yes) + region_or_error.value()->set_syscall_region(true); if (program_header.offset() == 0) load_base_address = (FlatPtr)region_or_error.value()->vaddr().as_ptr(); return IterationDecision::Continue; @@ -442,7 +450,7 @@ KResultOr<LoadResult> Process::load(NonnullRefPtr<FileDescription> main_program_ }); if (interpreter_description.is_null()) { - auto result = load_elf_object(new_space.release_nonnull(), main_program_description, FlatPtr { 0 }, ShouldAllocateTls::Yes); + auto result = load_elf_object(new_space.release_nonnull(), main_program_description, FlatPtr { 0 }, ShouldAllocateTls::Yes, ShouldAllowSyscalls::No); if (result.is_error()) return result.error(); @@ -458,7 +466,7 @@ KResultOr<LoadResult> Process::load(NonnullRefPtr<FileDescription> main_program_ return interpreter_load_offset.error(); } - auto interpreter_load_result = load_elf_object(new_space.release_nonnull(), *interpreter_description, interpreter_load_offset.value(), ShouldAllocateTls::No); + auto interpreter_load_result = load_elf_object(new_space.release_nonnull(), *interpreter_description, interpreter_load_offset.value(), ShouldAllocateTls::No, ShouldAllowSyscalls::Yes); if (interpreter_load_result.is_error()) return interpreter_load_result.error(); |