mirror of
https://github.com/ioquake/ioq3.git
synced 2024-11-10 07:11:46 +00:00
security fix: prevent command injection via callvote
This commit is contained in:
parent
cde5fcfb9b
commit
f5aae78481
4 changed files with 29 additions and 3 deletions
|
@ -1213,6 +1213,7 @@ Cmd_CallVote_f
|
|||
==================
|
||||
*/
|
||||
void Cmd_CallVote_f( gentity_t *ent ) {
|
||||
char* c;
|
||||
int i;
|
||||
char arg1[MAX_STRING_TOKENS];
|
||||
char arg2[MAX_STRING_TOKENS];
|
||||
|
@ -1239,9 +1240,16 @@ void Cmd_CallVote_f( gentity_t *ent ) {
|
|||
trap_Argv( 1, arg1, sizeof( arg1 ) );
|
||||
trap_Argv( 2, arg2, sizeof( arg2 ) );
|
||||
|
||||
if( strchr( arg1, ';' ) || strchr( arg2, ';' ) ) {
|
||||
trap_SendServerCommand( ent-g_entities, "print \"Invalid vote string.\n\"" );
|
||||
return;
|
||||
// check for command separators in arg2
|
||||
for( c = arg2; *c; ++c) {
|
||||
switch(*c) {
|
||||
case '\n':
|
||||
case '\r':
|
||||
case ';':
|
||||
trap_SendServerCommand( ent-g_entities, "print \"Invalid vote string.\n\"" );
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !Q_stricmp( arg1, "map_restart" ) ) {
|
||||
|
|
|
@ -433,6 +433,22 @@ char *Cmd_Cmd(void)
|
|||
return cmd_cmd;
|
||||
}
|
||||
|
||||
/*
|
||||
Replace command separators with space to prevent interpretation
|
||||
This is a hack to protect buggy qvms
|
||||
https://bugzilla.icculus.org/show_bug.cgi?id=3593
|
||||
*/
|
||||
void Cmd_Args_Sanitize( void ) {
|
||||
int i;
|
||||
for ( i = 1 ; i < cmd_argc ; i++ ) {
|
||||
char* c = cmd_argv[i];
|
||||
while ((c = strpbrk(c, "\n\r;"))) {
|
||||
*c = ' ';
|
||||
++c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cmd_TokenizeString
|
||||
|
|
|
@ -434,6 +434,7 @@ char *Cmd_Args (void);
|
|||
char *Cmd_ArgsFrom( int arg );
|
||||
void Cmd_ArgsBuffer( char *buffer, int bufferLength );
|
||||
char *Cmd_Cmd (void);
|
||||
void Cmd_Args_Sanitize( void );
|
||||
// The functions that execute commands get their parameters with these
|
||||
// functions. Cmd_Argv () will return an empty string, not a NULL
|
||||
// if arg > argc, so string operations are allways safe.
|
||||
|
|
|
@ -1500,6 +1500,7 @@ void SV_ExecuteClientCommand( client_t *cl, const char *s, qboolean clientOK ) {
|
|||
if (clientOK) {
|
||||
// pass unknown strings to the game
|
||||
if (!u->name && sv.state == SS_GAME) {
|
||||
Cmd_Args_Sanitize();
|
||||
VM_Call( gvm, GAME_CLIENT_COMMAND, cl - svs.clients );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue