1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 03:47:34 +00:00

ELF: Fail layout when program header hooks return nullptr (#673)

ELFLoader::layout() had a "failed" variable that was never set. This
patch checks the return value of each hook (alloc/map section and tls)
and fails the load if they return null.

I also needed to patch Process so that the alloc_section_hook and 
map_section_hook actually return nullptr when allocating a region fails.

Fixes #664 :)
This commit is contained in:
Andrew Kaster 2019-10-20 08:24:42 -06:00 committed by Andreas Kling
parent eb77e680ed
commit 138abb9098
2 changed files with 21 additions and 8 deletions

View file

@ -38,6 +38,10 @@ bool ELFLoader::layout()
if (program_header.type() == PT_TLS) {
#ifdef KERNEL
auto* tls_image = tls_section_hook(program_header.size_in_memory(), program_header.alignment());
if (!tls_image) {
failed = true;
return;
}
memcpy(tls_image, program_header.raw_data(), program_header.size_in_image());
#endif
return;
@ -49,16 +53,20 @@ bool ELFLoader::layout()
#endif
#ifdef KERNEL
if (program_header.is_writable()) {
alloc_section_hook(
auto* allocated_section = alloc_section_hook(
program_header.vaddr(),
program_header.size_in_memory(),
program_header.alignment(),
program_header.is_readable(),
program_header.is_writable(),
String::format("elf-alloc-%s%s", program_header.is_readable() ? "r" : "", program_header.is_writable() ? "w" : ""));
if (!allocated_section) {
failed = true;
return;
}
memcpy(program_header.vaddr().as_ptr(), program_header.raw_data(), program_header.size_in_image());
} else {
map_section_hook(
auto* mapped_section = map_section_hook(
program_header.vaddr(),
program_header.size_in_memory(),
program_header.alignment(),
@ -67,6 +75,9 @@ bool ELFLoader::layout()
program_header.is_writable(),
program_header.is_executable(),
String::format("elf-map-%s%s%s", program_header.is_readable() ? "r" : "", program_header.is_writable() ? "w" : "", program_header.is_executable() ? "x" : ""));
if (!mapped_section) {
failed = true;
}
}
#endif
});

View file

@ -19,6 +19,7 @@
#include <Kernel/FileSystem/SharedMemory.h>
#include <Kernel/FileSystem/TmpFS.h>
#include <Kernel/FileSystem/VirtualFileSystem.h>
#include <Kernel/Heap/kmalloc.h>
#include <Kernel/IO.h>
#include <Kernel/KBufferBuilder.h>
#include <Kernel/KSyms.h>
@ -33,7 +34,6 @@
#include <Kernel/Syscall.h>
#include <Kernel/TTY/MasterPTY.h>
#include <Kernel/VM/InodeVMObject.h>
#include <Kernel/Heap/kmalloc.h>
#include <LibC/errno_numbers.h>
#include <LibC/signal_numbers.h>
@ -423,7 +423,7 @@ int Process::do_exec(String path, Vector<String> arguments, Vector<String> envir
auto old_regions = move(m_regions);
m_regions.append(move(executable_region));
loader = make<ELFLoader>(region->vaddr().as_ptr());
loader->map_section_hook = [&](VirtualAddress vaddr, size_t size, size_t alignment, size_t offset_in_image, bool is_readable, bool is_writable, bool is_executable, const String& name) {
loader->map_section_hook = [&](VirtualAddress vaddr, size_t size, size_t alignment, size_t offset_in_image, bool is_readable, bool is_writable, bool is_executable, const String& name) -> u8* {
ASSERT(size);
ASSERT(alignment == PAGE_SIZE);
int prot = 0;
@ -433,10 +433,11 @@ int Process::do_exec(String path, Vector<String> arguments, Vector<String> envir
prot |= PROT_WRITE;
if (is_executable)
prot |= PROT_EXEC;
(void)allocate_region_with_vmo(vaddr, size, vmo, offset_in_image, String(name), prot);
if (!allocate_region_with_vmo(vaddr, size, vmo, offset_in_image, String(name), prot))
return nullptr;
return vaddr.as_ptr();
};
loader->alloc_section_hook = [&](VirtualAddress vaddr, size_t size, size_t alignment, bool is_readable, bool is_writable, const String& name) {
loader->alloc_section_hook = [&](VirtualAddress vaddr, size_t size, size_t alignment, bool is_readable, bool is_writable, const String& name) -> u8* {
ASSERT(size);
ASSERT(alignment == PAGE_SIZE);
int prot = 0;
@ -444,7 +445,8 @@ int Process::do_exec(String path, Vector<String> arguments, Vector<String> envir
prot |= PROT_READ;
if (is_writable)
prot |= PROT_WRITE;
(void)allocate_region(vaddr, size, String(name), prot);
if (!allocate_region(vaddr, size, String(name), prot))
return nullptr;
return vaddr.as_ptr();
};
loader->tls_section_hook = [&](size_t size, size_t alignment) {