From 9873bcfb2bc17b2cbd605e0da7248520fcca1fc7 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Fri, 29 Mar 2024 21:32:11 +0100 Subject: [PATCH] IOS: Remove calls to GetPointer Typically when someone uses GetPointer, it's because they want to read from a range of memory. GetPointer is unsafe to use for this. While it does check that the passed-in address is valid, it doesn't know the size of the range that will be accessed, so it can't check that the end address is valid. The safer alternative GetPointerForRange should be used instead. Note that there is still the problem of many callers not checking for nullptr. This is the first part of a series of changes that will remove the usage of GetPointer in different parts of the code base. This commit gets rid of every GetPointer call from our IOS code except for a particularly tricky one in BluetoothEmuDevice. --- Source/Core/Core/HW/Memmap.h | 2 + Source/Core/Core/IOS/Device.cpp | 6 +- Source/Core/Core/IOS/ES/ES.cpp | 3 +- Source/Core/Core/IOS/ES/Identity.cpp | 19 ++--- Source/Core/Core/IOS/ES/TitleContents.cpp | 2 +- Source/Core/Core/IOS/ES/TitleManagement.cpp | 13 ++-- Source/Core/Core/IOS/ES/Views.cpp | 18 +++-- Source/Core/Core/IOS/FS/FileSystemProxy.cpp | 8 +- Source/Core/Core/IOS/Network/IP/Top.cpp | 29 ++++--- Source/Core/Core/IOS/Network/SSL.cpp | 7 +- Source/Core/Core/IOS/Network/Socket.cpp | 81 +++++++++++--------- Source/Core/Core/IOS/Network/Socket.h | 6 +- Source/Core/Core/IOS/Network/WD/Command.cpp | 3 +- Source/Core/Core/IOS/SDIO/SDIOSlot0.cpp | 4 +- Source/Core/Core/IOS/USB/Bluetooth/BTEmu.cpp | 16 ++-- Source/Core/Core/IOS/WFS/WFSI.cpp | 10 +-- Source/Core/Core/IOS/WFS/WFSSRV.cpp | 4 +- 17 files changed, 128 insertions(+), 103 deletions(-) diff --git a/Source/Core/Core/HW/Memmap.h b/Source/Core/Core/HW/Memmap.h index 39c8c438bb1b..e90e641f557b 100644 --- a/Source/Core/Core/HW/Memmap.h +++ b/Source/Core/Core/HW/Memmap.h @@ -105,6 +105,8 @@ class MemoryManager // Routines to access physically addressed memory, designed for use by // emulated hardware outside the CPU. Use "Device_" prefix. std::string GetString(u32 em_address, size_t size = 0); + // WARNING: Incrementing the pointer returned by GetPointer is unsafe without additional bounds + // checks. New code should use other functions instead, like GetPointerForRange or CopyFromEmu. u8* GetPointer(u32 address) const; u8* GetPointerForRange(u32 address, size_t size) const; void CopyFromEmu(void* data, u32 address, size_t size) const; diff --git a/Source/Core/Core/IOS/Device.cpp b/Source/Core/Core/IOS/Device.cpp index d826f981a6d5..3fdbcaed62b6 100644 --- a/Source/Core/Core/IOS/Device.cpp +++ b/Source/Core/Core/IOS/Device.cpp @@ -116,9 +116,9 @@ void IOCtlRequest::Dump(Core::System& system, const std::string& description, Log("===== " + description, type, level); GENERIC_LOG_FMT(type, level, "In buffer\n{}", - HexDump(memory.GetPointer(buffer_in), buffer_in_size)); + HexDump(memory.GetPointerForRange(buffer_in, buffer_in_size), buffer_in_size)); GENERIC_LOG_FMT(type, level, "Out buffer\n{}", - HexDump(memory.GetPointer(buffer_out), buffer_out_size)); + HexDump(memory.GetPointerForRange(buffer_out, buffer_out_size), buffer_out_size)); } void IOCtlRequest::DumpUnknown(Core::System& system, const std::string& description, @@ -139,7 +139,7 @@ void IOCtlVRequest::Dump(Core::System& system, std::string_view description, for (const auto& vector : in_vectors) { GENERIC_LOG_FMT(type, level, "in[{}] (size={:#x}):\n{}", i++, vector.size, - HexDump(memory.GetPointer(vector.address), vector.size)); + HexDump(memory.GetPointerForRange(vector.address, vector.size), vector.size)); } i = 0; diff --git a/Source/Core/Core/IOS/ES/ES.cpp b/Source/Core/Core/IOS/ES/ES.cpp index 42513ecd8bed..810353a893a9 100644 --- a/Source/Core/Core/IOS/ES/ES.cpp +++ b/Source/Core/Core/IOS/ES/ES.cpp @@ -982,7 +982,8 @@ IPCReply ESDevice::SetUpStreamKey(const Context& context, const IOCtlVRequest& r u32 handle; const ReturnCode ret = m_core.SetUpStreamKey( - context.uid, memory.GetPointer(request.in_vectors[0].address), tmd, &handle); + context.uid, memory.GetPointerForRange(request.in_vectors[0].address, sizeof(ES::TicketView)), + tmd, &handle); memory.Write_U32(handle, request.io_vectors[0].address); return IPCReply(ret); } diff --git a/Source/Core/Core/IOS/ES/Identity.cpp b/Source/Core/Core/IOS/ES/Identity.cpp index a69045bebc62..34fc6861f0dd 100644 --- a/Source/Core/Core/IOS/ES/Identity.cpp +++ b/Source/Core/Core/IOS/ES/Identity.cpp @@ -51,10 +51,10 @@ IPCReply ESDevice::Encrypt(u32 uid, const IOCtlVRequest& request) auto& system = GetSystem(); auto& memory = system.GetMemory(); u32 keyIndex = memory.Read_U32(request.in_vectors[0].address); - u8* source = memory.GetPointer(request.in_vectors[2].address); u32 size = request.in_vectors[2].size; - u8* iv = memory.GetPointer(request.io_vectors[0].address); - u8* destination = memory.GetPointer(request.io_vectors[1].address); + u8* source = memory.GetPointerForRange(request.in_vectors[2].address, size); + u8* iv = memory.GetPointerForRange(request.io_vectors[0].address, 16); + u8* destination = memory.GetPointerForRange(request.io_vectors[1].address, size); // TODO: Check whether the active title is allowed to encrypt. @@ -71,10 +71,10 @@ IPCReply ESDevice::Decrypt(u32 uid, const IOCtlVRequest& request) auto& system = GetSystem(); auto& memory = system.GetMemory(); u32 keyIndex = memory.Read_U32(request.in_vectors[0].address); - u8* source = memory.GetPointer(request.in_vectors[2].address); u32 size = request.in_vectors[2].size; - u8* iv = memory.GetPointer(request.io_vectors[0].address); - u8* destination = memory.GetPointer(request.io_vectors[1].address); + u8* source = memory.GetPointerForRange(request.in_vectors[2].address, size); + u8* iv = memory.GetPointerForRange(request.io_vectors[0].address, 16); + u8* destination = memory.GetPointerForRange(request.io_vectors[1].address, size); // TODO: Check whether the active title is allowed to decrypt. @@ -118,10 +118,11 @@ IPCReply ESDevice::Sign(const IOCtlVRequest& request) INFO_LOG_FMT(IOS_ES, "IOCTL_ES_SIGN"); auto& system = GetSystem(); auto& memory = system.GetMemory(); - u8* ap_cert_out = memory.GetPointer(request.io_vectors[1].address); - u8* data = memory.GetPointer(request.in_vectors[0].address); + u8* ap_cert_out = memory.GetPointerForRange(request.io_vectors[1].address, sizeof(CertECC)); u32 data_size = request.in_vectors[0].size; - u8* sig_out = memory.GetPointer(request.io_vectors[0].address); + u8* data = memory.GetPointerForRange(request.in_vectors[0].address, data_size); + u8* sig_out = + memory.GetPointerForRange(request.io_vectors[0].address, sizeof(Common::ec::Signature)); if (!m_core.m_title_context.active) return IPCReply(ES_EINVAL); diff --git a/Source/Core/Core/IOS/ES/TitleContents.cpp b/Source/Core/Core/IOS/ES/TitleContents.cpp index 5d9d84f23544..70500f72e94d 100644 --- a/Source/Core/Core/IOS/ES/TitleContents.cpp +++ b/Source/Core/Core/IOS/ES/TitleContents.cpp @@ -122,7 +122,7 @@ IPCReply ESDevice::ReadContent(u32 uid, const IOCtlVRequest& request) INFO_LOG_FMT(IOS_ES, "ReadContent(uid={:#x}, cfd={}, size={}, addr={:08x})", uid, cfd, size, addr); - return m_core.ReadContent(cfd, memory.GetPointer(addr), size, uid, ticks); + return m_core.ReadContent(cfd, memory.GetPointerForRange(addr, size), size, uid, ticks); }); } diff --git a/Source/Core/Core/IOS/ES/TitleManagement.cpp b/Source/Core/Core/IOS/ES/TitleManagement.cpp index 4ff3d2702613..9ff28fc5455e 100644 --- a/Source/Core/Core/IOS/ES/TitleManagement.cpp +++ b/Source/Core/Core/IOS/ES/TitleManagement.cpp @@ -369,9 +369,9 @@ IPCReply ESDevice::ImportContentData(Context& context, const IOCtlVRequest& requ auto& memory = system.GetMemory(); u32 content_fd = memory.Read_U32(request.in_vectors[0].address); - u8* data_start = memory.GetPointer(request.in_vectors[1].address); - return IPCReply( - m_core.ImportContentData(context, content_fd, data_start, request.in_vectors[1].size)); + u32 data_size = request.in_vectors[1].size; + u8* data_start = memory.GetPointerForRange(request.in_vectors[1].address, data_size); + return IPCReply(m_core.ImportContentData(context, content_fd, data_start, data_size)); } static bool CheckIfContentHashMatches(const std::vector& content, const ES::Content& info) @@ -630,7 +630,8 @@ IPCReply ESDevice::DeleteTicket(const IOCtlVRequest& request) auto& system = GetSystem(); auto& memory = system.GetMemory(); - return IPCReply(m_core.DeleteTicket(memory.GetPointer(request.in_vectors[0].address))); + return IPCReply(m_core.DeleteTicket( + memory.GetPointerForRange(request.in_vectors[0].address, sizeof(ES::TicketView)))); } ReturnCode ESCore::DeleteTitleContent(u64 title_id) const @@ -732,8 +733,8 @@ IPCReply ESDevice::ExportTitleInit(Context& context, const IOCtlVRequest& reques auto& memory = system.GetMemory(); const u64 title_id = memory.Read_U64(request.in_vectors[0].address); - u8* tmd_bytes = memory.GetPointer(request.io_vectors[0].address); const u32 tmd_size = request.io_vectors[0].size; + u8* tmd_bytes = memory.GetPointerForRange(request.io_vectors[0].address, tmd_size); return IPCReply(m_core.ExportTitleInit(context, title_id, tmd_bytes, tmd_size, m_core.m_title_context.tmd.GetTitleId(), @@ -832,8 +833,8 @@ IPCReply ESDevice::ExportContentData(Context& context, const IOCtlVRequest& requ auto& memory = system.GetMemory(); const u32 content_fd = memory.Read_U32(request.in_vectors[0].address); - u8* data = memory.GetPointer(request.io_vectors[0].address); const u32 bytes_to_read = request.io_vectors[0].size; + u8* data = memory.GetPointerForRange(request.io_vectors[0].address, bytes_to_read); return IPCReply(m_core.ExportContentData(context, content_fd, data, bytes_to_read)); } diff --git a/Source/Core/Core/IOS/ES/Views.cpp b/Source/Core/Core/IOS/ES/Views.cpp index 92012ef64146..71d03ea0edfc 100644 --- a/Source/Core/Core/IOS/ES/Views.cpp +++ b/Source/Core/Core/IOS/ES/Views.cpp @@ -162,9 +162,9 @@ IPCReply ESDevice::GetV0TicketFromView(const IOCtlVRequest& request) auto& system = GetSystem(); auto& memory = system.GetMemory(); - return IPCReply(m_core.GetTicketFromView(memory.GetPointer(request.in_vectors[0].address), - memory.GetPointer(request.io_vectors[0].address), - nullptr, 0)); + return IPCReply(m_core.GetTicketFromView( + memory.GetPointerForRange(request.in_vectors[0].address, sizeof(ES::TicketView)), + memory.GetPointerForRange(request.io_vectors[0].address, sizeof(ES::Ticket)), nullptr, 0)); } IPCReply ESDevice::GetTicketSizeFromView(const IOCtlVRequest& request) @@ -179,8 +179,9 @@ IPCReply ESDevice::GetTicketSizeFromView(const IOCtlVRequest& request) auto& system = GetSystem(); auto& memory = system.GetMemory(); - const ReturnCode ret = m_core.GetTicketFromView(memory.GetPointer(request.in_vectors[0].address), - nullptr, &ticket_size, std::nullopt); + const ReturnCode ret = m_core.GetTicketFromView( + memory.GetPointerForRange(request.in_vectors[0].address, sizeof(ES::TicketView)), nullptr, + &ticket_size, std::nullopt); memory.Write_U32(ticket_size, request.io_vectors[0].address); return IPCReply(ret); } @@ -201,9 +202,10 @@ IPCReply ESDevice::GetTicketFromView(const IOCtlVRequest& request) if (ticket_size != request.io_vectors[0].size) return IPCReply(ES_EINVAL); - return IPCReply(m_core.GetTicketFromView(memory.GetPointer(request.in_vectors[0].address), - memory.GetPointer(request.io_vectors[0].address), - &ticket_size, std::nullopt)); + return IPCReply(m_core.GetTicketFromView( + memory.GetPointerForRange(request.in_vectors[0].address, sizeof(ES::TicketView)), + memory.GetPointerForRange(request.io_vectors[0].address, ticket_size), &ticket_size, + std::nullopt)); } IPCReply ESDevice::GetTMDViewSize(const IOCtlVRequest& request) diff --git a/Source/Core/Core/IOS/FS/FileSystemProxy.cpp b/Source/Core/Core/IOS/FS/FileSystemProxy.cpp index ca923061e0c0..f69da2f9b5e6 100644 --- a/Source/Core/Core/IOS/FS/FileSystemProxy.cpp +++ b/Source/Core/Core/IOS/FS/FileSystemProxy.cpp @@ -326,8 +326,8 @@ std::optional FSDevice::Read(const ReadWriteRequest& request) return MakeIPCReply([&](Ticks t) { auto& system = GetSystem(); auto& memory = system.GetMemory(); - return m_core.Read(request.fd, memory.GetPointer(request.buffer), request.size, request.buffer, - t); + return m_core.Read(request.fd, memory.GetPointerForRange(request.buffer, request.size), + request.size, request.buffer, t); }); } @@ -357,8 +357,8 @@ std::optional FSDevice::Write(const ReadWriteRequest& request) return MakeIPCReply([&](Ticks t) { auto& system = GetSystem(); auto& memory = system.GetMemory(); - return m_core.Write(request.fd, memory.GetPointer(request.buffer), request.size, request.buffer, - t); + return m_core.Write(request.fd, memory.GetPointerForRange(request.buffer, request.size), + request.size, request.buffer, t); }); } diff --git a/Source/Core/Core/IOS/Network/IP/Top.cpp b/Source/Core/Core/IOS/Network/IP/Top.cpp index 1cf70e8df308..8a04c2e6dd86 100644 --- a/Source/Core/Core/IOS/Network/IP/Top.cpp +++ b/Source/Core/Core/IOS/Network/IP/Top.cpp @@ -4,6 +4,7 @@ #include "Core/IOS/Network/IP/Top.h" #include +#include #include #include #include @@ -20,6 +21,7 @@ #include #include "Common/Assert.h" +#include "Common/BitUtils.h" #include "Common/CommonTypes.h" #include "Common/Logging/Log.h" #include "Common/Network.h" @@ -80,12 +82,12 @@ void NetIPTopDevice::DoState(PointerWrap& p) Device::DoState(p); } -static int inet_pton(const char* src, unsigned char* dst) +static std::optional inet_pton(const char* src) { int saw_digit = 0; int octets = 0; - unsigned char tmp[4]{}; - unsigned char* tp = tmp; + std::array tmp{}; + unsigned char* tp = tmp.data(); char ch; while ((ch = *src++) != '\0') @@ -95,31 +97,30 @@ static int inet_pton(const char* src, unsigned char* dst) unsigned int newt = (*tp * 10) + (ch - '0'); if (newt > 255) - return 0; + return std::nullopt; *tp = newt; if (!saw_digit) { if (++octets > 4) - return 0; + return std::nullopt; saw_digit = 1; } } else if (ch == '.' && saw_digit) { if (octets == 4) - return 0; + return std::nullopt; *++tp = 0; saw_digit = 0; } else { - return 0; + return std::nullopt; } } if (octets < 4) - return 0; - memcpy(dst, tmp, 4); - return 1; + return std::nullopt; + return Common::BitCast(tmp); } // Maps SOCKOPT level from Wii to native @@ -655,7 +656,13 @@ IPCReply NetIPTopDevice::HandleInetPToNRequest(const IOCtlRequest& request) const std::string address = memory.GetString(request.buffer_in); INFO_LOG_FMT(IOS_NET, "IOCTL_SO_INETPTON (Translating: {})", address); - return IPCReply(inet_pton(address.c_str(), memory.GetPointer(request.buffer_out + 4))); + + const std::optional result = inet_pton(address.c_str()); + if (!result) + return IPCReply(0); + + memory.CopyToEmu(request.buffer_out + 4, &*result, sizeof(u32)); + return IPCReply(1); } IPCReply NetIPTopDevice::HandleInetNToPRequest(const IOCtlRequest& request) diff --git a/Source/Core/Core/IOS/Network/SSL.cpp b/Source/Core/Core/IOS/Network/SSL.cpp index c2ed3b3b02a9..36caab63057a 100644 --- a/Source/Core/Core/IOS/Network/SSL.cpp +++ b/Source/Core/Core/IOS/Network/SSL.cpp @@ -350,13 +350,14 @@ std::optional NetSSLDevice::IOCtlV(const IOCtlVRequest& request) if (IsSSLIDValid(sslID)) { WII_SSL* ssl = &_SSL[sslID]; - int ret = - mbedtls_x509_crt_parse_der(&ssl->cacert, memory.GetPointer(BufferOut2), BufferOutSize2); + int ret = mbedtls_x509_crt_parse_der( + &ssl->cacert, memory.GetPointerForRange(BufferOut2, BufferOutSize2), BufferOutSize2); if (Config::Get(Config::MAIN_NETWORK_SSL_DUMP_ROOT_CA)) { std::string filename = File::GetUserPath(D_DUMPSSL_IDX) + ssl->hostname + "_rootca.der"; - File::IOFile(filename, "wb").WriteBytes(memory.GetPointer(BufferOut2), BufferOutSize2); + File::IOFile(filename, "wb") + .WriteBytes(memory.GetPointerForRange(BufferOut2, BufferOutSize2), BufferOutSize2); } if (ret) diff --git a/Source/Core/Core/IOS/Network/Socket.cpp b/Source/Core/Core/IOS/Network/Socket.cpp index 6c987eca4198..4b7c2e2c8a3a 100644 --- a/Source/Core/Core/IOS/Network/Socket.cpp +++ b/Source/Core/Core/IOS/Network/Socket.cpp @@ -275,9 +275,9 @@ void WiiSocket::Update(bool read, bool write, bool except) } case IOCTL_SO_BIND: { - sockaddr_in local_name; - const u8* addr = memory.GetPointer(ioctl.buffer_in + 8); - WiiSockMan::ToNativeAddrIn(addr, &local_name); + WiiSockAddrIn addr; + memory.CopyFromEmu(&addr, ioctl.buffer_in + 8, sizeof(WiiSockAddrIn)); + sockaddr_in local_name = WiiSockMan::ToNativeAddrIn(addr); int ret = bind(fd, (sockaddr*)&local_name, sizeof(local_name)); ReturnValue = m_socket_manager.GetNetErrorCode(ret, "SO_BIND", false); @@ -288,9 +288,9 @@ void WiiSocket::Update(bool read, bool write, bool except) } case IOCTL_SO_CONNECT: { - sockaddr_in local_name; - const u8* addr = memory.GetPointer(ioctl.buffer_in + 8); - WiiSockMan::ToNativeAddrIn(addr, &local_name); + WiiSockAddrIn addr; + memory.CopyFromEmu(&addr, ioctl.buffer_in + 8, sizeof(WiiSockAddrIn)); + sockaddr_in local_name = WiiSockMan::ToNativeAddrIn(addr); int ret = connect(fd, (sockaddr*)&local_name, sizeof(local_name)); ReturnValue = m_socket_manager.GetNetErrorCode(ret, "SO_CONNECT", false); @@ -305,14 +305,15 @@ void WiiSocket::Update(bool read, bool write, bool except) s32 ret; if (ioctl.buffer_out_size > 0) { - sockaddr_in local_name; - u8* addr = memory.GetPointer(ioctl.buffer_out); - WiiSockMan::ToNativeAddrIn(addr, &local_name); + WiiSockAddrIn addr; + memory.CopyFromEmu(&addr, ioctl.buffer_out, sizeof(WiiSockAddrIn)); + sockaddr_in local_name = WiiSockMan::ToNativeAddrIn(addr); socklen_t addrlen = sizeof(sockaddr_in); ret = static_cast(accept(fd, (sockaddr*)&local_name, &addrlen)); - WiiSockMan::ToWiiAddrIn(local_name, addr, addrlen); + WiiSockAddrIn new_addr = WiiSockMan::ToWiiAddrIn(local_name, addrlen); + memory.CopyToEmu(ioctl.buffer_out, &new_addr, sizeof(WiiSockAddrIn)); } else { @@ -489,13 +490,13 @@ void WiiSocket::Update(bool read, bool write, bool except) case IOCTLV_NET_SSL_WRITE: { WII_SSL* ssl = &NetSSLDevice::_SSL[sslID]; - const int ret = - mbedtls_ssl_write(&ssl->ctx, memory.GetPointer(BufferOut2), BufferOutSize2); + const int ret = mbedtls_ssl_write( + &ssl->ctx, memory.GetPointerForRange(BufferOut2, BufferOutSize2), BufferOutSize2); if (ret >= 0) { system.GetPowerPC().GetDebugInterface().NetworkLogger()->LogSSLWrite( - memory.GetPointer(BufferOut2), ret, ssl->hostfd); + memory.GetPointerForRange(BufferOut2, ret), ret, ssl->hostfd); // Return bytes written or SSL_ERR_ZERO if none WriteReturnValue(memory, (ret == 0) ? SSL_ERR_ZERO : ret, BufferIn); } @@ -523,13 +524,13 @@ void WiiSocket::Update(bool read, bool write, bool except) case IOCTLV_NET_SSL_READ: { WII_SSL* ssl = &NetSSLDevice::_SSL[sslID]; - const int ret = - mbedtls_ssl_read(&ssl->ctx, memory.GetPointer(BufferIn2), BufferInSize2); + const int ret = mbedtls_ssl_read( + &ssl->ctx, memory.GetPointerForRange(BufferIn2, BufferInSize2), BufferInSize2); if (ret >= 0) { system.GetPowerPC().GetDebugInterface().NetworkLogger()->LogSSLRead( - memory.GetPointer(BufferIn2), ret, ssl->hostfd); + memory.GetPointerForRange(BufferIn2, ret), ret, ssl->hostfd); // Return bytes read or SSL_ERR_ZERO if none WriteReturnValue(memory, (ret == 0) ? SSL_ERR_ZERO : ret, BufferIn); } @@ -600,8 +601,9 @@ void WiiSocket::Update(bool read, bool write, bool except) sockaddr_in local_name = {0}; if (has_destaddr) { - const u8* addr = memory.GetPointer(BufferIn2 + 0x0C); - WiiSockMan::ToNativeAddrIn(addr, &local_name); + WiiSockAddrIn addr; + memory.CopyFromEmu(&addr, BufferIn2 + 0x0C, sizeof(WiiSockAddrIn)); + local_name = WiiSockMan::ToNativeAddrIn(addr); } auto* to = has_destaddr ? reinterpret_cast(&local_name) : nullptr; @@ -634,17 +636,18 @@ void WiiSocket::Update(bool read, bool write, bool except) } u32 flags = memory.Read_U32(BufferIn + 0x04); - // Not a string, Windows requires a char* for recvfrom - char* data = (char*)memory.GetPointer(BufferOut); int data_len = BufferOutSize; + // Not a string, Windows requires a char* for recvfrom + char* data = reinterpret_cast(memory.GetPointerForRange(BufferOut, BufferOutSize)); sockaddr_in local_name; memset(&local_name, 0, sizeof(sockaddr_in)); if (BufferOutSize2 != 0) { - const u8* addr = memory.GetPointer(BufferOut2); - WiiSockMan::ToNativeAddrIn(addr, &local_name); + WiiSockAddrIn addr; + memory.CopyFromEmu(&addr, BufferOut2, sizeof(WiiSockAddrIn)); + local_name = WiiSockMan::ToNativeAddrIn(addr); } // Act as non blocking when SO_MSG_NONBLOCK is specified @@ -680,8 +683,8 @@ void WiiSocket::Update(bool read, bool write, bool except) if (BufferOutSize2 != 0) { - u8* addr = memory.GetPointer(BufferOut2); - WiiSockMan::ToWiiAddrIn(local_name, addr, addrlen); + WiiSockAddrIn new_addr = WiiSockMan::ToWiiAddrIn(local_name, addrlen); + memory.CopyToEmu(BufferOut2, &new_addr, sizeof(WiiSockAddrIn)); } break; } @@ -1110,12 +1113,15 @@ void WiiSockMan::UpdatePollCommands() }); } -void WiiSockMan::ToNativeAddrIn(const u8* addr, sockaddr_in* to) +sockaddr_in WiiSockMan::ToNativeAddrIn(WiiSockAddrIn from) { - const WiiSockAddrIn from = Common::BitCastPtr(addr); - to->sin_addr.s_addr = from.addr.addr; - to->sin_family = from.family; - to->sin_port = from.port; + sockaddr_in result; + + result.sin_addr.s_addr = from.addr.addr; + result.sin_family = from.family; + result.sin_port = from.port; + + return result; } s32 WiiSockMan::ConvertEvents(s32 events, ConvertDirection dir) @@ -1155,15 +1161,16 @@ s32 WiiSockMan::ConvertEvents(s32 events, ConvertDirection dir) return converted_events; } -void WiiSockMan::ToWiiAddrIn(const sockaddr_in& from, u8* to, socklen_t addrlen) +WiiSockAddrIn WiiSockMan::ToWiiAddrIn(const sockaddr_in& from, socklen_t addrlen) { - to[offsetof(WiiSockAddrIn, len)] = - u8(addrlen > sizeof(WiiSockAddrIn) ? sizeof(WiiSockAddrIn) : addrlen); - to[offsetof(WiiSockAddrIn, family)] = u8(from.sin_family & 0xFF); - const u16& from_port = from.sin_port; - memcpy(to + offsetof(WiiSockAddrIn, port), &from_port, sizeof(from_port)); - const u32& from_addr = from.sin_addr.s_addr; - memcpy(to + offsetof(WiiSockAddrIn, addr.addr), &from_addr, sizeof(from_addr)); + WiiSockAddrIn result; + + result.len = u8(addrlen > sizeof(WiiSockAddrIn) ? sizeof(WiiSockAddrIn) : addrlen); + result.family = u8(from.sin_family & 0xFF); + result.port = from.sin_port; + result.addr.addr = from.sin_addr.s_addr; + + return result; } void WiiSockMan::DoState(PointerWrap& p) diff --git a/Source/Core/Core/IOS/Network/Socket.h b/Source/Core/Core/IOS/Network/Socket.h index afbd3b210f2d..abfc752afa59 100644 --- a/Source/Core/Core/IOS/Network/Socket.h +++ b/Source/Core/Core/IOS/Network/Socket.h @@ -266,9 +266,9 @@ class WiiSockMan s32 GetNetErrorCode(s32 ret, std::string_view caller, bool is_rw); void Update(); - static void ToNativeAddrIn(const u8* from, sockaddr_in* to); - static void ToWiiAddrIn(const sockaddr_in& from, u8* to, - socklen_t addrlen = sizeof(WiiSockAddrIn)); + static sockaddr_in ToNativeAddrIn(WiiSockAddrIn from); + static WiiSockAddrIn ToWiiAddrIn(const sockaddr_in& from, + socklen_t addrlen = sizeof(WiiSockAddrIn)); static s32 ConvertEvents(s32 events, ConvertDirection dir); void DoState(PointerWrap& p); diff --git a/Source/Core/Core/IOS/Network/WD/Command.cpp b/Source/Core/Core/IOS/Network/WD/Command.cpp index 5489f310ed07..d86ee5f39fc8 100644 --- a/Source/Core/Core/IOS/Network/WD/Command.cpp +++ b/Source/Core/Core/IOS/Network/WD/Command.cpp @@ -346,7 +346,8 @@ std::optional NetWDCommandDevice::IOCtlV(const IOCtlVRequest& request) auto& system = GetSystem(); auto& memory = system.GetMemory(); - u16* results = (u16*)memory.GetPointer(request.io_vectors.at(0).address); + u16* results = (u16*)memory.GetPointerForRange(request.io_vectors.at(0).address, + sizeof(u16) + sizeof(BSSInfo)); // first u16 indicates number of BSSInfo following results[0] = Common::swap16(1); diff --git a/Source/Core/Core/IOS/SDIO/SDIOSlot0.cpp b/Source/Core/Core/IOS/SDIO/SDIOSlot0.cpp index 6339ec087a5e..5edff3a556c5 100644 --- a/Source/Core/Core/IOS/SDIO/SDIOSlot0.cpp +++ b/Source/Core/Core/IOS/SDIO/SDIOSlot0.cpp @@ -287,7 +287,7 @@ s32 SDIOSlot0Device::ExecuteCommand(const Request& request, u32 buffer_in, u32 b if (!m_card.Seek(address, File::SeekOrigin::Begin)) ERROR_LOG_FMT(IOS_SD, "Seek failed"); - if (m_card.ReadBytes(memory.GetPointer(req.addr), size)) + if (m_card.ReadBytes(memory.GetPointerForRange(req.addr, size), size)) { DEBUG_LOG_FMT(IOS_SD, "Outbuffer size {} got {}", rw_buffer_size, size); } @@ -317,7 +317,7 @@ s32 SDIOSlot0Device::ExecuteCommand(const Request& request, u32 buffer_in, u32 b if (!m_card.Seek(address, File::SeekOrigin::Begin)) ERROR_LOG_FMT(IOS_SD, "Seek failed"); - if (!m_card.WriteBytes(memory.GetPointer(req.addr), size)) + if (!m_card.WriteBytes(memory.GetPointerForRange(req.addr, size), size)) { ERROR_LOG_FMT(IOS_SD, "Write Failed - error: {}, eof: {}", std::ferror(m_card.GetHandle()), std::feof(m_card.GetHandle())); diff --git a/Source/Core/Core/IOS/USB/Bluetooth/BTEmu.cpp b/Source/Core/Core/IOS/USB/Bluetooth/BTEmu.cpp index 4896e678b82e..125036bd279c 100644 --- a/Source/Core/Core/IOS/USB/Bluetooth/BTEmu.cpp +++ b/Source/Core/Core/IOS/USB/Bluetooth/BTEmu.cpp @@ -168,14 +168,15 @@ std::optional BluetoothEmuDevice::IOCtlV(const IOCtlVRequest& request) auto& memory = system.GetMemory(); // This is the ACL datapath from CPU to Wii Remote - const auto* acl_header = - reinterpret_cast(memory.GetPointer(ctrl.data_address)); + const auto* acl_header = reinterpret_cast( + memory.GetPointerForRange(ctrl.data_address, sizeof(hci_acldata_hdr_t))); DEBUG_ASSERT(HCI_BC_FLAG(acl_header->con_handle) == HCI_POINT2POINT); DEBUG_ASSERT(HCI_PB_FLAG(acl_header->con_handle) == HCI_PACKET_START); SendToDevice(HCI_CON_HANDLE(acl_header->con_handle), - memory.GetPointer(ctrl.data_address + sizeof(hci_acldata_hdr_t)), + memory.GetPointerForRange(ctrl.data_address + sizeof(hci_acldata_hdr_t), + acl_header->length), acl_header->length); break; } @@ -250,8 +251,8 @@ void BluetoothEmuDevice::SendACLPacket(const bdaddr_t& source, const u8* data, u auto& system = GetSystem(); auto& memory = system.GetMemory(); - hci_acldata_hdr_t* header = - reinterpret_cast(memory.GetPointer(m_acl_endpoint->data_address)); + hci_acldata_hdr_t* header = reinterpret_cast( + memory.GetPointerForRange(m_acl_endpoint->data_address, sizeof(hci_acldata_hdr_t))); header->con_handle = HCI_MK_CON_HANDLE(connection_handle, HCI_PACKET_START, HCI_POINT2POINT); header->length = size; @@ -431,7 +432,8 @@ void BluetoothEmuDevice::ACLPool::WriteToEndpoint(const USB::V0BulkMessage& endp auto& system = m_ios.GetSystem(); auto& memory = system.GetMemory(); - hci_acldata_hdr_t* header = (hci_acldata_hdr_t*)memory.GetPointer(endpoint.data_address); + hci_acldata_hdr_t* header = (hci_acldata_hdr_t*)memory.GetPointerForRange( + endpoint.data_address, sizeof(hci_acldata_hdr_t)); header->con_handle = HCI_MK_CON_HANDLE(conn_handle, HCI_PACKET_START, HCI_POINT2POINT); header->length = size; @@ -973,7 +975,7 @@ void BluetoothEmuDevice::ExecuteHCICommandMessage(const USB::V0CtrlMessage& ctrl const u8* input = memory.GetPointer(ctrl_message.data_address + 3); SCommandMessage msg; - std::memcpy(&msg, memory.GetPointer(ctrl_message.data_address), sizeof(msg)); + memory.CopyFromEmu(&msg, ctrl_message.data_address, sizeof(msg)); const u16 ocf = HCI_OCF(msg.Opcode); const u16 ogf = HCI_OGF(msg.Opcode); diff --git a/Source/Core/Core/IOS/WFS/WFSI.cpp b/Source/Core/Core/IOS/WFS/WFSI.cpp index 04bebfee0088..d362c3d312bc 100644 --- a/Source/Core/Core/IOS/WFS/WFSI.cpp +++ b/Source/Core/Core/IOS/WFS/WFSI.cpp @@ -230,8 +230,8 @@ std::optional WFSIDevice::IOCtl(const IOCtlRequest& request) input_size, input_ptr, content_id); std::vector decrypted(input_size); - m_aes_ctx->Crypt(m_aes_iv, m_aes_iv, memory.GetPointer(input_ptr), decrypted.data(), - input_size); + m_aes_ctx->Crypt(m_aes_iv, m_aes_iv, memory.GetPointerForRange(input_ptr, input_size), + decrypted.data(), input_size); m_arc_unpacker.AddBytes(decrypted); break; @@ -519,7 +519,7 @@ std::optional WFSIDevice::IOCtl(const IOCtlRequest& request) } else { - fp.ReadBytes(memory.GetPointer(dol_addr), max_dol_size); + fp.ReadBytes(memory.GetPointerForRange(dol_addr, max_dol_size), max_dol_size); } memory.Write_U32(real_dol_size, request.buffer_out); break; @@ -565,13 +565,13 @@ u32 WFSIDevice::GetTmd(u16 group_id, u32 title_id, u64 subtitle_id, u32 address, WARN_LOG_FMT(IOS_WFS, "GetTmd: no such file or directory: {}", path); return WFS_ENOENT; } + *size = static_cast(fp.GetSize()); if (address) { auto& system = GetSystem(); auto& memory = system.GetMemory(); - fp.ReadBytes(memory.GetPointer(address), fp.GetSize()); + fp.ReadBytes(memory.GetPointerForRange(address, *size), *size); } - *size = fp.GetSize(); return IPC_SUCCESS; } diff --git a/Source/Core/Core/IOS/WFS/WFSSRV.cpp b/Source/Core/Core/IOS/WFS/WFSSRV.cpp index db1a71658163..3bc36f5fcd6d 100644 --- a/Source/Core/Core/IOS/WFS/WFSSRV.cpp +++ b/Source/Core/Core/IOS/WFS/WFSSRV.cpp @@ -297,7 +297,7 @@ std::optional WFSSRVDevice::IOCtl(const IOCtlRequest& request) fd_obj->file.Seek(position, File::SeekOrigin::Begin); } size_t read_bytes; - fd_obj->file.ReadArray(memory.GetPointer(addr), size, &read_bytes); + fd_obj->file.ReadArray(memory.GetPointerForRange(addr, size), size, &read_bytes); // TODO(wfs): Handle read errors. if (absolute) { @@ -337,7 +337,7 @@ std::optional WFSSRVDevice::IOCtl(const IOCtlRequest& request) { fd_obj->file.Seek(position, File::SeekOrigin::Begin); } - fd_obj->file.WriteArray(memory.GetPointer(addr), size); + fd_obj->file.WriteArray(memory.GetPointerForRange(addr, size), size); // TODO(wfs): Handle write errors. if (absolute) {