VirtualBox

Changeset 52431 in vbox for trunk/src/VBox/HostDrivers


Ignore:
Timestamp:
Aug 20, 2014 12:31:03 PM (10 years ago)
Author:
vboxsync
Message:

SUP: Process the WinVerityTrust todo list from LdrLoadDll, avoid doing it from under NtCreateSection as to avoid messing up the loader. Simplified the WinVerifyTrust redo code in supR3HardenedScreenImage.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp

    r52426 r52431  
    137137    /** The verification result. */
    138138    int                     rc;
     139    /** The validation flags (for WinVerifyTrust retry). */
     140    uint32_t                fFlags;
    139141    /** Whether IndexNumber is valid  */
    140142    bool                    fIndexNumberValid;
     
    204206static NTSTATUS (NTAPI *    g_pfnLdrLoadDllReal)(PWSTR, PULONG, PUNICODE_STRING, PHANDLE);
    205207/** The hash table of verifier cache . */
    206 static VERIFIERCACHEENTRY * volatile g_apVerifierCache[128];
     208static PVERIFIERCACHEENTRY volatile g_apVerifierCache[128];
    207209/** Queue of cached images which needs WinVerifyTrust to check them. */
    208 static VERIFIERCACHEENTRY * volatile g_pVerifierCacheTodoWvt = NULL;
     210static PVERIFIERCACHEENTRY volatile g_pVerifierCacheTodoWvt = NULL;
    209211/** Queue of cached images which needs their imports checked. */
    210 static VERIFIERCACHEIMPORT * volatile g_pVerifierCacheTodoImports = NULL;
     212static PVERIFIERCACHEIMPORT volatile g_pVerifierCacheTodoImports = NULL;
    211213/** @ */
    212214
     
    222224*******************************************************************************/
    223225static NTSTATUS supR3HardenedScreenImage(HANDLE hFile, bool fImage, PULONG pfAccess, PULONG pfProtect,
    224                                          bool *pfCallRealApi, const char *pszCaller);
     226                                         bool *pfCallRealApi, const char *pszCaller, bool fAvoidWinVerifyTrust);
    225227
    226228#ifdef RT_ARCH_AMD64
     
    490492 * @param   rc                  The verifier result.
    491493 * @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 */
     496static void supR3HardenedWinVerifyCacheInsert(PCUNICODE_STRING pUniStr, HANDLE hFile, int rc,
     497                                              bool fWinVerifyTrust, uint32_t fFlags)
    494498{
    495499    /*
     
    505509        pEntry->rc              = rc;
    506510        pEntry->uHash           = supR3HardenedWinVerifyCacheHashPath(pUniStr);
     511        pEntry->fFlags          = fFlags;
    507512        pEntry->fWinVerifyTrust = fWinVerifyTrust;
    508513        pEntry->cbPath          = pUniStr->Length;
     
    534539            if (   pOther->uHash  == pEntry->uHash
    535540                && pOther->cbPath == pEntry->cbPath
    536                 && memcmp(pOther->wszPath, pEntry->wszPath, pEntry->cbPath) == 0)
     541                && supR3HardenedWinVerifyCacheIsMatch(pOther->wszPath, pEntry->wszPath, pEntry->cbPath))
    537542                break;
    538543            ppEntry = &pOther->pNext;
    539544        }
    540545
    541         /* Duplicate entry. */
    542 #ifdef DEBUG_bird
    543         __debugbreak();
    544 #endif
     546        /* Duplicate entry (may happen due to races). */
    545547        HeapFree(GetProcessHeap(), 0 /* dwFlags*/, pEntry);
    546548    }
     
    864866                    ULONG fProtect = 0;
    865867                    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*/);
    867870                    NtClose(hFile);
    868871                }
     
    875878            HeapFree(GetProcessHeap(), 0 /* dwFlags*/, pCur);
    876879        } while (pTodo);
     880    }
     881}
     882
     883
     884/**
     885 * Processes the list of WinVerifyTrust todos.
     886 */
     887static 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));
    877943    }
    878944}
     
    10241090
    10251091static NTSTATUS supR3HardenedScreenImage(HANDLE hFile, bool fImage, PULONG pfAccess, PULONG pfProtect,
    1026                                          bool *pfCallRealApi, const char *pszCaller)
     1092                                         bool *pfCallRealApi, const char *pszCaller, bool fAvoidWinVerifyTrust)
    10271093{
    10281094    *pfCallRealApi = false;
     
    10561122    /*
    10571123     * Check the cache.
    1058      * If we haven't done the WinVerifyTrust thing, do it if we can.
    10591124     */
    10601125    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. */
    10681161        if (RT_SUCCESS(pCacheHit->rc))
    10691162        {
     
    12561349    int  rc;
    12571350    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);
    12661352    if (RT_FAILURE(rc))
    12671353    {
     
    12751361
    12761362    /*
    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);
    12911367
    12921368    *pfCallRealApi = true;
     
    13381414    bool  fCallRealApi;
    13391415    //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*/);
    13411417    //SUP_DPRINTF(("supR3HardenedWinVerifyCachePreload: done %ls\n", pwszName));
    13421418
     
    13751451            bool fCallRealApi;
    13761452            //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*/);
    13781455            //SUP_DPRINTF(("supR3HardenedMonitor_NtCreateSection: 2 rcNt=%#x fCallRealApi=%#x\n", rcNt, fCallRealApi));
    13791456
     
    14171494{
    14181495    DWORD dwSavedLastError = GetLastError();
     1496
     1497    /*
     1498     * Process WinVerifyTrust todo before and after.
     1499     */
     1500    supR3HardenedWinVerifyCacheProcessWvtTodos();
    14191501
    14201502    /*
     
    15591641            ULONG fProtect = 0;
    15601642            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*/);
    15621645            NtClose(hFile);
    15631646            if (!NT_SUCCESS(rcNt))
     
    15881671    else
    15891672        SUP_DPRINTF(("supR3HardenedMonitor_LdrLoadDll: returns rcNt=%#x '%ls'\n", rcNt, wszPath));
     1673    supR3HardenedWinVerifyCacheProcessWvtTodos();
    15901674    SetLastError(dwSavedLastError);
    15911675
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette