diff --git a/Kernel/Syscalls/execve.cpp b/Kernel/Syscalls/execve.cpp index c8c361d0e1..04b9d29d61 100644 --- a/Kernel/Syscalls/execve.cpp +++ b/Kernel/Syscalls/execve.cpp @@ -714,7 +714,7 @@ ErrorOr> Process::find_elf_interpreter_for_executabl { // Not using ErrorOr here because we'll want to do the same thing in userspace in the RTLD StringBuilder interpreter_path_builder; - if (!TRY(ELF::validate_program_headers(main_executable_header, file_size, (u8 const*)&main_executable_header, main_executable_header_size, &interpreter_path_builder))) { + if (!TRY(ELF::validate_program_headers(main_executable_header, file_size, { &main_executable_header, main_executable_header_size }, &interpreter_path_builder))) { dbgln("exec({}): File has invalid ELF Program headers", path); return ENOEXEC; } @@ -747,7 +747,7 @@ ErrorOr> Process::find_elf_interpreter_for_executabl // Not using ErrorOr here because we'll want to do the same thing in userspace in the RTLD StringBuilder interpreter_interpreter_path_builder; - if (!TRY(ELF::validate_program_headers(*elf_header, interp_metadata.size, (u8*)first_page, nread, &interpreter_interpreter_path_builder))) { + if (!TRY(ELF::validate_program_headers(*elf_header, interp_metadata.size, { first_page, nread }, &interpreter_interpreter_path_builder))) { dbgln("exec({}): Interpreter ({}) has invalid ELF Program headers", path, interpreter_path); return ENOEXEC; } diff --git a/Userland/DevTools/UserspaceEmulator/Emulator.cpp b/Userland/DevTools/UserspaceEmulator/Emulator.cpp index f91cb636db..3cb1e04e5d 100644 --- a/Userland/DevTools/UserspaceEmulator/Emulator.cpp +++ b/Userland/DevTools/UserspaceEmulator/Emulator.cpp @@ -167,7 +167,7 @@ bool Emulator::load_elf() } StringBuilder interpreter_path_builder; - auto result_or_error = ELF::validate_program_headers(*(Elf32_Ehdr const*)elf_image_data.data(), elf_image_data.size(), (u8 const*)elf_image_data.data(), elf_image_data.size(), &interpreter_path_builder); + auto result_or_error = ELF::validate_program_headers(*(Elf32_Ehdr const*)elf_image_data.data(), elf_image_data.size(), elf_image_data, &interpreter_path_builder); if (result_or_error.is_error() || !result_or_error.value()) { reportln("failed to validate ELF file"); return false; diff --git a/Userland/Libraries/LibELF/DynamicLoader.cpp b/Userland/Libraries/LibELF/DynamicLoader.cpp index d2a986f483..200413d595 100644 --- a/Userland/Libraries/LibELF/DynamicLoader.cpp +++ b/Userland/Libraries/LibELF/DynamicLoader.cpp @@ -123,7 +123,7 @@ bool DynamicLoader::validate() if (!validate_elf_header(*elf_header, m_file_size)) return false; StringBuilder interpreter_path_builder; - auto result_or_error = validate_program_headers(*elf_header, m_file_size, (u8*)m_file_data, m_file_size, &interpreter_path_builder); + auto result_or_error = validate_program_headers(*elf_header, m_file_size, { m_file_data, m_file_size }, &interpreter_path_builder); if (result_or_error.is_error() || !result_or_error.value()) return false; m_program_interpreter = interpreter_path_builder.string_view(); diff --git a/Userland/Libraries/LibELF/Image.cpp b/Userland/Libraries/LibELF/Image.cpp index 88e66dee5d..ac865222bb 100644 --- a/Userland/Libraries/LibELF/Image.cpp +++ b/Userland/Libraries/LibELF/Image.cpp @@ -126,7 +126,7 @@ bool Image::parse() return false; } - auto result_or_error = validate_program_headers(header(), m_size, m_buffer, m_size, nullptr, m_verbose_logging); + auto result_or_error = validate_program_headers(header(), m_size, { m_buffer, m_size }, nullptr, m_verbose_logging); if (result_or_error.is_error()) { if (m_verbose_logging) dbgln("ELF::Image::parse(): Failed validating ELF Program Headers"); diff --git a/Userland/Libraries/LibELF/Validation.cpp b/Userland/Libraries/LibELF/Validation.cpp index d363dfef11..fa7130d6fc 100644 --- a/Userland/Libraries/LibELF/Validation.cpp +++ b/Userland/Libraries/LibELF/Validation.cpp @@ -14,7 +14,7 @@ namespace ELF { -bool validate_elf_header(const ElfW(Ehdr) & elf_header, size_t file_size, bool verbose) +bool validate_elf_header(ElfW(Ehdr) const& elf_header, size_t file_size, bool verbose) { if (!IS_ELF(elf_header)) { if (verbose) @@ -192,7 +192,7 @@ bool validate_elf_header(const ElfW(Ehdr) & elf_header, size_t file_size, bool v return true; } -ErrorOr validate_program_headers(const ElfW(Ehdr) & elf_header, size_t file_size, const u8* buffer, size_t buffer_size, StringBuilder* interpreter_path_builder, bool verbose) +ErrorOr validate_program_headers(ElfW(Ehdr) const& elf_header, size_t file_size, ReadonlyBytes buffer, StringBuilder* interpreter_path_builder, bool verbose) { Checked total_size_of_program_headers = elf_header.e_phnum; total_size_of_program_headers *= elf_header.e_phentsize; @@ -207,19 +207,19 @@ ErrorOr validate_program_headers(const ElfW(Ehdr) & elf_header, size_t fil } // Can we actually parse all the program headers in the given buffer? - if (end_of_last_program_header > buffer_size) { + if (end_of_last_program_header > buffer.size()) { if (verbose) - dbgln("Unable to parse program headers from buffer, buffer too small! Buffer size: {}, End of program headers {}", buffer_size, end_of_last_program_header.value()); + dbgln("Unable to parse program headers from buffer, buffer too small! Buffer size: {}, End of program headers {}", buffer.size(), end_of_last_program_header.value()); return false; } - if (file_size < buffer_size) { + if (file_size < buffer.size()) { dbgln("We somehow read more from a file than was in the file in the first place!"); VERIFY_NOT_REACHED(); } size_t num_program_headers = elf_header.e_phnum; - auto program_header_begin = (const ElfW(Phdr)*)&(buffer[elf_header.e_phoff]); + auto program_header_begin = (const ElfW(Phdr)*)buffer.offset(elf_header.e_phoff); for (size_t header_index = 0; header_index < num_program_headers; ++header_index) { auto& program_header = program_header_begin[header_index]; @@ -258,7 +258,7 @@ ErrorOr validate_program_headers(const ElfW(Ehdr) & elf_header, size_t fil dbgln("Integer overflow while validating PT_INTERP header"); return false; } - if (program_header.p_offset + program_header.p_filesz > buffer_size) { + if (program_header.p_offset + program_header.p_filesz > buffer.size()) { if (verbose) dbgln("Found PT_INTERP header ({}), but the .interp section was not within the buffer :(", header_index); return false; @@ -269,7 +269,7 @@ ErrorOr validate_program_headers(const ElfW(Ehdr) & elf_header, size_t fil return false; } if (interpreter_path_builder) - TRY(interpreter_path_builder->try_append({ &buffer[program_header.p_offset], program_header.p_filesz - 1 })); + TRY(interpreter_path_builder->try_append({ buffer.offset(program_header.p_offset), program_header.p_filesz - 1 })); break; case PT_LOAD: case PT_DYNAMIC: diff --git a/Userland/Libraries/LibELF/Validation.h b/Userland/Libraries/LibELF/Validation.h index 41b6b4957e..665cf90101 100644 --- a/Userland/Libraries/LibELF/Validation.h +++ b/Userland/Libraries/LibELF/Validation.h @@ -12,7 +12,7 @@ namespace ELF { -bool validate_elf_header(const ElfW(Ehdr) & elf_header, size_t file_size, bool verbose = true); -ErrorOr validate_program_headers(const ElfW(Ehdr) & elf_header, size_t file_size, const u8* buffer, size_t buffer_size, StringBuilder* interpreter_path_builder, bool verbose = true); +bool validate_elf_header(ElfW(Ehdr) const& elf_header, size_t file_size, bool verbose = true); +ErrorOr validate_program_headers(ElfW(Ehdr) const& elf_header, size_t file_size, ReadonlyBytes buffer, StringBuilder* interpreter_path_builder, bool verbose = true); } // end namespace ELF diff --git a/Userland/Utilities/file.cpp b/Userland/Utilities/file.cpp index 212dfc2a5e..b529434ab0 100644 --- a/Userland/Utilities/file.cpp +++ b/Userland/Utilities/file.cpp @@ -68,7 +68,7 @@ static Optional elf_details(String description, const String& path) return {}; StringBuilder interpreter_path_builder; - auto result_or_error = ELF::validate_program_headers(*(const ElfW(Ehdr)*)elf_data.data(), elf_data.size(), (const u8*)elf_data.data(), elf_data.size(), &interpreter_path_builder); + auto result_or_error = ELF::validate_program_headers(*(const ElfW(Ehdr)*)elf_data.data(), elf_data.size(), elf_data, &interpreter_path_builder); if (result_or_error.is_error() || !result_or_error.value()) return {}; auto interpreter_path = interpreter_path_builder.string_view(); diff --git a/Userland/Utilities/readelf.cpp b/Userland/Utilities/readelf.cpp index 473b4a216a..66a99ba958 100644 --- a/Userland/Utilities/readelf.cpp +++ b/Userland/Utilities/readelf.cpp @@ -299,7 +299,7 @@ int main(int argc, char** argv) } StringBuilder interpreter_path_builder; - auto result_or_error = ELF::validate_program_headers(*(const ElfW(Ehdr)*)elf_image_data.data(), elf_image_data.size(), (const u8*)elf_image_data.data(), elf_image_data.size(), &interpreter_path_builder); + auto result_or_error = ELF::validate_program_headers(*(const ElfW(Ehdr)*)elf_image_data.data(), elf_image_data.size(), elf_image_data, &interpreter_path_builder); if (result_or_error.is_error() || !result_or_error.value()) { warnln("Invalid ELF headers"); return -1;