mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-09 00:11:24 +12:00
cellSave fix plus bugfixes (#2631)
* cellSave fix plus bugfixes allows allocation of last byte in memory block prevents rpcs3 from crashing when closing non existent socket * Fix overflow * add more socket options fix typo prevent sys_net from operating on nullptr sockets
This commit is contained in:
parent
1ae334e500
commit
22e679e23e
3 changed files with 86 additions and 1 deletions
|
@ -307,6 +307,10 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||||
return CELL_OK; // ???
|
return CELL_OK; // ???
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ((result->result == CELL_SAVEDATA_CBRESULT_OK_LAST) || (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM))
|
||||||
|
{
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (funcFixed)
|
if (funcFixed)
|
||||||
|
@ -338,6 +342,10 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||||
{
|
{
|
||||||
save_entry.dirName = fixedSet->dirName.get_ptr();
|
save_entry.dirName = fixedSet->dirName.get_ptr();
|
||||||
}
|
}
|
||||||
|
if ((result->result == CELL_SAVEDATA_CBRESULT_OK_LAST) || (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM))
|
||||||
|
{
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selected >= 0)
|
if (selected >= 0)
|
||||||
|
@ -519,6 +527,11 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((result->result == CELL_SAVEDATA_CBRESULT_OK_LAST) || (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM))
|
||||||
|
{
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// Create save directory if necessary
|
// Create save directory if necessary
|
||||||
if (psf.size() && save_entry.isNew && !fs::create_dir(dir_path))
|
if (psf.size() && save_entry.isNew && !fs::create_dir(dir_path))
|
||||||
{
|
{
|
||||||
|
|
|
@ -222,6 +222,12 @@ namespace sys_net
|
||||||
libnet.warning("accept(s=%d, family=*0x%x, paddrlen=*0x%x)", s, addr, paddrlen);
|
libnet.warning("accept(s=%d, family=*0x%x, paddrlen=*0x%x)", s, addr, paddrlen);
|
||||||
std::shared_ptr<sys_net_socket> sock = idm::get<sys_net_socket>(s);
|
std::shared_ptr<sys_net_socket> sock = idm::get<sys_net_socket>(s);
|
||||||
|
|
||||||
|
if (!sock)
|
||||||
|
{
|
||||||
|
libnet.error("accept(): socket does not exist");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
s32 ret;
|
s32 ret;
|
||||||
|
|
||||||
if (!addr)
|
if (!addr)
|
||||||
|
@ -261,6 +267,12 @@ namespace sys_net
|
||||||
libnet.warning("bind(s=%d, family=*0x%x, addrlen=%d)", s, addr, addrlen);
|
libnet.warning("bind(s=%d, family=*0x%x, addrlen=%d)", s, addr, addrlen);
|
||||||
std::shared_ptr<sys_net_socket> sock = idm::get<sys_net_socket>(s);
|
std::shared_ptr<sys_net_socket> sock = idm::get<sys_net_socket>(s);
|
||||||
|
|
||||||
|
if (!sock)
|
||||||
|
{
|
||||||
|
libnet.error("bind(): socket does not exist");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
::sockaddr_in saddr;
|
::sockaddr_in saddr;
|
||||||
memcpy(&saddr, addr.get_ptr(), sizeof(::sockaddr_in));
|
memcpy(&saddr, addr.get_ptr(), sizeof(::sockaddr_in));
|
||||||
saddr.sin_family = addr->sa_family;
|
saddr.sin_family = addr->sa_family;
|
||||||
|
@ -282,6 +294,12 @@ namespace sys_net
|
||||||
libnet.warning("connect(s=%d, family=*0x%x, addrlen=%d)", s, addr, addrlen);
|
libnet.warning("connect(s=%d, family=*0x%x, addrlen=%d)", s, addr, addrlen);
|
||||||
std::shared_ptr<sys_net_socket> sock = idm::get<sys_net_socket>(s);
|
std::shared_ptr<sys_net_socket> sock = idm::get<sys_net_socket>(s);
|
||||||
|
|
||||||
|
if (!sock)
|
||||||
|
{
|
||||||
|
libnet.error("connect(): socket does not exist");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
::sockaddr_in saddr;
|
::sockaddr_in saddr;
|
||||||
memcpy(&saddr, addr.get_ptr(), sizeof(::sockaddr_in));
|
memcpy(&saddr, addr.get_ptr(), sizeof(::sockaddr_in));
|
||||||
saddr.sin_family = addr->sa_family;
|
saddr.sin_family = addr->sa_family;
|
||||||
|
@ -406,6 +424,12 @@ namespace sys_net
|
||||||
libnet.warning("listen(s=%d, backlog=%d)", s, backlog);
|
libnet.warning("listen(s=%d, backlog=%d)", s, backlog);
|
||||||
std::shared_ptr<sys_net_socket> sock = idm::get<sys_net_socket>(s);
|
std::shared_ptr<sys_net_socket> sock = idm::get<sys_net_socket>(s);
|
||||||
|
|
||||||
|
if (!sock)
|
||||||
|
{
|
||||||
|
libnet.error("listen(): socket does not exist");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
s32 ret = ::listen(sock->s, backlog);
|
s32 ret = ::listen(sock->s, backlog);
|
||||||
|
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
|
@ -422,6 +446,12 @@ namespace sys_net
|
||||||
libnet.warning("recv(s=%d, buf=*0x%x, len=%d, flags=0x%x)", s, buf, len, flags);
|
libnet.warning("recv(s=%d, buf=*0x%x, len=%d, flags=0x%x)", s, buf, len, flags);
|
||||||
std::shared_ptr<sys_net_socket> sock = idm::get<sys_net_socket>(s);
|
std::shared_ptr<sys_net_socket> sock = idm::get<sys_net_socket>(s);
|
||||||
|
|
||||||
|
if (!sock)
|
||||||
|
{
|
||||||
|
libnet.error("recv(): socket does not exist");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
s32 ret = ::recv(sock->s, buf.get_ptr(), len, flags);
|
s32 ret = ::recv(sock->s, buf.get_ptr(), len, flags);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -478,6 +508,12 @@ namespace sys_net
|
||||||
libnet.warning("send(s=%d, buf=*0x%x, len=%d, flags=0x%x)", s, buf, len, flags);
|
libnet.warning("send(s=%d, buf=*0x%x, len=%d, flags=0x%x)", s, buf, len, flags);
|
||||||
std::shared_ptr<sys_net_socket> sock = idm::get<sys_net_socket>(s);
|
std::shared_ptr<sys_net_socket> sock = idm::get<sys_net_socket>(s);
|
||||||
|
|
||||||
|
if (!sock)
|
||||||
|
{
|
||||||
|
libnet.error("send(): socket does not exist");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
s32 ret = ::send(sock->s, buf.get_ptr(), len, flags);
|
s32 ret = ::send(sock->s, buf.get_ptr(), len, flags);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -500,6 +536,12 @@ namespace sys_net
|
||||||
libnet.warning("sendto(s=%d, buf=*0x%x, len=%d, flags=0x%x, addr=*0x%x, addrlen=%d)", s, buf, len, flags, addr, addrlen);
|
libnet.warning("sendto(s=%d, buf=*0x%x, len=%d, flags=0x%x, addr=*0x%x, addrlen=%d)", s, buf, len, flags, addr, addrlen);
|
||||||
std::shared_ptr<sys_net_socket> sock = idm::get<sys_net_socket>(s);
|
std::shared_ptr<sys_net_socket> sock = idm::get<sys_net_socket>(s);
|
||||||
|
|
||||||
|
if (!sock)
|
||||||
|
{
|
||||||
|
libnet.error("sendto(): socket does not exist");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
::sockaddr _addr;
|
::sockaddr _addr;
|
||||||
memcpy(&_addr, addr.get_ptr(), sizeof(::sockaddr));
|
memcpy(&_addr, addr.get_ptr(), sizeof(::sockaddr));
|
||||||
_addr.sa_family = addr->sa_family;
|
_addr.sa_family = addr->sa_family;
|
||||||
|
@ -519,6 +561,12 @@ namespace sys_net
|
||||||
libnet.warning("setsockopt(s=%d, level=%d, optname=%d, optval=*0x%x, optlen=%d)", s, level, optname, optval, optlen);
|
libnet.warning("setsockopt(s=%d, level=%d, optname=%d, optval=*0x%x, optlen=%d)", s, level, optname, optval, optlen);
|
||||||
std::shared_ptr<sys_net_socket> sock = idm::get<sys_net_socket>(s);
|
std::shared_ptr<sys_net_socket> sock = idm::get<sys_net_socket>(s);
|
||||||
|
|
||||||
|
if (!sock)
|
||||||
|
{
|
||||||
|
libnet.error("setsockopt(): socket does not exist");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (level != SOL_SOCKET && level != IPPROTO_TCP)
|
if (level != SOL_SOCKET && level != IPPROTO_TCP)
|
||||||
{
|
{
|
||||||
fmt::throw_exception("Invalid socket option level!" HERE);
|
fmt::throw_exception("Invalid socket option level!" HERE);
|
||||||
|
@ -583,6 +631,18 @@ namespace sys_net
|
||||||
libnet.warning("Socket option OP_SO_USESIGNATURE is unimplemented");
|
libnet.warning("Socket option OP_SO_USESIGNATURE is unimplemented");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case OP_SO_BROADCAST:
|
||||||
|
{
|
||||||
|
u32 enablebroadcast = *(u32*)optval.get_ptr();
|
||||||
|
ret = ::setsockopt(sock->s, SOL_SOCKET, SO_BROADCAST, (char*)&enablebroadcast, sizeof(enablebroadcast));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OP_SO_REUSEADDR:
|
||||||
|
{
|
||||||
|
u32 reuseaddr = *(u32*)optval.get_ptr();
|
||||||
|
ret = ::setsockopt(sock->s, SOL_SOCKET, SO_REUSEADDR, (char*)&reuseaddr, sizeof(reuseaddr));
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
libnet.error("Unknown socket option for Win32: 0x%x", optname);
|
libnet.error("Unknown socket option for Win32: 0x%x", optname);
|
||||||
}
|
}
|
||||||
|
@ -673,6 +733,12 @@ namespace sys_net
|
||||||
libnet.warning("shutdown(s=%d, how=%d)", s, how);
|
libnet.warning("shutdown(s=%d, how=%d)", s, how);
|
||||||
std::shared_ptr<sys_net_socket> sock = idm::get<sys_net_socket>(s);
|
std::shared_ptr<sys_net_socket> sock = idm::get<sys_net_socket>(s);
|
||||||
|
|
||||||
|
if (!sock)
|
||||||
|
{
|
||||||
|
libnet.error("shutdown(): non existent socket cannot be shutdown");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
s32 ret = ::shutdown(sock->s, how);
|
s32 ret = ::shutdown(sock->s, how);
|
||||||
|
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
|
@ -723,6 +789,12 @@ namespace sys_net
|
||||||
libnet.warning("socketclose(s=%d)", s);
|
libnet.warning("socketclose(s=%d)", s);
|
||||||
std::shared_ptr<sys_net_socket> sock = idm::get<sys_net_socket>(s);
|
std::shared_ptr<sys_net_socket> sock = idm::get<sys_net_socket>(s);
|
||||||
|
|
||||||
|
if (!sock)
|
||||||
|
{
|
||||||
|
libnet.error("socketclose(): socket does not exist, or was already closed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
s32 ret = ::closesocket(sock->s);
|
s32 ret = ::closesocket(sock->s);
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -621,7 +621,7 @@ namespace vm
|
||||||
size = ::align(size, 4096);
|
size = ::align(size, 4096);
|
||||||
|
|
||||||
// return if addr or size is invalid
|
// return if addr or size is invalid
|
||||||
if (!size || size > this->size || addr < this->addr || addr + size - 1 >= this->addr + this->size - 1)
|
if (!size || size > this->size || addr < this->addr || addr + size - 1 > this->addr + this->size - 1)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue