From e93fa7f2cccfaaf655f62a0627e002676800a44d Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 3 Aug 2018 20:45:39 -0400 Subject: kernel/thread: Fix potential crashes introduced in 26de4bb521b1ace7af76eff4f6956cb23ac0d58c This amends cases where crashes can occur that were missed due to the odd way the previous code was set up (using 3DS memory regions that don't exist). --- src/core/hle/kernel/shared_memory.cpp | 38 +++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 13 deletions(-) (limited to 'src/core/hle/kernel/shared_memory.cpp') diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index b3ddebb3d..21ddc2f7d 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp @@ -28,20 +28,32 @@ SharedPtr SharedMemory::Create(SharedPtr owner_process, u shared_memory->permissions = permissions; shared_memory->other_permissions = other_permissions; - auto& vm_manager = shared_memory->owner_process->vm_manager; - - // The memory is already available and mapped in the owner process. - auto vma = vm_manager.FindVMA(address); - ASSERT_MSG(vma != vm_manager.vma_map.end(), "Invalid memory address"); - ASSERT_MSG(vma->second.backing_block, "Backing block doesn't exist for address"); - - // The returned VMA might be a bigger one encompassing the desired address. - auto vma_offset = address - vma->first; - ASSERT_MSG(vma_offset + size <= vma->second.size, - "Shared memory exceeds bounds of mapped block"); + if (address == 0) { + shared_memory->backing_block = std::make_shared>(size); + shared_memory->backing_block_offset = 0; + + // Refresh the address mappings for the current process. + if (Core::CurrentProcess() != nullptr) { + Core::CurrentProcess()->vm_manager.RefreshMemoryBlockMappings( + shared_memory->backing_block.get()); + } + } else { + auto& vm_manager = shared_memory->owner_process->vm_manager; + + // The memory is already available and mapped in the owner process. + auto vma = vm_manager.FindVMA(address); + ASSERT_MSG(vma != vm_manager.vma_map.end(), "Invalid memory address"); + ASSERT_MSG(vma->second.backing_block, "Backing block doesn't exist for address"); + + // The returned VMA might be a bigger one encompassing the desired address. + auto vma_offset = address - vma->first; + ASSERT_MSG(vma_offset + size <= vma->second.size, + "Shared memory exceeds bounds of mapped block"); + + shared_memory->backing_block = vma->second.backing_block; + shared_memory->backing_block_offset = vma->second.offset + vma_offset; + } - shared_memory->backing_block = vma->second.backing_block; - shared_memory->backing_block_offset = vma->second.offset + vma_offset; shared_memory->base_address = address; return shared_memory; -- cgit v1.2.3