VirtualBox

Changeset 52962 in vbox for trunk


Ignore:
Timestamp:
Oct 6, 2014 8:09:04 PM (10 years ago)
Author:
vboxsync
Message:

SUP: Check the entire NTDLL during process verification now that we're opening vboxdrv[stub] before it is initialized. check the stub process for extra threads and debugger when the VM process opens vboxdrv.

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/err.h

    r52815 r52962  
    25132513/** The image is outside the expected range. */
    25142514#define VERR_SUP_VP_IMAGE_TOO_BIG                   (-5668)
     2515/** Stub process not found so it cannot be revalidated when vboxdrv is opened
     2516 * by the VM process. */
     2517#define VERR_SUP_VP_STUB_NOT_FOUND                  (-5669)
     2518/** Error openeing the stub process for revalidation when vboxdrv is opened by
     2519 *  the VM process. */
     2520#define VERR_SUP_VP_STUB_OPEN_ERROR                 (-5670)
     2521/** Stub process thread not found during revalidation upon vboxdrv opening by
     2522 * the VM process. */
     2523#define VERR_SUP_VP_STUB_THREAD_NOT_FOUND           (-5671)
     2524/** Error opening the stub process thread for revalidation when vboxdrv is
     2525 * opened by the VM process. */
     2526#define VERR_SUP_VP_STUB_THREAD_OPEN_ERROR          (-5672)
    25152527
    25162528/** @} */
  • trunk/src/VBox/HostDrivers/Support/SUPLibInternal.h

    r52949 r52962  
    450450DECLHIDDEN(void)    supR3HardenedWinInitImportsEarly(uintptr_t uNtDllAddr);
    451451DECLHIDDEN(PFNRT)   supR3HardenedWinGetRealDllSymbol(const char *pszDll, const char *pszProcedure);
    452 DECLHIDDEN(void)    supR3HardenedWinVerifyProcess(void);
    453452DECLHIDDEN(void)    supR3HardenedWinEnableThreadCreation(void);
    454453DECLHIDDEN(void)    supR3HardenedWinResolveVerifyTrustApiAndHookThreadCreation(const char *pszProgName);
     
    466465DECLHIDDEN(void)    supR3HardenedWinCompactHeaps(void);
    467466DECLHIDDEN(void)    supR3HardenedMainOpenDevice(void);
    468 DECLHIDDEN(void)    supR3HardenedWinReportErrorToParent(int rc, const char *pszFormat, va_list va);
     467DECLHIDDEN(void)    supR3HardenedWinReportErrorToParent(const char *pszWhere, SUPINITOP enmWhat, int rc,
     468                                                        const char *pszFormat, va_list va);
    469469#endif
    470470
  • trunk/src/VBox/HostDrivers/Support/SUPR3HardenedMain.cpp

    r52949 r52962  
    11431143    else if (   g_enmSupR3HardenedMainState < SUPR3HARDENEDMAINSTATE_WIN_IMPORTS_RESOLVED
    11441144             && g_enmSupR3HardenedMainState != SUPR3HARDENEDMAINSTATE_NOT_YET_CALLED)
    1145         supR3HardenedWinReportErrorToParent(rc, pszMsgFmt, va);
     1145        supR3HardenedWinReportErrorToParent(pszWhere, enmWhat, rc, pszMsgFmt, va);
    11461146#endif
    11471147
     
    11761176    if (   g_enmSupR3HardenedMainState < SUPR3HARDENEDMAINSTATE_WIN_IMPORTS_RESOLVED
    11771177        && g_enmSupR3HardenedMainState != SUPR3HARDENEDMAINSTATE_NOT_YET_CALLED)
    1178         supR3HardenedWinReportErrorToParent(VERR_INTERNAL_ERROR, pszFormat, va);
     1178        supR3HardenedWinReportErrorToParent(NULL, kSupInitOp_Invalid, VERR_INTERNAL_ERROR, pszFormat, va);
    11791179    else
    11801180#endif
     
    17811781#ifdef RT_OS_WINDOWS
    17821782        /*
    1783          * Windows: Verify the process (repeated by the kernel later).
    1784          */
    1785         if (!g_fSupEarlyProcessInit)
    1786             supR3HardenedWinVerifyProcess();
    1787 
    1788         /*
    17891783         * Windows: The second respawn.  This time we make a special arrangement
    17901784         * with vboxdrv to monitor access to the new process from its inception.
     
    17971791        SUP_DPRINTF(("SUPR3HardenedMain: Final process, opening VBoxDrv...\n"));
    17981792        supR3HardenedWinFlushLoaderCache();
    1799 #endif /* RT_OS_WINDOWS */
    1800 
     1793
     1794#else
    18011795        /*
    18021796         * Open the vboxdrv device.
    18031797         */
    1804 #ifdef RT_OS_WINDOWS
    1805         if (!g_fSupEarlyProcessInit)
    1806 #endif
    1807             supR3HardenedMainOpenDevice();
     1798        supR3HardenedMainOpenDevice();
     1799#endif /* !RT_OS_WINDOWS */
    18081800    }
    18091801
  • trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp

    r52949 r52962  
    187187    /** The parent PID for VM processes, otherwise NULL. */
    188188    HANDLE              hParentPid;
     189    /** The TID of the thread opening VBoxDrv or VBoxDrvStub, NULL if not opened. */
     190    HANDLE              hOpenTid;
    189191    /** The PID of the CSRSS process associated with this process. */
    190192    HANDLE              hCsrssPid;
     
    200202        /** A process in the VmProcessUnconfirmed state will keep a weak
    201203         * reference to the parent's protection structure so it can clean up the pChild
    202          * refernece the parent has to it. */
     204         * reference the parent has to it. */
    203205        struct SUPDRVNTPROTECT *pParent;
    204206    } u;
     
    34013403    pNtProtect->enmProcessKind               = enmProcessKind;
    34023404    pNtProtect->hParentPid                   = NULL;
     3405    pNtProtect->hOpenTid                     = NULL;
    34033406    pNtProtect->hCsrssPid                    = NULL;
    34043407    pNtProtect->pCsrssProcess                = NULL;
     
    35023505    RTSpinlockRelease(g_hNtProtectLock);
    35033506    return pFound;
     3507}
     3508
     3509
     3510/**
     3511 * Validates a few facts about the stub process when the VM process opens
     3512 * vboxdrv.
     3513 *
     3514 * This makes sure the stub process is still around and that it has neither
     3515 * debugger nor extra threads in it.
     3516 *
     3517 * @returns VBox status code.
     3518 * @param   pNtProtect          The unconfirmed VM process currently trying to
     3519 *                              open vboxdrv.
     3520 * @param   pErrInfo            Additional error information.
     3521 */
     3522static int supdrvNtProtectVerifyStubForVmProcess(PSUPDRVNTPROTECT pNtProtect, PRTERRINFO pErrInfo)
     3523{
     3524    /*
     3525     * Grab a reference to the parent stub process.
     3526     */
     3527    SUPDRVNTPROTECTKIND enmStub = kSupDrvNtProtectKind_Invalid;
     3528    PSUPDRVNTPROTECT    pNtStub = NULL;
     3529    RTSpinlockAcquire(g_hNtProtectLock);
     3530    if (pNtProtect->enmProcessKind == kSupDrvNtProtectKind_VmProcessUnconfirmed)
     3531    {
     3532        pNtStub = pNtProtect->u.pParent; /* weak reference. */
     3533        if (pNtStub)
     3534        {
     3535            enmStub = pNtStub->enmProcessKind;
     3536            if (enmStub == kSupDrvNtProtectKind_StubParent)
     3537            {
     3538                uint32_t cRefs = ASMAtomicIncU32(&pNtStub->cRefs);
     3539                Assert(cRefs > 0 && cRefs < 1024);
     3540            }
     3541            else
     3542                pNtStub = NULL;
     3543        }
     3544    }
     3545    RTSpinlockRelease(g_hNtProtectLock);
     3546
     3547    /*
     3548     * We require the stub process to be present.
     3549     */
     3550    if (!pNtStub)
     3551        return RTErrInfoSetF(pErrInfo, VERR_SUP_VP_STUB_NOT_FOUND, "Missing stub process (enmStub=%d).", enmStub);
     3552
     3553    /*
     3554     * Open the parent process and thread so we can check for debuggers and unwanted threads.
     3555     */
     3556    int rc;
     3557    PEPROCESS pStubProcess;
     3558    NTSTATUS rcNt = PsLookupProcessByProcessId(pNtStub->AvlCore.Key, &pStubProcess);
     3559    if (NT_SUCCESS(rcNt))
     3560    {
     3561        HANDLE hStubProcess;
     3562        rcNt = ObOpenObjectByPointer(pStubProcess, OBJ_KERNEL_HANDLE, NULL /*PassedAccessState*/,
     3563                                     0 /*DesiredAccess*/, *PsProcessType, KernelMode, &hStubProcess);
     3564        if (NT_SUCCESS(rcNt))
     3565        {
     3566            PETHREAD pStubThread;
     3567            rcNt = PsLookupThreadByThreadId(pNtStub->hOpenTid, &pStubThread);
     3568            if (NT_SUCCESS(rcNt))
     3569            {
     3570                HANDLE hStubThread;
     3571                rcNt = ObOpenObjectByPointer(pStubThread, OBJ_KERNEL_HANDLE, NULL /*PassedAccessState*/,
     3572                                             0 /*DesiredAccess*/, *PsThreadType, KernelMode, &hStubThread);
     3573                if (NT_SUCCESS(rcNt))
     3574                {
     3575                    /*
     3576                     * Do some simple sanity checking.
     3577                     */
     3578                    rc = supHardNtVpDebugger(hStubProcess, pErrInfo);
     3579                    if (RT_SUCCESS(rc))
     3580                        rc = supHardNtVpThread(hStubProcess, hStubThread, pErrInfo);
     3581
     3582                    /* Clean up. */
     3583                    rcNt = NtClose(hStubThread); AssertMsg(NT_SUCCESS(rcNt), ("%#x\n", rcNt));
     3584                }
     3585                else
     3586                    rc = RTErrInfoSetF(pErrInfo, VERR_SUP_VP_STUB_THREAD_OPEN_ERROR,
     3587                                       "Error opening stub thread %p (tid %p, pid %p): %#x",
     3588                                       pStubThread, pNtStub->hOpenTid, pNtStub->AvlCore.Key, rcNt);
     3589            }
     3590            else
     3591                rc = RTErrInfoSetF(pErrInfo, VERR_SUP_VP_STUB_THREAD_NOT_FOUND,
     3592                                   "Failed to locate thread %p in %p: %#x", pNtStub->hOpenTid, pNtStub->AvlCore.Key, rcNt);
     3593            rcNt = NtClose(hStubProcess); AssertMsg(NT_SUCCESS(rcNt), ("%#x\n", rcNt));
     3594        }
     3595        else
     3596            rc = RTErrInfoSetF(pErrInfo, VERR_SUP_VP_STUB_OPEN_ERROR,
     3597                               "Error opening stub process %p (pid %p): %#x", pStubProcess, pNtStub->AvlCore.Key, rcNt);
     3598        ObDereferenceObject(pStubProcess);
     3599    }
     3600    else
     3601        rc = RTErrInfoSetF(pErrInfo, VERR_SUP_VP_STUB_NOT_FOUND,
     3602                           "Failed to locate stub process %p: %#x", pNtStub->AvlCore.Key, rcNt);
     3603
     3604    supdrvNtProtectRelease(pNtStub);
     3605    return rc;
    35043606}
    35053607
     
    36983800        rc = supHardenedWinVerifyProcess(NtCurrentProcess(), NtCurrentThread(), SUPHARDNTVPKIND_VERIFY_ONLY,
    36993801                                         NULL /*pcFixes*/, &ErrInfo);
     3802        if (RT_SUCCESS(rc) && pNtProtect->enmProcessKind >= kSupDrvNtProtectKind_VmProcessUnconfirmed)
     3803            rc = supdrvNtProtectVerifyStubForVmProcess(pNtProtect, &ErrInfo);
    37003804        if (RT_FAILURE(rc))
    37013805            RTLogWriteDebugger(szErr, strlen(szErr));
     
    37053809     * Upgrade and return.
    37063810     */
     3811    HANDLE hOpenTid = PsGetCurrentThreadId();
    37073812    RTSpinlockAcquire(g_hNtProtectLock);
    37083813
    37093814    /* Stub process verficiation is pretty much straight forward. */
    37103815    if (pNtProtect->enmProcessKind == kSupDrvNtProtectKind_StubUnverified)
     3816    {
    37113817        pNtProtect->enmProcessKind = RT_SUCCESS(rc) ? kSupDrvNtProtectKind_StubSpawning : kSupDrvNtProtectKind_StubDead;
    3712 
     3818        pNtProtect->hOpenTid       = hOpenTid;
     3819    }
    37133820    /* The VM process verification is a little bit more complicated
    37143821       because we need to drop the parent process reference as well. */
     
    37263833
    37273834        if (RT_SUCCESS(rc))
     3835        {
    37283836            pNtProtect->enmProcessKind = kSupDrvNtProtectKind_VmProcessConfirmed;
     3837            pNtProtect->hOpenTid       = hOpenTid;
     3838        }
    37293839        else
    37303840            pNtProtect->enmProcessKind = kSupDrvNtProtectKind_VmProcessDead;
  • trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyProcess-win.cpp

    r52954 r52962  
    953953            }
    954954
    955             /* The section bits, only child purification verifies all bits . */
    956             if (   pThis->enmKind == SUPHARDNTVPKIND_CHILD_PURIFICATION
    957                 || (   (pThis->aSecHdrs[i].Characteristics & (IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_CNT_CODE))
     955            /* The section bits. Child purification verifies all, normal
     956               verification verifies all except where the executable is
     957               concerned (due to opening vboxdrv during early process init). */
     958            if (   (   (pThis->aSecHdrs[i].Characteristics & (IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_CNT_CODE))
    958959                    && !(pThis->aSecHdrs[i].Characteristics & IMAGE_SCN_MEM_WRITE))
    959                 || (pThis->aSecHdrs[i].Characteristics & (IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE)) == IMAGE_SCN_MEM_READ)
     960                || (pThis->aSecHdrs[i].Characteristics & (IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE)) == IMAGE_SCN_MEM_READ
     961                || (pThis->enmKind == SUPHARDNTVPKIND_VERIFY_ONLY && pImage->fDll)
     962                || pThis->enmKind == SUPHARDNTVPKIND_CHILD_PURIFICATION)
    960963            {
    961964                rc = VINF_SUCCESS;
  • trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp

    r52954 r52962  
    189189    /** The last status. */
    190190    int32_t         rc;
     191    /** The init operation the error relates to if message, kSupInitOp_Invalid if
     192     *  not message. */
     193    SUPINITOP       enmWhat;
     194    /** Where if message. */
     195    char            szWhere[80];
    191196    /** Error message / path name string space. */
    192197    char            szErrorMsg[4096];
     
    27852790
    27862791/**
    2787  * Verifies the process integrity.
    2788  */
    2789 DECLHIDDEN(void) supR3HardenedWinVerifyProcess(void)
    2790 {
    2791     RTErrInfoInitStatic(&g_ErrInfoStatic);
    2792     int rc = supHardenedWinVerifyProcess(NtCurrentProcess(), NtCurrentThread(),
    2793                                          SUPHARDNTVPKIND_VERIFY_ONLY, NULL /*pcFixes*/, &g_ErrInfoStatic.Core);
    2794     if (RT_FAILURE(rc))
    2795         supR3HardenedFatalMsg("supR3HardenedWinVerifyProcess", kSupInitOp_Integrity, rc,
    2796                               "Failed to verify process integrity: %s", g_ErrInfoStatic.szMsg);
    2797 }
    2798 
    2799 
    2800 /**
    28012792 * Gets the SID of the user associated with the process.
    28022793 *
     
    39033894    /* An error occurred, report it. */
    39043895    ChildProcParams.szErrorMsg[sizeof(ChildProcParams.szErrorMsg) - 1] = '\0';
    3905     supR3HardenedFatalMsg("supR3HardenedWinCheckChild", kSupInitOp_Misc, ChildProcParams.rc, "%s", ChildProcParams.szErrorMsg);
     3896    ChildProcParams.szWhere[sizeof(ChildProcParams.szWhere) - 1] = '\0';
     3897    SUP_DPRINTF(("supR3HardenedWinCheckChild: rc=%d enmWhat=%d %s: %s\n",
     3898                 ChildProcParams.rc, ChildProcParams.enmWhat, ChildProcParams.szWhere, ChildProcParams.szErrorMsg));
     3899
     3900    if (ChildProcParams.enmWhat == kSupInitOp_Invalid)
     3901        supR3HardenedFatalMsg("supR3HardenedWinCheckChild", kSupInitOp_Misc, ChildProcParams.rc,
     3902                              "%s", ChildProcParams.szErrorMsg);
     3903    else
     3904        supR3HardenedFatalMsg(ChildProcParams.szWhere, ChildProcParams.enmWhat, ChildProcParams.rc,
     3905                              "%s", ChildProcParams.szErrorMsg);
    39063906}
    39073907
     
    55455545 * Reports an error to the parent process via the process parameter structure.
    55465546 *
     5547 * @param   pszWhere            Where this error occured, if fatal message. NULL
     5548 *                              if not message.
     5549 * @param   enmWhat             Which init operation went wrong if fatal
     5550 *                              message. kSupInitOp_Invalid if not message.
    55475551 * @param   rc                  The status code to report.
    55485552 * @param   pszFormat           The format string.
    55495553 * @param   va                  The format arguments.
    55505554 */
    5551 DECLHIDDEN(void) supR3HardenedWinReportErrorToParent(int rc, const char *pszFormat, va_list va)
    5552 {
     5555DECLHIDDEN(void) supR3HardenedWinReportErrorToParent(const char *pszWhere, SUPINITOP enmWhat, int rc,
     5556                                                     const char *pszFormat, va_list va)
     5557{
     5558    if (pszWhere)
     5559        RTStrCopy(g_ProcParams.szWhere, sizeof(g_ProcParams.szWhere), pszWhere);
     5560    else
     5561        g_ProcParams.szWhere[0] = '\0';
    55535562    RTStrPrintfV(g_ProcParams.szErrorMsg, sizeof(g_ProcParams.szErrorMsg), pszFormat, va);
    5554     g_ProcParams.rc = RT_SUCCESS(rc) ? VERR_INTERNAL_ERROR_2 : rc;
     5563    g_ProcParams.enmWhat = enmWhat;
     5564    g_ProcParams.rc      = RT_SUCCESS(rc) ? VERR_INTERNAL_ERROR_2 : rc;
    55555565
    55565566    NTSTATUS rcNt = NtSetEvent(g_ProcParams.hEvtParent, NULL);
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