diff --git a/Userland/DynamicLoader/main.cpp b/Userland/DynamicLoader/main.cpp index f9a430e9c2..38504ab18f 100644 --- a/Userland/DynamicLoader/main.cpp +++ b/Userland/DynamicLoader/main.cpp @@ -83,21 +83,21 @@ void _entry(int argc, char** argv, char** envp) init_libc(); int main_program_fd = -1; - String main_program_name; + String main_program_path; bool is_secure = false; for (; auxvp->a_type != AT_NULL; ++auxvp) { if (auxvp->a_type == ELF::AuxiliaryValue::ExecFileDescriptor) { main_program_fd = auxvp->a_un.a_val; } if (auxvp->a_type == ELF::AuxiliaryValue::ExecFilename) { - main_program_name = (char const*)auxvp->a_un.a_ptr; + main_program_path = (char const*)auxvp->a_un.a_ptr; } if (auxvp->a_type == ELF::AuxiliaryValue::Secure) { is_secure = auxvp->a_un.a_val == 1; } } - if (main_program_name == "/usr/lib/Loader.so"sv) { + if (main_program_path == "/usr/lib/Loader.so"sv) { // We've been invoked directly as an executable rather than as the // ELF interpreter for some other binary. In the future we may want // to support launching a program directly from the dynamic loader @@ -107,9 +107,9 @@ void _entry(int argc, char** argv, char** envp) } VERIFY(main_program_fd >= 0); - VERIFY(!main_program_name.is_empty()); + VERIFY(!main_program_path.is_empty()); - ELF::DynamicLinker::linker_main(move(main_program_name), main_program_fd, is_secure, argc, argv, envp); + ELF::DynamicLinker::linker_main(move(main_program_path), main_program_fd, is_secure, argc, argv, envp); VERIFY_NOT_REACHED(); } } diff --git a/Userland/Libraries/LibELF/DynamicLinker.cpp b/Userland/Libraries/LibELF/DynamicLinker.cpp index eaf7e871be..9e83a388f0 100644 --- a/Userland/Libraries/LibELF/DynamicLinker.cpp +++ b/Userland/Libraries/LibELF/DynamicLinker.cpp @@ -35,7 +35,7 @@ namespace ELF { static HashMap> s_loaders; -static String s_main_program_name; +static String s_main_program_path; static OrderedHashMap> s_global_objects; using EntryPointFunction = int (*)(int, char**, char**); @@ -459,7 +459,7 @@ static Result __dlopen(char const* filename, int flags) dbgln_if(DYNAMIC_LOAD_DEBUG, "__dlopen invoked, filename={}, flags={}", filename, flags); - auto library_name = get_library_name(filename ? filename : s_main_program_name); + auto library_name = get_library_name(filename ? filename : s_main_program_path); if (pthread_mutex_trylock(&s_loader_lock) != 0) return DlErrorMessage { "Nested calls to dlopen() are not permitted." }; @@ -474,7 +474,7 @@ static Result __dlopen(char const* filename, int flags) VERIFY(!library_name.is_empty()); - auto const& parent_object = **s_global_objects.get(get_library_name(s_main_program_name)); + auto const& parent_object = **s_global_objects.get(get_library_name(s_main_program_path)); auto result1 = map_library(filename, parent_object); if (result1.is_error()) { @@ -598,21 +598,23 @@ static void read_environment_variables() } } -void ELF::DynamicLinker::linker_main(String&& main_program_name, int main_program_fd, bool is_secure, int argc, char** argv, char** envp) +void ELF::DynamicLinker::linker_main(String&& main_program_path, int main_program_fd, bool is_secure, int argc, char** argv, char** envp) { + VERIFY(main_program_path.starts_with('/')); + s_envp = envp; s_allowed_to_check_environment_variables = !is_secure; if (s_allowed_to_check_environment_variables) read_environment_variables(); - s_main_program_name = main_program_name; + s_main_program_path = main_program_path; - auto library_name = get_library_name(main_program_name); + auto library_name = get_library_name(main_program_path); // NOTE: We always map the main library first, since it may require // placement at a specific address. - auto result1 = map_library(main_program_name, main_program_fd, main_program_name); + auto result1 = map_library(main_program_path, main_program_fd, main_program_path); if (result1.is_error()) { warnln("{}", result1.error().text); fflush(stderr); @@ -634,8 +636,8 @@ void ELF::DynamicLinker::linker_main(String&& main_program_name, int main_progra allocate_tls(); - auto entry_point_function = [&main_program_name] { - auto library_name = get_library_name(main_program_name); + auto entry_point_function = [&main_program_path] { + auto library_name = get_library_name(main_program_path); auto result = link_main_library(library_name, RTLD_GLOBAL | RTLD_LAZY); if (result.is_error()) { warnln("{}", result.error().text); diff --git a/Userland/Libraries/LibELF/DynamicLinker.h b/Userland/Libraries/LibELF/DynamicLinker.h index a09f18bf5b..9aa256c926 100644 --- a/Userland/Libraries/LibELF/DynamicLinker.h +++ b/Userland/Libraries/LibELF/DynamicLinker.h @@ -15,7 +15,7 @@ namespace ELF { class DynamicLinker { public: static Optional lookup_global_symbol(StringView symbol); - [[noreturn]] static void linker_main(String&& main_program_name, int fd, bool is_secure, int argc, char** argv, char** envp); + [[noreturn]] static void linker_main(String&& main_program_path, int fd, bool is_secure, int argc, char** argv, char** envp); private: DynamicLinker() = delete; diff --git a/Userland/Libraries/LibELF/DynamicLoader.cpp b/Userland/Libraries/LibELF/DynamicLoader.cpp index 1e7cd74032..e2babf86ae 100644 --- a/Userland/Libraries/LibELF/DynamicLoader.cpp +++ b/Userland/Libraries/LibELF/DynamicLoader.cpp @@ -39,6 +39,8 @@ namespace ELF { Result, DlErrorMessage> DynamicLoader::try_create(int fd, String filename, String filepath) { + VERIFY(filepath.starts_with('/')); + struct stat stat; if (fstat(fd, &stat) < 0) { return DlErrorMessage { "DynamicLoader::try_create fstat" }; diff --git a/Userland/Utilities/readelf.cpp b/Userland/Utilities/readelf.cpp index 2dc1bcb5e4..b5a0556bba 100644 --- a/Userland/Utilities/readelf.cpp +++ b/Userland/Utilities/readelf.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -232,7 +233,7 @@ ErrorOr serenity_main(Main::Arguments arguments) { TRY(Core::System::pledge("stdio rpath")); - StringView path {}; + String path {}; static bool display_all = false; static bool display_elf_header = false; static bool display_program_headers = false; @@ -288,6 +289,8 @@ ErrorOr serenity_main(Main::Arguments arguments) display_hardening = true; } + path = LexicalPath::absolute_path(TRY(Core::System::getcwd()), path); + auto file_or_error = Core::MappedFile::map(path); if (file_or_error.is_error()) {