diff --git a/Source/Core/Core/Boot/Boot_BS2Emu.cpp b/Source/Core/Core/Boot/Boot_BS2Emu.cpp index 31ce5c8c8b..b462e89edc 100644 --- a/Source/Core/Core/Boot/Boot_BS2Emu.cpp +++ b/Source/Core/Core/Boot/Boot_BS2Emu.cpp @@ -237,6 +237,11 @@ bool CBoot::RunApploader(Core::System& system, const Core::CPUThreadGuard& guard // Load game into RAM, like on the actual Triforce u8* dimm = AMMediaboard::InitDIMM(disc_size); + if (!dimm) + { + ERROR_LOG_FMT(BOOT, "AMMediaboard::InitDIMM failed"); + return false; + } volume.Read(0, disc_size, dimm, DiscIO::PARTITION_NONE); diff --git a/Source/Core/Core/HW/DVD/AMMediaboard.cpp b/Source/Core/Core/HW/DVD/AMMediaboard.cpp index 18d0b220c1..8167d49f19 100644 --- a/Source/Core/Core/HW/DVD/AMMediaboard.cpp +++ b/Source/Core/Core/HW/DVD/AMMediaboard.cpp @@ -14,6 +14,7 @@ #include "Common/FileUtil.h" #include "Common/IOFile.h" #include "Common/Logging/Log.h" +#include "Common/Network.h" #include "Core/Boot/Boot.h" #include "Core/BootManager.h" @@ -245,7 +246,14 @@ static SOCKET socket_(int af, int type, int protocol) { if (s_sockets[i] == SOCKET_ERROR) { - s_sockets[i] = socket(af, type, protocol); + const s32 host_fd = socket(af, type, protocol); + if (host_fd < 0) + { + ERROR_LOG_FMT(AMMEDIABOARD, "GC-AM: failed to create socket ({})", + Common::StrNetworkError()); + return SOCKET_ERROR; + } + s_sockets[i] = host_fd; return i; } } @@ -372,14 +380,11 @@ u8* InitDIMM(u32 size) if (size == 0) return nullptr; + s_dimm_disc.reset(size); if (s_dimm_disc.empty()) { - s_dimm_disc.reset(size); - if (s_dimm_disc.empty()) - { - PanicAlertFmt("Failed to allocate DIMM memory."); - return nullptr; - } + PanicAlertFmt("Failed to allocate DIMM memory."); + return nullptr; } s_firmware_map = false; @@ -409,6 +414,8 @@ static s32 NetDIMMAccept(int fd, sockaddr* addr, socklen_t* len) return client_sock; } + ERROR_LOG_FMT(AMMEDIABOARD, "GC-AM: accept() failed in NetDIMMAccept ({})", + Common::StrNetworkError()); s_last_error = SOCKET_ERROR; return SOCKET_ERROR; } @@ -420,7 +427,8 @@ static s32 NetDIMMAccept(int fd, sockaddr* addr, socklen_t* len) } else { - // select() failed + ERROR_LOG_FMT(AMMEDIABOARD, "GC-AM: select() failed in NetDIMMAccept ({})", + Common::StrNetworkError()); s_last_error = SOCKET_ERROR; } @@ -494,6 +502,8 @@ static s32 NetDIMMConnect(int fd, sockaddr_in* addr, int len) } else { + ERROR_LOG_FMT(AMMEDIABOARD, "GC-AM: getsockopt() failed in NetDIMMConnect ({})", + Common::StrNetworkError()); s_last_error = SOCKET_ERROR; ret = SOCKET_ERROR; } @@ -506,7 +516,8 @@ static s32 NetDIMMConnect(int fd, sockaddr_in* addr, int len) } else { - // select() failed + ERROR_LOG_FMT(AMMEDIABOARD, "GC-AM: select() failed in NetDIMMConnect ({})", + Common::StrNetworkError()); s_last_error = SOCKET_ERROR; ret = SOCKET_ERROR; } @@ -514,6 +525,8 @@ static s32 NetDIMMConnect(int fd, sockaddr_in* addr, int len) else if (ret == SOCKET_ERROR) { // Immediate failure (e.g. WSAECONNREFUSED) + ERROR_LOG_FMT(AMMEDIABOARD, "GC-AM: NetDIMMConnect failed, connect() = {} ({})", err, + Common::DecodeNetworkError(err)); s_last_error = ret; } else @@ -799,8 +812,8 @@ u32 ExecuteCommand(std::array& dicmd_buf, u32* diimm_buf, u32 address, u ret = NetDIMMAccept(fd, &addr, &len); if (len) { - memcpy(s_network_command_buffer + addr_off, &addr, len); - memcpy(s_network_command_buffer + len_off, &len, sizeof(int)); + memcpy(s_network_command_buffer + addr_off, &addr, sizeof(sockaddr)); + memcpy(s_network_command_buffer + len_off, &len, sizeof(u32)); } } @@ -815,7 +828,7 @@ u32 ExecuteCommand(std::array& dicmd_buf, u32* diimm_buf, u32 address, u const u32 off = s_media_buffer_32[3] - NetworkCommandAddress2; const u32 len = s_media_buffer_32[4]; - if (!NetworkCMDBufferCheck(off, len)) + if (!NetworkCMDBufferCheck(off, std::max(sizeof(sockaddr_in), len))) { break; } @@ -836,7 +849,12 @@ u32 ExecuteCommand(std::array& dicmd_buf, u32* diimm_buf, u32 address, u const int err = WSAGetLastError(); if (ret < 0) - PanicAlertFmt("Socket Bind Failed with{0}", err); + { + const auto err_msg = Common::DecodeNetworkError(err); + PanicAlertFmt("Failed to bind socket (error {}: {})", err, err_msg); + ERROR_LOG_FMT(AMMEDIABOARD, "GC-AM: AMMBCommand::Bind failed, bind() = {} ({})", err, + err_msg); + } NOTICE_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: bind( {}, ({},{:08x}:{}), {} ):{} ({})\n", fd, addr.sin_family, addr.sin_addr.s_addr, Common::swap16(addr.sin_port), len, @@ -867,7 +885,7 @@ u32 ExecuteCommand(std::array& dicmd_buf, u32* diimm_buf, u32 address, u const u32 off = s_media_buffer_32[3] - NetworkCommandAddress2; const u32 len = s_media_buffer_32[4]; - if (!NetworkCMDBufferCheck(off, len)) + if (!NetworkCMDBufferCheck(off, std::max(sizeof(sockaddr_in), len))) { break; } diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceBaseboard.cpp b/Source/Core/Core/HW/EXI/EXI_DeviceBaseboard.cpp index 90577ec8cc..e5566ce2ba 100644 --- a/Source/Core/Core/HW/EXI/EXI_DeviceBaseboard.cpp +++ b/Source/Core/Core/HW/EXI/EXI_DeviceBaseboard.cpp @@ -80,7 +80,7 @@ CEXIBaseboard::CEXIBaseboard(Core::System& system) : IEXIDevice(system) if (AMMediaboard::GetGameType() == VirtuaStriker4 || AMMediaboard::GetGameType() == GekitouProYakyuu) { - if (m_backup.GetSize()) + if (m_backup.GetSize() >= 0x20C + 0x1F4) { Common::UniqueBuffer data(m_backup.GetSize()); m_backup.ReadBytes(data.data(), data.size()); @@ -133,11 +133,18 @@ void CEXIBaseboard::DMAWrite(u32 addr, u32 size) { const auto& system = Core::System::GetInstance(); const auto& memory = system.GetMemory(); + auto span = memory.GetSpanForAddress(addr); + if (span.size() < size) + { + ERROR_LOG_FMT(SP1, "AM-BB: Backup DMA Write overflow: address=0x{:08x}, length={}, span={}", + addr, size, span.size()); + return; + } NOTICE_LOG_FMT(SP1, "AM-BB: COMMAND: Backup DMA Write: {:08x} {:x}", addr, size); m_backup.Seek(m_backup_offset, File::SeekOrigin::Begin); - m_backup.WriteBytes(memory.GetSpanForAddress(addr).data(), size); + m_backup.WriteBytes(span.data(), size); m_backup.Flush(); } @@ -145,11 +152,18 @@ void CEXIBaseboard::DMARead(u32 addr, u32 size) { const auto& system = Core::System::GetInstance(); const auto& memory = system.GetMemory(); + auto span = memory.GetSpanForAddress(addr); + if (span.size() < size) + { + ERROR_LOG_FMT(SP1, "AM-BB: Backup DMA Read overflow: address=0x{:08x}, length={}, span={}", + addr, size, span.size()); + return; + } NOTICE_LOG_FMT(SP1, "AM-BB: COMMAND: Backup DMA Read: {:08x} {:x}", addr, size); m_backup.Seek(m_backup_offset, File::SeekOrigin::Begin); - m_backup.ReadBytes(memory.GetSpanForAddress(addr).data(), size); + m_backup.ReadBytes(span.data(), size); } void CEXIBaseboard::TransferByte(u8& byte)