mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 18:27:35 +00:00
Kernel: Tighten up exec/do_exec and allow for PT_INTERP iterpreters
This patch changes how exec() figures out which program image to actually load. Previously, we opened the path to our main executable in find_shebang_interpreter_for_executable, read the first page (or less, if the file was smaller) and then decided whether to recurse with the interpreter instead. We then then re-opened the main executable in do_exec. However, since we now want to parse the ELF header and Program Headers of an elf image before even doing any memory region work, we can change the way this whole process works. We open the file and read (up to) the first page in exec() itself, then pass just the page and the amount read to find_shebang_interpreter_for_executable. Since we now have that page and the FileDescription for the main executable handy, we can do a few things. First, validate the ELF header and ELF program headers for any shenanigans. ELF32 Little Endian i386 only, please. Second, we can grab the PT_INTERP interpreter from any ET_DYN files, and open that guy right away if it exists. Finally, we can pass the main executable's and optionally the PT_INTERP interpreter's file descriptions down to do_exec and not have to feel guilty about opening the file twice. In do_exec, we now have a choice. Are we going to load the main executable, or the interpreter? We could load both, but it'll be way easier for the inital pass on the RTLD if we only load the interpreter. Then it can load the main executable itself like any old shared object, just, the one with main in it :). Later on we can load both of them into memory and the RTLD can relocate itself before trying to do anything. The way it's written now the RTLD will get dibs on its requested virtual addresses being the actual virtual addresses.
This commit is contained in:
parent
046d6a6bbb
commit
7a7e7c82b5
2 changed files with 208 additions and 62 deletions
|
@ -317,7 +317,7 @@ public:
|
|||
size_t amount_purgeable_volatile() const;
|
||||
size_t amount_purgeable_nonvolatile() const;
|
||||
|
||||
int exec(String path, Vector<String> arguments, Vector<String> environment);
|
||||
int exec(String path, Vector<String> arguments, Vector<String> environment, int recusion_depth = 0);
|
||||
|
||||
bool is_superuser() const { return m_euid == 0; }
|
||||
|
||||
|
@ -364,14 +364,14 @@ private:
|
|||
|
||||
Range allocate_range(VirtualAddress, size_t);
|
||||
|
||||
int do_exec(String path, Vector<String> arguments, Vector<String> environment);
|
||||
int do_exec(NonnullRefPtr<FileDescription> main_program_description, Vector<String> arguments, Vector<String> environment, RefPtr<FileDescription> interpreter_description);
|
||||
ssize_t do_write(FileDescription&, const u8*, int data_size);
|
||||
|
||||
KResultOr<NonnullRefPtr<FileDescription>> find_elf_interpreter_for_executable(const String& path, char (&first_page)[PAGE_SIZE], int nread, size_t file_size);
|
||||
|
||||
int alloc_fd(int first_candidate_fd = 0);
|
||||
void disown_all_shared_buffers();
|
||||
|
||||
KResultOr<Vector<String>> find_shebang_interpreter_for_executable(const String& executable_path);
|
||||
|
||||
KResult do_kill(Process&, int signal);
|
||||
KResult do_killpg(pid_t pgrp, int signal);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue