Fix VMs being able to change CVAR_PROTECTED cvars

VM could use Cvar_Register to set a protected cvar as user created and
was then able to use Cvar_Register with CVAR_ROM to change the value.

Don't allow Cvar_Register to affect protected cvars and prevent VMs
from adding internal flags to any cvars (creator, modified, protected,
nonexistent).

Reported by Noah Metzger (Chomenor).
This commit is contained in:
Zack Middleton 2018-01-21 02:02:47 -06:00
parent 917bca4f7d
commit 3a6af1bc48

View file

@ -1332,12 +1332,42 @@ void Cvar_Register(vmCvar_t *vmCvar, const char *varName, const char *defaultVal
// flags. Unfortunately some historical game code (including single player // flags. Unfortunately some historical game code (including single player
// baseq3) sets both flags. We unset CVAR_ROM for such cvars. // baseq3) sets both flags. We unset CVAR_ROM for such cvars.
if ((flags & (CVAR_ARCHIVE | CVAR_ROM)) == (CVAR_ARCHIVE | CVAR_ROM)) { if ((flags & (CVAR_ARCHIVE | CVAR_ROM)) == (CVAR_ARCHIVE | CVAR_ROM)) {
Com_DPrintf( S_COLOR_YELLOW "WARNING: Unsetting CVAR_ROM cvar '%s', " Com_DPrintf( S_COLOR_YELLOW "WARNING: Unsetting CVAR_ROM from cvar '%s', "
"since it is also CVAR_ARCHIVE\n", varName ); "since it is also CVAR_ARCHIVE\n", varName );
flags &= ~CVAR_ROM; flags &= ~CVAR_ROM;
} }
// Don't allow VM to specific a different creator or other internal flags.
if ( flags & CVAR_USER_CREATED ) {
Com_DPrintf( S_COLOR_YELLOW "WARNING: VM tried to set CVAR_USER_CREATED on cvar '%s'\n", varName );
flags &= ~CVAR_USER_CREATED;
}
if ( flags & CVAR_SERVER_CREATED ) {
Com_DPrintf( S_COLOR_YELLOW "WARNING: VM tried to set CVAR_SERVER_CREATED on cvar '%s'\n", varName );
flags &= ~CVAR_SERVER_CREATED;
}
if ( flags & CVAR_PROTECTED ) {
Com_DPrintf( S_COLOR_YELLOW "WARNING: VM tried to set CVAR_PROTECTED on cvar '%s'\n", varName );
flags &= ~CVAR_PROTECTED;
}
if ( flags & CVAR_MODIFIED ) {
Com_DPrintf( S_COLOR_YELLOW "WARNING: VM tried to set CVAR_MODIFIED on cvar '%s'\n", varName );
flags &= ~CVAR_MODIFIED;
}
if ( flags & CVAR_NONEXISTENT ) {
Com_DPrintf( S_COLOR_YELLOW "WARNING: VM tried to set CVAR_NONEXISTENT on cvar '%s'\n", varName );
flags &= ~CVAR_NONEXISTENT;
}
cv = Cvar_FindVar(varName);
// Don't modify cvar if it's protected.
if ( cv && ( cv->flags & CVAR_PROTECTED ) ) {
Com_DPrintf( S_COLOR_YELLOW "WARNING: VM tried to register protected cvar '%s' with value '%s'%s\n",
varName, defaultValue, ( flags & ~cv->flags ) != 0 ? " and new flags" : "" );
} else {
cv = Cvar_Get(varName, defaultValue, flags | CVAR_VM_CREATED); cv = Cvar_Get(varName, defaultValue, flags | CVAR_VM_CREATED);
}
if (!vmCvar) if (!vmCvar)
return; return;