From 3a6af1bc48dca97d589b9643e39bc96be31acba9 Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Sun, 21 Jan 2018 02:02:47 -0600 Subject: [PATCH] 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). --- code/qcommon/cvar.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/code/qcommon/cvar.c b/code/qcommon/cvar.c index f07705db..5a0e6906 100644 --- a/code/qcommon/cvar.c +++ b/code/qcommon/cvar.c @@ -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 // baseq3) sets both flags. We unset CVAR_ROM for such cvars. 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 ); flags &= ~CVAR_ROM; } - cv = Cvar_Get(varName, defaultValue, flags | CVAR_VM_CREATED); + // 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); + } if (!vmCvar) return;