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:
parent
eb77e680ed
commit
138abb9098
2 changed files with 21 additions and 8 deletions
|
@ -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
|
||||
});
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue