mirror of
https://gitea.wildfiregames.com/0ad/0ad.git
synced 2026-11-08 10:29:00 +00:00
Kick players sending commands for out-of-range turns
A command for a huge turn made the server resize saved commands and clients their command queues to that size, running out of memory. Reject turns below 0 or beyond MAX_COMMAND_TURN_FACTOR * COMMAND_DELAY_MP ahead of the ready turn, before relaying, and kick the sender.
This commit is contained in:
1 parent
6fb9d7b86b
commit
642a492c92
1 file changed
+19
@@ -100,6 +100,12 @@ static const int HOST_SERVICE_TIMEOUT = 50;
|
||||
*/
|
||||
constexpr std::uint32_t NETWORK_BAD_PING = DEFAULT_TURN_LENGTH * COMMAND_DELAY_MP / 2;
|
||||
|
||||
/**
|
||||
* Legitimate clients only send commands for turns up to about ready turn + COMMAND_DELAY_MP.
|
||||
* Commands further ahead than MAX_COMMAND_TURN_FACTOR * COMMAND_DELAY_MP are treated as an attack.
|
||||
*/
|
||||
constexpr std::int32_t MAX_COMMAND_TURN_FACTOR = 5;
|
||||
|
||||
CNetServer* g_NetServer = NULL;
|
||||
|
||||
static CStr DebugName(CNetServerSession* session)
|
||||
@@ -1202,6 +1208,19 @@ bool CNetServerWorker::OnSimulationCommand(CNetServerSession* session, CFsmEvent
|
||||
if (!cheatsEnabled && (it == server.m_PlayerAssignments.end() || it->second.m_PlayerID != message->m_Player))
|
||||
return true;
|
||||
|
||||
// Prevent high turn attack that will cause OOM.
|
||||
// The command is always dropped; the sender is kicked unless it is the host.
|
||||
const turn_id_t readyTurn = server.m_ServerTurnManager->GetReadyTurn();
|
||||
if (message->m_Turn < 0 ||
|
||||
message->m_Turn > readyTurn + MAX_COMMAND_TURN_FACTOR * static_cast<std::int32_t>(COMMAND_DELAY_MP))
|
||||
{
|
||||
LOGMESSAGERENDER("Net server: %s sent a command for invalid turn %d (ready turn is %d)",
|
||||
utf8_from_wstring(session->GetUserName()), message->m_Turn, readyTurn);
|
||||
|
||||
server.KickPlayer(session->GetUserName(), false);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Send it back to all clients that have finished
|
||||
// the loading screen (and the synchronization when rejoining)
|
||||
server.Multicast(message, { NSS_INGAME });
|
||||
|
||||
Reference in new issue
Block a user