summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-03-06 09:58:59 +0100
committerAndreas Kling <kling@serenityos.org>2020-03-06 09:58:59 +0100
commit94f287b1c0ba5fac47e77e97d00292fefb85d468 (patch)
treef8850ddfac0044c02572bda4680f4f0aaff6cfca
parentaf29dff2244db68a81e2f4812e8b92e95b31b181 (diff)
downloadserenity-94f287b1c0ba5fac47e77e97d00292fefb85d468.zip
Kernel: Unmap non-readable pages
This was caught by running all crash tests with "crash -A". Basically, non-readable pages need to not be mapped *at all* so that a "page not present" exception is provoked on access. Unfortunately x86 does not support write-only mappings, so this is the best we can do. Fixes #1336.
-rw-r--r--Kernel/VM/Region.cpp7
1 files changed, 5 insertions, 2 deletions
diff --git a/Kernel/VM/Region.cpp b/Kernel/VM/Region.cpp
index d498ca910a..a64c66a7f9 100644
--- a/Kernel/VM/Region.cpp
+++ b/Kernel/VM/Region.cpp
@@ -213,7 +213,7 @@ void Region::map_individual_page_impl(size_t page_index)
auto page_vaddr = vaddr().offset(page_index * PAGE_SIZE);
auto& pte = MM.ensure_pte(*m_page_directory, page_vaddr);
auto& physical_page = vmobject().physical_pages()[first_page_index() + page_index];
- if (!physical_page) {
+ if (!physical_page || !is_readable()) {
pte.clear();
} else {
pte.set_cache_disabled(!m_cacheable);
@@ -291,7 +291,10 @@ PageFaultResponse Region::handle_fault(const PageFault& fault)
dbg() << "NP(non-readable) fault in Region{" << this << "}[" << page_index_in_region << "]";
return PageFaultResponse::ShouldCrash;
}
-
+ if (fault.is_write() && !is_writable()) {
+ dbg() << "NP(non-writable) write fault in Region{" << this << "}[" << page_index_in_region << "] at " << fault.vaddr();
+ return PageFaultResponse::ShouldCrash;
+ }
if (vmobject().is_inode()) {
#ifdef PAGE_FAULT_DEBUG
dbg() << "NP(inode) fault in Region{" << this << "}[" << page_index_in_region << "]";