security fix: prevent command injection via callvote

This commit is contained in:
Ludwig Nussel 2009-01-17 23:09:58 +00:00
parent cde5fcfb9b
commit f5aae78481
4 changed files with 29 additions and 3 deletions

View file

@ -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" ) ) {

View file

@ -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

View file

@ -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.

View file

@ -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 );
}
}