diff options
author | Andreas Kling <kling@serenityos.org> | 2020-03-06 09:58:59 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-03-06 09:58:59 +0100 |
commit | 94f287b1c0ba5fac47e77e97d00292fefb85d468 (patch) | |
tree | f8850ddfac0044c02572bda4680f4f0aaff6cfca | |
parent | af29dff2244db68a81e2f4812e8b92e95b31b181 (diff) | |
download | serenity-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.cpp | 7 |
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 << "]"; |