LibELF: Accept Span instead of Pointer+Size in validate_program_headers
This commit is contained in:
parent
3e959618c3
commit
cfb9f889ac
Notes:
sideshowbarker
2024-07-17 20:56:08 +09:00
Author: https://github.com/IdanHo Commit: https://github.com/SerenityOS/serenity/commit/cfb9f889ac9 Pull-request: https://github.com/SerenityOS/serenity/pull/11871 Reviewed-by: https://github.com/bgianfo
8 changed files with 17 additions and 17 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue