diff --git a/Kernel/Syscalls/fork.cpp b/Kernel/Syscalls/fork.cpp index d1c3303784..e97928388c 100644 --- a/Kernel/Syscalls/fork.cpp +++ b/Kernel/Syscalls/fork.cpp @@ -102,8 +102,13 @@ KResultOr Process::sys$fork(RegisterState& regs) return ENOMEM; } - auto& child_region = child->space().add_region(region_clone.release_nonnull()); - child_region.map(child->space().page_directory(), ShouldFlushTLB::No); + auto* child_region = child->space().add_region(region_clone.release_nonnull()); + if (!child_region) { + dbgln("fork: Cannot add region, insufficient memory"); + // TODO: tear down new process? + return ENOMEM; + } + child_region->map(child->space().page_directory(), ShouldFlushTLB::No); if (region == m_master_tls_region.unsafe_ptr()) child->m_master_tls_region = child_region; diff --git a/Kernel/VM/Space.cpp b/Kernel/VM/Space.cpp index b2899a00eb..211a14a2e4 100644 --- a/Kernel/VM/Space.cpp +++ b/Kernel/VM/Space.cpp @@ -156,16 +156,18 @@ KResultOr Space::try_allocate_split_region(Region const& source_region, m_process, range, source_region.vmobject(), offset_in_vmobject, KString::try_create(source_region.name()), source_region.access(), source_region.is_cacheable() ? Region::Cacheable::Yes : Region::Cacheable::No, source_region.is_shared()); if (!new_region) return ENOMEM; - auto& region = add_region(new_region.release_nonnull()); - region.set_syscall_region(source_region.is_syscall_region()); - region.set_mmap(source_region.is_mmap()); - region.set_stack(source_region.is_stack()); + auto* region = add_region(new_region.release_nonnull()); + if (!region) + return ENOMEM; + region->set_syscall_region(source_region.is_syscall_region()); + region->set_mmap(source_region.is_mmap()); + region->set_stack(source_region.is_stack()); size_t page_offset_in_source_region = (offset_in_vmobject - source_region.offset_in_vmobject()) / PAGE_SIZE; - for (size_t i = 0; i < region.page_count(); ++i) { + for (size_t i = 0; i < region->page_count(); ++i) { if (source_region.should_cow(page_offset_in_source_region + i)) - region.set_should_cow(i, true); + region->set_should_cow(i, true); } - return ®ion; + return region; } KResultOr Space::allocate_region(Range const& range, StringView name, int prot, AllocationStrategy strategy) @@ -179,7 +181,10 @@ KResultOr Space::allocate_region(Range const& range, StringView name, i return ENOMEM; if (!region->map(page_directory())) return ENOMEM; - return &add_region(region.release_nonnull()); + auto* added_region = add_region(region.release_nonnull()); + if (!added_region) + return ENOMEM; + return added_region; } KResultOr Space::allocate_region_with_vmobject(Range const& range, NonnullRefPtr vmobject, size_t offset_in_vmobject, StringView name, int prot, bool shared) @@ -202,14 +207,16 @@ KResultOr Space::allocate_region_with_vmobject(Range const& range, Nonn auto region = Region::try_create_user_accessible(m_process, range, move(vmobject), offset_in_vmobject, KString::try_create(name), prot_to_region_access_flags(prot), Region::Cacheable::Yes, shared); if (!region) { dbgln("allocate_region_with_vmobject: Unable to allocate Region"); - return nullptr; + return ENOMEM; } - auto& region_ref = add_region(region.release_nonnull()); - if (!region_ref.map(page_directory())) { + auto* added_region = add_region(region.release_nonnull()); + if (!added_region) + return ENOMEM; + if (!added_region->map(page_directory())) { // FIXME: What is an appropriate error code here, really? return ENOMEM; } - return ®ion_ref; + return added_region; } bool Space::deallocate_region(Region& region) @@ -284,12 +291,12 @@ Vector Space::find_regions_intersecting(const Range& range) return regions; } -Region& Space::add_region(NonnullOwnPtr region) +Region* Space::add_region(NonnullOwnPtr region) { auto* ptr = region.ptr(); ScopedSpinLock lock(m_lock); - m_regions.insert(region->vaddr().get(), move(region)); - return *ptr; + auto success = m_regions.try_insert(region->vaddr().get(), move(region)); + return success ? ptr : nullptr; } // Carve out a virtual address range from a region and return the two regions on either side diff --git a/Kernel/VM/Space.h b/Kernel/VM/Space.h index 39b9c6f61c..97171c84b6 100644 --- a/Kernel/VM/Space.h +++ b/Kernel/VM/Space.h @@ -24,7 +24,7 @@ public: PageDirectory& page_directory() { return *m_page_directory; } const PageDirectory& page_directory() const { return *m_page_directory; } - Region& add_region(NonnullOwnPtr); + Region* add_region(NonnullOwnPtr); size_t region_count() const { return m_regions.size(); }