DECLASM(int) VBoxDrvIOCtlFast(uint16_t sfn, uint8_t iFunction) { /* * Find the session. */ const RTPROCESS Process = RTProcSelf(); const unsigned iHash = SESSION_HASH(sfn); PSUPDRVSESSION pSession; RTSpinlockAcquire(g_Spinlock); pSession = g_apSessionHashTab[iHash]; if (pSession && pSession->Process != Process) { do pSession = pSession->pNextHash; while ( pSession && ( pSession->sfn != sfn || pSession->Process != Process)); if (RT_LIKELY(pSession)) supdrvSessionRetain(pSession); } RTSpinlockReleaseNoInts(g_Spinlock); if (RT_UNLIKELY(!pSession)) { OSDBGPRINT(("VBoxDrvIoctl: WHUT?!? pSession == NULL! This must be a mistake... pid=%d\n", (int)Process)); return VERR_INVALID_PARAMETER; } /* * Dispatch the fast IOCtl. */ supdrvIOCtlFast(iFunction, 0, &g_DevExt, pSession); supdrvSessionRelease(pSession); return 0; }
/** * Device I/O Control entry point. * * @returns Darwin for slow IOCtls and VBox status code for the fast ones. * @param Dev The device number (major+minor). * @param iCmd The IOCtl command. * @param pData Pointer to the data (if any it's a VBOXGUESTIOCTLDATA (kernel copy)). * @param fFlags Flag saying we're a character device (like we didn't know already). * @param pProcess The process issuing this request. */ static int VbgdDarwinIOCtl(dev_t Dev, u_long iCmd, caddr_t pData, int fFlags, struct proc *pProcess) { //const bool fUnrestricted = minor(Dev) == 0; const RTPROCESS Process = proc_pid(pProcess); const unsigned iHash = SESSION_HASH(Process); PVBOXGUESTSESSION pSession; /* * Find the session. */ RTSpinlockAcquire(g_Spinlock); pSession = g_apSessionHashTab[iHash]; while (pSession && pSession->Process != Process && (/*later: pSession->fUnrestricted != fUnrestricted ||*/ !pSession->fOpened)) pSession = pSession->pNextHash; RTSpinlockRelease(g_Spinlock); if (!pSession) { Log(("VBoxDrvDarwinIOCtl: WHAT?!? pSession == NULL! This must be a mistake... pid=%d iCmd=%#lx\n", (int)Process, iCmd)); return EINVAL; } /* * No high speed IOCtls here yet. */ return VbgdDarwinIOCtlSlow(pSession, iCmd, pData, pProcess); }
/** * Device I/O Control entry point. * * @returns Darwin for slow IOCtls and VBox status code for the fast ones. * @param Dev The device number (major+minor). * @param iCmd The IOCtl command. * @param pData Pointer to the data (if any it's a SUPDRVIOCTLDATA (kernel copy)). * @param fFlags Flag saying we're a character device (like we didn't know already). * @param pProcess The process issuing this request. */ static int VBoxDrvDarwinIOCtl(dev_t Dev, u_long iCmd, caddr_t pData, int fFlags, struct proc *pProcess) { const bool fUnrestricted = minor(Dev) == 0; const RTPROCESS Process = proc_pid(pProcess); const unsigned iHash = SESSION_HASH(Process); PSUPDRVSESSION pSession; /* * Find the session. */ RTSpinlockAcquire(g_Spinlock); pSession = g_apSessionHashTab[iHash]; while (pSession && pSession->Process != Process && pSession->fUnrestricted == fUnrestricted && pSession->fOpened) pSession = pSession->pNextHash; RTSpinlockReleaseNoInts(g_Spinlock); if (!pSession) { OSDBGPRINT(("VBoxDrvDarwinIOCtl: WHAT?!? pSession == NULL! This must be a mistake... pid=%d iCmd=%#lx\n", (int)Process, iCmd)); return EINVAL; } /* * Deal with the two high-speed IOCtl that takes it's arguments from * the session and iCmd, and only returns a VBox status code. */ if ( ( iCmd == SUP_IOCTL_FAST_DO_RAW_RUN || iCmd == SUP_IOCTL_FAST_DO_HM_RUN || iCmd == SUP_IOCTL_FAST_DO_NOP) && fUnrestricted) return supdrvIOCtlFast(iCmd, *(uint32_t *)pData, &g_DevExt, pSession); return VBoxDrvDarwinIOCtlSlow(pSession, iCmd, pData, pProcess); }
DECLASM(int) VBoxDrvOpen(uint16_t sfn) { int rc; PSUPDRVSESSION pSession; /* * Create a new session. */ rc = supdrvCreateSession(&g_DevExt, true /* fUser */, true /*fUnrestricted*/, &pSession); if (RT_SUCCESS(rc)) { pSession->sfn = sfn; /* * Insert it into the hash table. */ unsigned iHash = SESSION_HASH(sfn); RTSpinlockAcquire(g_Spinlock); pSession->pNextHash = g_apSessionHashTab[iHash]; g_apSessionHashTab[iHash] = pSession; RTSpinlockReleaseNoInts(g_Spinlock); } Log(("VBoxDrvOpen: g_DevExt=%p pSession=%p rc=%d pid=%d\n", &g_DevExt, pSession, rc, (int)RTProcSelf())); return rc; }
/** * Driver ioctl, an alternate entry point for this character driver. * * @param Dev Device number * @param Cmd Operation identifier * @param pArg Arguments from user to driver * @param Mode Information bitfield (read/write, address space etc.) * @param pCred User credentials * @param pVal Return value for calling process. * * @return corresponding solaris error code. */ static int VBoxDrvSolarisIOCtl(dev_t Dev, int Cmd, intptr_t pArgs, int Mode, cred_t *pCred, int *pVal) { #ifndef USE_SESSION_HASH /* * Get the session from the soft state item. */ vbox_devstate_t *pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, getminor(Dev)); if (!pState) { LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtl: no state data for %#x (%d)\n", Dev, getminor(Dev))); return EINVAL; } PSUPDRVSESSION pSession = pState->pSession; if (!pSession) { LogRel((DEVICE_NAME ":VBoxDrvSolarisIOCtl: no session in state data for %#x (%d)\n", Dev, getminor(Dev))); return DDI_SUCCESS; } #else const RTPROCESS Process = RTProcSelf(); const unsigned iHash = SESSION_HASH(Process); PSUPDRVSESSION pSession; /* * Find the session. */ RTSpinlockAcquire(g_Spinlock); pSession = g_apSessionHashTab[iHash]; if (pSession && pSession->Process != Process) { do pSession = pSession->pNextHash; while (pSession && pSession->Process != Process); } RTSpinlockReleaseNoInts(g_Spinlock); if (!pSession) { LogRel((DEVICE_NAME ":VBoxSupDrvIOCtl: WHAT?!? pSession == NULL! This must be a mistake... pid=%d iCmd=%#x\n", (int)Process, Cmd)); return EINVAL; } #endif /* * Deal with the two high-speed IOCtl that takes it's arguments from * the session and iCmd, and only returns a VBox status code. */ if ( Cmd == SUP_IOCTL_FAST_DO_RAW_RUN || Cmd == SUP_IOCTL_FAST_DO_HWACC_RUN || Cmd == SUP_IOCTL_FAST_DO_NOP) { *pVal = supdrvIOCtlFast(Cmd, pArgs, &g_DevExt, pSession); return 0; } return VBoxDrvSolarisIOCtlSlow(pSession, Cmd, Mode, pArgs); }
/** * Device open. Called on open /dev/vboxguest and (later) /dev/vboxguestu. * * @param Dev The device number. * @param fFlags ???. * @param fDevType ???. * @param pProcess The process issuing this request. */ static int VbgdDarwinOpen(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess) { /* * Only two minor devices numbers are allowed. */ if (minor(Dev) != 0 && minor(Dev) != 1) return EACCES; /* * Find the session created by org_virtualbox_VBoxGuestClient, fail * if no such session, and mark it as opened. We set the uid & gid * here too, since that is more straight forward at this point. */ //const bool fUnrestricted = minor(Dev) == 0; int rc = VINF_SUCCESS; PVBOXGUESTSESSION pSession = NULL; kauth_cred_t pCred = kauth_cred_proc_ref(pProcess); if (pCred) { RTPROCESS Process = RTProcSelf(); unsigned iHash = SESSION_HASH(Process); RTSpinlockAcquire(g_Spinlock); pSession = g_apSessionHashTab[iHash]; while (pSession && pSession->Process != Process) pSession = pSession->pNextHash; if (pSession) { if (!pSession->fOpened) { pSession->fOpened = true; /*pSession->fUnrestricted = fUnrestricted; - later */ } else rc = VERR_ALREADY_LOADED; } else rc = VERR_GENERAL_FAILURE; RTSpinlockRelease(g_Spinlock); #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 kauth_cred_unref(&pCred); #else /* 10.4 */ /* The 10.4u SDK headers and 10.4.11 kernel source have inconsistent definitions of kauth_cred_unref(), so use the other (now deprecated) API for releasing it. */ kauth_cred_rele(pCred); #endif /* 10.4 */ } else rc = VERR_INVALID_PARAMETER; Log(("VbgdDarwinOpen: g_DevExt=%p pSession=%p rc=%d pid=%d\n", &g_DevExt, pSession, rc, proc_pid(pProcess))); return VbgdDarwinErr2DarwinErr(rc); }
DECLASM(int) VBoxDrvClose(uint16_t sfn) { Log(("VBoxDrvClose: pid=%d sfn=%d\n", (int)RTProcSelf(), sfn)); /* * Remove from the hash table. */ PSUPDRVSESSION pSession; const RTPROCESS Process = RTProcSelf(); const unsigned iHash = SESSION_HASH(sfn); RTSpinlockAcquire(g_Spinlock); pSession = g_apSessionHashTab[iHash]; if (pSession) { if ( pSession->sfn == sfn && pSession->Process == Process) { g_apSessionHashTab[iHash] = pSession->pNextHash; pSession->pNextHash = NULL; } else { PSUPDRVSESSION pPrev = pSession; pSession = pSession->pNextHash; while (pSession) { if ( pSession->sfn == sfn && pSession->Process == Process) { pPrev->pNextHash = pSession->pNextHash; pSession->pNextHash = NULL; break; } /* next */ pPrev = pSession; pSession = pSession->pNextHash; } } } RTSpinlockReleaseNoInts(g_Spinlock); if (!pSession) { OSDBGPRINT(("VBoxDrvIoctl: WHUT?!? pSession == NULL! This must be a mistake... pid=%d sfn=%d\n", (int)Process, sfn)); return VERR_INVALID_PARAMETER; } /* * Close the session. */ supdrvSessionRelease(pSession); return 0; }
static int VBoxDrvSolarisClose(dev_t Dev, int flag, int otyp, cred_t *cred) { LogFlowFunc(("VBoxDrvSolarisClose: Dev=%#x\n", Dev)); #ifndef USE_SESSION_HASH /* * Get the session and free the soft state item. */ vbox_devstate_t *pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, getminor(Dev)); if (!pState) { LogRel(("VBoxDrvSolarisClose: no state data for %#x (%d)\n", Dev, getminor(Dev))); return EFAULT; } PSUPDRVSESSION pSession = pState->pSession; pState->pSession = NULL; ddi_soft_state_free(g_pVBoxDrvSolarisState, getminor(Dev)); if (!pSession) { LogRel(("VBoxDrvSolarisClose: no session in state data for %#x (%d)\n", Dev, getminor(Dev))); return EFAULT; } LogFlow(("VBoxDrvSolarisClose: Dev=%#x pSession=%p pid=%d r0proc=%p thread=%p\n", Dev, pSession, RTProcSelf(), RTR0ProcHandleSelf(), RTThreadNativeSelf() )); #else const RTPROCESS Process = RTProcSelf(); const unsigned iHash = SESSION_HASH(Process); PSUPDRVSESSION pSession; /* * Remove from the hash table. */ RTSpinlockAcquire(g_Spinlock); pSession = g_apSessionHashTab[iHash]; if (pSession) { if (pSession->Process == Process) { g_apSessionHashTab[iHash] = pSession->pNextHash; pSession->pNextHash = NULL; } else { PSUPDRVSESSION pPrev = pSession; pSession = pSession->pNextHash; while (pSession) { if (pSession->Process == Process) { pPrev->pNextHash = pSession->pNextHash; pSession->pNextHash = NULL; break; } /* next */ pPrev = pSession; pSession = pSession->pNextHash; } } } RTSpinlockRelease(g_Spinlock); if (!pSession) { LogRel(("VBoxDrvSolarisClose: WHAT?!? pSession == NULL! This must be a mistake... pid=%d (close)\n", (int)Process)); return EFAULT; } #endif /* * Close the session. */ supdrvSessionRelease(pSession); return 0; }
/** * open() worker. */ static int VBoxDrvSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred) { const bool fUnrestricted = getminor(*pDev) == 0; PSUPDRVSESSION pSession; int rc; LogFlowFunc(("VBoxDrvSolarisOpen: pDev=%p:%#x\n", pDev, *pDev)); /* * Validate input */ if ( (getminor(*pDev) != 0 && getminor(*pDev) != 1) || fType != OTYP_CHR) return EINVAL; /* See mmopen for precedent. */ #ifndef USE_SESSION_HASH /* * Locate a new device open instance. * * For each open call we'll allocate an item in the soft state of the device. * The item index is stored in the dev_t. I hope this is ok... */ vbox_devstate_t *pState = NULL; unsigned iOpenInstance; for (iOpenInstance = 0; iOpenInstance < 4096; iOpenInstance++) { if ( !ddi_get_soft_state(g_pVBoxDrvSolarisState, iOpenInstance) /* faster */ && ddi_soft_state_zalloc(g_pVBoxDrvSolarisState, iOpenInstance) == DDI_SUCCESS) { pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, iOpenInstance); break; } } if (!pState) { LogRel(("VBoxDrvSolarisOpen: too many open instances.\n")); return ENXIO; } /* * Create a new session. */ rc = supdrvCreateSession(&g_DevExt, true /* fUser */, fUnrestricted, &pSession); if (RT_SUCCESS(rc)) { pSession->Uid = crgetruid(pCred); pSession->Gid = crgetrgid(pCred); pState->pSession = pSession; *pDev = makedevice(getmajor(*pDev), iOpenInstance); LogFlow(("VBoxDrvSolarisOpen: Dev=%#x pSession=%p pid=%d r0proc=%p thread=%p\n", *pDev, pSession, RTProcSelf(), RTR0ProcHandleSelf(), RTThreadNativeSelf() )); return 0; } /* failed - clean up */ ddi_soft_state_free(g_pVBoxDrvSolarisState, iOpenInstance); #else /* * Create a new session. * Sessions in Solaris driver are mostly useless. It's however needed * in VBoxDrvSolarisIOCtlSlow() while calling supdrvIOCtl() */ rc = supdrvCreateSession(&g_DevExt, true /* fUser */, fUnrestricted, &pSession); if (RT_SUCCESS(rc)) { unsigned iHash; pSession->Uid = crgetruid(pCred); pSession->Gid = crgetrgid(pCred); /* * Insert it into the hash table. */ # error "Only one entry per process!" iHash = SESSION_HASH(pSession->Process); RTSpinlockAcquire(g_Spinlock); pSession->pNextHash = g_apSessionHashTab[iHash]; g_apSessionHashTab[iHash] = pSession; RTSpinlockRelease(g_Spinlock); LogFlow(("VBoxDrvSolarisOpen success\n")); } int instance; for (instance = 0; instance < DEVICE_MAXINSTANCES; instance++) { vbox_devstate_t *pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, instance); if (pState) break; } if (instance >= DEVICE_MAXINSTANCES) { LogRel(("VBoxDrvSolarisOpen: All instances exhausted\n")); return ENXIO; } *pDev = makedevice(getmajor(*pDev), instance); #endif return VBoxSupDrvErr2SolarisErr(rc); }
/** * Device open. Called on open /dev/vboxdrv * * @param Dev The device number. * @param fFlags ???. * @param fDevType ???. * @param pProcess The process issuing this request. */ static int VBoxDrvDarwinOpen(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess) { #ifdef DEBUG_DARWIN_GIP char szName[128]; szName[0] = '\0'; proc_name(proc_pid(pProcess), szName, sizeof(szName)); Log(("VBoxDrvDarwinOpen: pid=%d '%s'\n", proc_pid(pProcess), szName)); #endif /* * Only two minor devices numbers are allowed. */ if (minor(Dev) != 0 && minor(Dev) != 1) return EACCES; /* * Find the session created by org_virtualbox_SupDrvClient, fail * if no such session, and mark it as opened. We set the uid & gid * here too, since that is more straight forward at this point. */ const bool fUnrestricted = minor(Dev) == 0; int rc = VINF_SUCCESS; PSUPDRVSESSION pSession = NULL; kauth_cred_t pCred = kauth_cred_proc_ref(pProcess); if (pCred) { #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 RTUID Uid = kauth_cred_getruid(pCred); RTGID Gid = kauth_cred_getrgid(pCred); #else RTUID Uid = pCred->cr_ruid; RTGID Gid = pCred->cr_rgid; #endif RTPROCESS Process = RTProcSelf(); unsigned iHash = SESSION_HASH(Process); RTSpinlockAcquire(g_Spinlock); pSession = g_apSessionHashTab[iHash]; while (pSession && pSession->Process != Process) pSession = pSession->pNextHash; if (pSession) { if (!pSession->fOpened) { pSession->fOpened = true; pSession->fUnrestricted = fUnrestricted; pSession->Uid = Uid; pSession->Gid = Gid; } else rc = VERR_ALREADY_LOADED; } else rc = VERR_GENERAL_FAILURE; RTSpinlockReleaseNoInts(g_Spinlock); #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 kauth_cred_unref(&pCred); #else /* 10.4 */ /* The 10.4u SDK headers and 10.4.11 kernel source have inconsistent definitions of kauth_cred_unref(), so use the other (now deprecated) API for releasing it. */ kauth_cred_rele(pCred); #endif /* 10.4 */ } else rc = VERR_INVALID_PARAMETER; #ifdef DEBUG_DARWIN_GIP OSDBGPRINT(("VBoxDrvDarwinOpen: pid=%d '%s' pSession=%p rc=%d\n", proc_pid(pProcess), szName, pSession, rc)); #else Log(("VBoxDrvDarwinOpen: g_DevExt=%p pSession=%p rc=%d pid=%d\n", &g_DevExt, pSession, rc, proc_pid(pProcess))); #endif return VBoxDrvDarwinErr2DarwinErr(rc); }
/** * Common worker for clientClose and VBoxDrvDarwinClose. */ /* static */ void org_virtualbox_SupDrvClient::sessionClose(RTPROCESS Process) { /* * Find the session and remove it from the hash table. * * Note! Only one session per process. (Both start() and * VBoxDrvDarwinOpen makes sure this is so.) */ const unsigned iHash = SESSION_HASH(Process); RTSpinlockAcquire(g_Spinlock); PSUPDRVSESSION pSession = g_apSessionHashTab[iHash]; if (pSession) { if (pSession->Process == Process) { g_apSessionHashTab[iHash] = pSession->pNextHash; pSession->pNextHash = NULL; ASMAtomicDecS32(&g_cSessions); } else { PSUPDRVSESSION pPrev = pSession; pSession = pSession->pNextHash; while (pSession) { if (pSession->Process == Process) { pPrev->pNextHash = pSession->pNextHash; pSession->pNextHash = NULL; ASMAtomicDecS32(&g_cSessions); break; } /* next */ pPrev = pSession; pSession = pSession->pNextHash; } } } RTSpinlockReleaseNoInts(g_Spinlock); if (!pSession) { Log(("SupDrvClient::sessionClose: pSession == NULL, pid=%d; freed already?\n", (int)Process)); return; } /* * Remove it from the client object. */ org_virtualbox_SupDrvClient *pThis = (org_virtualbox_SupDrvClient *)pSession->pvSupDrvClient; pSession->pvSupDrvClient = NULL; if (pThis) { Assert(pThis->m_pSession == pSession); pThis->m_pSession = NULL; } /* * Close the session. */ supdrvCloseSession(&g_DevExt, pSession); }
/** * Start the client service. */ bool org_virtualbox_SupDrvClient::start(IOService *pProvider) { LogFlow(("org_virtualbox_SupDrvClient::start([%p], %p) (cur pid=%d proc=%p)\n", this, pProvider, RTProcSelf(), RTR0ProcHandleSelf() )); AssertMsgReturn((RTR0PROCESS)m_Task == RTR0ProcHandleSelf(), ("%p %p\n", m_Task, RTR0ProcHandleSelf()), false); if (IOUserClient::start(pProvider)) { m_pProvider = OSDynamicCast(org_virtualbox_SupDrv, pProvider); if (m_pProvider) { Assert(!m_pSession); /* * Create a new session. */ int rc = supdrvCreateSession(&g_DevExt, true /* fUser */, false /*fUnrestricted*/, &m_pSession); if (RT_SUCCESS(rc)) { m_pSession->fOpened = false; /* The Uid, Gid and fUnrestricted fields are set on open. */ /* * Insert it into the hash table, checking that there isn't * already one for this process first. (One session per proc!) */ unsigned iHash = SESSION_HASH(m_pSession->Process); RTSpinlockAcquire(g_Spinlock); PSUPDRVSESSION pCur = g_apSessionHashTab[iHash]; if (pCur && pCur->Process != m_pSession->Process) { do pCur = pCur->pNextHash; while (pCur && pCur->Process != m_pSession->Process); } if (!pCur) { m_pSession->pNextHash = g_apSessionHashTab[iHash]; g_apSessionHashTab[iHash] = m_pSession; m_pSession->pvSupDrvClient = this; ASMAtomicIncS32(&g_cSessions); rc = VINF_SUCCESS; } else rc = VERR_ALREADY_LOADED; RTSpinlockReleaseNoInts(g_Spinlock); if (RT_SUCCESS(rc)) { Log(("org_virtualbox_SupDrvClient::start: created session %p for pid %d\n", m_pSession, (int)RTProcSelf())); return true; } LogFlow(("org_virtualbox_SupDrvClient::start: already got a session for this process (%p)\n", pCur)); supdrvCloseSession(&g_DevExt, m_pSession); } m_pSession = NULL; LogFlow(("org_virtualbox_SupDrvClient::start: rc=%Rrc from supdrvCreateSession\n", rc)); } else LogFlow(("org_virtualbox_SupDrvClient::start: %p isn't org_virtualbox_SupDrv\n", pProvider)); } return false; }
DECLASM(int) VBoxDrvIOCtl(uint16_t sfn, uint8_t iCat, uint8_t iFunction, void *pvParm, void *pvData, uint16_t *pcbParm, uint16_t *pcbData) { /* * Find the session. */ const RTPROCESS Process = RTProcSelf(); const unsigned iHash = SESSION_HASH(sfn); PSUPDRVSESSION pSession; RTSpinlockAcquire(g_Spinlock); pSession = g_apSessionHashTab[iHash]; if (pSession && pSession->Process != Process) { do pSession = pSession->pNextHash; while ( pSession && ( pSession->sfn != sfn || pSession->Process != Process)); if (RT_LIKELY(pSession)) supdrvSessionRetain(pSession); } RTSpinlockReleaseNoInts(g_Spinlock); if (!pSession) { OSDBGPRINT(("VBoxDrvIoctl: WHUT?!? pSession == NULL! This must be a mistake... pid=%d\n", (int)Process)); return VERR_INVALID_PARAMETER; } /* * Verify the category and dispatch the IOCtl. */ if (RT_LIKELY(iCat == SUP_CTL_CATEGORY)) { Log(("VBoxDrvIOCtl: pSession=%p iFunction=%#x pvParm=%p pvData=%p *pcbParm=%d *pcbData=%d\n", pSession, iFunction, pvParm, pvData, *pcbParm, *pcbData)); Assert(pvParm); Assert(!pvData); /* * Lock the header. */ PSUPREQHDR pHdr = (PSUPREQHDR)pvParm; AssertReturn(*pcbParm == sizeof(*pHdr), VERR_INVALID_PARAMETER); KernVMLock_t Lock; int rc = KernVMLock(VMDHL_WRITE, pHdr, *pcbParm, &Lock, (KernPageList_t *)-1, NULL); AssertMsgReturn(!rc, ("KernVMLock(VMDHL_WRITE, %p, %#x, &p, NULL, NULL) -> %d\n", pHdr, *pcbParm, &Lock, rc), VERR_LOCK_FAILED); /* * Validate the header. */ if (RT_LIKELY((pHdr->fFlags & SUPREQHDR_FLAGS_MAGIC_MASK) == SUPREQHDR_FLAGS_MAGIC)) { uint32_t cbReq = RT_MAX(pHdr->cbIn, pHdr->cbOut); if (RT_LIKELY( pHdr->cbIn >= sizeof(*pHdr) && pHdr->cbOut >= sizeof(*pHdr) && cbReq <= _1M*16)) { /* * Lock the rest of the buffer if necessary. */ if (((uintptr_t)pHdr & PAGE_OFFSET_MASK) + cbReq > PAGE_SIZE) { rc = KernVMUnlock(&Lock); AssertMsgReturn(!rc, ("KernVMUnlock(Lock) -> %#x\n", rc), VERR_LOCK_FAILED); rc = KernVMLock(VMDHL_WRITE, pHdr, cbReq, &Lock, (KernPageList_t *)-1, NULL); AssertMsgReturn(!rc, ("KernVMLock(VMDHL_WRITE, %p, %#x, &p, NULL, NULL) -> %d\n", pHdr, cbReq, &Lock, rc), VERR_LOCK_FAILED); } /* * Process the IOCtl. */ rc = supdrvIOCtl(iFunction, &g_DevExt, pSession, pHdr); } else { OSDBGPRINT(("VBoxDrvIOCtl: max(%#x,%#x); iCmd=%#x\n", pHdr->cbIn, pHdr->cbOut, iFunction)); rc = VERR_INVALID_PARAMETER; } } else { OSDBGPRINT(("VBoxDrvIOCtl: bad magic fFlags=%#x; iCmd=%#x\n", pHdr->fFlags, iFunction)); rc = VERR_INVALID_PARAMETER; } /* * Unlock and return. */ int rc2 = KernVMUnlock(&Lock); AssertMsg(!rc2, ("rc2=%d\n", rc2)); NOREF(rc2);s }