From 82ecdd0104802c917a1f321f48576aba6964438c Mon Sep 17 00:00:00 2001
From: David Marcec <dmarcecguzman@gmail.com>
Date: Wed, 24 Jun 2020 22:50:27 +1000
Subject: [PATCH] Mark invalid IPC buffers as ASSERT_OR_EXECUTE_MSG

Previously if applications would send faulty buffers(example homebrew) it would lead to us returning uninitalized data. Switching from ASSERT_MSG to ASSERT_OR_EXECUTE_MSG allows us to have a fail safe to prevent crashes but also continue execution without introducing undefined behavior
---
 src/core/hle/kernel/hle_ipc.cpp | 47 +++++++++++++++------------------
 1 file changed, 22 insertions(+), 25 deletions(-)

diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index ba0eac4c27..0d01a70477 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/kernel/hle_ipc.cpp
@@ -282,18 +282,18 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(Thread& thread) {
 }
 
 std::vector<u8> HLERequestContext::ReadBuffer(std::size_t buffer_index) const {
-    std::vector<u8> buffer;
+    std::vector<u8> buffer{};
     const bool is_buffer_a{BufferDescriptorA().size() > buffer_index &&
                            BufferDescriptorA()[buffer_index].Size()};
 
     if (is_buffer_a) {
-        ASSERT_MSG(BufferDescriptorA().size() > buffer_index,
-                   "BufferDescriptorA invalid buffer_index {}", buffer_index);
+        ASSERT_OR_EXECUTE_MSG(BufferDescriptorA().size() > buffer_index, { return buffer; },
+                              "BufferDescriptorA invalid buffer_index {}", buffer_index);
         buffer.resize(BufferDescriptorA()[buffer_index].Size());
         memory.ReadBlock(BufferDescriptorA()[buffer_index].Address(), buffer.data(), buffer.size());
     } else {
-        ASSERT_MSG(BufferDescriptorX().size() > buffer_index,
-                   "BufferDescriptorX invalid buffer_index {}", buffer_index);
+        ASSERT_OR_EXECUTE_MSG(BufferDescriptorX().size() > buffer_index, { return buffer; },
+                              "BufferDescriptorX invalid buffer_index {}", buffer_index);
         buffer.resize(BufferDescriptorX()[buffer_index].Size());
         memory.ReadBlock(BufferDescriptorX()[buffer_index].Address(), buffer.data(), buffer.size());
     }
@@ -318,16 +318,16 @@ std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size,
     }
 
     if (is_buffer_b) {
-        ASSERT_MSG(BufferDescriptorB().size() > buffer_index,
-                   "BufferDescriptorB invalid buffer_index {}", buffer_index);
-        ASSERT_MSG(BufferDescriptorB()[buffer_index].Size() >= size,
-                   "BufferDescriptorB buffer_index {} is not large enough", buffer_index);
+        ASSERT_OR_EXECUTE_MSG(BufferDescriptorB().size() > buffer_index &&
+                                  BufferDescriptorB()[buffer_index].Size() >= size,
+                              { return 0; }, "BufferDescriptorB is invalid, index={}, size={}",
+                              buffer_index, size);
         memory.WriteBlock(BufferDescriptorB()[buffer_index].Address(), buffer, size);
     } else {
-        ASSERT_MSG(BufferDescriptorC().size() > buffer_index,
-                   "BufferDescriptorC invalid buffer_index {}", buffer_index);
-        ASSERT_MSG(BufferDescriptorC()[buffer_index].Size() >= size,
-                   "BufferDescriptorC buffer_index {} is not large enough", buffer_index);
+        ASSERT_OR_EXECUTE_MSG(BufferDescriptorC().size() > buffer_index &&
+                                  BufferDescriptorC()[buffer_index].Size() >= size,
+                              { return 0; }, "BufferDescriptorC is invalid, index={}, size={}",
+                              buffer_index, size);
         memory.WriteBlock(BufferDescriptorC()[buffer_index].Address(), buffer, size);
     }
 
@@ -338,16 +338,12 @@ std::size_t HLERequestContext::GetReadBufferSize(std::size_t buffer_index) const
     const bool is_buffer_a{BufferDescriptorA().size() > buffer_index &&
                            BufferDescriptorA()[buffer_index].Size()};
     if (is_buffer_a) {
-        ASSERT_MSG(BufferDescriptorA().size() > buffer_index,
-                   "BufferDescriptorA invalid buffer_index {}", buffer_index);
-        ASSERT_MSG(BufferDescriptorA()[buffer_index].Size() > 0,
-                   "BufferDescriptorA buffer_index {} is empty", buffer_index);
+        ASSERT_OR_EXECUTE_MSG(BufferDescriptorA().size() > buffer_index, { return 0; },
+                              "BufferDescriptorA invalid buffer_index {}", buffer_index);
         return BufferDescriptorA()[buffer_index].Size();
     } else {
-        ASSERT_MSG(BufferDescriptorX().size() > buffer_index,
-                   "BufferDescriptorX invalid buffer_index {}", buffer_index);
-        ASSERT_MSG(BufferDescriptorX()[buffer_index].Size() > 0,
-                   "BufferDescriptorX buffer_index {} is empty", buffer_index);
+        ASSERT_OR_EXECUTE_MSG(BufferDescriptorX().size() > buffer_index, { return 0; },
+                              "BufferDescriptorX invalid buffer_index {}", buffer_index);
         return BufferDescriptorX()[buffer_index].Size();
     }
 }
@@ -356,14 +352,15 @@ std::size_t HLERequestContext::GetWriteBufferSize(std::size_t buffer_index) cons
     const bool is_buffer_b{BufferDescriptorB().size() > buffer_index &&
                            BufferDescriptorB()[buffer_index].Size()};
     if (is_buffer_b) {
-        ASSERT_MSG(BufferDescriptorB().size() > buffer_index,
-                   "BufferDescriptorB invalid buffer_index {}", buffer_index);
+        ASSERT_OR_EXECUTE_MSG(BufferDescriptorB().size() > buffer_index, { return 0; },
+                              "BufferDescriptorB invalid buffer_index {}", buffer_index);
         return BufferDescriptorB()[buffer_index].Size();
     } else {
-        ASSERT_MSG(BufferDescriptorC().size() > buffer_index,
-                   "BufferDescriptorC invalid buffer_index {}", buffer_index);
+        ASSERT_OR_EXECUTE_MSG(BufferDescriptorC().size() > buffer_index, { return 0; },
+                              "BufferDescriptorC invalid buffer_index {}", buffer_index);
         return BufferDescriptorC()[buffer_index].Size();
     }
+    return 0;
 }
 
 std::string HLERequestContext::Description() const {
-- 
GitLab