1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 16:27:35 +00:00

Kernel: Don't turn I/O errors during sys$execve() into ENOEXEC

Instead, just propagate whatever the real error was.
This commit is contained in:
Andreas Kling 2021-09-06 13:05:20 +02:00
parent 84addef10f
commit 645e29a88b

View file

@ -710,14 +710,14 @@ static Vector<ELF::AuxiliaryValue> generate_auxiliary_vector(FlatPtr load_base,
return auxv; return auxv;
} }
static KResultOr<Vector<String>> find_shebang_interpreter_for_executable(const char first_page[], int nread) static KResultOr<Vector<String>> find_shebang_interpreter_for_executable(char const first_page[], size_t nread)
{ {
int word_start = 2; int word_start = 2;
int word_length = 0; int word_length = 0;
if (nread > 2 && first_page[0] == '#' && first_page[1] == '!') { if (nread > 2 && first_page[0] == '#' && first_page[1] == '!') {
Vector<String> interpreter_words; Vector<String> interpreter_words;
for (int i = 2; i < nread; ++i) { for (size_t i = 2; i < nread; ++i) {
if (first_page[i] == '\n') { if (first_page[i] == '\n') {
break; break;
} }
@ -773,12 +773,9 @@ KResultOr<RefPtr<FileDescription>> Process::find_elf_interpreter_for_executable(
char first_page[PAGE_SIZE] = {}; char first_page[PAGE_SIZE] = {};
auto first_page_buffer = UserOrKernelBuffer::for_kernel_buffer((u8*)&first_page); auto first_page_buffer = UserOrKernelBuffer::for_kernel_buffer((u8*)&first_page);
auto nread_or_error = interpreter_description->read(first_page_buffer, sizeof(first_page)); auto nread = TRY(interpreter_description->read(first_page_buffer, sizeof(first_page)));
if (nread_or_error.is_error())
return ENOEXEC;
nread = nread_or_error.value();
if (nread < (int)sizeof(ElfW(Ehdr))) if (nread < sizeof(ElfW(Ehdr)))
return ENOEXEC; return ENOEXEC;
auto elf_header = (ElfW(Ehdr)*)first_page; auto elf_header = (ElfW(Ehdr)*)first_page;
@ -847,12 +844,10 @@ KResult Process::exec(String path, Vector<String> arguments, Vector<String> envi
// Read the first page of the program into memory so we can validate the binfmt of it // Read the first page of the program into memory so we can validate the binfmt of it
char first_page[PAGE_SIZE]; char first_page[PAGE_SIZE];
auto first_page_buffer = UserOrKernelBuffer::for_kernel_buffer((u8*)&first_page); auto first_page_buffer = UserOrKernelBuffer::for_kernel_buffer((u8*)&first_page);
auto nread_or_error = description->read(first_page_buffer, sizeof(first_page)); auto nread = TRY(description->read(first_page_buffer, sizeof(first_page)));
if (nread_or_error.is_error())
return ENOEXEC;
// 1) #! interpreted file // 1) #! interpreted file
auto shebang_result = find_shebang_interpreter_for_executable(first_page, nread_or_error.value()); auto shebang_result = find_shebang_interpreter_for_executable(first_page, nread);
if (!shebang_result.is_error()) { if (!shebang_result.is_error()) {
auto shebang_words = shebang_result.release_value(); auto shebang_words = shebang_result.release_value();
auto shebang_path = shebang_words.first(); auto shebang_path = shebang_words.first();
@ -864,7 +859,7 @@ KResult Process::exec(String path, Vector<String> arguments, Vector<String> envi
// #2) ELF32 for i386 // #2) ELF32 for i386
if (nread_or_error.value() < (int)sizeof(ElfW(Ehdr))) if (nread < sizeof(ElfW(Ehdr)))
return ENOEXEC; return ENOEXEC;
auto main_program_header = (ElfW(Ehdr)*)first_page; auto main_program_header = (ElfW(Ehdr)*)first_page;
@ -873,7 +868,7 @@ KResult Process::exec(String path, Vector<String> arguments, Vector<String> envi
return ENOEXEC; return ENOEXEC;
} }
auto elf_result = find_elf_interpreter_for_executable(path, *main_program_header, nread_or_error.value(), metadata.size); auto elf_result = find_elf_interpreter_for_executable(path, *main_program_header, nread, metadata.size);
// Assume a static ELF executable by default // Assume a static ELF executable by default
RefPtr<FileDescription> interpreter_description; RefPtr<FileDescription> interpreter_description;
// We're getting either an interpreter, an error, or KSuccess (i.e. no interpreter but file checks out) // We're getting either an interpreter, an error, or KSuccess (i.e. no interpreter but file checks out)