after some tests:
- vulnerables (all latest versions till today):
Jedi Academy
Jedi Knight 2
Quake 3
ioquake3
Medal of Honor (crash with more bytes ~700)
- seem not vulnerables:
Call of Duty series
Enemy Territory
the good way to fix this bug would be to patch game\g_cmds.c from:
Code:
trap_Argv( 1, arg1, sizeof( arg1 ) );
trap_Argv( 2, arg2, sizeof( arg2 ) );
to
Code:
trap_Argv( 1, arg1, sizeof( arg1 ) );
trap_Argv( 2, arg2, 64 ); // must be minor than 256
but the problem is that Cmd_CallVote_f is a part of the code not located in the core of the game, so it's not possible to make an universal fix because the code is located in the *game*.dll file or in the vm one (depending by what solution is adopted by the game, easy job with the dll).
example of how looks the compiled code in qagamex86.dll:
Code:
:6D6F94BE C7042401000000 mov dword ptr [esp], 00000001
:6D6F94C5 B800040000 mov eax, 00000400 ; sizeof( arg1 )
:6D6F94CA 8DBDE8FBFFFF lea edi, dword ptr [ebp+FFFFFBE8]
:6D6F94D0 89442408 mov dword ptr [esp+08], eax
:6D6F94D4 BE00040000 mov esi, 00000400 ; sizeof( arg2 ) (set it to 0000003F!)
:6D6F94D9 897C2404 mov dword ptr [esp+04], edi
:6D6F94DD E83E810100 call 6D711620 ; trap_Argv
:6D6F94E2 89742408 mov dword ptr [esp+08], esi
:6D6F94E6 8D8DE8F7FFFF lea ecx, dword ptr [ebp+FFFFF7E8]
:6D6F94EC 894C2404 mov dword ptr [esp+04], ecx
:6D6F94F0 C7042402000000 mov dword ptr [esp], 00000002 ; 2
:6D6F94F7 E824810100 call 6D711620 ; trap_Argv
and example of jampgame.dll (remember that must be updated the one in the pk3 files):
Code:
:2007DA2B 6800040000 push 00000400
:2007DA30 8D54240C lea edx, dword ptr [esp+0C]
:2007DA34 52 push edx
:2007DA35 6A01 push 00000001
:2007DA37 E834850200 call 200A5F70
:2007DA3C 6800040000 push 00000400 ; fix this one
:2007DA41 8D842418040000 lea eax, dword ptr [esp+00000418]
:2007DA48 50 push eax
:2007DA49 6A02 push 00000002
:2007DA4B E820850200 call 200A5F70
so an alternative solution would be to remove the shutdown of the server caused by the following instructions in qcommon\cvar.c:
Code:
if ( strlen(cv->string)+1 > MAX_CVAR_VALUE_STRING )
Com_Error( ERR_DROP, "Cvar_Update: src %s length %zd exceeds MAX_CVAR_VALUE_STRING",
cv->string,
strlen(cv->string));
Q_strncpyz( vmCvar->string, cv->string, MAX_CVAR_VALUE_STRING );
the quake 3 engine uses the safe Q_strncpyz function so there is absolutely no problem in removing Com_Error.
but there is a little problem when the server (or the match) restarts because some games like JKA crash during the building of the init string containing the long cvar while in others this string could result truncated.
so the admin should force the resetting of these cvars in some way.
obviously the best "fix" is to disable callvote as I have ever suggested