VirtualBox

Changeset 19398 in vbox


Ignore:
Timestamp:
May 5, 2009 9:05:11 PM (16 years ago)
Author:
vboxsync
Message:

GVMM: Address the GVMMR0GetVMByEMT issue and added access restrictions on gvmmR0ByVM (only same process).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR0/GVMMR0.cpp

    r19396 r19398  
    4545#include <VBox/vm.h>
    4646#include <VBox/vmm.h>
     47#include <VBox/param.h>
    4748#include <VBox/err.h>
    4849#include <iprt/alloc.h>
     
    5152#include <VBox/log.h>
    5253#include <iprt/thread.h>
     54#include <iprt/process.h>
    5355#include <iprt/param.h>
    5456#include <iprt/string.h>
     
    7981    /** The session this VM is associated with. */
    8082    PSUPDRVSESSION      pSession;
    81     /** The ring-0 handle of the EMT thread (VCPU 0).
    82      * This is used for assertions and similar cases where we need to find the VM handle. */
    83     RTNATIVETHREAD      hEMTCpu0;
     83    /** The ring-0 handle of the EMT0 thread.
     84     * This is used for ownership checks as well as looking up a VM handle by thread
     85     * at times like assertions. */
     86    RTNATIVETHREAD      hEMT0;
     87    /** The process ID of the handle owner.
     88     * This is used for access checks. */
     89    RTPROCESS           ProcId;
    8490} GVMHANDLE;
    8591/** Pointer to a global VM handle. */
     
    521527        return VERR_INVALID_PARAMETER;
    522528
    523     RTNATIVETHREAD hEMT = RTThreadNativeSelf();
    524     AssertReturn(hEMT != NIL_RTNATIVETHREAD, VERR_INTERNAL_ERROR);
     529    RTNATIVETHREAD hEMT0 = RTThreadNativeSelf();
     530    AssertReturn(hEMT0 != NIL_RTNATIVETHREAD, VERR_INTERNAL_ERROR);
     531    RTNATIVETHREAD ProcId = RTProcSelf();
     532    AssertReturn(ProcId != NIL_RTPROCESS, VERR_INTERNAL_ERROR);
    525533
    526534    /*
     
    561569                pHandle->pGVM     = NULL;
    562570                pHandle->pSession = pSession;
    563                 pHandle->hEMTCpu0 = NIL_RTNATIVETHREAD;
     571                pHandle->hEMT0    = NIL_RTNATIVETHREAD;
     572                pHandle->ProcId   = NIL_RTPROCESS;
    564573
    565574                gvmmR0UsedUnlock(pGVMM);
     
    641650                                        pHandle->pVM        = pVM;
    642651                                        pHandle->pGVM       = pGVM;
    643                                         pHandle->hEMTCpu0   = hEMT;
     652                                        pHandle->hEMT0      = hEMT0;
     653                                        pHandle->ProcId     = ProcId;
    644654                                        pGVM->pVM           = pVM;
    645                                         pGVM->aCpus[0].hEMT = hEMT;
     655                                        pGVM->aCpus[0].hEMT = hEMT0;
    646656
    647657                                        gvmmR0UsedUnlock(pGVMM);
     
    839849    AssertReturn(pHandle->pVM == pVM, VERR_NOT_OWNER);
    840850
     851    RTPROCESS      ProcId = RTProcSelf();
    841852    RTNATIVETHREAD hSelf = RTThreadNativeSelf();
    842     AssertReturn(pHandle->hEMTCpu0 == hSelf || pHandle->hEMTCpu0 == NIL_RTNATIVETHREAD, VERR_NOT_OWNER);
     853    AssertReturn(   (   pHandle->hEMT0  == hSelf
     854                     && pHandle->ProcId == ProcId)
     855                 || pHandle->hEMT0 == NIL_RTNATIVETHREAD, VERR_NOT_OWNER);
    843856
    844857    /*
     
    852865    /* be careful here because we might theoretically be racing someone else cleaning up. */
    853866    if (    pHandle->pVM == pVM
    854         &&  (   pHandle->hEMTCpu0 == hSelf
    855              || pHandle->hEMTCpu0 == NIL_RTNATIVETHREAD)
     867        &&  (   (   pHandle->hEMT0  == hSelf
     868                 && pHandle->ProcId == ProcId)
     869             || pHandle->hEMT0 == NIL_RTNATIVETHREAD)
    856870        &&  VALID_PTR(pHandle->pvObj)
    857871        &&  VALID_PTR(pHandle->pSession)
     
    867881    else
    868882    {
    869         SUPR0Printf("GVMMR0DestroyVM: pHandle=%p:{.pVM=%p, hEMTCpu0=%p, .pvObj=%p} pVM=%p hSelf=%p\n",
    870                     pHandle, pHandle->pVM, pHandle->hEMTCpu0, pHandle->pvObj, pVM, hSelf);
     883        SUPR0Printf("GVMMR0DestroyVM: pHandle=%p:{.pVM=%p, .hEMT0=%p, .ProcId=%u, .pvObj=%p} pVM=%p hSelf=%p\n",
     884                    pHandle, pHandle->pVM, pHandle->hEMT0, pHandle->ProcId, pHandle->pvObj, pVM, hSelf);
    871885        gvmmR0CreateDestroyUnlock(pGVMM);
    872886        rc = VERR_INTERNAL_ERROR;
     
    10491063    ASMAtomicXchgPtr((void * volatile *)&pHandle->pvObj, NULL);
    10501064    ASMAtomicXchgPtr((void * volatile *)&pHandle->pSession, NULL);
    1051     ASMAtomicXchgSize(&pHandle->hEMTCpu0, NIL_RTNATIVETHREAD);
     1065    ASMAtomicXchgSize(&pHandle->hEMT0, NIL_RTNATIVETHREAD);
     1066    ASMAtomicXchgSize(&pHandle->ProcId, NIL_RTPROCESS);
    10521067
    10531068    gvmmR0UsedUnlock(pGVMM);
     
    11201135/**
    11211136 * Lookup a GVM structure by the shared VM structure.
     1137 *
     1138 * The calling thread must be in the same process as the VM. All current lookups
     1139 * are by threads inside the same process, so this will not be an issue.
    11221140 *
    11231141 * @returns VBox status code.
     
    11331151static int gvmmR0ByVM(PVM pVM, PGVM *ppGVM, PGVMM *ppGVMM, bool fTakeUsedLock)
    11341152{
     1153    RTPROCESS ProcId = RTProcSelf();
    11351154    PGVMM pGVMM;
    11361155    GVMM_GET_VALID_INSTANCE(pGVMM, VERR_INTERNAL_ERROR);
     
    11631182        pGVM = pHandle->pGVM;
    11641183        if (RT_UNLIKELY(    pHandle->pVM != pVM
     1184                        ||  pHandle->ProcId != ProcId
    11651185                        ||  !VALID_PTR(pHandle->pvObj)
    11661186                        ||  !VALID_PTR(pGVM)
     
    11741194    {
    11751195        if (RT_UNLIKELY(pHandle->pVM != pVM))
     1196            return VERR_INVALID_HANDLE;
     1197        if (RT_UNLIKELY(pHandle->ProcId != ProcId))
    11761198            return VERR_INVALID_HANDLE;
    11771199        if (RT_UNLIKELY(!VALID_PTR(pHandle->pvObj)))
     
    12021224GVMMR0DECL(PGVM) GVMMR0ByVM(PVM pVM)
    12031225{
     1226    PGVM pGVM;
    12041227    PGVMM pGVMM;
    1205     PGVM pGVM;
    12061228    int rc = gvmmR0ByVM(pVM, &pGVM, &pGVMM, false /* fTakeUsedLock */);
    12071229    if (RT_SUCCESS(rc))
     
    12131235
    12141236/**
    1215  * Lookup a GVM structure by the shared VM structure
    1216  * and ensuring that the caller is the EMT thread.
     1237 * Lookup a GVM structure by the shared VM structure and ensuring that the
     1238 * caller is an EMT thread.
    12171239 *
    12181240 * @returns VBox status code.
     
    12451267    PGVMHANDLE pHandle = &pGVMM->aHandles[hGVM];
    12461268    AssertReturn(pHandle->pVM == pVM, VERR_NOT_OWNER);
     1269    RTPROCESS ProcId = RTProcSelf();
     1270    AssertReturn(pHandle->ProcId == ProcId, VERR_NOT_OWNER);
    12471271    AssertPtrReturn(pHandle->pvObj, VERR_INTERNAL_ERROR);
    12481272
     
    13151339    if (hEMT == NIL_RTNATIVETHREAD)
    13161340        hEMT = RTThreadNativeSelf();
     1341    RTPROCESS ProcId = RTProcSelf();
    13171342
    13181343    /*
     
    13221347    {
    13231348        if (    pGVMM->aHandles[i].iSelf == i
     1349            &&  pGVMM->aHandles[i].ProcId == ProcId
    13241350            &&  VALID_PTR(pGVMM->aHandles[i].pvObj)
    13251351            &&  VALID_PTR(pGVMM->aHandles[i].pVM)
    13261352            &&  VALID_PTR(pGVMM->aHandles[i].pGVM))
    13271353        {
    1328             if (pGVMM->aHandles[i].hEMTCpu0 == hEMT)
     1354            if (pGVMM->aHandles[i].hEMT0 == hEMT)
    13291355                return pGVMM->aHandles[i].pVM;
    13301356
    1331             /** @todo this isn't safe as GVM may be deallocated while we're running.
    1332              * Will change this to use RTPROCESS on the handle level as storing all the
    1333              * thread handles there doesn't scale very well. */
     1357            /* This is fearly safe with the current process per VM approach. */
    13341358            PGVM pGVM = pGVMM->aHandles[i].pGVM;
    1335             for (VMCPUID idCpu = 0; idCpu < pGVM->cCpus; idCpu++)
     1359            VMCPUID const cCpus = pGVM->cCpus;
     1360            if (    cCpus < 1
     1361                ||  cCpus > VMM_MAX_CPUS)
     1362                continue;
     1363            for (VMCPUID idCpu = 1; idCpu < cCpus; idCpu++)
    13361364                if (pGVM->aCpus[idCpu].hEMT == hEMT)
    13371365                    return pGVMM->aHandles[i].pVM;
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