From d25011c92fe4ab7bf00e7273a3a4daa9b9d05a2b Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 13 Feb 2021 02:30:33 -0800 Subject: [PATCH 1/3] hle: service: am: IStorageAccessor: Fix out of bounds error handling. --- src/core/hle/service/am/am.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index bb77c2569f..8e1fe94387 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -1047,20 +1047,21 @@ void IStorageAccessor::Write(Kernel::HLERequestContext& ctx) { const u64 offset{rp.Pop()}; const std::vector data{ctx.ReadBuffer()}; + const std::size_t size{std::min(data.size(), backing.GetSize() - offset)}; - LOG_DEBUG(Service_AM, "called, offset={}, size={}", offset, data.size()); + LOG_DEBUG(Service_AM, "called, offset={}, size={}", offset, size); - if (data.size() > backing.GetSize() - offset) { + if (offset > backing.GetSize()) { LOG_ERROR(Service_AM, "offset is out of bounds, backing_buffer_sz={}, data_size={}, offset={}", - backing.GetSize(), data.size(), offset); + backing.GetSize(), size, offset); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ERR_SIZE_OUT_OF_BOUNDS); return; } - std::memcpy(backing.GetData().data() + offset, data.data(), data.size()); + std::memcpy(backing.GetData().data() + offset, data.data(), size); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); @@ -1070,11 +1071,11 @@ void IStorageAccessor::Read(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const u64 offset{rp.Pop()}; - const std::size_t size{ctx.GetWriteBufferSize()}; + const std::size_t size{std::min(ctx.GetWriteBufferSize(), backing.GetSize() - offset)}; LOG_DEBUG(Service_AM, "called, offset={}, size={}", offset, size); - if (size > backing.GetSize() - offset) { + if (offset > backing.GetSize()) { LOG_ERROR(Service_AM, "offset is out of bounds, backing_buffer_sz={}, size={}, offset={}", backing.GetSize(), size, offset); From 51c13606d6b9a25a93bd008db53a2553b16126e5 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 13 Feb 2021 02:32:13 -0800 Subject: [PATCH 2/3] hle: service: ldn: IUserLocalCommunicationService: Indicate that LDN is disabled. - Fixes crash on Pokemon Sword/Shield when pressing 'Y'. --- src/core/CMakeLists.txt | 1 + src/core/hle/service/ldn/errors.h | 13 +++++++++++++ src/core/hle/service/ldn/ldn.cpp | 8 +++++--- 3 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 src/core/hle/service/ldn/errors.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 1662ec63d1..e74e6a6688 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -400,6 +400,7 @@ add_library(core STATIC hle/service/hid/controllers/xpad.h hle/service/lbl/lbl.cpp hle/service/lbl/lbl.h + hle/service/ldn/errors.h hle/service/ldn/ldn.cpp hle/service/ldn/ldn.h hle/service/ldr/ldr.cpp diff --git a/src/core/hle/service/ldn/errors.h b/src/core/hle/service/ldn/errors.h new file mode 100644 index 0000000000..a718c5c66b --- /dev/null +++ b/src/core/hle/service/ldn/errors.h @@ -0,0 +1,13 @@ +// Copyright 2021 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/result.h" + +namespace Service::LDN { + +constexpr ResultCode ERROR_DISABLED{ErrorModule::LDN, 22}; + +} // namespace Service::LDN diff --git a/src/core/hle/service/ldn/ldn.cpp b/src/core/hle/service/ldn/ldn.cpp index ee908f3990..1c46609aeb 100644 --- a/src/core/hle/service/ldn/ldn.cpp +++ b/src/core/hle/service/ldn/ldn.cpp @@ -6,6 +6,7 @@ #include "core/hle/ipc_helpers.h" #include "core/hle/result.h" +#include "core/hle/service/ldn/errors.h" #include "core/hle/service/ldn/ldn.h" #include "core/hle/service/sm/sm.h" @@ -140,10 +141,11 @@ public: void Initialize2(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_LDN, "(STUBBED) called"); - // Result success seem make this services start network and continue. - // If we just pass result error then it will stop and maybe try again and again. + + // Return the disabled error to indicate that LDN is currently unavailable, otherwise games + // will continue to try to make a connection. IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(RESULT_UNKNOWN); + rb.Push(ERROR_DISABLED); } }; From d9a8060ce3eba6472a629f22bda105215dacb219 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 13 Feb 2021 21:45:09 -0800 Subject: [PATCH 3/3] hle: service: ldn: IUserLocalCommunicationService: Improve the stub. --- src/core/hle/service/ldn/ldn.cpp | 36 ++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/src/core/hle/service/ldn/ldn.cpp b/src/core/hle/service/ldn/ldn.cpp index 1c46609aeb..c630d93cd0 100644 --- a/src/core/hle/service/ldn/ldn.cpp +++ b/src/core/hle/service/ldn/ldn.cpp @@ -104,7 +104,7 @@ public: : ServiceFramework{system_, "IUserLocalCommunicationService"} { // clang-format off static const FunctionInfo functions[] = { - {0, nullptr, "GetState"}, + {0, &IUserLocalCommunicationService::GetState, "GetState"}, {1, nullptr, "GetNetworkInfo"}, {2, nullptr, "GetIpv4Address"}, {3, nullptr, "GetDisconnectReason"}, @@ -139,14 +139,38 @@ public: RegisterHandlers(functions); } - void Initialize2(Kernel::HLERequestContext& ctx) { + void GetState(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_LDN, "(STUBBED) called"); - // Return the disabled error to indicate that LDN is currently unavailable, otherwise games - // will continue to try to make a connection. - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_DISABLED); + IPC::ResponseBuilder rb{ctx, 3}; + + // Indicate a network error, as we do not actually emulate LDN + rb.Push(static_cast(State::Error)); + + rb.Push(RESULT_SUCCESS); } + + void Initialize2(Kernel::HLERequestContext& ctx) { + LOG_DEBUG(Service_LDN, "called"); + + is_initialized = true; + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + } + +private: + enum class State { + None, + Initialized, + AccessPointOpened, + AccessPointCreated, + StationOpened, + StationConnected, + Error, + }; + + bool is_initialized{}; }; class LDNS final : public ServiceFramework {