Changeset 2961 in kBuild
- Timestamp:
- Sep 22, 2016 7:41:00 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kWorker/kWorker.c
r2959 r2961 96 96 * Keep history of the last jobs. For debugging. */ 97 97 #define WITH_HISTORY 98 99 /** @def WITH_FIXED_VIRTUAL_ALLOCS 100 * Whether to pre allocate memory for known fixed VirtualAlloc calls (currently 101 * there is only one, but an important one, from cl.exe). 102 */ 103 #if K_ARCH == K_ARCH_X86_32 104 # define WITH_FIXED_VIRTUAL_ALLOCS 105 #endif 98 106 99 107 /** @def WITH_PCH_CACHING … … 338 346 /** Cached file handle. */ 339 347 HANDLE hCached; 348 /** Cached file section handle. */ 349 HANDLE hSection; 340 350 /** Cached file content. */ 341 351 KU8 *pbCached; … … 572 582 void *pvAlloc; 573 583 KSIZE cbAlloc; 584 /** This is KU32_MAX if not a preallocated chunk. */ 585 KU32 idxPreAllocated; 574 586 } KWVIRTALLOC; 575 587 … … 896 908 static KBOOL g_fRestart = K_FALSE; 897 909 910 /** Whether control-C/SIGINT or Control-Break/SIGBREAK have been seen. */ 911 static KBOOL volatile g_fCtrlC = K_FALSE; 912 898 913 /* Further down. */ 899 914 extern KWREPLACEMENTFUNCTION const g_aSandboxReplacements[]; … … 919 934 /** Log file handle. */ 920 935 static HANDLE g_hLogFile = INVALID_HANDLE_VALUE; 936 #endif 937 938 939 #ifdef WITH_FIXED_VIRTUAL_ALLOCS 940 /** Virtual address space reserved for CL.EXE heap manager. 941 * 942 * Visual C++ 2010 reserves a 78MB chunk of memory from cl.exe at a fixed 943 * address. It's among other things used for precompiled headers, which 944 * seemingly have addresses hardcoded into them and won't work if mapped 945 * elsewhere. Thus, we have to make sure the area is available when cl.exe asks 946 * for it. (The /Zm option may affect this allocation.) 947 */ 948 static struct 949 { 950 /** The memory address we need. */ 951 KUPTR const uFixed; 952 /** How much we need to fix. */ 953 KSIZE const cbFixed; 954 /** What we actually got, NULL if given back. */ 955 void *pvReserved; 956 /** Whether it is in use or not. */ 957 KBOOL fInUse; 958 } g_aFixedVirtualAllocs[] = 959 { 960 # if K_ARCH == K_ARCH_X86_32 961 /* Visual C++ 2010 reserves 0x04b00000, Visual C++ 2015 reserves 0x05300000. We get 0x06800000. */ 962 { KUPTR_C( 0x11000000), KSIZE_C( 0x06800000), NULL }, 963 # else 964 { KUPTR_C(0x000006BB00000000), KSIZE_C(0x000000002EE00000), NULL }, 965 # endif 966 }; 921 967 #endif 922 968 … … 4474 4520 4475 4521 4522 #ifndef NDEBUG 4523 /* 4524 * This wraps up to three InvokeCompilerPassW functions and dumps their arguments to the log. 4525 */ 4526 # if K_ARCH == K_ARCH_X86_32 4527 static char g_szInvokeCompilePassW[] = "_InvokeCompilerPassW@16"; 4528 # else 4529 static char g_szInvokeCompilePassW[] = "InvokeCompilerPassW"; 4530 # endif 4531 typedef KIPTR __stdcall FNINVOKECOMPILERPASSW(int cArgs, wchar_t **papwszArgs, KUPTR fFlags, void **phCluiInstance); 4532 typedef FNINVOKECOMPILERPASSW *PFNINVOKECOMPILERPASSW; 4533 typedef struct KWCXINTERCEPTORENTRY 4534 { 4535 PFNINVOKECOMPILERPASSW pfnOrg; 4536 PKWMODULE pModule; 4537 PFNINVOKECOMPILERPASSW pfnWrap; 4538 } KWCXINTERCEPTORENTRY; 4539 4540 static KIPTR kwSandbox_Cx_InvokeCompilerPassW_Common(int cArgs, wchar_t **papwszArgs, KUPTR fFlags, void **phCluiInstance, 4541 KWCXINTERCEPTORENTRY *pEntry) 4542 { 4543 int i; 4544 KIPTR rcExit; 4545 KW_LOG(("%s!InvokeCompilerPassW(%d, %p, %#x, %p)\n", 4546 &pEntry->pModule->pszPath[pEntry->pModule->offFilename], cArgs, papwszArgs, fFlags, phCluiInstance)); 4547 for (i = 0; i < cArgs; i++) 4548 KW_LOG((" papwszArgs[%u]='%ls'\n", i, papwszArgs[i])); 4549 4550 rcExit = pEntry->pfnOrg(cArgs, papwszArgs, fFlags, phCluiInstance); 4551 4552 KW_LOG(("%s!InvokeCompilerPassW returns %d\n", &pEntry->pModule->pszPath[pEntry->pModule->offFilename], rcExit)); 4553 return rcExit; 4554 } 4555 4556 static FNINVOKECOMPILERPASSW kwSandbox_Cx_InvokeCompilerPassW_0; 4557 static FNINVOKECOMPILERPASSW kwSandbox_Cx_InvokeCompilerPassW_1; 4558 static FNINVOKECOMPILERPASSW kwSandbox_Cx_InvokeCompilerPassW_2; 4559 4560 static KWCXINTERCEPTORENTRY g_aCxInterceptorEntries[] = 4561 { 4562 { NULL, NULL, kwSandbox_Cx_InvokeCompilerPassW_0 }, 4563 { NULL, NULL, kwSandbox_Cx_InvokeCompilerPassW_1 }, 4564 { NULL, NULL, kwSandbox_Cx_InvokeCompilerPassW_2 }, 4565 }; 4566 4567 static KIPTR __stdcall kwSandbox_Cx_InvokeCompilerPassW_0(int cArgs, wchar_t **papwszArgs, KUPTR fFlags, void **phCluiInstance) 4568 { 4569 return kwSandbox_Cx_InvokeCompilerPassW_Common(cArgs, papwszArgs, fFlags, phCluiInstance, &g_aCxInterceptorEntries[0]); 4570 } 4571 4572 static KIPTR __stdcall kwSandbox_Cx_InvokeCompilerPassW_1(int cArgs, wchar_t **papwszArgs, KUPTR fFlags, void **phCluiInstance) 4573 { 4574 return kwSandbox_Cx_InvokeCompilerPassW_Common(cArgs, papwszArgs, fFlags, phCluiInstance, &g_aCxInterceptorEntries[1]); 4575 } 4576 4577 static KIPTR __stdcall kwSandbox_Cx_InvokeCompilerPassW_2(int cArgs, wchar_t **papwszArgs, KUPTR fFlags, void **phCluiInstance) 4578 { 4579 return kwSandbox_Cx_InvokeCompilerPassW_Common(cArgs, papwszArgs, fFlags, phCluiInstance, &g_aCxInterceptorEntries[2]); 4580 } 4581 4582 #endif /* !NDEBUG */ 4583 4584 4476 4585 /** Kernel32 - GetProcAddress() */ 4477 4586 static FARPROC WINAPI kwSandbox_Kernel32_GetProcAddress(HMODULE hmod, LPCSTR pszProc) … … 4522 4631 } 4523 4632 4633 #ifndef NDEBUG 4634 /* Intercept the compiler pass method, dumping arguments. */ 4635 if (kHlpStrComp(pszProc, g_szInvokeCompilePassW) == 0) 4636 { 4637 KU32 i; 4638 for (i = 0; i < K_ELEMENTS(g_aCxInterceptorEntries); i++) 4639 if ((KUPTR)g_aCxInterceptorEntries[i].pfnOrg == uValue) 4640 { 4641 uValue = (KUPTR)g_aCxInterceptorEntries[i].pfnWrap; 4642 KW_LOG(("GetProcAddress: intercepting InvokeCompilerPassW\n")); 4643 break; 4644 } 4645 if (i >= K_ELEMENTS(g_aCxInterceptorEntries)) 4646 while (i-- > 0) 4647 if (g_aCxInterceptorEntries[i].pfnOrg == NULL) 4648 { 4649 g_aCxInterceptorEntries[i].pfnOrg = (PFNINVOKECOMPILERPASSW)(KUPTR)uValue; 4650 g_aCxInterceptorEntries[i].pModule = pMod; 4651 uValue = (KUPTR)g_aCxInterceptorEntries[i].pfnWrap; 4652 KW_LOG(("GetProcAddress: intercepting InvokeCompilerPassW (new)\n")); 4653 break; 4654 } 4655 } 4656 #endif 4524 4657 KW_LOG(("GetProcAddress(%s, %s) -> %p\n", pMod->pszPath, pszProc, (KUPTR)uValue)); 4525 4658 kwLdrModuleRelease(pMod); … … 5125 5258 { 5126 5259 KU32 cbCache = (KU32)cbFile.QuadPart; 5127 #if 05128 KU8 *pbCache = (KU8 *)kHlpAlloc(cbCache);5129 if (pbCache)5130 {5131 DWORD cbActually = 0;5132 if ( ReadFile(hFile, pbCache, cbCache, &cbActually, NULL)5133 && cbActually == cbCache)5134 {5135 LARGE_INTEGER offZero;5136 offZero.QuadPart = 0;5137 if (SetFilePointerEx(hFile, offZero, NULL /*poffNew*/, FILE_BEGIN))5138 {5139 #else5140 5260 HANDLE hMapping = CreateFileMappingW(hFile, NULL /*pSecAttrs*/, PAGE_READONLY, 5141 5261 0 /*cbMaxLow*/, 0 /*cbMaxHigh*/, NULL /*pwszName*/); … … 5143 5263 { 5144 5264 KU8 *pbCache = (KU8 *)MapViewOfFile(hMapping, FILE_MAP_READ, 0 /*offFileHigh*/, 0 /*offFileLow*/, cbCache); 5145 CloseHandle(hMapping);5146 5265 if (pbCache) 5147 5266 { 5148 #endif 5149 /* 5150 * Create the cached file object. 5151 */ 5152 PKFSWCACHEDFILE pCachedFile; 5153 KU32 cbPath = pFsObj->cchParent + pFsObj->cchName + 2; 5154 pCachedFile = (PKFSWCACHEDFILE)kFsCacheObjAddUserData(g_pFsCache, pFsObj, KW_DATA_KEY_CACHED_FILE, 5155 sizeof(*pCachedFile) + cbPath); 5156 if (pCachedFile) 5157 { 5158 pCachedFile->hCached = hFile; 5159 pCachedFile->cbCached = cbCache; 5160 pCachedFile->pbCached = pbCache; 5161 pCachedFile->pFsObj = pFsObj; 5162 kFsCacheObjGetFullPathA(pFsObj, pCachedFile->szPath, cbPath, '/'); 5163 kFsCacheObjRetain(pFsObj); 5164 KWFS_LOG(("Cached '%s': %p LB %#x, hCached=%p\n", pCachedFile->szPath, pbCache, cbCache, hFile)); 5165 return pCachedFile; 5166 } 5167 5168 KWFS_LOG(("Failed to allocate KFSWCACHEDFILE structure!\n")); 5169 #if 1 5267 /* 5268 * Create the cached file object. 5269 */ 5270 PKFSWCACHEDFILE pCachedFile; 5271 KU32 cbPath = pFsObj->cchParent + pFsObj->cchName + 2; 5272 pCachedFile = (PKFSWCACHEDFILE)kFsCacheObjAddUserData(g_pFsCache, pFsObj, KW_DATA_KEY_CACHED_FILE, 5273 sizeof(*pCachedFile) + cbPath); 5274 if (pCachedFile) 5275 { 5276 pCachedFile->hCached = hFile; 5277 pCachedFile->hSection = hMapping; 5278 pCachedFile->cbCached = cbCache; 5279 pCachedFile->pbCached = pbCache; 5280 pCachedFile->pFsObj = pFsObj; 5281 kFsCacheObjGetFullPathA(pFsObj, pCachedFile->szPath, cbPath, '/'); 5282 kFsCacheObjRetain(pFsObj); 5283 KWFS_LOG(("Cached '%s': %p LB %#x, hCached=%p\n", pCachedFile->szPath, pbCache, cbCache, hFile)); 5284 return pCachedFile; 5285 } 5286 5287 KWFS_LOG(("Failed to allocate KFSWCACHEDFILE structure!\n")); 5170 5288 } 5171 5289 else 5172 5290 KWFS_LOG(("Failed to cache file: MapViewOfFile failed: %u\n", GetLastError())); 5291 CloseHandle(hMapping); 5173 5292 } 5174 5293 else 5175 5294 KWFS_LOG(("Failed to cache file: CreateFileMappingW failed: %u\n", GetLastError())); 5176 #else5177 }5178 else5179 KWFS_LOG(("Failed to seek to start of cached file! err=%u\n", GetLastError()));5180 }5181 else5182 KWFS_LOG(("Failed to read %#x bytes into cache! err=%u cbActually=%#x\n",5183 cbCache, GetLastError(), cbActually));5184 kHlpFree(pbCache);5185 }5186 else5187 KWFS_LOG(("Failed to allocate %#x bytes for cache!\n", cbCache));5188 #endif5189 5295 } 5190 5296 else … … 5208 5314 { 5209 5315 HANDLE hProcSelf = GetCurrentProcess(); 5210 if (DuplicateHandle(hProcSelf, pCachedFile->hCached,5316 if (DuplicateHandle(hProcSelf, fIsFileHandle ? pCachedFile->hCached : pCachedFile->hSection, 5211 5317 hProcSelf, phFile, 5212 5318 dwDesiredAccess, fInheritHandle, … … 5526 5632 if (pcbMoveHi) 5527 5633 *pcbMoveHi = (KU64)offMove >> 32; 5528 KWFS_LOG(("SetFilePointer(%p) -> %#llx [cached]\n", hFile, offMove)); 5634 KWFS_LOG(("SetFilePointer(%p,%#x,?,%u) -> %#llx [%s]\n", hFile, cbMove, dwMoveMethod, offMove, 5635 pHandle->enmType == KWHANDLETYPE_FSOBJ_READ_CACHE ? "cached" : "temp")); 5529 5636 SetLastError(NO_ERROR); 5530 5637 return (KU32)offMove; … … 5608 5715 if (poffNew) 5609 5716 poffNew->QuadPart = offMyMove; 5610 KWFS_LOG(("SetFilePointerEx(%p) -> TRUE, %#llx [cached]\n", hFile, offMyMove)); 5717 KWFS_LOG(("SetFilePointerEx(%p,%#llx,,%u) -> TRUE, %#llx [%s]\n", hFile, offMove.QuadPart, dwMoveMethod, offMyMove, 5718 pHandle->enmType == KWHANDLETYPE_FSOBJ_READ_CACHE ? "cached" : "temp")); 5611 5719 return TRUE; 5612 5720 } … … 5947 6055 { 5948 6056 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hFile); 5949 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread );6057 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread || g_fCtrlC); 5950 6058 if (idxHandle < g_Sandbox.cHandles) 5951 6059 { … … 6499 6607 return pvRet; 6500 6608 } 6501 /** @todo MapViewOfFileEx */ 6502 6609 6610 6611 /** Kernel32 - MapViewOfFileEx */ 6612 static PVOID WINAPI kwSandbox_Kernel32_MapViewOfFileEx(HANDLE hSection, DWORD dwDesiredAccess, 6613 DWORD offFileHigh, DWORD offFileLow, SIZE_T cbToMap, PVOID pvMapAddr) 6614 { 6615 PVOID pvRet; 6616 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hSection); 6617 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread); 6618 if (idxHandle < g_Sandbox.cHandles) 6619 { 6620 PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle]; 6621 if (pHandle != NULL) 6622 { 6623 switch (pHandle->enmType) 6624 { 6625 case KWHANDLETYPE_TEMP_FILE_MAPPING: 6626 KWFS_LOG(("MapViewOfFileEx(%p, %#x, %#x, %#x, %#x, %p) - temporary file!\n", 6627 hSection, dwDesiredAccess, offFileHigh, offFileLow, cbToMap, pvMapAddr)); 6628 if (!pvMapAddr) 6629 return kwSandbox_Kernel32_MapViewOfFile(hSection, dwDesiredAccess, offFileHigh, offFileLow, cbToMap); 6630 kHlpAssertFailed(); 6631 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 6632 return NULL; 6633 6634 case KWHANDLETYPE_FSOBJ_READ_CACHE_MAPPING: 6635 KWFS_LOG(("MapViewOfFileEx(%p, %#x, %#x, %#x, %#x, %p) - read cached file!\n", 6636 hSection, dwDesiredAccess, offFileHigh, offFileLow, cbToMap, pvMapAddr)); 6637 if (!pvMapAddr) 6638 return kwSandbox_Kernel32_MapViewOfFile(hSection, dwDesiredAccess, offFileHigh, offFileLow, cbToMap); 6639 /* We can use fallback here as the handle is an actual section handle. */ 6640 break; 6641 6642 case KWHANDLETYPE_FSOBJ_READ_CACHE: 6643 case KWHANDLETYPE_TEMP_FILE: 6644 case KWHANDLETYPE_OUTPUT_BUF: 6645 default: 6646 kHlpAssertFailed(); 6647 SetLastError(ERROR_INVALID_OPERATION); 6648 return NULL; 6649 } 6650 } 6651 } 6652 6653 pvRet = MapViewOfFileEx(hSection, dwDesiredAccess, offFileHigh, offFileLow, cbToMap, pvMapAddr); 6654 KWFS_LOG(("MapViewOfFileEx(%p, %#x, %#x, %#x, %#x, %p) -> %p\n", 6655 hSection, dwDesiredAccess, offFileHigh, offFileLow, cbToMap, pvMapAddr, pvRet)); 6656 return pvRet; 6657 6658 } 6503 6659 6504 6660 /** Kernel32 - UnmapViewOfFile */ … … 6601 6757 BOOL fRet; 6602 6758 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hObject); 6603 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread );6759 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread || g_fCtrlC); 6604 6760 if (idxHandle < g_Sandbox.cHandles) 6605 6761 { … … 7328 7484 */ 7329 7485 7330 /** Kernel32 - VirtualAlloc - for c1[xx].dll 78GB leaks. */ 7486 #ifdef WITH_FIXED_VIRTUAL_ALLOCS 7487 7488 /** For debug logging. */ 7489 # ifndef NDEBUG 7490 static void kwSandboxLogFixedAllocation(KU32 idxFixed, const char *pszWhere) 7491 { 7492 MEMORY_BASIC_INFORMATION MemInfo = { NULL, NULL, 0, 0, 0, 0, 0}; 7493 SIZE_T cbMemInfo = VirtualQuery(g_aFixedVirtualAllocs[idxFixed].pvReserved, &MemInfo, sizeof(MemInfo)); 7494 kHlpAssert(cbMemInfo == sizeof(MemInfo)); 7495 if (cbMemInfo != 0) 7496 KW_LOG(("%s: #%u %p LB %#x: base=%p alloc=%p region=%#x state=%#x prot=%#x type=%#x\n", 7497 pszWhere, idxFixed, g_aFixedVirtualAllocs[idxFixed].pvReserved, g_aFixedVirtualAllocs[idxFixed].cbFixed, 7498 MemInfo.BaseAddress, 7499 MemInfo.AllocationBase, 7500 MemInfo.RegionSize, 7501 MemInfo.State, 7502 MemInfo.Protect, 7503 MemInfo.Type)); 7504 } 7505 # else 7506 # define kwSandboxLogFixedAllocation(idxFixed, pszWhere) do { } while (0) 7507 # endif 7508 7509 /** 7510 * Used by both kwSandbox_Kernel32_VirtualFree and kwSandboxCleanupLate 7511 * 7512 * @param idxFixed The fixed allocation index to "free". 7513 */ 7514 static void kwSandboxResetFixedAllocation(KU32 idxFixed) 7515 { 7516 BOOL fRc; 7517 kwSandboxLogFixedAllocation(idxFixed, "kwSandboxResetFixedAllocation[pre]"); 7518 fRc = VirtualFree(g_aFixedVirtualAllocs[idxFixed].pvReserved, g_aFixedVirtualAllocs[idxFixed].cbFixed, MEM_DECOMMIT); 7519 kHlpAssert(fRc); K_NOREF(fRc); 7520 kwSandboxLogFixedAllocation(idxFixed, "kwSandboxResetFixedAllocation[pst]"); 7521 g_aFixedVirtualAllocs[idxFixed].fInUse = K_FALSE; 7522 } 7523 7524 #endif /* WITH_FIXED_VIRTUAL_ALLOCS */ 7525 7526 7527 /** Kernel32 - VirtualAlloc - for managing cl.exe / c1[xx].dll heap with fixed 7528 * location (~78MB in 32-bit 2010 compiler). */ 7331 7529 static PVOID WINAPI kwSandbox_Kernel32_VirtualAlloc(PVOID pvAddr, SIZE_T cb, DWORD fAllocType, DWORD fProt) 7332 7530 { 7333 PVOID pvMem = VirtualAlloc(pvAddr, cb, fAllocType, fProt); 7531 PVOID pvMem; 7532 if (g_Sandbox.pTool->u.Sandboxed.enmHint == KWTOOLHINT_VISUAL_CPP_CL) 7533 { 7534 KU32 idxPreAllocated = KU32_MAX; 7535 7536 #ifdef WITH_FIXED_VIRTUAL_ALLOCS 7537 /* 7538 * Look for a pre-reserved CL.exe heap allocation. 7539 */ 7540 pvMem = NULL; 7541 if ( pvAddr != 0 7542 && (fAllocType & MEM_RESERVE)) 7543 { 7544 KU32 idxFixed = K_ELEMENTS(g_aFixedVirtualAllocs); 7545 kHlpAssert(!(fAllocType & ~(MEM_RESERVE | MEM_TOP_DOWN))); 7546 while (idxFixed-- > 0) 7547 if ( g_aFixedVirtualAllocs[idxFixed].uFixed == (KUPTR)pvAddr 7548 && g_aFixedVirtualAllocs[idxFixed].pvReserved) 7549 { 7550 if (g_aFixedVirtualAllocs[idxFixed].cbFixed >= cb) 7551 { 7552 if (!g_aFixedVirtualAllocs[idxFixed].fInUse) 7553 { 7554 g_aFixedVirtualAllocs[idxFixed].fInUse = K_TRUE; 7555 pvMem = pvAddr; 7556 idxPreAllocated = idxFixed; 7557 KW_LOG(("VirtualAlloc: pvAddr=%p cb=%p type=%#x prot=%#x -> %p [pre allocated]\n", 7558 pvAddr, cb, fAllocType, fProt, pvMem)); 7559 kwSandboxLogFixedAllocation(idxFixed, "kwSandbox_Kernel32_VirtualAlloc"); 7560 SetLastError(NO_ERROR); 7561 break; 7562 } 7563 kwErrPrintf("VirtualAlloc: Fixed allocation at %p is already in use!\n", pvAddr); 7564 } 7565 else 7566 kwErrPrintf("VirtualAlloc: Fixed allocation at %p LB %#x not large enough: %#x\n", 7567 pvAddr, g_aFixedVirtualAllocs[idxFixed].cbFixed, cb); 7568 } 7569 } 7570 if (!pvMem) 7571 #endif 7572 { 7573 pvMem = VirtualAlloc(pvAddr, cb, fAllocType, fProt); 7574 KW_LOG(("VirtualAlloc: pvAddr=%p cb=%p type=%#x prot=%#x -> %p (last=%d)\n", 7575 pvAddr, cb, fAllocType, fProt, pvMem, GetLastError())); 7576 if (pvAddr && pvAddr != pvMem) 7577 kwErrPrintf("VirtualAlloc %p LB %#x (%#x,%#x) failed: %p / %u\n", 7578 pvAddr, cb, fAllocType, fProt, pvMem, GetLastError()); 7579 } 7580 7581 if (pvMem) 7582 { 7583 /* 7584 * Track it. 7585 */ 7586 PKWVIRTALLOC pTracker; 7587 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread); 7588 7589 pTracker = g_Sandbox.pVirtualAllocHead; 7590 while ( pTracker 7591 && (KUPTR)pvMem - (KUPTR)pTracker->pvAlloc >= pTracker->cbAlloc) 7592 pTracker = pTracker->pNext; 7593 if (!pTracker) 7594 { 7595 DWORD dwErr = GetLastError(); 7596 PKWVIRTALLOC pTracker = (PKWVIRTALLOC)kHlpAlloc(sizeof(*pTracker)); 7597 if (pTracker) 7598 { 7599 pTracker->pvAlloc = pvMem; 7600 pTracker->cbAlloc = cb; 7601 pTracker->idxPreAllocated = idxPreAllocated; 7602 pTracker->pNext = g_Sandbox.pVirtualAllocHead; 7603 g_Sandbox.pVirtualAllocHead = pTracker; 7604 } 7605 SetLastError(dwErr); 7606 } 7607 } 7608 } 7609 else 7610 pvMem = VirtualAlloc(pvAddr, cb, fAllocType, fProt); 7334 7611 KW_LOG(("VirtualAlloc: pvAddr=%p cb=%p type=%#x prot=%#x -> %p (last=%d)\n", 7335 7612 pvAddr, cb, fAllocType, fProt, pvMem, GetLastError())); 7336 if ( g_Sandbox.pTool->u.Sandboxed.enmHint == KWTOOLHINT_VISUAL_CPP_CL7337 && pvMem)7338 {7339 PKWVIRTALLOC pTracker;7340 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread);7341 7342 pTracker = g_Sandbox.pVirtualAllocHead;7343 while ( pTracker7344 && (KUPTR)pvMem - (KUPTR)pTracker->pvAlloc >= pTracker->cbAlloc)7345 pTracker = pTracker->pNext;7346 if (!pTracker)7347 {7348 DWORD dwErr = GetLastError();7349 PKWVIRTALLOC pTracker = (PKWVIRTALLOC)kHlpAlloc(sizeof(*pTracker));7350 if (pTracker)7351 {7352 pTracker->pvAlloc = pvMem;7353 pTracker->cbAlloc = cb;7354 pTracker->pNext = g_Sandbox.pVirtualAllocHead;7355 g_Sandbox.pVirtualAllocHead = pTracker;7356 }7357 SetLastError(dwErr);7358 }7359 }7360 7613 return pvMem; 7361 7614 } … … 7365 7618 static BOOL WINAPI kwSandbox_Kernel32_VirtualFree(PVOID pvAddr, SIZE_T cb, DWORD dwFreeType) 7366 7619 { 7367 BOOL fRc = VirtualFree(pvAddr, cb, dwFreeType); 7368 KW_LOG(("VirtualFree: pvAddr=%p cb=%p type=%#x -> %d\n", pvAddr, cb, dwFreeType, fRc)); 7620 BOOL fRc; 7369 7621 if (g_Sandbox.pTool->u.Sandboxed.enmHint == KWTOOLHINT_VISUAL_CPP_CL) 7370 7622 { … … 7389 7641 } 7390 7642 if (pTracker) 7391 kHlpFree(pTracker); 7392 else 7393 KW_LOG(("VirtualFree: pvAddr=%p not found!\n", pvAddr)); 7394 } 7395 } 7396 } 7643 { 7644 #ifdef WITH_FIXED_VIRTUAL_ALLOCS 7645 if (pTracker->idxPreAllocated != KU32_MAX) 7646 { 7647 kwSandboxResetFixedAllocation(pTracker->idxPreAllocated); 7648 KW_LOG(("VirtualFree: pvAddr=%p cb=%p type=%#x -> TRUE [pre allocated #%u]\n", 7649 pvAddr, cb, dwFreeType, pTracker->idxPreAllocated)); 7650 kHlpFree(pTracker); 7651 return TRUE; 7652 } 7653 #endif 7654 7655 fRc = VirtualFree(pvAddr, cb, dwFreeType); 7656 if (fRc) 7657 kHlpFree(pTracker); 7658 else 7659 { 7660 pTracker->pNext = g_Sandbox.pVirtualAllocHead; 7661 g_Sandbox.pVirtualAllocHead = pTracker; 7662 } 7663 KW_LOG(("VirtualFree: pvAddr=%p cb=%p type=%#x -> %d\n", pvAddr, cb, dwFreeType, fRc)); 7664 return fRc; 7665 } 7666 7667 KW_LOG(("VirtualFree: pvAddr=%p not found!\n", pvAddr)); 7668 } 7669 } 7670 } 7671 7672 #ifdef WITH_FIXED_VIRTUAL_ALLOCS 7673 /* 7674 * Protect our fixed allocations (this isn't just paranoia, btw.). 7675 */ 7676 if (dwFreeType & MEM_RELEASE) 7677 { 7678 KU32 idxFixed = K_ELEMENTS(g_aFixedVirtualAllocs); 7679 while (idxFixed-- > 0) 7680 if (g_aFixedVirtualAllocs[idxFixed].pvReserved == pvAddr) 7681 { 7682 KW_LOG(("VirtualFree: Damn it! Don't free g_aFixedVirtualAllocs[#%u]: %p LB %#x\n", 7683 idxFixed, g_aFixedVirtualAllocs[idxFixed].pvReserved, g_aFixedVirtualAllocs[idxFixed].cbFixed)); 7684 return TRUE; 7685 } 7686 } 7687 #endif 7688 7689 /* 7690 * Not tracker or not actually free the virtual range. 7691 */ 7692 fRc = VirtualFree(pvAddr, cb, dwFreeType); 7693 KW_LOG(("VirtualFree: pvAddr=%p cb=%p type=%#x -> %d\n", pvAddr, cb, dwFreeType, fRc)); 7397 7694 return fRc; 7398 7695 } … … 8398 8695 { TUPLE("CreateFileMappingW"), NULL, (KUPTR)kwSandbox_Kernel32_CreateFileMappingW }, 8399 8696 { TUPLE("MapViewOfFile"), NULL, (KUPTR)kwSandbox_Kernel32_MapViewOfFile }, 8697 { TUPLE("MapViewOfFileEx"), NULL, (KUPTR)kwSandbox_Kernel32_MapViewOfFileEx }, 8400 8698 { TUPLE("UnmapViewOfFile"), NULL, (KUPTR)kwSandbox_Kernel32_UnmapViewOfFile }, 8401 8699 #endif … … 8534 8832 { TUPLE("CreateFileMappingW"), NULL, (KUPTR)kwSandbox_Kernel32_CreateFileMappingW }, 8535 8833 { TUPLE("MapViewOfFile"), NULL, (KUPTR)kwSandbox_Kernel32_MapViewOfFile }, 8834 { TUPLE("MapViewOfFileEx"), NULL, (KUPTR)kwSandbox_Kernel32_MapViewOfFileEx }, 8536 8835 { TUPLE("UnmapViewOfFile"), NULL, (KUPTR)kwSandbox_Kernel32_UnmapViewOfFile }, 8537 8836 #endif … … 8612 8911 case CTRL_C_EVENT: 8613 8912 fprintf(stderr, "kWorker: Ctrl-C\n"); 8913 g_fCtrlC = K_TRUE; 8614 8914 exit(9); 8615 8915 break; … … 8617 8917 case CTRL_BREAK_EVENT: 8618 8918 fprintf(stderr, "kWorker: Ctrl-Break\n"); 8919 g_fCtrlC = K_TRUE; 8619 8920 exit(10); 8620 8921 break; … … 8622 8923 case CTRL_CLOSE_EVENT: 8623 8924 fprintf(stderr, "kWorker: console closed\n"); 8925 g_fCtrlC = K_TRUE; 8624 8926 exit(11); 8625 8927 break; … … 8627 8929 case CTRL_LOGOFF_EVENT: 8628 8930 fprintf(stderr, "kWorker: logoff event\n"); 8931 g_fCtrlC = K_TRUE; 8629 8932 exit(11); 8630 8933 break; … … 8632 8935 case CTRL_SHUTDOWN_EVENT: 8633 8936 fprintf(stderr, "kWorker: shutdown event\n"); 8937 g_fCtrlC = K_TRUE; 8634 8938 exit(11); 8635 8939 break; … … 9072 9376 PKWVIRTALLOC pNext = pTracker->pNext; 9073 9377 KW_LOG(("Freeing VirtualFree leak %p LB %#x\n", pTracker->pvAlloc, pTracker->cbAlloc)); 9074 VirtualFree(pTracker->pvAlloc, 0, MEM_RELEASE); 9378 9379 #ifdef WITH_FIXED_VIRTUAL_ALLOCS 9380 if (pTracker->idxPreAllocated != KU32_MAX) 9381 kwSandboxResetFixedAllocation(pTracker->idxPreAllocated); 9382 else 9383 #endif 9384 VirtualFree(pTracker->pvAlloc, 0, MEM_RELEASE); 9075 9385 kHlpFree(pTracker); 9076 9386 pTracker = pNext; … … 9833 10143 int main(int argc, char **argv) 9834 10144 { 9835 KSIZE cbMsgBuf = 0;9836 KU8 *pbMsgBuf = NULL;9837 int i;9838 HANDLE hPipe = INVALID_HANDLE_VALUE;9839 const char *pszTmp;9840 KFSLOOKUPERROR enmIgnored;10145 KSIZE cbMsgBuf = 0; 10146 KU8 *pbMsgBuf = NULL; 10147 int i; 10148 HANDLE hPipe = INVALID_HANDLE_VALUE; 10149 const char *pszTmp; 10150 KFSLOOKUPERROR enmIgnored; 9841 10151 #if defined(KBUILD_OS_WINDOWS) && defined(KBUILD_ARCH_X86) 9842 PVOID pvVecXcptHandler = AddVectoredExceptionHandler(0 /*called last*/, kwSandboxVecXcptEmulateChained); 10152 PVOID pvVecXcptHandler = AddVectoredExceptionHandler(0 /*called last*/, 10153 kwSandboxVecXcptEmulateChained); 9843 10154 #endif 9844 10155 #ifdef WITH_CONSOLE_OUTPUT_BUFFERING … … 9847 10158 PMY_RTL_USER_PROCESS_PARAMETERS pProcessParams = (PMY_RTL_USER_PROCESS_PARAMETERS)pPeb->ProcessParameters; 9848 10159 DWORD dwType; 10160 #endif 10161 10162 10163 #ifdef WITH_FIXED_VIRTUAL_ALLOCS 10164 /* 10165 * Reserve memory for cl.exe 10166 */ 10167 for (i = 0; i < K_ELEMENTS(g_aFixedVirtualAllocs); i++) 10168 { 10169 g_aFixedVirtualAllocs[i].fInUse = K_FALSE; 10170 g_aFixedVirtualAllocs[i].pvReserved = VirtualAlloc((void *)g_aFixedVirtualAllocs[i].uFixed, 10171 g_aFixedVirtualAllocs[i].cbFixed, 10172 MEM_RESERVE, PAGE_READWRITE); 10173 if ( !g_aFixedVirtualAllocs[i].pvReserved 10174 || g_aFixedVirtualAllocs[i].pvReserved != (void *)g_aFixedVirtualAllocs[i].uFixed) 10175 { 10176 kwErrPrintf("Failed to reserve %p LB %#x: %u\n", g_aFixedVirtualAllocs[i].uFixed, g_aFixedVirtualAllocs[i].cbFixed, 10177 GetLastError()); 10178 if (g_aFixedVirtualAllocs[i].pvReserved) 10179 { 10180 VirtualFree(g_aFixedVirtualAllocs[i].pvReserved, g_aFixedVirtualAllocs[i].cbFixed, MEM_RELEASE); 10181 g_aFixedVirtualAllocs[i].pvReserved = NULL; 10182 } 10183 } 10184 } 9849 10185 #endif 9850 10186
Note:
See TracChangeset
for help on using the changeset viewer.