mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-31 23:22:03 +03:00
LibELF: Use StringBuilders instead of Strings for the interpreter path
This is required for the Kernel's usage of LibELF, since Strings do not expose allocation failure.
This commit is contained in:
parent
fb3e46e930
commit
3e959618c3
Notes:
sideshowbarker
2024-07-17 20:56:12 +09:00
Author: https://github.com/IdanHo Commit: https://github.com/SerenityOS/serenity/commit/3e959618c3b Pull-request: https://github.com/SerenityOS/serenity/pull/11871 Reviewed-by: https://github.com/bgianfo
@ -713,11 +713,12 @@ static ErrorOr<NonnullOwnPtrVector<KString>> find_shebang_interpreter_for_execut
|
||||
ErrorOr<RefPtr<OpenFileDescription>> Process::find_elf_interpreter_for_executable(StringView path, ElfW(Ehdr) const& main_executable_header, size_t main_executable_header_size, size_t file_size)
|
||||
{
|
||||
// Not using ErrorOr here because we'll want to do the same thing in userspace in the RTLD
|
||||
String interpreter_path;
|
||||
if (!ELF::validate_program_headers(main_executable_header, file_size, (u8 const*)&main_executable_header, main_executable_header_size, &interpreter_path)) {
|
||||
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))) {
|
||||
dbgln("exec({}): File has invalid ELF Program headers", path);
|
||||
return ENOEXEC;
|
||||
}
|
||||
auto interpreter_path = interpreter_path_builder.string_view();
|
||||
|
||||
if (!interpreter_path.is_empty()) {
|
||||
dbgln_if(EXEC_DEBUG, "exec({}): Using program interpreter {}", path, interpreter_path);
|
||||
@ -745,11 +746,12 @@ ErrorOr<RefPtr<OpenFileDescription>> Process::find_elf_interpreter_for_executabl
|
||||
}
|
||||
|
||||
// Not using ErrorOr here because we'll want to do the same thing in userspace in the RTLD
|
||||
String interpreter_interpreter_path;
|
||||
if (!ELF::validate_program_headers(*elf_header, interp_metadata.size, (u8*)first_page, nread, &interpreter_interpreter_path)) {
|
||||
StringBuilder interpreter_interpreter_path_builder;
|
||||
if (!TRY(ELF::validate_program_headers(*elf_header, interp_metadata.size, (u8*)first_page, nread, &interpreter_interpreter_path_builder))) {
|
||||
dbgln("exec({}): Interpreter ({}) has invalid ELF Program headers", path, interpreter_path);
|
||||
return ENOEXEC;
|
||||
}
|
||||
auto interpreter_interpreter_path = interpreter_interpreter_path_builder.string_view();
|
||||
|
||||
if (!interpreter_interpreter_path.is_empty()) {
|
||||
dbgln("exec({}): Interpreter ({}) has its own interpreter ({})! No thank you!", path, interpreter_path, interpreter_interpreter_path);
|
||||
|
@ -166,11 +166,13 @@ bool Emulator::load_elf()
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
String interpreter_path;
|
||||
if (!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)) {
|
||||
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);
|
||||
if (result_or_error.is_error() || !result_or_error.value()) {
|
||||
reportln("failed to validate ELF file");
|
||||
return false;
|
||||
}
|
||||
auto interpreter_path = interpreter_path_builder.string_view();
|
||||
|
||||
VERIFY(!interpreter_path.is_null());
|
||||
dbgln("interpreter: {}", interpreter_path);
|
||||
|
@ -122,8 +122,11 @@ bool DynamicLoader::validate()
|
||||
auto* elf_header = (ElfW(Ehdr)*)m_file_data;
|
||||
if (!validate_elf_header(*elf_header, m_file_size))
|
||||
return false;
|
||||
if (!validate_program_headers(*elf_header, m_file_size, (u8*)m_file_data, m_file_size, &m_program_interpreter))
|
||||
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);
|
||||
if (result_or_error.is_error() || !result_or_error.value())
|
||||
return false;
|
||||
m_program_interpreter = interpreter_path_builder.string_view();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -126,7 +126,14 @@ bool Image::parse()
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!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");
|
||||
m_valid = false;
|
||||
return false;
|
||||
}
|
||||
if (!result_or_error.value()) {
|
||||
if (m_verbose_logging)
|
||||
dbgln("ELF::Image::parse(): ELF Program Headers not valid");
|
||||
m_valid = false;
|
||||
|
@ -192,7 +192,7 @@ bool validate_elf_header(const ElfW(Ehdr) & elf_header, size_t file_size, bool v
|
||||
return true;
|
||||
}
|
||||
|
||||
bool validate_program_headers(const ElfW(Ehdr) & elf_header, size_t file_size, const u8* buffer, size_t buffer_size, String* interpreter_path, bool verbose)
|
||||
ErrorOr<bool> 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)
|
||||
{
|
||||
Checked<size_t> total_size_of_program_headers = elf_header.e_phnum;
|
||||
total_size_of_program_headers *= elf_header.e_phentsize;
|
||||
@ -268,8 +268,8 @@ bool validate_program_headers(const ElfW(Ehdr) & elf_header, size_t file_size, c
|
||||
dbgln("Found PT_INTERP header ({}), but p_filesz is invalid ({})", header_index, program_header.p_filesz);
|
||||
return false;
|
||||
}
|
||||
if (interpreter_path)
|
||||
*interpreter_path = String((const char*)&buffer[program_header.p_offset], program_header.p_filesz - 1);
|
||||
if (interpreter_path_builder)
|
||||
TRY(interpreter_path_builder->try_append({ &buffer[program_header.p_offset], program_header.p_filesz - 1 }));
|
||||
break;
|
||||
case PT_LOAD:
|
||||
case PT_DYNAMIC:
|
||||
|
@ -8,10 +8,11 @@
|
||||
|
||||
#include <AK/String.h>
|
||||
#include <LibC/elf.h>
|
||||
#include <limits.h>
|
||||
|
||||
namespace ELF {
|
||||
|
||||
bool validate_elf_header(const ElfW(Ehdr) & elf_header, size_t file_size, bool verbose = true);
|
||||
bool validate_program_headers(const ElfW(Ehdr) & elf_header, size_t file_size, const u8* buffer, size_t buffer_size, String* interpreter_path, bool verbose = true);
|
||||
ErrorOr<bool> 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);
|
||||
|
||||
} // end namespace ELF
|
||||
|
@ -67,9 +67,11 @@ static Optional<String> elf_details(String description, const String& path)
|
||||
if (!elf_image.is_valid())
|
||||
return {};
|
||||
|
||||
String interpreter_path;
|
||||
if (!ELF::validate_program_headers(*(const ElfW(Ehdr)*)elf_data.data(), elf_data.size(), (const u8*)elf_data.data(), elf_data.size(), &interpreter_path))
|
||||
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);
|
||||
if (result_or_error.is_error() || !result_or_error.value())
|
||||
return {};
|
||||
auto interpreter_path = interpreter_path_builder.string_view();
|
||||
|
||||
auto& header = *reinterpret_cast<const ElfW(Ehdr)*>(elf_data.data());
|
||||
|
||||
|
@ -298,12 +298,13 @@ int main(int argc, char** argv)
|
||||
return -1;
|
||||
}
|
||||
|
||||
String interpreter_path;
|
||||
|
||||
if (!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)) {
|
||||
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);
|
||||
if (result_or_error.is_error() || !result_or_error.value()) {
|
||||
warnln("Invalid ELF headers");
|
||||
return -1;
|
||||
}
|
||||
auto interpreter_path = interpreter_path_builder.string_view();
|
||||
|
||||
auto& header = *reinterpret_cast<const ElfW(Ehdr)*>(elf_image_data.data());
|
||||
|
||||
@ -311,7 +312,7 @@ int main(int argc, char** argv)
|
||||
|
||||
if (elf_image.is_dynamic()) {
|
||||
if (interpreter_path.is_null()) {
|
||||
interpreter_path = "/usr/lib/Loader.so";
|
||||
interpreter_path = "/usr/lib/Loader.so"sv;
|
||||
warnln("Warning: Dynamic ELF object has no interpreter path. Using: {}", interpreter_path);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user