From d85875b910b09696c84feb820628d1fde0a1d009 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 29 Apr 2022 15:46:55 -0700 Subject: [PATCH] os: fix various regressions since 1.3.1 --- .../os_aslr_space_manager_impl.os.horizon.hpp | 40 +++++++++++-------- .../os/impl/os_aslr_space_manager_types.hpp | 9 ++++- .../source/os/impl/os_multiple_wait_impl.cpp | 22 ++++++---- ...os_process_code_memory_impl.os.horizon.cpp | 2 + 4 files changed, 47 insertions(+), 26 deletions(-) diff --git a/libraries/libstratosphere/source/os/impl/os_aslr_space_manager_impl.os.horizon.hpp b/libraries/libstratosphere/source/os/impl/os_aslr_space_manager_impl.os.horizon.hpp index 6a626329c..0e4305493 100644 --- a/libraries/libstratosphere/source/os/impl/os_aslr_space_manager_impl.os.horizon.hpp +++ b/libraries/libstratosphere/source/os/impl/os_aslr_space_manager_impl.os.horizon.hpp @@ -32,9 +32,9 @@ namespace ams::os::impl { static constexpr size_t ForbiddenRegionCount = 2; private: - static u64 GetAslrInfo(svc::InfoType type) { + static u64 GetAslrInfo(os::NativeHandle process_handle, svc::InfoType type) { u64 value; - R_ABORT_UNLESS(svc::GetInfo(std::addressof(value), type, svc::PseudoHandle::CurrentProcess, 0)); + R_ABORT_UNLESS(svc::GetInfo(std::addressof(value), type, process_handle, 0)); static_assert(std::same_as); AMS_ASSERT(value <= std::numeric_limits::max()); @@ -45,8 +45,11 @@ namespace ams::os::impl { AddressSpaceAllocatorForbiddenRegion m_forbidden_regions[ForbiddenRegionCount]; public: AslrSpaceManagerHorizonImpl() { - m_forbidden_regions[0] = { .address = GetHeapSpaceBeginAddress(), .size = GetHeapSpaceSize() }; - m_forbidden_regions[1] = { .address = GetAliasSpaceBeginAddress(), .size = GetAliasSpaceSize() }; + this->InitializeForbiddenRegions(svc::PseudoHandle::CurrentProcess); + } + + AslrSpaceManagerHorizonImpl(os::NativeHandle process_handle) { + this->InitializeForbiddenRegions(process_handle); } const AddressSpaceAllocatorForbiddenRegion *GetForbiddenRegions() const { @@ -57,28 +60,33 @@ namespace ams::os::impl { return ForbiddenRegionCount; } - static u64 GetHeapSpaceBeginAddress() { - return GetAslrInfo(svc::InfoType_HeapRegionAddress); + static u64 GetHeapSpaceBeginAddress(os::NativeHandle process_handle = svc::PseudoHandle::CurrentProcess) { + return GetAslrInfo(process_handle, svc::InfoType_HeapRegionAddress); } - static u64 GetHeapSpaceSize() { - return GetAslrInfo(svc::InfoType_HeapRegionSize); + static u64 GetHeapSpaceSize(os::NativeHandle process_handle = svc::PseudoHandle::CurrentProcess) { + return GetAslrInfo(process_handle, svc::InfoType_HeapRegionSize); } - static u64 GetAliasSpaceBeginAddress() { - return GetAslrInfo(svc::InfoType_AliasRegionAddress); + static u64 GetAliasSpaceBeginAddress(os::NativeHandle process_handle = svc::PseudoHandle::CurrentProcess) { + return GetAslrInfo(process_handle, svc::InfoType_AliasRegionAddress); } - static u64 GetAliasSpaceSize() { - return GetAslrInfo(svc::InfoType_AliasRegionSize); + static u64 GetAliasSpaceSize(os::NativeHandle process_handle = svc::PseudoHandle::CurrentProcess) { + return GetAslrInfo(process_handle, svc::InfoType_AliasRegionSize); } - static u64 GetAslrSpaceBeginAddress() { - return GetAslrInfo(svc::InfoType_AslrRegionAddress); + static u64 GetAslrSpaceBeginAddress(os::NativeHandle process_handle = svc::PseudoHandle::CurrentProcess) { + return GetAslrInfo(process_handle, svc::InfoType_AslrRegionAddress); } - static u64 GetAslrSpaceEndAddress() { - return GetAslrInfo(svc::InfoType_AslrRegionAddress) + GetAslrInfo(svc::InfoType_AslrRegionSize); + static u64 GetAslrSpaceEndAddress(os::NativeHandle process_handle = svc::PseudoHandle::CurrentProcess) { + return GetAslrInfo(process_handle, svc::InfoType_AslrRegionAddress) + GetAslrInfo(process_handle, svc::InfoType_AslrRegionSize); + } + private: + void InitializeForbiddenRegions(os::NativeHandle process_handle) { + m_forbidden_regions[0] = { .address = GetHeapSpaceBeginAddress(process_handle), .size = GetHeapSpaceSize(process_handle) }; + m_forbidden_regions[1] = { .address = GetAliasSpaceBeginAddress(process_handle), .size = GetAliasSpaceSize(process_handle) }; } }; diff --git a/libraries/libstratosphere/source/os/impl/os_aslr_space_manager_types.hpp b/libraries/libstratosphere/source/os/impl/os_aslr_space_manager_types.hpp index 2caaa543a..5f4ccb105 100644 --- a/libraries/libstratosphere/source/os/impl/os_aslr_space_manager_types.hpp +++ b/libraries/libstratosphere/source/os/impl/os_aslr_space_manager_types.hpp @@ -45,11 +45,16 @@ namespace ams::os::impl { Impl m_impl; Allocator m_allocator; public: - template - AslrSpaceManagerTemplate(Args &&... args) : m_impl(), m_allocator(m_impl.GetAslrSpaceBeginAddress(), m_impl.GetAslrSpaceEndAddress(), AslrSpaceGuardSize, m_impl.GetForbiddenRegions(), m_impl.GetForbiddenRegionCount(), std::forward(args)...) { + AslrSpaceManagerTemplate() : m_impl(), m_allocator(m_impl.GetAslrSpaceBeginAddress(), m_impl.GetAslrSpaceEndAddress(), AslrSpaceGuardSize, m_impl.GetForbiddenRegions(), m_impl.GetForbiddenRegionCount()) { /* ... */ } + #if defined(ATMOSPHERE_OS_HORIZON) + AslrSpaceManagerTemplate(os::NativeHandle process_handle) : m_impl(process_handle), m_allocator(m_impl.GetAslrSpaceBeginAddress(process_handle), m_impl.GetAslrSpaceEndAddress(process_handle), AslrSpaceGuardSize, m_impl.GetForbiddenRegions(), m_impl.GetForbiddenRegionCount(), process_handle) { + /* ... */ + } + #endif + AddressType AllocateSpace(SizeType size, SizeType align_offset) { /* Try to allocate a large-aligned space, if we can. */ if (align_offset || (size / AslrSpaceLargeAlign) != 0) { diff --git a/libraries/libstratosphere/source/os/impl/os_multiple_wait_impl.cpp b/libraries/libstratosphere/source/os/impl/os_multiple_wait_impl.cpp index ef2921597..91b279c6f 100644 --- a/libraries/libstratosphere/source/os/impl/os_multiple_wait_impl.cpp +++ b/libraries/libstratosphere/source/os/impl/os_multiple_wait_impl.cpp @@ -29,6 +29,18 @@ namespace ams::os::impl { /* Add each holder to the object list, and try to find one that's signaled. */ MultiWaitHolderBase *signaled_holder = this->AddToEachObjectListAndCheckObjectState(); + /* When we're done, cleanup and set output. */ + ON_SCOPE_EXIT { + /* Remove each holder from the current object list. */ + this->RemoveFromEachObjectList(); + + /* Clear cancel wait. */ + m_target_impl.ClearCurrentThreadHandleForCancelWait(); + + /* Set output holder. */ + *out = signaled_holder; + }; + /* Check if we've been signaled. */ { std::scoped_lock lk(m_cs_wait); @@ -43,6 +55,8 @@ namespace ams::os::impl { if constexpr (AllowReply) { /* Try to reply to the reply target. */ if (reply_target != os::InvalidNativeHandle) { + ON_RESULT_FAILURE { signaled_holder = nullptr; }; + s32 index; R_TRY(m_target_impl.TimedReplyAndReceive(std::addressof(index), nullptr, 0, 0, reply_target, TimeSpan::FromNanoSeconds(0))); } @@ -52,14 +66,6 @@ namespace ams::os::impl { R_TRY(this->InternalWaitAnyImpl(std::addressof(signaled_holder), infinite, timeout, reply_target)); } - /* Remove each holder from the current object list. */ - this->RemoveFromEachObjectList(); - - /* Clear cancel wait. */ - m_target_impl.ClearCurrentThreadHandleForCancelWait(); - - /* Set output holder. */ - *out = signaled_holder; R_SUCCEED(); } diff --git a/libraries/libstratosphere/source/os/impl/os_process_code_memory_impl.os.horizon.cpp b/libraries/libstratosphere/source/os/impl/os_process_code_memory_impl.os.horizon.cpp index ecbddac82..7bafacc50 100644 --- a/libraries/libstratosphere/source/os/impl/os_process_code_memory_impl.os.horizon.cpp +++ b/libraries/libstratosphere/source/os/impl/os_process_code_memory_impl.os.horizon.cpp @@ -96,6 +96,8 @@ namespace ams::os::impl { R_THROW(os::ResultInvalidCurrentMemoryState()); } } R_END_TRY_CATCH_WITH_ABORT_UNLESS; + + mapped_size += regions[i].size; } R_SUCCEED();