LibELF: Accept Span instead of Pointer+Size in validate_program_headers

This commit is contained in:
Idan Horowitz 2022-01-13 20:54:53 +02:00 committed by Andreas Kling
parent 3e959618c3
commit cfb9f889ac
Notes: sideshowbarker 2024-07-17 20:56:08 +09:00
8 changed files with 17 additions and 17 deletions

View file

@ -714,7 +714,7 @@ 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
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<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
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;
}

View file

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

View file

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

View file

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

View file

@ -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<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)
ErrorOr<bool> validate_program_headers(ElfW(Ehdr) const& elf_header, size_t file_size, ReadonlyBytes buffer, 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;
@ -207,19 +207,19 @@ ErrorOr<bool> 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<bool> 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<bool> 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:

View file

@ -12,7 +12,7 @@
namespace ELF {
bool validate_elf_header(const ElfW(Ehdr) & elf_header, size_t file_size, 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);
bool validate_elf_header(ElfW(Ehdr) const& elf_header, size_t file_size, bool verbose = true);
ErrorOr<bool> validate_program_headers(ElfW(Ehdr) const& elf_header, size_t file_size, ReadonlyBytes buffer, StringBuilder* interpreter_path_builder, bool verbose = true);
} // end namespace ELF

View file

@ -68,7 +68,7 @@ static Optional<String> 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();

View file

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