1
Fork 0
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:
Andrew Kaster 2020-01-10 18:28:02 -07:00 committed by Andreas Kling
parent 046d6a6bbb
commit 7a7e7c82b5
2 changed files with 208 additions and 62 deletions

View file

@ -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);