summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-11-29 16:15:30 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-11-29 16:30:05 +0100
commite56daf547c120adfcdab1e1e8ea189a1f369bd0c (patch)
tree89d1aac5b5ccdc6c0aa25b735a351b5623b6f139 /Kernel
parentea52fe528a1b34590661c4556b6a4bbf68bb75f0 (diff)
downloadserenity-e56daf547c120adfcdab1e1e8ea189a1f369bd0c.zip
Kernel: Disallow syscalls from writeable memory
Processes will now crash with SIGSEGV if they attempt making a syscall from PROT_WRITE memory. This neat idea comes from OpenBSD. :^)
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/Syscall.cpp13
-rw-r--r--Kernel/VM/MemoryManager.cpp1
-rw-r--r--Kernel/VM/MemoryManager.h8
3 files changed, 17 insertions, 5 deletions
diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp
index 708bfc23b3..1bd5e7e71c 100644
--- a/Kernel/Syscall.cpp
+++ b/Kernel/Syscall.cpp
@@ -105,6 +105,19 @@ void syscall_trap_entry(RegisterDump regs)
ASSERT_NOT_REACHED();
}
+ auto* calling_region = MM.region_from_vaddr(process, VirtualAddress(regs.eip));
+ if (!calling_region) {
+ dbgprintf("Syscall from %p which has no region\n", regs.eip);
+ handle_crash(regs, "Syscall from unknown region", SIGSEGV);
+ ASSERT_NOT_REACHED();
+ }
+
+ if (calling_region->is_writable()) {
+ dbgprintf("Syscall from writable memory at %p\n", regs.eip);
+ handle_crash(regs, "Syscall from writable memory", SIGSEGV);
+ ASSERT_NOT_REACHED();
+ }
+
process.big_lock().lock();
u32 function = regs.eax;
u32 arg1 = regs.edx;
diff --git a/Kernel/VM/MemoryManager.cpp b/Kernel/VM/MemoryManager.cpp
index 540081d26c..5e5c5a9b88 100644
--- a/Kernel/VM/MemoryManager.cpp
+++ b/Kernel/VM/MemoryManager.cpp
@@ -289,7 +289,6 @@ Region* MemoryManager::user_region_from_vaddr(Process& process, VirtualAddress v
Region* MemoryManager::region_from_vaddr(Process& process, VirtualAddress vaddr)
{
- ASSERT_INTERRUPTS_DISABLED();
if (auto* region = kernel_region_from_vaddr(vaddr))
return region;
return user_region_from_vaddr(process, vaddr);
diff --git a/Kernel/VM/MemoryManager.h b/Kernel/VM/MemoryManager.h
index 619f95630c..b4c7cac06d 100644
--- a/Kernel/VM/MemoryManager.h
+++ b/Kernel/VM/MemoryManager.h
@@ -1,6 +1,5 @@
#pragma once
-#include <AK/String.h>
#include <AK/Badge.h>
#include <AK/Bitmap.h>
#include <AK/ByteBuffer.h>
@@ -8,6 +7,7 @@
#include <AK/NonnullRefPtrVector.h>
#include <AK/RefCounted.h>
#include <AK/RefPtr.h>
+#include <AK/String.h>
#include <AK/Types.h>
#include <AK/Vector.h>
#include <AK/Weakable.h>
@@ -79,6 +79,9 @@ public:
}
}
+ static Region* region_from_vaddr(Process&, VirtualAddress);
+ static const Region* region_from_vaddr(const Process&, VirtualAddress);
+
private:
MemoryManager(u32 physical_address_for_kernel_page_tables);
~MemoryManager();
@@ -96,9 +99,6 @@ private:
void create_identity_mapping(PageDirectory&, VirtualAddress, size_t length);
- static Region* region_from_vaddr(Process&, VirtualAddress);
- static const Region* region_from_vaddr(const Process&, VirtualAddress);
-
static Region* user_region_from_vaddr(Process&, VirtualAddress);
static Region* kernel_region_from_vaddr(VirtualAddress);