From 46935fea8081e83e7681d22ebcbbf387d2afe1d0 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 23 Jul 2020 19:26:46 -0700 Subject: [PATCH] kern: fix resource leak bugs --- .../libmesosphere/include/mesosphere/kern_k_memory_manager.hpp | 1 + libraries/libmesosphere/source/kern_k_device_address_space.cpp | 3 +++ libraries/libmesosphere/source/kern_k_process.cpp | 2 +- libraries/libmesosphere/source/kern_k_thread.cpp | 3 ++- 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_memory_manager.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_memory_manager.hpp index c59a39ca5..1c240e437 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_memory_manager.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_memory_manager.hpp @@ -77,6 +77,7 @@ namespace ams::kern { void InitializeOptimizedMemory() { std::memset(GetVoidPointer(this->metadata_region), 0, CalculateOptimizedProcessOverheadSize(this->heap.GetSize())); } void TrackAllocationForOptimizedProcess(KVirtualAddress block, size_t num_pages); + constexpr Pool GetPool() const { return this->pool; } constexpr size_t GetSize() const { return this->heap.GetSize(); } constexpr KVirtualAddress GetEndAddress() const { return this->heap.GetEndAddress(); } diff --git a/libraries/libmesosphere/source/kern_k_device_address_space.cpp b/libraries/libmesosphere/source/kern_k_device_address_space.cpp index a83eb141b..b53ff2611 100644 --- a/libraries/libmesosphere/source/kern_k_device_address_space.cpp +++ b/libraries/libmesosphere/source/kern_k_device_address_space.cpp @@ -75,6 +75,9 @@ namespace ams::kern { KPageGroup pg(page_table->GetBlockInfoManager()); R_TRY(page_table->LockForDeviceAddressSpace(std::addressof(pg), process_address, size, ConvertToKMemoryPermission(device_perm), is_aligned)); + /* Close the pages we opened when we're done with them. */ + ON_SCOPE_EXIT { pg.Close(); }; + /* Ensure that if we fail, we don't keep unmapped pages locked. */ ON_SCOPE_EXIT { if (*out_mapped_size != size) { diff --git a/libraries/libmesosphere/source/kern_k_process.cpp b/libraries/libmesosphere/source/kern_k_process.cpp index bd1f33eef..cb47993fa 100644 --- a/libraries/libmesosphere/source/kern_k_process.cpp +++ b/libraries/libmesosphere/source/kern_k_process.cpp @@ -796,7 +796,7 @@ namespace ams::kern { R_UNLESS(stack_size + this->code_size >= this->code_size, svc::ResultOutOfMemory()); /* Place a tentative reservation of memory for our new stack. */ - KScopedResourceReservation mem_reservation(this, ams::svc::LimitableResource_PhysicalMemoryMax); + KScopedResourceReservation mem_reservation(this, ams::svc::LimitableResource_PhysicalMemoryMax, stack_size); R_UNLESS(mem_reservation.Succeeded(), svc::ResultLimitReached()); /* Allocate and map our stack. */ diff --git a/libraries/libmesosphere/source/kern_k_thread.cpp b/libraries/libmesosphere/source/kern_k_thread.cpp index 4894573cc..9ec2802ca 100644 --- a/libraries/libmesosphere/source/kern_k_thread.cpp +++ b/libraries/libmesosphere/source/kern_k_thread.cpp @@ -143,7 +143,7 @@ namespace ams::kern { this->num_kernel_waiters = 0; this->entrypoint = reinterpret_cast(func); - /* We don't need a release (probably), and we've spent no time on the cpu. */ + /* We haven't released our resource limit hint, and we've spent no time on the cpu. */ this->resource_limit_release_hint = 0; this->cpu_time = 0; @@ -825,6 +825,7 @@ namespace ams::kern { /* Release the thread resource hint from parent. */ if (this->parent != nullptr) { this->parent->ReleaseResource(ams::svc::LimitableResource_ThreadCountMax, 0, 1); + this->resource_limit_release_hint = true; } /* Perform termination. */