Changeset 68565 in vbox for trunk/src/VBox/Additions/common
- Timestamp:
- Aug 31, 2017 12:10:25 PM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 117782
- 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 49 49 #include <iprt/spinlock.h> 50 50 #include <iprt/semaphore.h> 51 #include <iprt/string.h> 51 52 #include <VBox/log.h> 52 53 … … 892 893 * keep them all up to date when making changes! 893 894 */ 894 int VBOXCALL VBoxGuestIDC(void *pvSession, uint 32_t uReq, PVBGLREQHDR pReq, size_t cbReq)895 int VBOXCALL VBoxGuestIDC(void *pvSession, uintptr_t uReq, PVBGLREQHDR pReqHdr, size_t cbReq) 895 896 { 896 897 /* … … 898 899 */ 899 900 int rc; 900 if ( RT_VALID_PTR(pReq )901 && cbReq >= sizeof(*pReq ))901 if ( RT_VALID_PTR(pReqHdr) 902 && cbReq >= sizeof(*pReqHdr)) 902 903 { 903 904 /* … … 909 910 if ( RT_VALID_PTR(pSession) 910 911 && pSession->pDevExt == &g_DevExt) 911 rc = VGDrvCommonIoCtl(uReq, &g_DevExt, pSession, pReq , cbReq);912 rc = VGDrvCommonIoCtl(uReq, &g_DevExt, pSession, pReqHdr, cbReq); 912 913 else 913 914 rc = VERR_INVALID_HANDLE; … … 918 919 if (RT_SUCCESS(rc)) 919 920 { 920 rc = VGDrvCommonIoCtl(uReq, &g_DevExt, pSession, pReq , cbReq);921 rc = VGDrvCommonIoCtl(uReq, &g_DevExt, pSession, pReqHdr, cbReq); 921 922 if (RT_FAILURE(rc)) 922 923 VGDrvCommonCloseSession(&g_DevExt, pSession); -
trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-solaris.c
r68550 r68565 69 69 static int vgdrvSolarisRead(dev_t Dev, struct uio *pUio, cred_t *pCred); 70 70 static 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); 71 static int vgdrvSolarisIOCtl(dev_t Dev, int iCmd, intptr_t pArg, int Mode, cred_t *pCred, int *pVal); 72 static int vgdrvSolarisIOCtlSlow(PVBOXGUESTSESSION pSession, int iCmd, int Mode, intptr_t pArgs); 72 73 static int vgdrvSolarisPoll(dev_t Dev, short fEvents, int fAnyYet, short *pReqEvents, struct pollhead **ppPollHead); 73 74 … … 596 597 597 598 598 /** @def IOCPARM_LEN599 * Gets the length from the ioctl number.600 * This is normally defined by sys/ioccom.h on BSD systems...601 */602 #ifndef IOCPARM_LEN603 # define IOCPARM_LEN(Code) (((Code) >> 16) & IOCPARM_MASK)604 #endif605 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 > -1000620 && 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 644 599 /** 645 600 * Driver ioctl, an alternate entry point for this character driver. 646 601 * 647 602 * @param Dev Device number 648 * @param CmdOperation identifier603 * @param iCmd Operation identifier 649 604 * @param pArg Arguments from user to driver 650 605 * @param Mode Information bitfield (read/write, address space etc.) … … 654 609 * @return corresponding solaris error code. 655 610 */ 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 611 static int vgdrvSolarisIOCtl(dev_t Dev, int iCmd, intptr_t pArgs, int Mode, cred_t *pCred, int *pVal) 612 { 660 613 /* 661 614 * Get the session from the soft state item. … … 664 617 if (!pState) 665 618 { 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))); 667 620 return EINVAL; 668 621 } … … 671 624 if (!pSession) 672 625 { 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 */ 662 static 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))); 674 680 return EINVAL; 675 681 } 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 } 676 701 677 702 /* 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. 679 707 */ 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); 688 720 if (RT_UNLIKELY(rc)) 689 721 { 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 } 733 727 734 728 /* 735 729 * Process the IOCtl. 736 730 */ 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 */ 739 736 if (RT_SUCCESS(rc)) 740 737 { 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; 756 750 } 757 751 } 758 752 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); 771 757 return rc; 772 758 } -
trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp
r68561 r68565 3978 3978 #if defined(VBOXGUEST_MOUSE_NOTIFY_CAN_PREEMPT) && !defined(RT_OS_WINDOWS) /* (Windows does this in the Dpc callback) */ 3979 3979 if ( fMousePositionChanged 3980 && pDevExt-> MouseNotifyCallback.pfnNotify)3981 pDevExt-> MouseNotifyCallback.pfnNotify(pDevExt->MouseNotifyCallback.pvUser);3980 && pDevExt->pfnMouseNotifyCallback) 3981 pDevExt->pfnMouseNotifyCallback(pDevExt->pvMouseNotifyCallbackArg); 3982 3982 #endif 3983 3983
Note:
See TracChangeset
for help on using the changeset viewer.