mirror of
https://github.com/rehlds/rehlds.git
synced 2025-01-17 17:17:56 +03:00
Fix for the Buffer Overload 4 exploit
This commit is contained in:
parent
1306b8fda7
commit
b0e4e5fa4f
@ -958,6 +958,9 @@ void _Host_Frame(float time)
|
|||||||
Host_Quit_f();
|
Host_Quit_f();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Rehlds Security
|
||||||
|
Rehlds_Security_Frame();
|
||||||
|
|
||||||
#ifdef REHLDS_FLIGHT_REC
|
#ifdef REHLDS_FLIGHT_REC
|
||||||
if (rehlds_flrec_frame.string[0] != '0') {
|
if (rehlds_flrec_frame.string[0] != '0') {
|
||||||
FR_EndFrame(frameCounter);
|
FR_EndFrame(frameCounter);
|
||||||
@ -1177,6 +1180,8 @@ int Host_Init(quakeparms_t *parms)
|
|||||||
//SystemWrapper_Init();
|
//SystemWrapper_Init();
|
||||||
Host_Version();
|
Host_Version();
|
||||||
|
|
||||||
|
//Rehlds Security
|
||||||
|
Rehlds_Security_Init();
|
||||||
|
|
||||||
|
|
||||||
Q_snprintf(versionString, sizeof(versionString), "%s,%i,%i", gpszVersionString, PROTOCOL_VERSION, build_number());
|
Q_snprintf(versionString, sizeof(versionString), "%s,%i,%i", gpszVersionString, PROTOCOL_VERSION, build_number());
|
||||||
@ -1266,6 +1271,9 @@ void Host_Shutdown(void)
|
|||||||
if (g_pcls.state != ca_dedicated)
|
if (g_pcls.state != ca_dedicated)
|
||||||
ClientDLL_Shutdown();
|
ClientDLL_Shutdown();
|
||||||
|
|
||||||
|
//Rehlds Security
|
||||||
|
Rehlds_Security_Shutdown();
|
||||||
|
|
||||||
Cmd_RemoveGameCmds();
|
Cmd_RemoveGameCmds();
|
||||||
Cmd_Shutdown();
|
Cmd_Shutdown();
|
||||||
Cvar_Shutdown();
|
Cvar_Shutdown();
|
||||||
|
@ -2395,6 +2395,9 @@ void EXT_FUNC SV_ConnectClient_internal(void)
|
|||||||
host_client->datagram.buffername = host_client->name;
|
host_client->datagram.buffername = host_client->name;
|
||||||
host_client->sendinfo_time = 0.0f;
|
host_client->sendinfo_time = 0.0f;
|
||||||
|
|
||||||
|
//Rehlds Security
|
||||||
|
Rehlds_Security_ClientConnected(host_client - g_psvs.clients);
|
||||||
|
|
||||||
g_RehldsHookchains.m_ClientConnected.callChain(NULL, GetRehldsApiClient(host_client));
|
g_RehldsHookchains.m_ClientConnected.callChain(NULL, GetRehldsApiClient(host_client));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1560,6 +1560,19 @@ void SV_ParseMove(client_t *pSenderClient)
|
|||||||
net_drop = 0;
|
net_drop = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//check move commands rate for this player
|
||||||
|
#ifdef REHLDS_FIXES
|
||||||
|
int numCmdsToIssue = numcmds;
|
||||||
|
if (net_drop > 0) {
|
||||||
|
numCmdsToIssue += net_drop;
|
||||||
|
}
|
||||||
|
g_MoveCommandRateLimiter.MoveCommandsIssued(host_client - g_psvs.clients, numCmdsToIssue);
|
||||||
|
|
||||||
|
if (!host_client->active) {
|
||||||
|
return; //return if player was kicked
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
sv_player->v.button = cmds[0].buttons;
|
sv_player->v.button = cmds[0].buttons;
|
||||||
sv_player->v.light_level = cmds[0].lightlevel;
|
sv_player->v.light_level = cmds[0].lightlevel;
|
||||||
SV_EstablishTimeBase(host_client, cmds, net_drop, numbackup, numcmds);
|
SV_EstablishTimeBase(host_client, cmds, net_drop, numbackup, numcmds);
|
||||||
|
@ -212,6 +212,7 @@
|
|||||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Test Fixes|Win32'">precompiled.h</PrecompiledHeaderFile>
|
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Test Fixes|Win32'">precompiled.h</PrecompiledHeaderFile>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\rehlds\RehldsRuntimeConfig.cpp" />
|
<ClCompile Include="..\rehlds\RehldsRuntimeConfig.cpp" />
|
||||||
|
<ClCompile Include="..\rehlds\rehlds_security.cpp" />
|
||||||
<ClCompile Include="..\rehlds\structSizeCheck.cpp" />
|
<ClCompile Include="..\rehlds\structSizeCheck.cpp" />
|
||||||
<ClCompile Include="..\testsuite\anonymizer.cpp" />
|
<ClCompile Include="..\testsuite\anonymizer.cpp" />
|
||||||
<ClCompile Include="..\testsuite\funccalls.cpp" />
|
<ClCompile Include="..\testsuite\funccalls.cpp" />
|
||||||
@ -542,6 +543,7 @@
|
|||||||
<ClInclude Include="..\rehlds\RehldsRuntimeConfig.h" />
|
<ClInclude Include="..\rehlds\RehldsRuntimeConfig.h" />
|
||||||
<ClInclude Include="..\rehlds\rehlds_api_impl.h" />
|
<ClInclude Include="..\rehlds\rehlds_api_impl.h" />
|
||||||
<ClInclude Include="..\rehlds\rehlds_interfaces_impl.h" />
|
<ClInclude Include="..\rehlds\rehlds_interfaces_impl.h" />
|
||||||
|
<ClInclude Include="..\rehlds\rehlds_security.h" />
|
||||||
<ClInclude Include="..\testsuite\anonymizer.h" />
|
<ClInclude Include="..\testsuite\anonymizer.h" />
|
||||||
<ClInclude Include="..\testsuite\funccalls.h" />
|
<ClInclude Include="..\testsuite\funccalls.h" />
|
||||||
<ClInclude Include="..\testsuite\player.h" />
|
<ClInclude Include="..\testsuite\player.h" />
|
||||||
|
@ -343,6 +343,9 @@
|
|||||||
<ClCompile Include="..\unittests\rehlds_tests_shared.cpp">
|
<ClCompile Include="..\unittests\rehlds_tests_shared.cpp">
|
||||||
<Filter>unittests</Filter>
|
<Filter>unittests</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\rehlds\rehlds_security.cpp">
|
||||||
|
<Filter>rehlds</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\hookers\memory.h">
|
<ClInclude Include="..\hookers\memory.h">
|
||||||
@ -1059,6 +1062,9 @@
|
|||||||
<ClInclude Include="..\unittests\rehlds_tests_shared.h">
|
<ClInclude Include="..\unittests\rehlds_tests_shared.h">
|
||||||
<Filter>unittests</Filter>
|
<Filter>unittests</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\rehlds\rehlds_security.h">
|
||||||
|
<Filter>rehlds</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\linux\appversion.sh">
|
<None Include="..\linux\appversion.sh">
|
||||||
|
@ -54,5 +54,6 @@
|
|||||||
#include "rehlds_api_impl.h"
|
#include "rehlds_api_impl.h"
|
||||||
#include "FlightRecorderImpl.h"
|
#include "FlightRecorderImpl.h"
|
||||||
#include "flight_recorder.h"
|
#include "flight_recorder.h"
|
||||||
|
#include "rehlds_security.h"
|
||||||
|
|
||||||
#include "dlls/cdll_dll.h"
|
#include "dlls/cdll_dll.h"
|
||||||
|
102
rehlds/rehlds/rehlds_security.cpp
Normal file
102
rehlds/rehlds/rehlds_security.cpp
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
#include "precompiled.h"
|
||||||
|
|
||||||
|
cvar_t sv_rehlds_movecmdrate_max_avg = { "sv_rehlds_movecmdrate_max_avg", "750", 0, 750.0f, NULL };
|
||||||
|
cvar_t sv_rehlds_movecmdrate_max_burst = { "sv_rehlds_movecmdrate_max_burst", "3500", 0, 3500.0f, NULL };
|
||||||
|
|
||||||
|
CMoveCommandRateLimiter g_MoveCommandRateLimiter;
|
||||||
|
|
||||||
|
CMoveCommandRateLimiter::CMoveCommandRateLimiter() {
|
||||||
|
memset(m_AverageMoveCmdRate, 0, sizeof(m_AverageMoveCmdRate));
|
||||||
|
memset(m_CurrentMoveCmds, 0, sizeof(m_CurrentMoveCmds));
|
||||||
|
m_LastCheckTime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMoveCommandRateLimiter::UpdateAverageRates(double currentTime) {
|
||||||
|
double dt = currentTime - m_LastCheckTime;
|
||||||
|
for (unsigned int i = 0; i < MAX_CLIENTS; i++) {
|
||||||
|
m_AverageMoveCmdRate[i] = (2.0 * m_AverageMoveCmdRate[i] / 3.0) + m_CurrentMoveCmds[i] / dt / 3.0;
|
||||||
|
m_CurrentMoveCmds[i] = 0;
|
||||||
|
|
||||||
|
CheckAverageRate(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMoveCommandRateLimiter::Frame() {
|
||||||
|
double currentTime = realtime;
|
||||||
|
double dt = currentTime - m_LastCheckTime;
|
||||||
|
|
||||||
|
if (dt < 0.5) { //refresh avg. rate every 0.5 sec
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateAverageRates(currentTime);
|
||||||
|
m_LastCheckTime = currentTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMoveCommandRateLimiter::ClientConnected(unsigned int clientId) {
|
||||||
|
if (clientId >= (unsigned)g_psvs.maxclients) {
|
||||||
|
rehlds_syserror(__FUNCTION__": Invalid clientId %u", clientId);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_CurrentMoveCmds[clientId] = 0;
|
||||||
|
m_AverageMoveCmdRate[clientId] = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMoveCommandRateLimiter::MoveCommandsIssued(unsigned int clientId, unsigned int numCmds) {
|
||||||
|
if (clientId >= (unsigned)g_psvs.maxclients) {
|
||||||
|
rehlds_syserror(__FUNCTION__": Invalid clientId %u", clientId);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_CurrentMoveCmds[clientId] += numCmds;
|
||||||
|
CheckBurstRate(clientId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMoveCommandRateLimiter::CheckBurstRate(unsigned int clientId) {
|
||||||
|
client_t* cl = &g_psvs.clients[clientId];
|
||||||
|
if (!cl->active || sv_rehlds_movecmdrate_max_burst.value <= 0.0f) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
double dt = realtime - m_LastCheckTime;
|
||||||
|
if (dt < 0.2) {
|
||||||
|
dt = 0.2; //small intervals may give too high rates
|
||||||
|
}
|
||||||
|
if ((m_CurrentMoveCmds[clientId] / dt) > sv_rehlds_movecmdrate_max_burst.value) {
|
||||||
|
Cbuf_AddText(va("addip %i %s\n", 5, NET_BaseAdrToString(cl->netchan.remote_address)));
|
||||||
|
SV_DropClient(cl, false, "Banned for move commands flooding (burst)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMoveCommandRateLimiter::CheckAverageRate(unsigned int clientId) {
|
||||||
|
client_t* cl = &g_psvs.clients[clientId];
|
||||||
|
if (!cl->active || sv_rehlds_movecmdrate_max_burst.value <= 0.0f) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_AverageMoveCmdRate[clientId] > sv_rehlds_movecmdrate_max_avg.value) {
|
||||||
|
Cbuf_AddText(va("addip %i %s\n", 5, NET_BaseAdrToString(cl->netchan.remote_address)));
|
||||||
|
SV_DropClient(cl, false, "Banned for move commands flooding (Avg)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Rehlds_Security_Init() {
|
||||||
|
#ifdef REHLDS_FIXES
|
||||||
|
Cvar_RegisterVariable(&sv_rehlds_movecmdrate_max_avg);
|
||||||
|
Cvar_RegisterVariable(&sv_rehlds_movecmdrate_max_burst);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void Rehlds_Security_Shutdown() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void Rehlds_Security_Frame() {
|
||||||
|
#ifdef REHLDS_FIXES
|
||||||
|
g_MoveCommandRateLimiter.Frame();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void Rehlds_Security_ClientConnected(unsigned int clientId) {
|
||||||
|
#ifdef REHLDS_FIXES
|
||||||
|
g_MoveCommandRateLimiter.ClientConnected(clientId);
|
||||||
|
#endif
|
||||||
|
}
|
28
rehlds/rehlds/rehlds_security.h
Normal file
28
rehlds/rehlds/rehlds_security.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "engine.h"
|
||||||
|
|
||||||
|
class CMoveCommandRateLimiter {
|
||||||
|
public:
|
||||||
|
CMoveCommandRateLimiter();
|
||||||
|
void Frame();
|
||||||
|
void MoveCommandsIssued(unsigned int clientId, unsigned int numCmds);
|
||||||
|
void ClientConnected(unsigned int clientId);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void UpdateAverageRates(double currentTime);
|
||||||
|
void CheckBurstRate(unsigned int clientId);
|
||||||
|
void CheckAverageRate(unsigned int clientId);
|
||||||
|
|
||||||
|
private:
|
||||||
|
float m_AverageMoveCmdRate[MAX_CLIENTS];
|
||||||
|
int m_CurrentMoveCmds[MAX_CLIENTS];
|
||||||
|
double m_LastCheckTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern CMoveCommandRateLimiter g_MoveCommandRateLimiter;
|
||||||
|
|
||||||
|
extern void Rehlds_Security_Init();
|
||||||
|
extern void Rehlds_Security_Shutdown();
|
||||||
|
extern void Rehlds_Security_Frame();
|
||||||
|
extern void Rehlds_Security_ClientConnected(unsigned int clientId);
|
Loading…
x
Reference in New Issue
Block a user