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) {