Changeset 52431 in vbox for trunk/src/VBox/HostDrivers
- Timestamp:
- Aug 20, 2014 12:31:03 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp
r52426 r52431 137 137 /** The verification result. */ 138 138 int rc; 139 /** The validation flags (for WinVerifyTrust retry). */ 140 uint32_t fFlags; 139 141 /** Whether IndexNumber is valid */ 140 142 bool fIndexNumberValid; … … 204 206 static NTSTATUS (NTAPI * g_pfnLdrLoadDllReal)(PWSTR, PULONG, PUNICODE_STRING, PHANDLE); 205 207 /** The hash table of verifier cache . */ 206 static VERIFIERCACHEENTRY *volatile g_apVerifierCache[128];208 static PVERIFIERCACHEENTRY volatile g_apVerifierCache[128]; 207 209 /** Queue of cached images which needs WinVerifyTrust to check them. */ 208 static VERIFIERCACHEENTRY *volatile g_pVerifierCacheTodoWvt = NULL;210 static PVERIFIERCACHEENTRY volatile g_pVerifierCacheTodoWvt = NULL; 209 211 /** Queue of cached images which needs their imports checked. */ 210 static VERIFIERCACHEIMPORT *volatile g_pVerifierCacheTodoImports = NULL;212 static PVERIFIERCACHEIMPORT volatile g_pVerifierCacheTodoImports = NULL; 211 213 /** @ */ 212 214 … … 222 224 *******************************************************************************/ 223 225 static NTSTATUS supR3HardenedScreenImage(HANDLE hFile, bool fImage, PULONG pfAccess, PULONG pfProtect, 224 bool *pfCallRealApi, const char *pszCaller );226 bool *pfCallRealApi, const char *pszCaller, bool fAvoidWinVerifyTrust); 225 227 226 228 #ifdef RT_ARCH_AMD64 … … 490 492 * @param rc The verifier result. 491 493 * @param fWinVerifyTrust Whether verified by WinVerifyTrust or not. 492 */ 493 static void supR3HardenedWinVerifyCacheInsert(PCUNICODE_STRING pUniStr, HANDLE hFile, int rc, bool fWinVerifyTrust) 494 * @param fFlags The image verification flags. 495 */ 496 static void supR3HardenedWinVerifyCacheInsert(PCUNICODE_STRING pUniStr, HANDLE hFile, int rc, 497 bool fWinVerifyTrust, uint32_t fFlags) 494 498 { 495 499 /* … … 505 509 pEntry->rc = rc; 506 510 pEntry->uHash = supR3HardenedWinVerifyCacheHashPath(pUniStr); 511 pEntry->fFlags = fFlags; 507 512 pEntry->fWinVerifyTrust = fWinVerifyTrust; 508 513 pEntry->cbPath = pUniStr->Length; … … 534 539 if ( pOther->uHash == pEntry->uHash 535 540 && pOther->cbPath == pEntry->cbPath 536 && memcmp(pOther->wszPath, pEntry->wszPath, pEntry->cbPath) == 0)541 && supR3HardenedWinVerifyCacheIsMatch(pOther->wszPath, pEntry->wszPath, pEntry->cbPath)) 537 542 break; 538 543 ppEntry = &pOther->pNext; 539 544 } 540 545 541 /* Duplicate entry. */ 542 #ifdef DEBUG_bird 543 __debugbreak(); 544 #endif 546 /* Duplicate entry (may happen due to races). */ 545 547 HeapFree(GetProcessHeap(), 0 /* dwFlags*/, pEntry); 546 548 } … … 864 866 ULONG fProtect = 0; 865 867 bool fCallRealApi = false; 866 rcNt = supR3HardenedScreenImage(hFile, true /*fImage*/, &fAccess, &fProtect, &fCallRealApi, "Imports"); 868 rcNt = supR3HardenedScreenImage(hFile, true /*fImage*/, &fAccess, &fProtect, &fCallRealApi, 869 "Imports", false /*fAvoidWinVerifyTrust*/); 867 870 NtClose(hFile); 868 871 } … … 875 878 HeapFree(GetProcessHeap(), 0 /* dwFlags*/, pCur); 876 879 } while (pTodo); 880 } 881 } 882 883 884 /** 885 * Processes the list of WinVerifyTrust todos. 886 */ 887 static void supR3HardenedWinVerifyCacheProcessWvtTodos(void) 888 { 889 PVERIFIERCACHEENTRY pReschedule = NULL; 890 PVERIFIERCACHEENTRY volatile *ppReschedLastNext = NULL; 891 892 /* 893 * Work until we've got nothing more todo. 894 */ 895 for (;;) 896 { 897 if (!supHardenedWinIsWinVerifyTrustCallable()) 898 break; 899 PVERIFIERCACHEENTRY pTodo = ASMAtomicXchgPtrT(&g_pVerifierCacheTodoWvt, NULL, PVERIFIERCACHEENTRY); 900 if (!pTodo) 901 break; 902 do 903 { 904 PVERIFIERCACHEENTRY pCur = pTodo; 905 pTodo = pTodo->pNextTodoWvt; 906 pCur->pNextTodoWvt = NULL; 907 908 if ( !pCur->fWinVerifyTrust 909 && RT_SUCCESS(pCur->rc)) 910 { 911 bool fWinVerifyTrust = false; 912 int rc = supHardenedWinVerifyImageTrust(pCur->hFile, pCur->wszPath, pCur->fFlags, pCur->rc, 913 &fWinVerifyTrust, NULL /* pErrInfo*/); 914 if (RT_FAILURE(rc) || fWinVerifyTrust) 915 { 916 SUP_DPRINTF(("supR3HardenedWinVerifyCacheProcessWvtTodos: %d (was %d) fWinVerifyTrust=%d for '%ls'\n", 917 rc, pCur->rc, fWinVerifyTrust, pCur->wszPath)); 918 pCur->fWinVerifyTrust = true; 919 pCur->rc = rc; 920 } 921 else 922 { 923 /* Retry it at a later time. */ 924 SUP_DPRINTF(("supR3HardenedWinVerifyCacheProcessWvtTodos: %d (was %d) fWinVerifyTrust=%d for '%ls' [rescheduled]\n", 925 rc, pCur->rc, fWinVerifyTrust, pCur->wszPath)); 926 if (!pReschedule) 927 ppReschedLastNext = &pCur->pNextTodoWvt; 928 pCur->pNextTodoWvt = pReschedule; 929 } 930 } 931 /* else: already processed. */ 932 } while (pTodo); 933 } 934 935 /* 936 * Anything to reschedule. 937 */ 938 if (pReschedule) 939 { 940 do 941 *ppReschedLastNext = g_pVerifierCacheTodoWvt; 942 while (!ASMAtomicCmpXchgPtr(&g_pVerifierCacheTodoWvt, pReschedule, *ppReschedLastNext)); 877 943 } 878 944 } … … 1024 1090 1025 1091 static NTSTATUS supR3HardenedScreenImage(HANDLE hFile, bool fImage, PULONG pfAccess, PULONG pfProtect, 1026 bool *pfCallRealApi, const char *pszCaller )1092 bool *pfCallRealApi, const char *pszCaller, bool fAvoidWinVerifyTrust) 1027 1093 { 1028 1094 *pfCallRealApi = false; … … 1056 1122 /* 1057 1123 * Check the cache. 1058 * If we haven't done the WinVerifyTrust thing, do it if we can.1059 1124 */ 1060 1125 PVERIFIERCACHEENTRY pCacheHit = supR3HardenedWinVerifyCacheLookup(&uBuf.UniStr, hFile); 1061 if ( pCacheHit 1062 && ( pCacheHit->fWinVerifyTrust 1063 || RT_FAILURE(pCacheHit->rc) 1064 || g_enmSupR3HardenedMainState < SUPR3HARDENEDMAINSTATE_VERIFY_TRUST_READY 1065 || !supHardenedWinIsWinVerifyTrustCallable() ) ) 1066 { 1067 SUP_DPRINTF(("supR3HardenedScreenImage/%s: cache hit (%Rrc) on %ls\n", pszCaller, pCacheHit->rc, pCacheHit->wszPath)); 1126 if (pCacheHit) 1127 { 1128 /* If we haven't done the WinVerifyTrust thing, do it if we can. */ 1129 if ( !pCacheHit->fWinVerifyTrust 1130 && RT_SUCCESS(pCacheHit->rc) 1131 && supHardenedWinIsWinVerifyTrustCallable() ) 1132 { 1133 if (!fAvoidWinVerifyTrust) 1134 { 1135 SUP_DPRINTF(("supR3HardenedScreenImage/%s: cache hit (%Rrc) on %ls [redoing WinVerifyTrust]\n", 1136 pszCaller, pCacheHit->rc, pCacheHit->wszPath)); 1137 1138 bool fWinVerifyTrust = false; 1139 int rc = supHardenedWinVerifyImageTrust(pCacheHit->hFile, pCacheHit->wszPath, pCacheHit->fFlags, pCacheHit->rc, 1140 &fWinVerifyTrust, NULL /* pErrInfo*/); 1141 if (RT_FAILURE(rc) || fWinVerifyTrust) 1142 { 1143 SUP_DPRINTF(("supR3HardenedScreenImage/%s: %d (was %d) fWinVerifyTrust=%d for '%ls'\n", 1144 pszCaller, rc, pCacheHit->rc, fWinVerifyTrust, pCacheHit->wszPath)); 1145 pCacheHit->fWinVerifyTrust = true; 1146 pCacheHit->rc = rc; 1147 } 1148 else 1149 SUP_DPRINTF(("supR3HardenedScreenImage/%s: WinVerifyTrust not available, rescheduling %ls\n", 1150 pszCaller, pCacheHit->wszPath)); 1151 } 1152 else 1153 SUP_DPRINTF(("supR3HardenedScreenImage/%s: cache hit (%Rrc) on %ls [avoiding WinVerifyTrust]\n", 1154 pszCaller, pCacheHit->rc, pCacheHit->wszPath)); 1155 } 1156 else 1157 SUP_DPRINTF(("supR3HardenedScreenImage/%s: cache hit (%Rrc) on %ls%s\n", 1158 pszCaller, pCacheHit->rc, pCacheHit->wszPath, pCacheHit->fWinVerifyTrust ? "" : " [lacks WinVerifyTrust]")); 1159 1160 /* Return the cached value. */ 1068 1161 if (RT_SUCCESS(pCacheHit->rc)) 1069 1162 { … … 1256 1349 int rc; 1257 1350 bool fWinVerifyTrust = false; 1258 if (!pCacheHit) 1259 rc = supHardenedWinVerifyImageByHandle(hMyFile, uBuf.UniStr.Buffer, fFlags, &fWinVerifyTrust, &ErrInfo); 1260 else 1261 { 1262 rc = supHardenedWinVerifyImageTrust(hMyFile, uBuf.UniStr.Buffer, fFlags, pCacheHit->rc, &fWinVerifyTrust, &ErrInfo); 1263 SUP_DPRINTF(("supR3HardenedScreenImage/%s: supHardenedWinVerifyImageTrust returns %d (was %d) fWinVerifyTrust=%d\n", 1264 pszCaller, rc, pCacheHit->rc, fWinVerifyTrust)); 1265 } 1351 rc = supHardenedWinVerifyImageByHandle(hMyFile, uBuf.UniStr.Buffer, fFlags, &fWinVerifyTrust, &ErrInfo); 1266 1352 if (RT_FAILURE(rc)) 1267 1353 { … … 1275 1361 1276 1362 /* 1277 * Insert or update the cache. 1278 */ 1279 if (!pCacheHit) 1280 { 1281 if (hMyFile != hFile) 1282 supR3HardenedWinVerifyCacheInsert(&uBuf.UniStr, hMyFile, rc, fWinVerifyTrust); 1283 } 1284 else 1285 { 1286 if (fWinVerifyTrust) 1287 pCacheHit->fWinVerifyTrust = fWinVerifyTrust; 1288 if (hMyFile != hFile) 1289 NtClose(hMyFile); 1290 } 1363 * Insert into the cache. 1364 */ 1365 if (hMyFile != hFile) 1366 supR3HardenedWinVerifyCacheInsert(&uBuf.UniStr, hMyFile, rc, fWinVerifyTrust, fFlags); 1291 1367 1292 1368 *pfCallRealApi = true; … … 1338 1414 bool fCallRealApi; 1339 1415 //SUP_DPRINTF(("supR3HardenedWinVerifyCachePreload: scanning %ls\n", pwszName)); 1340 supR3HardenedScreenImage(hFile, false, &fAccess, &fProtect, &fCallRealApi, "preload" );1416 supR3HardenedScreenImage(hFile, false, &fAccess, &fProtect, &fCallRealApi, "preload", false /*fAvoidWinVerifyTrust*/); 1341 1417 //SUP_DPRINTF(("supR3HardenedWinVerifyCachePreload: done %ls\n", pwszName)); 1342 1418 … … 1375 1451 bool fCallRealApi; 1376 1452 //SUP_DPRINTF(("supR3HardenedMonitor_NtCreateSection: 1\n")); 1377 NTSTATUS rcNt = supR3HardenedScreenImage(hFile, fImage, &fAccess, &fProtect, &fCallRealApi, "NtCreateSection"); 1453 NTSTATUS rcNt = supR3HardenedScreenImage(hFile, fImage, &fAccess, &fProtect, &fCallRealApi, 1454 "NtCreateSection", true /*fAvoidWinVerifyTrust*/); 1378 1455 //SUP_DPRINTF(("supR3HardenedMonitor_NtCreateSection: 2 rcNt=%#x fCallRealApi=%#x\n", rcNt, fCallRealApi)); 1379 1456 … … 1417 1494 { 1418 1495 DWORD dwSavedLastError = GetLastError(); 1496 1497 /* 1498 * Process WinVerifyTrust todo before and after. 1499 */ 1500 supR3HardenedWinVerifyCacheProcessWvtTodos(); 1419 1501 1420 1502 /* … … 1559 1641 ULONG fProtect = 0; 1560 1642 bool fCallRealApi = false; 1561 rcNt = supR3HardenedScreenImage(hFile, true /*fImage*/, &fAccess, &fProtect, &fCallRealApi, "LdrLoadDll"); 1643 rcNt = supR3HardenedScreenImage(hFile, true /*fImage*/, &fAccess, &fProtect, &fCallRealApi, 1644 "LdrLoadDll", false /*fAvoidWinVerifyTrust*/); 1562 1645 NtClose(hFile); 1563 1646 if (!NT_SUCCESS(rcNt)) … … 1588 1671 else 1589 1672 SUP_DPRINTF(("supR3HardenedMonitor_LdrLoadDll: returns rcNt=%#x '%ls'\n", rcNt, wszPath)); 1673 supR3HardenedWinVerifyCacheProcessWvtTodos(); 1590 1674 SetLastError(dwSavedLastError); 1591 1675
Note:
See TracChangeset
for help on using the changeset viewer.