Socket: Fix a nullptr dereference when operations are pending
This commit is contained in:
parent
57327be7f3
commit
e9fa335fbe
|
@ -573,7 +573,7 @@ void EmulationKernel::AddStaticDevices()
|
|||
if (HasFeature(features, Feature::KD) || HasFeature(features, Feature::SO) ||
|
||||
HasFeature(features, Feature::SSL))
|
||||
{
|
||||
m_socket_manager = std::make_shared<IOS::HLE::WiiSockMan>();
|
||||
m_socket_manager = std::make_shared<IOS::HLE::WiiSockMan>(*this);
|
||||
}
|
||||
if (HasFeature(features, Feature::KD))
|
||||
{
|
||||
|
|
|
@ -86,7 +86,9 @@ static s32 TranslateErrorCode(s32 native_error, bool is_rw)
|
|||
}
|
||||
}
|
||||
|
||||
WiiSockMan::WiiSockMan() = default;
|
||||
WiiSockMan::WiiSockMan(EmulationKernel& ios) : m_ios(ios)
|
||||
{
|
||||
}
|
||||
|
||||
WiiSockMan::~WiiSockMan() = default;
|
||||
|
||||
|
@ -176,19 +178,19 @@ s32 WiiSocket::Shutdown(u32 how)
|
|||
{
|
||||
case IOCTL_SO_ACCEPT:
|
||||
if (shut_write)
|
||||
op.Abort(-SO_EINVAL);
|
||||
Abort(&op, -SO_EINVAL);
|
||||
break;
|
||||
case IOCTL_SO_CONNECT:
|
||||
if (shut_write && !nonBlock)
|
||||
op.Abort(-SO_ENETUNREACH);
|
||||
Abort(&op, -SO_ENETUNREACH);
|
||||
break;
|
||||
case IOCTLV_SO_RECVFROM:
|
||||
if (shut_read)
|
||||
op.Abort(-SO_ENOTCONN);
|
||||
Abort(&op, -SO_ENOTCONN);
|
||||
break;
|
||||
case IOCTLV_SO_SENDTO:
|
||||
if (shut_write)
|
||||
op.Abort(-SO_ENOTCONN);
|
||||
Abort(&op, -SO_ENOTCONN);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -213,7 +215,7 @@ s32 WiiSocket::CloseFd()
|
|||
|
||||
for (auto it = pending_sockops.begin(); it != pending_sockops.end();)
|
||||
{
|
||||
GetIOS()->EnqueueIPCReply(it->request, -SO_ENOTCONN);
|
||||
m_socket_manager.EnqueueIPCReply(it->request, -SO_ENOTCONN);
|
||||
it = pending_sockops.erase(it);
|
||||
}
|
||||
connecting_state = ConnectingState::None;
|
||||
|
@ -705,8 +707,7 @@ void WiiSocket::Update(bool read, bool write, bool except)
|
|||
wii_fd, it->is_ssl ? static_cast<int>(it->ssl_type) : static_cast<int>(it->net_type),
|
||||
ReturnValue, nonBlock, forceNonBlock);
|
||||
|
||||
// TODO: remove the dependency on a running IOS instance.
|
||||
GetIOS()->EnqueueIPCReply(it->request, ReturnValue);
|
||||
m_socket_manager.EnqueueIPCReply(it->request, ReturnValue);
|
||||
it = pending_sockops.erase(it);
|
||||
}
|
||||
else
|
||||
|
@ -974,6 +975,11 @@ s32 WiiSockMan::DeleteSocket(s32 wii_fd)
|
|||
return ReturnValue;
|
||||
}
|
||||
|
||||
void WiiSockMan::EnqueueIPCReply(const Request& request, s32 return_value) const
|
||||
{
|
||||
m_ios.EnqueueIPCReply(request, return_value);
|
||||
}
|
||||
|
||||
void WiiSockMan::Update()
|
||||
{
|
||||
s32 nfds = 0;
|
||||
|
@ -1099,7 +1105,7 @@ void WiiSockMan::UpdatePollCommands()
|
|||
DEBUG_LOG_FMT(IOS_NET, "IOCTL_SO_POLL socket {} wevents {:08X} events {:08X} revents {:08X}",
|
||||
i, revents, pfds[i].events, pfds[i].revents);
|
||||
}
|
||||
GetIOS()->EnqueueIPCReply(request, ret);
|
||||
EnqueueIPCReply(request, ret);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
@ -1195,10 +1201,10 @@ void WiiSockMan::UpdateWantDeterminism(bool want)
|
|||
Clean();
|
||||
}
|
||||
|
||||
void WiiSocket::sockop::Abort(s32 value)
|
||||
void WiiSocket::Abort(WiiSocket::sockop* op, s32 value) const
|
||||
{
|
||||
is_aborted = true;
|
||||
GetIOS()->EnqueueIPCReply(request, value);
|
||||
op->is_aborted = true;
|
||||
m_socket_manager.EnqueueIPCReply(op->request, value);
|
||||
}
|
||||
#undef ERRORCODE
|
||||
#undef EITHER
|
||||
|
|
|
@ -199,7 +199,6 @@ private:
|
|||
NET_IOCTL net_type;
|
||||
SSL_IOCTL ssl_type;
|
||||
};
|
||||
void Abort(s32 value);
|
||||
};
|
||||
|
||||
enum class ConnectingState
|
||||
|
@ -216,6 +215,7 @@ private:
|
|||
s32 Shutdown(u32 how);
|
||||
s32 CloseFd();
|
||||
s32 FCntl(u32 cmd, u32 arg);
|
||||
void Abort(sockop* op, s32 value) const;
|
||||
|
||||
const Timeout& GetTimeout();
|
||||
void ResetTimeout();
|
||||
|
@ -256,7 +256,7 @@ public:
|
|||
s64 timeout = 0;
|
||||
};
|
||||
|
||||
WiiSockMan();
|
||||
explicit WiiSockMan(EmulationKernel& ios);
|
||||
WiiSockMan(const WiiSockMan&) = delete;
|
||||
WiiSockMan& operator=(const WiiSockMan&) = delete;
|
||||
WiiSockMan(WiiSockMan&&) = delete;
|
||||
|
@ -283,6 +283,7 @@ public:
|
|||
s32 GetLastNetError() const { return errno_last; }
|
||||
void SetLastNetError(s32 error) { errno_last = error; }
|
||||
void Clean() { WiiSockets.clear(); }
|
||||
void EnqueueIPCReply(const Request& request, s32 return_value) const;
|
||||
template <typename T>
|
||||
void DoSock(s32 sock, const Request& request, T type)
|
||||
{
|
||||
|
@ -291,7 +292,7 @@ public:
|
|||
{
|
||||
ERROR_LOG_FMT(IOS_NET, "DoSock: Error, fd not found ({:08x}, {:08X}, {:08X})", sock,
|
||||
request.address, Common::ToUnderlying(type));
|
||||
GetIOS()->EnqueueIPCReply(request, -SO_EBADF);
|
||||
EnqueueIPCReply(request, -SO_EBADF);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -304,6 +305,7 @@ public:
|
|||
private:
|
||||
void UpdatePollCommands();
|
||||
|
||||
EmulationKernel& m_ios;
|
||||
std::unordered_map<s32, WiiSocket> WiiSockets;
|
||||
s32 errno_last = 0;
|
||||
std::vector<PollCommand> pending_polls;
|
||||
|
|
Loading…
Reference in New Issue