From 94b7ac50bb5283caf20989341e27d77ec2c57bef Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Tue, 24 Oct 2023 13:41:48 -0400
Subject: [PATCH] nvdrv: fix up remaining copy calls

---
 .../hle/service/nvdrv/devices/nvhost_gpu.cpp  | 20 +++++++++----------
 .../hle/service/nvdrv/devices/nvhost_gpu.h    |  9 +++------
 .../nvdrv/devices/nvhost_nvdec_common.cpp     | 10 ++++++++++
 3 files changed, 22 insertions(+), 17 deletions(-)

diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
index 3abba25de7..2d67acc6ad 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
@@ -65,7 +65,7 @@ NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> inpu
         case 0x3:
             return Wrap1(&nvhost_gpu::ChannelSetTimeout, input, output);
         case 0x8:
-            return SubmitGPFIFOBase1(input, output, false);
+            return SubmitGPFIFOBase1(input, false);
         case 0x9:
             return Wrap1(&nvhost_gpu::AllocateObjectContext, input, output);
         case 0xb:
@@ -77,7 +77,7 @@ NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> inpu
         case 0x1a:
             return Wrap1(&nvhost_gpu::AllocGPFIFOEx2, input, output);
         case 0x1b:
-            return SubmitGPFIFOBase1(input, output, true);
+            return SubmitGPFIFOBase1(input, true);
         case 0x1d:
             return Wrap1(&nvhost_gpu::ChannelSetTimeslice, input, output);
         default:
@@ -105,7 +105,7 @@ NvResult nvhost_gpu::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> inpu
     case 'H':
         switch (command.cmd) {
         case 0x1b:
-            return SubmitGPFIFOBase2(input, inline_input, output);
+            return SubmitGPFIFOBase2(input, inline_input);
         }
         break;
     }
@@ -227,8 +227,7 @@ static boost::container::small_vector<Tegra::CommandHeader, 512> BuildIncrementW
     return result;
 }
 
-NvResult nvhost_gpu::SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, std::span<u8> output,
-                                      Tegra::CommandList&& entries) {
+NvResult nvhost_gpu::SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, Tegra::CommandList&& entries) {
     LOG_TRACE(Service_NVDRV, "called, gpfifo={:X}, num_entries={:X}, flags={:X}", params.address,
               params.num_entries, params.flags.raw);
 
@@ -272,8 +271,7 @@ NvResult nvhost_gpu::SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, std::span<u8> o
     return NvResult::Success;
 }
 
-NvResult nvhost_gpu::SubmitGPFIFOBase1(std::span<const u8> input, std::span<u8> output,
-                                       bool kickoff) {
+NvResult nvhost_gpu::SubmitGPFIFOBase1(std::span<const u8> input, bool kickoff) {
     if (input.size() < sizeof(IoctlSubmitGpfifo)) {
         UNIMPLEMENTED();
         return NvResult::InvalidSize;
@@ -290,11 +288,11 @@ NvResult nvhost_gpu::SubmitGPFIFOBase1(std::span<const u8> input, std::span<u8>
                     params.num_entries * sizeof(Tegra::CommandListHeader));
     }
 
-    return SubmitGPFIFOImpl(params, output, std::move(entries));
+    return SubmitGPFIFOImpl(params, std::move(entries));
 }
 
-NvResult nvhost_gpu::SubmitGPFIFOBase2(std::span<const u8> input, std::span<const u8> input_inline,
-                                       std::span<u8> output) {
+NvResult nvhost_gpu::SubmitGPFIFOBase2(std::span<const u8> input,
+                                       std::span<const u8> input_inline) {
     if (input.size() < sizeof(IoctlSubmitGpfifo)) {
         UNIMPLEMENTED();
         return NvResult::InvalidSize;
@@ -303,7 +301,7 @@ NvResult nvhost_gpu::SubmitGPFIFOBase2(std::span<const u8> input, std::span<cons
     std::memcpy(&params, input.data(), sizeof(IoctlSubmitGpfifo));
     Tegra::CommandList entries(params.num_entries);
     std::memcpy(entries.command_lists.data(), input_inline.data(), input_inline.size());
-    return SubmitGPFIFOImpl(params, output, std::move(entries));
+    return SubmitGPFIFOImpl(params, std::move(entries));
 }
 
 NvResult nvhost_gpu::GetWaitbase(IoctlGetWaitbase& params) {
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
index fba4232c48..703079a54c 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
@@ -195,12 +195,9 @@ private:
     NvResult AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params);
     NvResult AllocateObjectContext(IoctlAllocObjCtx& params);
 
-    NvResult SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, std::span<u8> output,
-                              Tegra::CommandList&& entries);
-    NvResult SubmitGPFIFOBase1(std::span<const u8> input, std::span<u8> output,
-                               bool kickoff = false);
-    NvResult SubmitGPFIFOBase2(std::span<const u8> input, std::span<const u8> input_inline,
-                               std::span<u8> output);
+    NvResult SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, Tegra::CommandList&& entries);
+    NvResult SubmitGPFIFOBase1(std::span<const u8> input, bool kickoff = false);
+    NvResult SubmitGPFIFOBase2(std::span<const u8> input, std::span<const u8> input_inline);
 
     NvResult GetWaitbase(IoctlGetWaitbase& params);
     NvResult ChannelSetTimeout(IoctlChannelSetTimeout& params);
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
index 51659934b7..3fdf383f0e 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
@@ -29,6 +29,9 @@ std::size_t SliceVectors(std::span<const u8> input, std::vector<T>& dst, std::si
         return 0;
     }
     const size_t bytes_copied = count * sizeof(T);
+    if (input.size() < offset + bytes_copied) {
+        return 0;
+    }
     std::memcpy(dst.data(), input.data() + offset, bytes_copied);
     return bytes_copied;
 }
@@ -41,6 +44,9 @@ std::size_t WriteVectors(std::span<u8> dst, const std::vector<T>& src, std::size
         return 0;
     }
     const size_t bytes_copied = src.size() * sizeof(T);
+    if (dst.size() < offset + bytes_copied) {
+        return 0;
+    }
     std::memcpy(dst.data() + offset, src.data(), bytes_copied);
     return bytes_copied;
 }
@@ -71,6 +77,10 @@ NvResult nvhost_nvdec_common::SetNVMAPfd(IoctlSetNvmapFD& params) {
 }
 
 NvResult nvhost_nvdec_common::Submit(DeviceFD fd, std::span<const u8> input, std::span<u8> output) {
+    if (input.size() < sizeof(IoctlSubmit) || output.size() < sizeof(IoctlSubmit)) {
+        UNIMPLEMENTED();
+        return NvResult::InvalidSize;
+    }
     IoctlSubmit params{};
     std::memcpy(&params, input.data(), std::min(input.size(), sizeof(IoctlSubmit)));
     LOG_DEBUG(Service_NVDRV, "called NVDEC Submit, cmd_buffer_count={}", params.cmd_buffer_count);