From d94590429862b34bafdf243498a11de422c40ed8 Mon Sep 17 00:00:00 2001 From: myT Date: Wed, 8 Mar 2017 16:10:34 +0100 Subject: [PATCH] fixed a memory leak due to an incorrect munmap argument (credit: Cyrax) --- code/qcommon/vm_local.h | 4 +++- code/qcommon/vm_x86.cpp | 22 ++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/code/qcommon/vm_local.h b/code/qcommon/vm_local.h index ecd53a5..e5ef473 100644 --- a/code/qcommon/vm_local.h +++ b/code/qcommon/vm_local.h @@ -182,6 +182,8 @@ struct vm_s { vmFunc_t codeBase; int codeLength; + int allocSize; // total allocation size, in bytes + int dataMask; int dataLength; // exact data segment length @@ -191,7 +193,7 @@ struct vm_s { int numSymbols; vmSymbol_t *symbols; - int callLevel; // counts recursive VM_Call + int callLevel; // counts recursive VM_Call int breakFunction; // increment breakCount on function entry to this int breakCount; diff --git a/code/qcommon/vm_x86.cpp b/code/qcommon/vm_x86.cpp index 9bf6f35..cd7a23f 100644 --- a/code/qcommon/vm_x86.cpp +++ b/code/qcommon/vm_x86.cpp @@ -41,7 +41,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #endif // bit mask: -// 1 - program stack overflow +// 1 - program stack overflow // 2 - opcode stack overflow // 4 - jump target range // 8 - data read / write range @@ -79,7 +79,7 @@ static void VM_Destroy_Compiled( vm_t *vm ); xmm4 scratch xmm5 scratch - Windows ABI: you are required to preserve the XMM6-XMM15 registers + Windows ABI: you are required to preserve the XMM6-XMM15 registers System V ABI: you don't have to preserve any of the XMM registers Example how data segment will look like during vmMain execution: @@ -2319,7 +2319,7 @@ __compile: VM_FreeBuffers(); #ifdef VM_X86_MMAP - if ( mprotect( vm->codeBase.ptr, compiledOfs + n, PROT_READ|PROT_EXEC ) ) { + if ( mprotect( vm->codeBase.ptr, vm->allocSize, PROT_READ|PROT_EXEC ) ) { VM_Destroy_Compiled( vm ); Com_Error( ERR_FATAL, "VM_CompileX86: mprotect failed" ); return qfalse; @@ -2329,7 +2329,7 @@ __compile: DWORD oldProtect = 0; // remove write permissions. - if ( !VirtualProtect( vm->codeBase.ptr, compiledOfs + n, PAGE_EXECUTE_READ, &oldProtect ) ) { + if ( !VirtualProtect( vm->codeBase.ptr, vm->allocSize, PAGE_EXECUTE_READ, &oldProtect ) ) { VM_Destroy_Compiled( vm ); Com_Error( ERR_FATAL, "VM_CompileX86: VirtualProtect failed" ); return qfalse; @@ -2352,25 +2352,22 @@ VM_Alloc_Compiled */ static void *VM_Alloc_Compiled(vm_t *vm, int codeLength, int tableLength) { - void *ptr; - int length; - - length = codeLength + tableLength; + const int length = codeLength + tableLength; #ifdef VM_X86_MMAP - ptr = mmap( NULL, length, PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0 ); + void* const ptr = mmap( NULL, length, PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0 ); if ( ptr == MAP_FAILED ) { Com_Error( ERR_FATAL, "VM_CompileX86: mmap failed" ); return NULL; } #elif _WIN32 // allocate memory with EXECUTE permissions under windows. - ptr = VirtualAlloc( NULL, length, MEM_COMMIT, PAGE_EXECUTE_READWRITE ); + void* const ptr = VirtualAlloc(NULL, length, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if ( !ptr ) { Com_Error( ERR_FATAL, "VM_CompileX86: VirtualAlloc failed" ); return NULL; } #else - ptr = malloc( length ); + void* const ptr = malloc( length ); if ( !ptr ) { Com_Error( ERR_FATAL, "VM_CompileX86: malloc failed" ); return NULL; @@ -2378,6 +2375,7 @@ static void *VM_Alloc_Compiled(vm_t *vm, int codeLength, int tableLength) #endif vm->codeBase.ptr = (byte*)ptr; vm->codeLength = codeLength; + vm->allocSize = length; return vm->codeBase.ptr; } @@ -2390,7 +2388,7 @@ VM_Destroy_Compiled static void VM_Destroy_Compiled(vm_t* vm) { #ifdef VM_X86_MMAP - munmap( vm->codeBase.ptr, vm->codeLength ); + munmap( vm->codeBase.ptr, vm->allocSize ); #elif _WIN32 VirtualFree( vm->codeBase.ptr, 0, MEM_RELEASE ); #else