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

Kernel: Implement some basic stack pointer validation

VM regions can now be marked as stack regions, which is then validated
on syscall, and on page fault.

If a thread is caught with its stack pointer pointing into anything
that's *not* a Region with its stack bit set, we'll crash the whole
process with SIGSTKFLT.

Userspace must now allocate custom stacks by using mmap() with the new
MAP_STACK flag. This mechanism was first introduced in OpenBSD, and now
we have it too, yay! :^)
This commit is contained in:
Andreas Kling 2019-11-17 12:11:43 +01:00
parent 197ed1bb2a
commit 794758df3a
12 changed files with 101 additions and 5 deletions

View file

@ -549,6 +549,12 @@ void MemoryManager::unquickmap_page()
m_quickmap_in_use = false;
}
bool MemoryManager::validate_user_stack(const Process& process, VirtualAddress vaddr) const
{
auto* region = region_from_vaddr(process, vaddr);
return region && region->is_stack();
}
bool MemoryManager::validate_user_read(const Process& process, VirtualAddress vaddr) const
{
auto* region = region_from_vaddr(process, vaddr);

View file

@ -46,6 +46,7 @@ public:
void enter_process_paging_scope(Process&);
bool validate_user_stack(const Process&, VirtualAddress) const;
bool validate_user_read(const Process&, VirtualAddress) const;
bool validate_user_write(const Process&, VirtualAddress) const;

View file

@ -58,6 +58,7 @@ NonnullOwnPtr<Region> Region::clone()
ASSERT(is_user_accessible());
if (m_shared || (is_readable() && !is_writable())) {
ASSERT(!m_stack);
#ifdef MM_DEBUG
dbgprintf("%s<%u> Region::clone(): sharing %s (V%p)\n",
current->process().name().characters(),
@ -81,6 +82,13 @@ NonnullOwnPtr<Region> Region::clone()
remap();
auto clone_region = Region::create_user_accessible(m_range, m_vmobject->clone(), m_offset_in_vmo, m_name, m_access);
clone_region->ensure_cow_map();
if (m_stack) {
ASSERT(is_readable());
ASSERT(is_writable());
ASSERT(!is_shared());
ASSERT(vmobject().is_anonymous());
clone_region->set_stack(true);
}
return clone_region;
}

View file

@ -50,6 +50,9 @@ public:
bool is_shared() const { return m_shared; }
void set_shared(bool shared) { m_shared = shared; }
bool is_stack() const { return m_stack; }
void set_stack(bool stack) { m_stack = stack; }
bool is_user_accessible() const { return m_user_accessible; }
PageFaultResponse handle_fault(const PageFault&);
@ -141,5 +144,6 @@ private:
u8 m_access { 0 };
bool m_shared { false };
bool m_user_accessible { false };
bool m_stack { false };
mutable OwnPtr<Bitmap> m_cow_map;
};