6220: Fix signed integer overflow on client input message, refactoring r=def- a=Robyt3



## Checklist

- [X] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test (especially base/) or added coverage to integration test
- [ ] Considered possible null pointers and out of bounds array indexing
- [ ] Changed no physics that affect existing maps
- [X] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)


Co-authored-by: Robert Müller <robytemueller@gmail.com>
This commit is contained in:
bors[bot] 2023-01-03 13:42:53 +00:00 committed by GitHub
commit 1f392b889a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 27 additions and 26 deletions

View file

@ -314,7 +314,7 @@ CServer::CServer()
m_pGameServer = 0;
m_CurrentGameTick = 0;
m_CurrentGameTick = MIN_TICK;
m_RunServer = UNINITIALIZED;
m_aShutdownReason[0] = 0;
@ -541,7 +541,7 @@ int CServer::Init()
Client.m_Sixup = false;
}
m_CurrentGameTick = 0;
m_CurrentGameTick = MIN_TICK;
m_AnnouncementLastLine = 0;
mem_zero(m_aPrevStates, sizeof(m_aPrevStates));
@ -748,7 +748,7 @@ static inline bool RepackMsg(const CMsgPacker *pMsg, CPacker &Packer, bool Sixup
MsgId += 1;
else if(MsgId == NETMSG_RCON_LINE)
MsgId = 13;
else if(MsgId >= NETMSG_AUTH_CHALLANGE && MsgId <= NETMSG_AUTH_RESULT)
else if(MsgId >= NETMSG_AUTH_CHALLENGE && MsgId <= NETMSG_AUTH_RESULT)
MsgId += 4;
else if(MsgId >= NETMSG_PING && MsgId <= NETMSG_ERROR)
MsgId += 4;
@ -1555,20 +1555,18 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
}
else if(Msg == NETMSG_INPUT)
{
CClient::CInput *pInput;
int64_t TagTime;
m_aClients[ClientID].m_LastAckedSnapshot = Unpacker.GetInt();
int IntendedTick = Unpacker.GetInt();
int Size = Unpacker.GetInt();
// check for errors
if(Unpacker.Error() || Size / 4 > MAX_INPUT_SIZE)
if(Unpacker.Error() || Size / 4 > MAX_INPUT_SIZE || IntendedTick < MIN_TICK || IntendedTick >= MAX_TICK)
return;
if(m_aClients[ClientID].m_LastAckedSnapshot > 0)
m_aClients[ClientID].m_SnapRate = CClient::SNAPRATE_FULL;
int64_t TagTime;
if(m_aClients[ClientID].m_Snapshots.Get(m_aClients[ClientID].m_LastAckedSnapshot, &TagTime, 0, 0) >= 0)
m_aClients[ClientID].m_Latency = (int)(((time_get() - TagTime) * 1000) / time_freq());
@ -1576,7 +1574,7 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
// skip packets that are old
if(IntendedTick > m_aClients[ClientID].m_LastInputTick)
{
int TimeLeft = ((TickStartTime(IntendedTick) - time_get()) * 1000) / time_freq();
const int TimeLeft = (TickStartTime(IntendedTick) - time_get()) / (time_freq() / 1000);
CMsgPacker Msgp(NETMSG_INPUTTIMING, true);
Msgp.AddInt(IntendedTick);
@ -1586,7 +1584,7 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
m_aClients[ClientID].m_LastInputTick = IntendedTick;
pInput = &m_aClients[ClientID].m_aInputs[m_aClients[ClientID].m_CurrentInput];
CClient::CInput *pInput = &m_aClients[ClientID].m_aInputs[m_aClients[ClientID].m_CurrentInput];
if(IntendedTick <= Tick())
IntendedTick = Tick() + 1;
@ -2640,7 +2638,7 @@ int CServer::Run()
int NewTicks = 0;
// load new map
if(m_MapReload || m_CurrentGameTick >= 0x6FFFFFFF) // force reload to make sure the ticks stay within a valid range
if(m_MapReload || m_CurrentGameTick >= MAX_TICK) // force reload to make sure the ticks stay within a valid range
{
// load map
if(LoadMap(Config()->m_SvMap))
@ -2671,7 +2669,7 @@ int CServer::Run()
}
m_GameStartTime = time_get();
m_CurrentGameTick = 0;
m_CurrentGameTick = MIN_TICK;
m_ServerInfoFirstRequest = 0;
Kernel()->ReregisterInterface(GameServer());
GameServer()->OnInit();

View file

@ -3,8 +3,6 @@
#ifndef ENGINE_SHARED_PROTOCOL_H
#define ENGINE_SHARED_PROTOCOL_H
#include <base/system.h>
/*
Connection diagram - How the initialization works.
@ -47,7 +45,7 @@ enum
NETMSG_RCON_AUTH_STATUS, // result of the authentication
NETMSG_RCON_LINE, // line that should be printed to the remote console
NETMSG_AUTH_CHALLANGE, //
NETMSG_AUTH_CHALLENGE, //
NETMSG_AUTH_RESULT, //
// sent by client
@ -87,6 +85,8 @@ enum
MAX_CLIENTS = 64,
VANILLA_MAX_CLIENTS = 16,
MAX_CHECKPOINTS = 25,
MIN_TICK = 0,
MAX_TICK = 0x6FFFFFFF,
MAX_INPUT_SIZE = 128,
MAX_SNAPSHOT_PACKSIZE = 900,

View file

@ -52,3 +52,16 @@ void CTeamsCore::Reset()
m_aIsSolo[i] = false;
}
}
void CTeamsCore::SetSolo(int ClientID, bool Value)
{
dbg_assert(ClientID >= 0 && ClientID < MAX_CLIENTS, "Invalid client id");
m_aIsSolo[ClientID] = Value;
}
bool CTeamsCore::GetSolo(int ClientID) const
{
if(ClientID < 0 || ClientID >= MAX_CLIENTS)
return false;
return m_aIsSolo[ClientID];
}

View file

@ -40,18 +40,8 @@ public:
void Team(int ClientID, int Team);
void Reset();
void SetSolo(int ClientID, bool Value)
{
dbg_assert(ClientID >= 0 && ClientID < MAX_CLIENTS, "Invalid client id");
m_aIsSolo[ClientID] = Value;
}
bool GetSolo(int ClientID) const
{
if(ClientID < 0 || ClientID >= MAX_CLIENTS)
return false;
return m_aIsSolo[ClientID];
}
void SetSolo(int ClientID, bool Value);
bool GetSolo(int ClientID) const;
};
#endif