From 0fcb9efd86da4c15a1aee87503348c5bee875c51 Mon Sep 17 00:00:00 2001 From: Brian Gianforcaro Date: Fri, 30 Jul 2021 01:17:59 -0700 Subject: [PATCH] Kernel: Return an error when unmap finds no intersecting region We currently always crash if a user attempts to unmap a range that does not intersect with an existing region, no matter the size. This happens because we will never explicitly check to see if the search for intersecting regions found anything, instead loop over the results, which might be an empty vector. We then attempt to deallocate the requested range from the `RangeAllocator` unconditionally, which will be invalid if the specified range is not managed by the RangeAllocator. We will assert validating m_total_range.contains(..) the range we are requesting to deallocate. This fix to this is straight forward, error out if we weren't able to find any intersections. You can get stress-ng to attempt this pattern with the following arguments, which will attempt to unmap 0x0 through some large offset: ``` stress-ng --vm-segv 1 ``` Fixes: #8483 Co-authored-by: Federico Guerinoni --- Kernel/VM/Space.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Kernel/VM/Space.cpp b/Kernel/VM/Space.cpp index 3cf4f55a62..cf165ea348 100644 --- a/Kernel/VM/Space.cpp +++ b/Kernel/VM/Space.cpp @@ -45,7 +45,6 @@ KResult Space::unmap_mmap_range(VirtualAddress addr, size_t size) auto range_or_error = Range::expand_to_page_boundaries(addr.get(), size); if (range_or_error.is_error()) return range_or_error.error(); - auto range_to_unmap = range_or_error.value(); if (!is_user_range(range_to_unmap)) @@ -92,6 +91,8 @@ KResult Space::unmap_mmap_range(VirtualAddress addr, size_t size) // Try again while checking multiple regions at a time. auto const& regions = find_regions_intersecting(range_to_unmap); + if (regions.is_empty()) + return EINVAL; // Check if any of the regions is not mmap'ed, to not accidentally // error out with just half a region map left.