mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 22:57:44 +00:00
LibELF: Validate the mapped file in DynamicLoader constructor
ELF::DynamicLoader now validates the ELF header and the program headers in its constructor. The requested program interpreter from the PT_INTERP program header is now avaiable via a getter. The dynamic loader program will want to check that this matches its name, for extra shenanigans checking.
This commit is contained in:
parent
61acca223f
commit
827e375297
2 changed files with 20 additions and 2 deletions
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
#include <AK/StringBuilder.h>
|
#include <AK/StringBuilder.h>
|
||||||
#include <LibELF/DynamicLoader.h>
|
#include <LibELF/DynamicLoader.h>
|
||||||
|
#include <LibELF/Validation.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
@ -59,11 +60,24 @@ DynamicLoader::DynamicLoader(const char* filename, int fd, size_t size)
|
||||||
, m_file_size(size)
|
, m_file_size(size)
|
||||||
, m_image_fd(fd)
|
, m_image_fd(fd)
|
||||||
{
|
{
|
||||||
|
if (m_file_size < sizeof(Elf32_Ehdr)) {
|
||||||
|
m_valid = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String file_mmap_name = String::format("ELF_DYN: %s", m_filename.characters());
|
String file_mmap_name = String::format("ELF_DYN: %s", m_filename.characters());
|
||||||
|
|
||||||
m_file_mapping = mmap_with_name(nullptr, size, PROT_READ, MAP_PRIVATE, m_image_fd, 0, file_mmap_name.characters());
|
m_file_mapping = mmap_with_name(nullptr, m_file_size, PROT_READ, MAP_PRIVATE, m_image_fd, 0, file_mmap_name.characters());
|
||||||
if (MAP_FAILED == m_file_mapping) {
|
if (MAP_FAILED == m_file_mapping) {
|
||||||
m_valid = false;
|
m_valid = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* elf_header = (Elf32_Ehdr*)m_file_mapping;
|
||||||
|
|
||||||
|
if (!validate_elf_header(*elf_header, m_file_size) ||
|
||||||
|
!validate_program_headers(*elf_header, m_file_size, (u8*)m_file_mapping, m_file_size, m_program_interpreter)) {
|
||||||
|
m_valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,9 @@ public:
|
||||||
// Will be called from _fixup_plt_entry, as part of the PLT trampoline
|
// Will be called from _fixup_plt_entry, as part of the PLT trampoline
|
||||||
Elf32_Addr patch_plt_entry(u32 relocation_offset);
|
Elf32_Addr patch_plt_entry(u32 relocation_offset);
|
||||||
|
|
||||||
|
// Requested program interpreter from program headers. May be empty string
|
||||||
|
StringView program_interpreter() const { return m_program_interpreter; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class ProgramHeaderRegion {
|
class ProgramHeaderRegion {
|
||||||
public:
|
public:
|
||||||
|
@ -103,9 +106,10 @@ private:
|
||||||
void call_object_init_functions();
|
void call_object_init_functions();
|
||||||
|
|
||||||
String m_filename;
|
String m_filename;
|
||||||
|
String m_program_interpreter;
|
||||||
size_t m_file_size { 0 };
|
size_t m_file_size { 0 };
|
||||||
int m_image_fd { -1 };
|
int m_image_fd { -1 };
|
||||||
void* m_file_mapping { nullptr };
|
void* m_file_mapping { MAP_FAILED };
|
||||||
bool m_valid { true };
|
bool m_valid { true };
|
||||||
|
|
||||||
OwnPtr<DynamicObject> m_dynamic_object;
|
OwnPtr<DynamicObject> m_dynamic_object;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue