1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-10 12:17:35 +00:00

Kernel+LibELF: Enable SMAP protection during non-syscall exec()

When loading a new executable, we now map the ELF image in kernel-only
memory and parse it there. Then we use copy_to_user() when initializing
writable regions with data from the executable.

Note that the exec() syscall still disables SMAP protection and will
require additional work. This patch only affects kernel-originated
process spawns.
This commit is contained in:
Andreas Kling 2020-01-10 06:57:18 +01:00
parent 66b0002acb
commit 197e73ee31
5 changed files with 20 additions and 10 deletions

View file

@ -165,13 +165,16 @@ Region* Process::allocate_file_backed_region(VirtualAddress vaddr, size_t size,
return &m_regions.last();
}
Region* Process::allocate_region_with_vmobject(VirtualAddress vaddr, size_t size, NonnullRefPtr<VMObject> vmobject, size_t offset_in_vmobject, const String& name, int prot)
Region* Process::allocate_region_with_vmobject(VirtualAddress vaddr, size_t size, NonnullRefPtr<VMObject> vmobject, size_t offset_in_vmobject, const String& name, int prot, bool user_accessible)
{
auto range = allocate_range(vaddr, size);
if (!range.is_valid())
return nullptr;
offset_in_vmobject &= PAGE_MASK;
m_regions.append(Region::create_user_accessible(range, move(vmobject), offset_in_vmobject, name, prot_to_region_access_flags(prot)));
if (user_accessible)
m_regions.append(Region::create_user_accessible(range, move(vmobject), offset_in_vmobject, name, prot_to_region_access_flags(prot)));
else
m_regions.append(Region::create_kernel_only(range, move(vmobject), offset_in_vmobject, name, prot_to_region_access_flags(prot)));
m_regions.last().map(page_directory());
return &m_regions.last();
}
@ -669,7 +672,7 @@ int Process::do_exec(String path, Vector<String> arguments, Vector<String> envir
ASSERT(description->inode());
auto vmobject = InodeVMObject::create_with_inode(*description->inode());
auto* region = allocate_region_with_vmobject(VirtualAddress(), metadata.size, vmobject, 0, description->absolute_path(), PROT_READ);
auto* region = allocate_region_with_vmobject(VirtualAddress(), metadata.size, vmobject, 0, description->absolute_path(), PROT_READ, false);
ASSERT(region);
// NOTE: We yank this out of 'm_regions' since we're about to manipulate the vector
@ -682,7 +685,6 @@ int Process::do_exec(String path, Vector<String> arguments, Vector<String> envir
OwnPtr<ELFLoader> loader;
{
SmapDisabler disabler;
// Okay, here comes the sleight of hand, pay close attention..
auto old_regions = move(m_regions);
m_regions.append(move(executable_region));
@ -741,9 +743,6 @@ int Process::do_exec(String path, Vector<String> arguments, Vector<String> envir
#endif
}
region->set_user_accessible(false);
region->remap();
m_elf_loader = move(loader);
m_executable = description->custody();