summaryrefslogtreecommitdiff
path: root/Kernel/Memory
diff options
context:
space:
mode:
authorLiav A <liavalb@gmail.com>2022-09-24 15:10:13 +0300
committerIdan Horowitz <idan.horowitz@gmail.com>2022-09-26 20:00:34 +0300
commit60b088b89a74af0a346a318c435113b22df53755 (patch)
treeb4833e6e1d9516237f6d95318753360d877c0041 /Kernel/Memory
parent69f7a59a347711879dfa76b922cb78a5c69f8f18 (diff)
downloadserenity-60b088b89a74af0a346a318c435113b22df53755.zip
Kernel: Send SIGBUS to threads that use after valid Inode mmaped range
According to Dr. POSIX, we should allow to call mmap on inodes even on ranges that currently don't map to any actual data. Trying to read or write to those ranges should result in SIGBUS being sent to the thread that did violating memory access. To implement this restriction, we simply check if the result of read_bytes on an Inode returns 0, which means we have nothing valid to map to the program, hence it should receive a SIGBUS in that case.
Diffstat (limited to 'Kernel/Memory')
-rw-r--r--Kernel/Memory/PageFaultResponse.h1
-rw-r--r--Kernel/Memory/Region.cpp5
2 files changed, 6 insertions, 0 deletions
diff --git a/Kernel/Memory/PageFaultResponse.h b/Kernel/Memory/PageFaultResponse.h
index 56297f6268..0a5c473230 100644
--- a/Kernel/Memory/PageFaultResponse.h
+++ b/Kernel/Memory/PageFaultResponse.h
@@ -10,6 +10,7 @@ namespace Kernel {
enum class PageFaultResponse {
ShouldCrash,
+ BusError,
OutOfMemory,
Continue,
};
diff --git a/Kernel/Memory/Region.cpp b/Kernel/Memory/Region.cpp
index a5ecc22fe6..ea042596a8 100644
--- a/Kernel/Memory/Region.cpp
+++ b/Kernel/Memory/Region.cpp
@@ -501,6 +501,11 @@ PageFaultResponse Region::handle_inode_fault(size_t page_index_in_region)
}
auto nread = result.value();
+ // Note: If we received 0, it means we are at the end of file or after it,
+ // which means we should return bus error.
+ if (nread == 0)
+ return PageFaultResponse::BusError;
+
if (nread < PAGE_SIZE) {
// If we read less than a page, zero out the rest to avoid leaking uninitialized data.
memset(page_buffer + nread, 0, PAGE_SIZE - nread);