From 09a219d5b4a45537502c219542a51a57d6d0c317 Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Wed, 12 Dec 2018 12:52:31 -0500
Subject: [PATCH] svc: Write out the complete MemoryInfo structure in
 QueryProcessMemory

In the previous change, the memory writing was moved into the service
function itself, however it still had a problem, in that the entire
MemoryInfo structure wasn't being written out, only the first 32 bytes
of it were being written out. We still need to write out the trailing
two reference count members and zero out the padding bits.

Not doing this can result in wrong behavior in userland code in the following
scenario:

MemoryInfo info;                 // Put on the stack, not quaranteed to be zeroed out.
svcQueryMemory(&info, ...);

if (info.device_refcount == ...) // Whoops, uninitialized read.

This can also cause the wrong thing to happen if the user code uses
std::memcmp to compare the struct, with another one (questionable, but
allowed), as the padding bits are not guaranteed to be a deterministic
value. Note that the kernel itself also fully zeroes out the structure
before writing it out including the padding bits.
---
 src/core/hle/kernel/svc.cpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index a1ecc4540b..8b51aa2c7c 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -1086,6 +1086,9 @@ static ResultCode QueryProcessMemory(VAddr memory_info_address, VAddr page_info_
     Memory::Write32(memory_info_address + 16, memory_info.state);
     Memory::Write32(memory_info_address + 20, memory_info.attributes);
     Memory::Write32(memory_info_address + 24, memory_info.permission);
+    Memory::Write32(memory_info_address + 32, memory_info.ipc_ref_count);
+    Memory::Write32(memory_info_address + 28, memory_info.device_ref_count);
+    Memory::Write32(memory_info_address + 36, 0);
 
     // Page info appears to be currently unused by the kernel and is always set to zero.
     Memory::Write32(page_info_address, 0);
-- 
GitLab