diff options
| author | bunnei <bunneidev@gmail.com> | 2020-02-07 16:25:42 -0500 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-02-07 16:25:42 -0500 | 
| commit | aa3f9b960697da4a62a9e9987bc2a0db6a1ce5a8 (patch) | |
| tree | 2d78c77be18d85f3c74be438fcef877cf55b5a1a | |
| parent | 09d766d3574b94dbc349ab24359e87e8d08177d9 (diff) | |
| parent | 2245c24e2153a54c2a5e1b802a685087129a1f54 (diff) | |
Merge pull request #3381 from bunnei/ipc-fix
hle: services: Fix prepo IPC, and add better error checking.
| -rw-r--r-- | src/core/hle/kernel/hle_ipc.cpp | 50 | ||||
| -rw-r--r-- | src/core/hle/service/prepo/prepo.cpp | 30 | 
2 files changed, 57 insertions, 23 deletions
| diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 2db28dcf0..ab05788d7 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -284,13 +284,18 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(Thread& thread) {  std::vector<u8> HLERequestContext::ReadBuffer(int buffer_index) const {      std::vector<u8> buffer; -    const bool is_buffer_a{BufferDescriptorA().size() && BufferDescriptorA()[buffer_index].Size()}; +    const bool is_buffer_a{BufferDescriptorA().size() > buffer_index && +                           BufferDescriptorA()[buffer_index].Size()};      auto& memory = Core::System::GetInstance().Memory();      if (is_buffer_a) { +        ASSERT_MSG(BufferDescriptorA().size() > buffer_index, +                   "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);          buffer.resize(BufferDescriptorX()[buffer_index].Size());          memory.ReadBlock(BufferDescriptorX()[buffer_index].Address(), buffer.data(), buffer.size());      } @@ -305,7 +310,8 @@ std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size,          return 0;      } -    const bool is_buffer_b{BufferDescriptorB().size() && BufferDescriptorB()[buffer_index].Size()}; +    const bool is_buffer_b{BufferDescriptorB().size() > buffer_index && +                           BufferDescriptorB()[buffer_index].Size()};      const std::size_t buffer_size{GetWriteBufferSize(buffer_index)};      if (size > buffer_size) {          LOG_CRITICAL(Core, "size ({:016X}) is greater than buffer_size ({:016X})", size, @@ -315,8 +321,16 @@ std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size,      auto& memory = Core::System::GetInstance().Memory();      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);          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);          memory.WriteBlock(BufferDescriptorC()[buffer_index].Address(), buffer, size);      } @@ -324,15 +338,35 @@ std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size,  }  std::size_t HLERequestContext::GetReadBufferSize(int buffer_index) const { -    const bool is_buffer_a{BufferDescriptorA().size() && BufferDescriptorA()[buffer_index].Size()}; -    return is_buffer_a ? BufferDescriptorA()[buffer_index].Size() -                       : BufferDescriptorX()[buffer_index].Size(); +    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); +        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); +        return BufferDescriptorX()[buffer_index].Size(); +    }  }  std::size_t HLERequestContext::GetWriteBufferSize(int buffer_index) const { -    const bool is_buffer_b{BufferDescriptorB().size() && BufferDescriptorB()[buffer_index].Size()}; -    return is_buffer_b ? BufferDescriptorB()[buffer_index].Size() -                       : BufferDescriptorC()[buffer_index].Size(); +    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); +        return BufferDescriptorB()[buffer_index].Size(); +    } else { +        ASSERT_MSG(BufferDescriptorC().size() > buffer_index, +                   "BufferDescriptorC invalid buffer_index {}", buffer_index); +        return BufferDescriptorC()[buffer_index].Size(); +    }  }  std::string HLERequestContext::Description() const { diff --git a/src/core/hle/service/prepo/prepo.cpp b/src/core/hle/service/prepo/prepo.cpp index 5eb26caf8..8f1be0e48 100644 --- a/src/core/hle/service/prepo/prepo.cpp +++ b/src/core/hle/service/prepo/prepo.cpp @@ -50,16 +50,16 @@ private:          IPC::RequestParser rp{ctx};          const auto process_id = rp.PopRaw<u64>(); -        const auto data1 = ctx.ReadBuffer(0); -        const auto data2 = ctx.ReadBuffer(1); +        std::vector<std::vector<u8>> data{ctx.ReadBuffer(0)}; +        if (Type == Core::Reporter::PlayReportType::New) { +            data.emplace_back(ctx.ReadBuffer(1)); +        } -        LOG_DEBUG(Service_PREPO, -                  "called, type={:02X}, process_id={:016X}, data1_size={:016X}, data2_size={:016X}", -                  static_cast<u8>(Type), process_id, data1.size(), data2.size()); +        LOG_DEBUG(Service_PREPO, "called, type={:02X}, process_id={:016X}, data1_size={:016X}", +                  static_cast<u8>(Type), process_id, data[0].size());          const auto& reporter{system.GetReporter()}; -        reporter.SavePlayReport(Type, system.CurrentProcess()->GetTitleID(), {data1, data2}, -                                process_id); +        reporter.SavePlayReport(Type, system.CurrentProcess()->GetTitleID(), data, process_id);          IPC::ResponseBuilder rb{ctx, 2};          rb.Push(RESULT_SUCCESS); @@ -70,19 +70,19 @@ private:          IPC::RequestParser rp{ctx};          const auto user_id = rp.PopRaw<u128>();          const auto process_id = rp.PopRaw<u64>(); - -        const auto data1 = ctx.ReadBuffer(0); -        const auto data2 = ctx.ReadBuffer(1); +        std::vector<std::vector<u8>> data{ctx.ReadBuffer(0)}; +        if (Type == Core::Reporter::PlayReportType::New) { +            data.emplace_back(ctx.ReadBuffer(1)); +        }          LOG_DEBUG(              Service_PREPO, -            "called, type={:02X}, user_id={:016X}{:016X}, process_id={:016X}, data1_size={:016X}, " -            "data2_size={:016X}", -            static_cast<u8>(Type), user_id[1], user_id[0], process_id, data1.size(), data2.size()); +            "called, type={:02X}, user_id={:016X}{:016X}, process_id={:016X}, data1_size={:016X}", +            static_cast<u8>(Type), user_id[1], user_id[0], process_id, data[0].size());          const auto& reporter{system.GetReporter()}; -        reporter.SavePlayReport(Type, system.CurrentProcess()->GetTitleID(), {data1, data2}, -                                process_id, user_id); +        reporter.SavePlayReport(Type, system.CurrentProcess()->GetTitleID(), data, process_id, +                                user_id);          IPC::ResponseBuilder rb{ctx, 2};          rb.Push(RESULT_SUCCESS); | 
