diff --git a/code/client/cl_cgame.c b/code/client/cl_cgame.c index 5d492d64..58a13c01 100644 --- a/code/client/cl_cgame.c +++ b/code/client/cl_cgame.c @@ -427,27 +427,27 @@ intptr_t CL_CgameSystemCalls( intptr_t *args ) { Cvar_SetSafe( VMA(1), VMA(2) ); return 0; case CG_CVAR_VARIABLESTRINGBUFFER: - VM_CHECKBOUNDS(cgvm, args[2], args[3]); + VM_CHECKBOUNDS( cgvm, args[2], args[3] ); Cvar_VariableStringBuffer( VMA(1), VMA(2), args[3] ); return 0; case CG_ARGC: return Cmd_Argc(); case CG_ARGV: - VM_CHECKBOUNDS(cgvm, args[2], args[3]); + VM_CHECKBOUNDS( cgvm, args[2], args[3] ); Cmd_ArgvBuffer( args[1], VMA(2), args[3] ); return 0; case CG_ARGS: - VM_CHECKBOUNDS(cgvm, args[1], args[2]); + VM_CHECKBOUNDS( cgvm, args[1], args[2] ); Cmd_ArgsBuffer( VMA(1), args[2] ); return 0; case CG_FS_FOPENFILE: return FS_FOpenFileByMode( VMA(1), VMA(2), args[3] ); case CG_FS_READ: - VM_CHECKBOUNDS(cgvm, args[1], args[2]); + VM_CHECKBOUNDS( cgvm, args[1], args[2] ); FS_Read( VMA(1), args[2], args[3] ); return 0; case CG_FS_WRITE: - VM_CHECKBOUNDS(cgvm, args[1], args[2]); + VM_CHECKBOUNDS( cgvm, args[1], args[2] ); FS_Write( VMA(1), args[2], args[3] ); return 0; case CG_FS_FCLOSEFILE: @@ -582,11 +582,11 @@ intptr_t CL_CgameSystemCalls( intptr_t *args ) { case CG_R_LERPTAG: return re.LerpTag( VMA(1), args[2], args[3], args[4], VMF(5), VMA(6) ); case CG_GETGLCONFIG: - VM_CHECKBOUNDS(cgvm, args[1], sizeof(glconfig_t)); + VM_CHECKBOUNDS( cgvm, args[1], sizeof(glconfig_t) ); CL_GetGlconfig( VMA(1) ); return 0; case CG_GETGAMESTATE: - VM_CHECKBOUNDS(cgvm, args[1], sizeof(gameState_t)); + VM_CHECKBOUNDS( cgvm, args[1], sizeof(gameState_t) ); CL_GetGameState( VMA(1) ); return 0; case CG_GETCURRENTSNAPSHOTNUMBER: @@ -619,15 +619,15 @@ intptr_t CL_CgameSystemCalls( intptr_t *args ) { case CG_MEMSET: - VM_CHECKBOUNDS(cgvm, args[1], args[3]); + VM_CHECKBOUNDS( cgvm, args[1], args[3] ); Com_Memset( VMA(1), args[2], args[3] ); return 0; case CG_MEMCPY: - VM_CHECKBOUNDS2(cgvm, args[1], args[2], args[3]); + VM_CHECKBOUNDS2( cgvm, args[1], args[2], args[3] ); Com_Memcpy( VMA(1), VMA(2), args[3] ); return 0; case CG_STRNCPY: - VM_CHECKBOUNDS2(cgvm, args[1], args[2], args[3]); + VM_CHECKBOUNDS2( cgvm, args[1], args[2], args[3] ); strncpy( VMA(1), VMA(2), args[3] ); return args[1]; case CG_SIN: @@ -699,7 +699,7 @@ intptr_t CL_CgameSystemCalls( intptr_t *args ) { return getCameraInfo(args[1], VMA(2), VMA(3)); */ case CG_GET_ENTITY_TOKEN: - VM_CHECKBOUNDS(cgvm, args[1], args[2]); + VM_CHECKBOUNDS( cgvm, args[1], args[2] ); return re.GetEntityToken( VMA(1), args[2] ); case CG_R_INPVS: return re.inPVS( VMA(1), VMA(2) ); diff --git a/code/qcommon/qcommon.h b/code/qcommon/qcommon.h index 04fe932c..bd3bb4b5 100644 --- a/code/qcommon/qcommon.h +++ b/code/qcommon/qcommon.h @@ -375,14 +375,14 @@ void VM_Debug( int level ); macros which cause them to be omitted, and is definitely unsafe, though more performant. */ #ifndef _IOQ3_INSECURE_QVM -void VM_CheckBounds(const vm_t* vm, unsigned int address, unsigned int length); -void VM_CheckBounds2(const vm_t* vm, unsigned int addr1, unsigned int addr2, unsigned int length); +void VM_CheckBounds( const vm_t* vm, unsigned int address, unsigned int length ); +void VM_CheckBounds2( const vm_t* vm, unsigned int addr1, unsigned int addr2, unsigned int length ); #define VM_CHECKBOUNDS VM_CheckBounds #define VM_CHECKBOUNDS2 VM_CheckBounds2 #else -#define VM_CHECKBOUNDS(a,b) -#define VM_CHECKBOUNDS2(a,b,c) +#define VM_CHECKBOUNDS( a, b ) +#define VM_CHECKBOUNDS2( a, b, c ) #endif void *VM_ArgPtr( intptr_t intValue ); void *VM_ExplicitArgPtr( vm_t *vm, intptr_t intValue ); diff --git a/code/qcommon/vm.c b/code/qcommon/vm.c index d3693757..de844f8f 100644 --- a/code/qcommon/vm.c +++ b/code/qcommon/vm.c @@ -71,9 +71,12 @@ VM_CheckBounds */ void VM_CheckBounds(const vm_t* vm, unsigned int address, unsigned int length) { - if ((address | length) > vm->dataMask || (address + length) > vm->dataAlloc) + if (!vm->entryPoint) { - Com_Error(ERR_DROP, "program tried to bypass data segment bounds"); + if ((address | length) > (unsigned)vm->dataMask || (address + length) > vm->dataAlloc) + { + Com_Error(ERR_DROP, "program tried to bypass data segment bounds"); + } } } @@ -85,9 +88,12 @@ VM_CheckBounds2 */ void VM_CheckBounds2(const vm_t* vm, unsigned int addr1, unsigned int addr2, unsigned int length) { - if ((addr1 | addr2 | length) > vm->dataMask || (addr1 + length) > vm->dataAlloc || (addr2 + length) > vm->dataAlloc) + if (!vm->entryPoint) { - Com_Error(ERR_DROP, "program tried to bypass data segment bounds"); + if ((addr1 | addr2 | length) > (unsigned)vm->dataMask || (addr1 + length) > vm->dataAlloc || (addr2 + length) > vm->dataAlloc) + { + Com_Error(ERR_DROP, "program tried to bypass data segment bounds"); + } } }