main.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. /*
  2. * Copyright (c) 2020, Itamar S. <itamar8910@gmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/LexicalPath.h>
  7. #include <AK/ScopeGuard.h>
  8. #include <Kernel/API/POSIX/sys/stat.h>
  9. #include <Kernel/API/VirtualMemoryAnnotations.h>
  10. #include <LibCore/ArgsParser.h>
  11. #include <LibELF/AuxiliaryVector.h>
  12. #include <LibELF/DynamicLinker.h>
  13. #include <LibELF/Relocation.h>
  14. #include <fcntl.h>
  15. #include <sys/internals.h>
  16. #include <syscall.h>
  17. #include <unistd.h>
  18. char* __static_environ[] = { nullptr }; // We don't get the environment without some libc workarounds..
  19. char** environ = __static_environ;
  20. uintptr_t __stack_chk_guard = 0;
  21. extern "C" {
  22. [[noreturn]] void _invoke_entry(int argc, char** argv, char** envp, ELF::EntryPointFunction entry);
  23. static ErrorOr<int> open_executable(StringView path)
  24. {
  25. int rc = open(path.characters_without_null_termination(), O_RDONLY | O_EXEC);
  26. if (rc < 0)
  27. return Error::from_errno(errno);
  28. int checked_fd = rc;
  29. ArmedScopeGuard close_on_failure([checked_fd] {
  30. close(checked_fd);
  31. });
  32. struct stat executable_stat = {};
  33. rc = fstat(checked_fd, &executable_stat);
  34. if (rc < 0)
  35. return Error::from_errno(errno);
  36. if (!S_ISREG(executable_stat.st_mode)) {
  37. if (S_ISDIR(executable_stat.st_mode))
  38. return Error::from_errno(EISDIR);
  39. return Error::from_errno(EINVAL);
  40. }
  41. close_on_failure.disarm();
  42. return checked_fd;
  43. }
  44. static int print_loaded_libraries_callback(struct dl_phdr_info* info, size_t, void*)
  45. {
  46. outln("{}", info->dlpi_name);
  47. return 0;
  48. }
  49. static int _main(int argc, char** argv, char** envp, bool is_secure)
  50. {
  51. Vector<StringView> arguments;
  52. arguments.ensure_capacity(argc);
  53. for (int i = 0; i < argc; ++i)
  54. arguments.unchecked_append({ argv[i], strlen(argv[i]) });
  55. bool flag_dry_run { false };
  56. bool flag_list_loaded_dependencies { false };
  57. Vector<StringView> command;
  58. StringView argv0;
  59. Core::ArgsParser args_parser;
  60. args_parser.set_general_help("Run dynamically-linked ELF executables");
  61. args_parser.set_stop_on_first_non_option(true);
  62. if (LexicalPath::basename(arguments[0]) == "ldd"sv) {
  63. flag_list_loaded_dependencies = true;
  64. flag_dry_run = true;
  65. } else {
  66. args_parser.add_option(flag_dry_run, "Run in dry-run mode", "dry-run", 'd');
  67. args_parser.add_option(flag_list_loaded_dependencies, "List all loaded dependencies", "list", 'l');
  68. args_parser.add_option(argv0, "Run with custom argv0", "argv0", 'E', "custom argv0");
  69. }
  70. args_parser.add_positional_argument(command, "Command to execute", "command");
  71. // NOTE: Don't use regular PrintUsageAndExit policy for ArgsParser, as it will simply
  72. // fail with a nullptr-dereference as the LibC exit function is not suitable for usage
  73. // in this piece of code.
  74. if (!args_parser.parse(arguments.span(), Core::ArgsParser::FailureBehavior::PrintUsage))
  75. return 1;
  76. if (command.is_empty()) {
  77. args_parser.print_usage(stderr, arguments[0]);
  78. return 1;
  79. }
  80. auto error_or_fd = open_executable(command[0]);
  81. if (error_or_fd.is_error()) {
  82. warnln("Loader.so: Loading {} failed: {}", command[0], strerror(error_or_fd.error().code()));
  83. return 1;
  84. }
  85. int main_program_fd = error_or_fd.release_value();
  86. ByteString main_program_path = command[0];
  87. // NOTE: We need to extract the command with its arguments to be able
  88. // to run the actual requested executable with the requested parameters
  89. // from argv.
  90. VERIFY(command.size() <= static_cast<size_t>(argc));
  91. auto command_with_args = command.span();
  92. for (size_t index = 0; index < command.size(); index++)
  93. argv[index] = const_cast<char*>(command_with_args[index].characters_without_null_termination());
  94. if (!argv0.is_empty())
  95. argv[0] = const_cast<char*>(argv0.characters_without_null_termination());
  96. auto entry_point = ELF::DynamicLinker::linker_main(move(main_program_path), main_program_fd, is_secure, envp);
  97. if (flag_list_loaded_dependencies)
  98. ELF::DynamicLinker::iterate_over_loaded_shared_objects(print_loaded_libraries_callback, nullptr);
  99. if (flag_dry_run)
  100. return 0;
  101. _invoke_entry(command.size(), argv, envp, entry_point);
  102. VERIFY_NOT_REACHED();
  103. }
  104. // The compiler expects a previous declaration
  105. void _start(int, char**, char**) __attribute__((used));
  106. void _entry(int, char**, char**) __attribute__((used));
  107. NAKED void _start(int, char**, char**)
  108. {
  109. #if ARCH(AARCH64)
  110. // Make sure backtrace computation stops here by setting FP and LR to 0.
  111. // FIXME: The kernel should ensure that registers are zeroed on program start
  112. asm(
  113. "mov x29, 0\n"
  114. "mov x30, 0\n"
  115. "bl _entry\n");
  116. #elif ARCH(RISCV64)
  117. asm(
  118. "li fp, 0\n"
  119. "li ra, 0\n"
  120. "tail _entry@plt\n");
  121. #elif ARCH(X86_64)
  122. asm(
  123. "push $0\n"
  124. "jmp _entry@plt\n");
  125. #else
  126. # error "Unknown architecture"
  127. #endif
  128. }
  129. ALWAYS_INLINE static void optimizer_fence()
  130. {
  131. asm("" ::: "memory");
  132. }
  133. [[gnu::no_stack_protector]] void _entry(int argc, char** argv, char** envp)
  134. {
  135. char** env;
  136. for (env = envp; *env; ++env) {
  137. }
  138. auxv_t* auxvp = (auxv_t*)++env;
  139. bool at_random_found = false;
  140. FlatPtr base_address = 0;
  141. bool base_address_found = false;
  142. for (auxv_t* entry = auxvp; entry->a_type != AT_NULL; ++entry) {
  143. if (entry->a_type == ELF::AuxiliaryValue::Random) {
  144. at_random_found = true;
  145. __stack_chk_guard = *reinterpret_cast<u64*>(entry->a_un.a_ptr);
  146. } else if (entry->a_type == ELF::AuxiliaryValue::BaseAddress) {
  147. base_address_found = true;
  148. base_address = entry->a_un.a_val;
  149. }
  150. }
  151. VERIFY(at_random_found && base_address_found);
  152. // Make sure compiler won't move any functions calls above __stack_chk_guard initialization even
  153. // if their definitions somehow become available.
  154. optimizer_fence();
  155. // We need to relocate ourselves.
  156. // (these relocations seem to be generated because of our vtables)
  157. if (!ELF::perform_relative_relocations(base_address)) {
  158. syscall(SC_dbgputstr, "Unable to perform relative relocations!\n", 40);
  159. VERIFY_NOT_REACHED();
  160. }
  161. // Similarly, make sure no non-offset-agnostic language features are used above this point.
  162. optimizer_fence();
  163. // Initialize the copy of libc included statically in Loader.so,
  164. // initialization of the dynamic libc.so is done by the DynamicLinker
  165. __libc_init();
  166. int main_program_fd = -1;
  167. ByteString main_program_path;
  168. bool is_secure = false;
  169. for (; auxvp->a_type != AT_NULL; ++auxvp) {
  170. if (auxvp->a_type == ELF::AuxiliaryValue::ExecFileDescriptor) {
  171. main_program_fd = auxvp->a_un.a_val;
  172. }
  173. if (auxvp->a_type == ELF::AuxiliaryValue::ExecFilename) {
  174. main_program_path = (char const*)auxvp->a_un.a_ptr;
  175. }
  176. if (auxvp->a_type == ELF::AuxiliaryValue::Secure) {
  177. is_secure = auxvp->a_un.a_val == 1;
  178. }
  179. }
  180. if (main_program_fd == -1) {
  181. // Allow syscalls from our code since the kernel won't do that automatically for us if we
  182. // were invoked directly.
  183. Elf_Ehdr* header = reinterpret_cast<Elf_Ehdr*>(base_address);
  184. Elf_Phdr* pheader = reinterpret_cast<Elf_Phdr*>(base_address + header->e_phoff);
  185. for (size_t i = 0; i < header->e_phnum; ++i) {
  186. auto const& segment = pheader[i];
  187. if (segment.p_type == PT_LOAD && (segment.p_flags & PF_X)) {
  188. auto flags = VirtualMemoryRangeFlags::SyscallCode | VirtualMemoryRangeFlags::Immutable;
  189. auto rc = syscall(Syscall::SC_annotate_mapping, segment.p_vaddr + base_address, flags);
  190. VERIFY(rc == 0);
  191. }
  192. }
  193. // We've been invoked directly as an executable rather than as the
  194. // ELF interpreter for some other binary.
  195. int exit_status = _main(argc, argv, envp, is_secure);
  196. _exit(exit_status);
  197. }
  198. VERIFY(main_program_fd >= 0);
  199. VERIFY(!main_program_path.is_empty());
  200. auto entry_point = ELF::DynamicLinker::linker_main(move(main_program_path), main_program_fd, is_secure, envp);
  201. _invoke_entry(argc, argv, envp, entry_point);
  202. VERIFY_NOT_REACHED();
  203. }
  204. }