VirtualBox

Changeset 68565 in vbox for trunk/src/VBox/Additions/common


Ignore:
Timestamp:
Aug 31, 2017 12:10:25 PM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
117782
Message:

merging vbglioc r117730: solaris adjustments.

Location:
trunk/src/VBox/Additions/common/VBoxGuest
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-linux.c

    r68561 r68565  
    4949#include <iprt/spinlock.h>
    5050#include <iprt/semaphore.h>
     51#include <iprt/string.h>
    5152#include <VBox/log.h>
    5253
     
    892893 *       keep them all up to date when making changes!
    893894 */
    894 int VBOXCALL VBoxGuestIDC(void *pvSession, uint32_t uReq, PVBGLREQHDR pReq, size_t cbReq)
     895int VBOXCALL VBoxGuestIDC(void *pvSession, uintptr_t uReq, PVBGLREQHDR pReqHdr, size_t cbReq)
    895896{
    896897    /*
     
    898899     */
    899900    int rc;
    900     if (   RT_VALID_PTR(pReq)
    901         && cbReq >= sizeof(*pReq))
     901    if (   RT_VALID_PTR(pReqHdr)
     902        && cbReq >= sizeof(*pReqHdr))
    902903    {
    903904        /*
     
    909910            if (   RT_VALID_PTR(pSession)
    910911                && pSession->pDevExt == &g_DevExt)
    911                 rc = VGDrvCommonIoCtl(uReq, &g_DevExt, pSession, pReq, cbReq);
     912                rc = VGDrvCommonIoCtl(uReq, &g_DevExt, pSession, pReqHdr, cbReq);
    912913            else
    913914                rc = VERR_INVALID_HANDLE;
     
    918919            if (RT_SUCCESS(rc))
    919920            {
    920                 rc = VGDrvCommonIoCtl(uReq, &g_DevExt, pSession, pReq, cbReq);
     921                rc = VGDrvCommonIoCtl(uReq, &g_DevExt, pSession, pReqHdr, cbReq);
    921922                if (RT_FAILURE(rc))
    922923                    VGDrvCommonCloseSession(&g_DevExt, pSession);
  • trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-solaris.c

    r68550 r68565  
    6969static int vgdrvSolarisRead(dev_t Dev, struct uio *pUio, cred_t *pCred);
    7070static int vgdrvSolarisWrite(dev_t Dev, struct uio *pUio, cred_t *pCred);
    71 static int vgdrvSolarisIOCtl(dev_t Dev, int Cmd, intptr_t pArg, int Mode, cred_t *pCred, int *pVal);
     71static int vgdrvSolarisIOCtl(dev_t Dev, int iCmd, intptr_t pArg, int Mode, cred_t *pCred, int *pVal);
     72static int vgdrvSolarisIOCtlSlow(PVBOXGUESTSESSION pSession, int iCmd, int Mode, intptr_t pArgs);
    7273static int vgdrvSolarisPoll(dev_t Dev, short fEvents, int fAnyYet, short *pReqEvents, struct pollhead **ppPollHead);
    7374
     
    596597
    597598
    598 /** @def IOCPARM_LEN
    599  * Gets the length from the ioctl number.
    600  * This is normally defined by sys/ioccom.h on BSD systems...
    601  */
    602 #ifndef IOCPARM_LEN
    603 # define IOCPARM_LEN(Code)                      (((Code) >> 16) & IOCPARM_MASK)
    604 #endif
    605 
    606 
    607 /**
    608  * Converts a VBox status code to a Solaris error code.
    609  *
    610  * @returns corresponding Solaris errno.
    611  * @param   rcVBox        VirtualBox error code to convert.
    612  */
    613 static int vgdrvSolarisConvertToErrno(int rcVBox)
    614 {
    615     /* RTErrConvertToErrno() below will ring-0 debug assert if we don't do such stuff. */
    616     if (rcVBox == VERR_PERMISSION_DENIED)
    617         rcVBox = VERR_ACCESS_DENIED;
    618 
    619     if (   rcVBox > -1000
    620         && rcVBox < 1000)
    621         return RTErrConvertToErrno(rcVBox);
    622 
    623     switch (rcVBox)
    624     {
    625         case VERR_HGCM_SERVICE_NOT_FOUND:      return ESRCH;
    626         case VINF_HGCM_CLIENT_REJECTED:        return 0;
    627         case VERR_HGCM_INVALID_CMD_ADDRESS:    return EFAULT;
    628         case VINF_HGCM_ASYNC_EXECUTE:          return 0;
    629         case VERR_HGCM_INTERNAL:               return EPROTO;
    630         case VERR_HGCM_INVALID_CLIENT_ID:      return EINVAL;
    631         case VINF_HGCM_SAVE_STATE:             return 0;
    632         /* No reason to return this to a guest. */
    633         /* case VERR_HGCM_SERVICE_EXISTS:      return EEXIST; */
    634 
    635         default:
    636         {
    637             AssertMsgFailed(("Unhandled error code %Rrc\n", rcVBox));
    638             return EINVAL;
    639         }
    640     }
    641 }
    642 
    643 
    644599/**
    645600 * Driver ioctl, an alternate entry point for this character driver.
    646601 *
    647602 * @param   Dev             Device number
    648  * @param   Cmd             Operation identifier
     603 * @param   iCmd            Operation identifier
    649604 * @param   pArg            Arguments from user to driver
    650605 * @param   Mode            Information bitfield (read/write, address space etc.)
     
    654609 * @return  corresponding solaris error code.
    655610 */
    656 static int vgdrvSolarisIOCtl(dev_t Dev, int Cmd, intptr_t pArg, int Mode, cred_t *pCred, int *pVal)
    657 {
    658     LogFlow(("vgdrvSolarisIOCtl: iCmd=%#x\n", Cmd));
    659 
     611static int vgdrvSolarisIOCtl(dev_t Dev, int iCmd, intptr_t pArgs, int Mode, cred_t *pCred, int *pVal)
     612{
    660613    /*
    661614     * Get the session from the soft state item.
     
    664617    if (!pState)
    665618    {
    666         LogRel((DEVICE_NAME "::IOCtl: no state data for %d\n", getminor(Dev)));
     619        LogRel(("vgdrvSolarisIOCtl: no state data for %#x (%d)\n", Dev, getminor(Dev)));
    667620        return EINVAL;
    668621    }
     
    671624    if (!pSession)
    672625    {
    673         LogRel((DEVICE_NAME "::IOCtl: no session data for %d\n", getminor(Dev)));
     626        LogRel(("vgdrvSolarisIOCtl: no session in state data for %#x (%d)\n", Dev, getminor(Dev)));
     627        return DDI_SUCCESS;
     628    }
     629
     630    /*
     631     * Deal with fast requests.
     632     */
     633    if (VBGL_IOCTL_IS_FAST(iCmd))
     634    {
     635        *pVal = VGDrvCommonIoCtlFast(iCmd, &g_DevExt, pSession);
     636        return 0;
     637    }
     638
     639    return vgdrvSolarisIOCtlSlow(pSession, iCmd, Mode, pArgs);
     640}
     641
     642
     643/** @def IOCPARM_LEN
     644 * Gets the length from the ioctl number.
     645 * This is normally defined by sys/ioccom.h on BSD systems...
     646 */
     647#ifndef IOCPARM_LEN
     648# define IOCPARM_LEN(x)     ( ((x) >> 16) & IOCPARM_MASK )
     649#endif
     650
     651
     652/**
     653 * Worker for VBoxSupDrvIOCtl that takes the slow IOCtl functions.
     654 *
     655 * @returns Solaris errno.
     656 *
     657 * @param   pSession    The session.
     658 * @param   iCmd        The IOCtl command.
     659 * @param   Mode        Information bitfield (for specifying ownership of data)
     660 * @param   iArg        User space address of the request buffer.
     661 */
     662static int vgdrvSolarisIOCtlSlow(PVBOXGUESTSESSION pSession, int iCmd, int Mode, intptr_t iArg)
     663{
     664    int         rc;
     665    uint32_t    cbBuf = 0;
     666    union
     667    {
     668        VBGLREQHDR  Hdr;
     669        uint8_t     abBuf[64];
     670    }           StackBuf;
     671    PVBGLREQHDR  pHdr;
     672
     673
     674    /*
     675     * Read the header.
     676     */
     677    if (RT_UNLIKELY(IOCPARM_LEN(iCmd) != sizeof(StackBuf.Hdr)))
     678    {
     679        LogRel(("vgdrvSolarisIOCtlSlow: iCmd=%#x len %d expected %d\n", iCmd, IOCPARM_LEN(iCmd), sizeof(StackBuf.Hdr)));
    674680        return EINVAL;
    675681    }
     682    rc = ddi_copyin((void *)iArg, &StackBuf.Hdr, sizeof(StackBuf.Hdr), Mode);
     683    if (RT_UNLIKELY(rc))
     684    {
     685        LogRel(("vgdrvSolarisIOCtlSlow: ddi_copyin(,%#lx,) failed; iCmd=%#x. rc=%d\n", iArg, iCmd, rc));
     686        return EFAULT;
     687    }
     688    if (RT_UNLIKELY(StackBuf.Hdr.uVersion != VBGLREQHDR_VERSION))
     689    {
     690        LogRel(("vgdrvSolarisIOCtlSlow: bad header version %#x; iCmd=%#x\n", StackBuf.Hdr.uVersion, iCmd));
     691        return EINVAL;
     692    }
     693    cbBuf = RT_MAX(StackBuf.Hdr.cbIn, StackBuf.Hdr.cbOut);
     694    if (RT_UNLIKELY(   StackBuf.Hdr.cbIn < sizeof(StackBuf.Hdr)
     695                    || StackBuf.Hdr.cbOut < sizeof(StackBuf.Hdr)
     696                    || cbBuf > _1M*16))
     697    {
     698        LogRel(("vgdrvSolarisIOCtlSlow: max(%#x,%#x); iCmd=%#x\n", StackBuf.Hdr.cbIn, StackBuf.Hdr.cbOut, iCmd));
     699        return EINVAL;
     700    }
    676701
    677702    /*
    678      * Read and validate the request wrapper.
     703     * Buffer the request.
     704     *
     705     * Note! Common code revalidates the header sizes and version. So it's
     706     *       fine to read it once more.
    679707     */
    680     VBGLBIGREQ ReqWrap;
    681     if (IOCPARM_LEN(Cmd) != sizeof(ReqWrap))
    682     {
    683         LogRel((DEVICE_NAME "::IOCtl: bad request %#x size=%d expected=%d\n", Cmd, IOCPARM_LEN(Cmd), sizeof(ReqWrap)));
    684         return ENOTTY;
    685     }
    686 
    687     int rc = ddi_copyin((void *)pArg, &ReqWrap, sizeof(ReqWrap), Mode);
     708    if (cbBuf <= sizeof(StackBuf))
     709        pHdr = &StackBuf.Hdr;
     710    else
     711    {
     712        pHdr = RTMemTmpAlloc(cbBuf);
     713        if (RT_UNLIKELY(!pHdr))
     714        {
     715            LogRel(("vgdrvSolarisIOCtlSlow: failed to allocate buffer of %d bytes for iCmd=%#x.\n", cbBuf, iCmd));
     716            return ENOMEM;
     717        }
     718    }
     719    rc = ddi_copyin((void *)iArg, pHdr, cbBuf, Mode);
    688720    if (RT_UNLIKELY(rc))
    689721    {
    690         LogRel((DEVICE_NAME "::IOCtl: ddi_copyin failed to read header pArg=%p Cmd=%d. rc=%#x.\n", pArg, Cmd, rc));
    691         return EINVAL;
    692     }
    693 
    694     if (ReqWrap.u32Magic != VBGLBIGREQ_MAGIC)
    695     {
    696         LogRel((DEVICE_NAME "::IOCtl: bad magic %#x; pArg=%p Cmd=%#x.\n", ReqWrap.u32Magic, pArg, Cmd));
    697         return EINVAL;
    698     }
    699     if (RT_UNLIKELY(ReqWrap.cbData > _1M*16))
    700     {
    701         LogRel((DEVICE_NAME "::IOCtl: bad size %#x; pArg=%p Cmd=%#x.\n", ReqWrap.cbData, pArg, Cmd));
    702         return EINVAL;
    703     }
    704 
    705     /*
    706      * Read the request payload if any; requests like VBOXGUEST_IOCTL_CANCEL_ALL_WAITEVENTS have no data payload.
    707      */
    708     void *pvBuf = NULL;
    709     if (RT_LIKELY(ReqWrap.cbData > 0))
    710     {
    711         pvBuf = RTMemTmpAlloc(ReqWrap.cbData);
    712         if (RT_UNLIKELY(!pvBuf))
    713         {
    714             LogRel((DEVICE_NAME "::IOCtl: RTMemTmpAlloc failed to alloc %d bytes.\n", ReqWrap.cbData));
    715             return ENOMEM;
    716         }
    717 
    718         rc = ddi_copyin((void *)(uintptr_t)ReqWrap.pvDataR3, pvBuf, ReqWrap.cbData, Mode);
    719         if (RT_UNLIKELY(rc))
    720         {
    721             RTMemTmpFree(pvBuf);
    722             LogRel((DEVICE_NAME "::IOCtl: ddi_copyin failed; pvBuf=%p pArg=%p Cmd=%d. rc=%d\n", pvBuf, pArg, Cmd, rc));
    723             return EFAULT;
    724         }
    725         if (RT_UNLIKELY(!VALID_PTR(pvBuf)))
    726         {
    727             RTMemTmpFree(pvBuf);
    728             LogRel((DEVICE_NAME "::IOCtl: pvBuf invalid pointer %p\n", pvBuf));
    729             return EINVAL;
    730         }
    731     }
    732     Log(("vgdrvSolarisIOCtl: pSession=%p pid=%d.\n", pSession, (int)RTProcSelf()));
     722        LogRel(("vgdrvSolarisIOCtlSlow: copy_from_user(,%#lx, %#x) failed; iCmd=%#x. rc=%d\n", iArg, cbBuf, iCmd, rc));
     723        if (pHdr != &StackBuf.Hdr)
     724            RTMemFree(pHdr);
     725        return EFAULT;
     726    }
    733727
    734728    /*
    735729     * Process the IOCtl.
    736730     */
    737     size_t cbDataReturned = 0;
    738     rc = VGDrvCommonIoCtl(Cmd, &g_DevExt, pSession, pvBuf, ReqWrap.cbData, &cbDataReturned);
     731    rc = VGDrvCommonIoCtl(iCmd, &g_DevExt, pSession, pHdr, cbBuf);
     732
     733    /*
     734     * Copy ioctl data and output buffer back to user space.
     735     */
    739736    if (RT_SUCCESS(rc))
    740737    {
    741         rc = 0;
    742         if (RT_UNLIKELY(cbDataReturned > ReqWrap.cbData))
    743         {
    744             LogRel((DEVICE_NAME "::IOCtl: too much output data %d expected %d\n", cbDataReturned, ReqWrap.cbData));
    745             cbDataReturned = ReqWrap.cbData;
    746         }
    747         if (cbDataReturned > 0)
    748         {
    749             rc = ddi_copyout(pvBuf, (void *)(uintptr_t)ReqWrap.pvDataR3, cbDataReturned, Mode);
    750             if (RT_UNLIKELY(rc))
    751             {
    752                 LogRel((DEVICE_NAME "::IOCtl: ddi_copyout failed; pvBuf=%p pArg=%p cbDataReturned=%u Cmd=%d. rc=%d\n",
    753                         pvBuf, pArg, cbDataReturned, Cmd, rc));
    754                 rc = EFAULT;
    755             }
     738        uint32_t cbOut = pHdr->cbOut;
     739        if (RT_UNLIKELY(cbOut > cbBuf))
     740        {
     741            LogRel(("vgdrvSolarisIOCtlSlow: too much output! %#x > %#x; iCmd=%#x!\n", cbOut, cbBuf, iCmd));
     742            cbOut = cbBuf;
     743        }
     744        rc = ddi_copyout(pHdr, (void *)iArg, cbOut, Mode);
     745        if (RT_UNLIKELY(rc != 0))
     746        {
     747            /* this is really bad */
     748            LogRel(("vgdrvSolarisIOCtlSlow: ddi_copyout(,%p,%d) failed. rc=%d\n", (void *)iArg, cbBuf, rc));
     749            rc = EFAULT;
    756750        }
    757751    }
    758752    else
    759     {
    760         /*
    761          * We Log() instead of LogRel() here because VBOXGUEST_IOCTL_WAITEVENT can return VERR_TIMEOUT,
    762          * VBOXGUEST_IOCTL_CANCEL_ALL_EVENTS can return VERR_INTERRUPTED and possibly more in the future;
    763          * which are not really failures that require logging.
    764          */
    765         Log(("vgdrvSolarisIOCtl: VGDrvCommonIoCtl failed. Cmd=%#x rc=%d\n", Cmd, rc));
    766         rc = vgdrvSolarisConvertToErrno(rc);
    767     }
    768     *pVal = rc;
    769     if (pvBuf)
    770         RTMemTmpFree(pvBuf);
     753        rc = EINVAL;
     754
     755    if (pHdr != &StackBuf.Hdr)
     756        RTMemTmpFree(pHdr);
    771757    return rc;
    772758}
  • trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp

    r68561 r68565  
    39783978#if defined(VBOXGUEST_MOUSE_NOTIFY_CAN_PREEMPT) && !defined(RT_OS_WINDOWS) /* (Windows does this in the Dpc callback) */
    39793979    if (   fMousePositionChanged
    3980         && pDevExt->MouseNotifyCallback.pfnNotify)
    3981         pDevExt->MouseNotifyCallback.pfnNotify(pDevExt->MouseNotifyCallback.pvUser);
     3980        && pDevExt->pfnMouseNotifyCallback)
     3981        pDevExt->pfnMouseNotifyCallback(pDevExt->pvMouseNotifyCallbackArg);
    39823982#endif
    39833983
Note: See TracChangeset for help on using the changeset viewer.

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