VirtualBox

Changeset 38016 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Jul 18, 2011 1:06:11 PM (13 years ago)
Author:
vboxsync
Message:

USB/Solaris: vboxuser group access constraint for USB devices.

Location:
trunk/src/VBox
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/VBoxUSB/solaris/VBoxUSB-solaris.c

    r36341 r38016  
    286286    int                     fPoll;           /* Polling status flag */
    287287    RTPROCESS               Process;         /* The process (id) of the session */
     288    bool                    fInstanceOpen;   /* If the process is still holding this instance */
    288289    VBOXUSBREQ_CLIENT_INFO  ClientInfo;      /* Registration data */
    289290    vboxusb_power_t        *pPower;          /* Power Management */
     
    352353int VBoxUSBMonSolarisUnregisterClient(dev_info_t *pClientDip);
    353354
     355/** Callbacks from Monitor */
     356LOCAL int vboxUSBSolarisSetConsumerCredentials(RTPROCESS Process, int Instance, void *pvReserved);
     357
    354358
    355359/*******************************************************************************
     
    464468            {
    465469                pState = ddi_get_soft_state(g_pVBoxUSBSolarisState, instance);
    466                 if (pState)
     470                if (RT_LIKELY(pState))
    467471                {
    468472                    pState->pDip = pDip;
     
    477481                    pState->fPoll = VBOXUSB_POLL_OFF;
    478482                    pState->Process = NIL_RTPROCESS;
     483                    pState->fInstanceOpen = false;
    479484                    pState->pPower = NULL;
    480485
     
    568573                                                                szDevicePath);
    569574                                                    pState->ClientInfo.Instance = instance;
     575                                                    pState->ClientInfo.pfnSetConsumerCredentials = &vboxUSBSolarisSetConsumerCredentials;
    570576                                                    rc = VBoxUSBMonSolarisRegisterClient(pState->pDip, &pState->ClientInfo);
    571577                                                    if (RT_SUCCESS(rc))
     
    817823
    818824
     825/**
     826 * Callback invoked from the Monitor driver when a VM process tries to access
     827 * this client instance. This determines which VM process will be allowed to
     828 * open and access the USB device.
     829 *
     830 * @returns  VBox status code.
     831 *
     832 * @param    Process        The VM process performing the client info. query.
     833 * @param    Instance       This client instance (the one set while we register
     834 *                          ourselves to the Monitor driver)
     835 * @param    pvReserved     Reserved for future, unused.
     836 */
     837LOCAL int vboxUSBSolarisSetConsumerCredentials(RTPROCESS Process, int Instance, void *pvReserved)
     838{
     839    LogFlowFunc((DEVICE_NAME ":vboxUSBSolarisSetConsumerCredentials Process=%u Instance=%d\n", Process, Instance));
     840    vboxusb_state_t *pState = ddi_get_soft_state(g_pVBoxUSBSolarisState, Instance);
     841    if (!pState)
     842    {
     843        LogRel((DEVICE_NAME ":vboxUSBSolarisSetConsumerCredentials failed to get device state for instance %d\n", Instance));
     844        return VERR_INVALID_STATE;
     845    }
     846
     847    int rc = VINF_SUCCESS;
     848    mutex_enter(&pState->Mtx);
     849
     850    if (pState->fInstanceOpen == false)
     851        pState->Process = Process;
     852    else
     853    {
     854        LogRel((DEVICE_NAME ":vboxUSBSolarisSetConsumerCredentials failed! Process %u already has client open.\n", pState->Process));
     855        rc = VERR_RESOURCE_BUSY;
     856    }
     857
     858    mutex_exit(&pState->Mtx);
     859
     860    return rc;
     861}
     862
     863
    819864int VBoxUSBSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred)
    820865{
     
    838883    }
    839884
     885    mutex_enter(&pState->Mtx);
     886
    840887    /*
    841888     * Only one user process can open a device instance at a time.
    842889     */
    843     if (pState->Process != NIL_RTPROCESS)
     890    if (pState->fInstanceOpen == true)
    844891    {
    845892        LogRel((DEVICE_NAME ":VBoxUSBSolarisOpen a process is already using this device instance.\n"));
     
    847894    }
    848895
    849     pState->Process = RTProcSelf();
     896    if (pState->Process != RTProcSelf())
     897    {
     898        LogRel((DEVICE_NAME ":VBoxUSBSolarisOpen invalid process.\n"));
     899        return EPERM;
     900    }
     901
    850902    pState->fPoll = VBOXUSB_POLL_ON;
     903    pState->fInstanceOpen = true;
     904
     905    mutex_exit(&pState->Mtx);
    851906
    852907    NOREF(fFlag);
     
    872927    pState->fPoll = VBOXUSB_POLL_OFF;
    873928    pState->Process = NIL_RTPROCESS;
     929    pState->fInstanceOpen = false;
    874930    mutex_exit(&pState->Mtx);
    875931
     
    15701626    AssertPtrReturn(pEp, VERR_INVALID_POINTER);
    15711627
    1572 //    LogFlowFunc((DEVICE_NAME ":vboxUSBSolarisSendUrb pState=%p pUrbReq=%p bEndpoint=%#x[%d] enmDir=%#x enmType=%#x cbData=%d pvData=%p\n",
    1573 //            pState, pUrbReq, pUrbReq->bEndpoint, EndPtIndex, pUrbReq->enmDir, pUrbReq->enmType, pUrbReq->cbData, pUrbReq->pvData));
     1628    /* LogFlowFunc((DEVICE_NAME ":vboxUSBSolarisSendUrb pState=%p pUrbReq=%p bEndpoint=%#x[%d] enmDir=%#x enmType=%#x cbData=%d pvData=%p\n",
     1629            pState, pUrbReq, pUrbReq->bEndpoint, EndPtIndex, pUrbReq->enmDir, pUrbReq->enmType, pUrbReq->cbData, pUrbReq->pvData)); */
    15741630
    15751631    if (RT_UNLIKELY(!pUrbReq->pvData))
  • trunk/src/VBox/HostDrivers/VBoxUSB/solaris/VBoxUSBMon-solaris.c

    r36361 r38016  
    165165*******************************************************************************/
    166166/** Global Device handle we only support one instance. */
    167 static dev_info_t *g_pDip;
     167static dev_info_t *g_pDip = NULL;
    168168/** Global Mutex. */
    169169static kmutex_t g_VBoxUSBMonSolarisMtx;
     
    171171static uint64_t g_cVBoxUSBMonSolarisClient = 0;
    172172/** Global list of client drivers registered with us. */
    173 vboxusbmon_client_t *g_pVBoxUSBMonSolarisClients = 0;
     173vboxusbmon_client_t *g_pVBoxUSBMonSolarisClients = NULL;
    174174/** Opaque pointer to list of soft states. */
    175175static void *g_pVBoxUSBMonSolarisState;
     
    293293        case DDI_ATTACH:
    294294        {
    295             vboxusbmon_state_t *pState = NULL;
     295            if (RT_UNLIKELY(g_pDip))
     296            {
     297                LogRel((DEVICE_NAME ":VBoxUSBMonSolarisAttach global instance already initialized.\n"));
     298                return DDI_FAILURE;
     299            }
     300
     301            g_pDip = pDip;
    296302            int instance = ddi_get_instance(pDip);
    297             int rc;
    298 
    299             pState = RTMemAllocZ(sizeof(*pState));
    300             if (pState)
     303            int rc = ddi_create_priv_minor_node(pDip, DEVICE_NAME, S_IFCHR, instance, DDI_PSEUDO, 0,
     304                                                        "none", "none", 0660);
     305            if (rc == DDI_SUCCESS)
    301306            {
    302                 g_pDip = pDip;
    303                 rc = ddi_create_priv_minor_node(pDip, DEVICE_NAME, S_IFCHR, instance, DDI_PSEUDO, 0,
    304                                                             "none", "none", 0666);
    305                 if (rc == DDI_SUCCESS)
    306                 {
    307                     ddi_set_driver_private(pDip, pState);
    308                     ddi_report_dev(pDip);
    309                     return rc;
    310                 }
    311                 else
    312                     LogRel((DEVICE_NAME ":ddi_create_minor_node failed! rc=%d\n", rc));
    313                 RTMemFree(pState);
     307                ddi_report_dev(pDip);
     308                return rc;
    314309            }
    315310            else
    316                 LogRel((DEVICE_NAME ":RTMemAllocZ failed to allocated %d bytes for pState\n", sizeof(*pState)));
     311                LogRel((DEVICE_NAME ":VBoxUSBMonSolarisAttach ddi_create_minor_node failed! rc=%d\n", rc));
    317312            return DDI_FAILURE;
    318313        }
     
    359354            mutex_exit(&g_VBoxUSBMonSolarisMtx);
    360355
    361             vboxusbmon_state_t *pState = ddi_get_driver_private(g_pDip);
    362             if (pState)
    363             {
    364                 ddi_remove_minor_node(pDip, NULL);
    365                 RTMemFree(pState);
    366                 return DDI_SUCCESS;
    367             }
    368             else
    369                 LogRel((DEVICE_NAME ":failed to get soft state on detach.\n"));
    370             break;
     356            ddi_remove_minor_node(pDip, NULL);
     357            g_pDip = NULL;
     358            return DDI_SUCCESS;
    371359        }
    372360
     
    853841}
    854842
     843
     844/**
     845 * Query client driver information. This also has a side-effect that it informs
     846 * the client driver which upcoming VM process should be allowed to open it.
     847 *
     848 * @returns  VBox status code.
     849 * @param    pState         Pointer to the device state.
     850 * @param    pClientInfo    Pointer to the client info. object.
     851 */
    855852static int vboxUSBMonSolarisClientInfo(vboxusbmon_state_t *pState, PVBOXUSB_CLIENT_INFO pClientInfo)
    856853{
     
    870867            RTStrPrintf(pClientInfo->szClientPath, sizeof(pClientInfo->szClientPath), "%s", pCur->Info.szClientPath);
    871868
     869            /*
     870             * Inform the client driver that this is the client process that is going to open it. We can predict the future!
     871             */
     872            int rc;
     873            if (pCur->Info.pfnSetConsumerCredentials)
     874            {
     875                rc = pCur->Info.pfnSetConsumerCredentials(pState->Process, pCur->Info.Instance, NULL /* pvReserved */);
     876                if (RT_FAILURE(rc))
     877                    LogRel((DEVICE_NAME ":vboxUSBMonSolarisClientInfo pfnSetConsumerCredentials failed. rc=%d\n", rc));
     878            }
     879            else
     880                rc = VERR_INVALID_FUNCTION;
     881
    872882            mutex_exit(&g_VBoxUSBMonSolarisMtx);
    873883
    874             LogFlow((DEVICE_NAME ":vboxUSBMonSolarisClientInfo found. %s\n", pClientInfo->szDeviceIdent));
    875             return VINF_SUCCESS;
     884            LogFlow((DEVICE_NAME ":vboxUSBMonSolarisClientInfo found. %s rc=%d\n", pClientInfo->szDeviceIdent, rc));
     885            return rc;
    876886        }
    877887        pPrev = pCur;
     
    900910    if (RT_LIKELY(g_pDip))
    901911    {
    902         vboxusbmon_state_t *pState = ddi_get_driver_private(g_pDip);
    903 
    904         if (RT_LIKELY(pState))
    905         {
    906             vboxusbmon_client_t *pClient = RTMemAlloc(sizeof(vboxusbmon_client_t));
    907             if (RT_LIKELY(pClient))
    908             {
    909                 bcopy(pClientInfo, &pClient->Info, sizeof(pClient->Info));
    910                 pClient->pDip = pClientDip;
    911 
    912                 mutex_enter(&g_VBoxUSBMonSolarisMtx);
    913                 pClient->pNext = g_pVBoxUSBMonSolarisClients;
    914                 g_pVBoxUSBMonSolarisClients = pClient;
    915                 mutex_exit(&g_VBoxUSBMonSolarisMtx);
    916 
    917                 LogFlow((DEVICE_NAME ":VBoxUSBMonSolarisRegisterClient registered. %d %s %s\n",
    918                             pClient->Info.Instance, pClient->Info.szClientPath, pClient->Info.szDeviceIdent));
    919 
    920                 return VINF_SUCCESS;
    921             }
    922             else
    923                 return VERR_NO_MEMORY;
     912        vboxusbmon_client_t *pClient = RTMemAllocZ(sizeof(vboxusbmon_client_t));
     913        if (RT_LIKELY(pClient))
     914        {
     915            pClient->Info.Instance = pClientInfo->Instance;
     916            strncpy(pClient->Info.szClientPath, pClientInfo->szClientPath, sizeof(pClient->Info.szClientPath));
     917            strncpy(pClient->Info.szDeviceIdent, pClientInfo->szDeviceIdent, sizeof(pClient->Info.szDeviceIdent));
     918            pClient->Info.pfnSetConsumerCredentials = pClientInfo->pfnSetConsumerCredentials;
     919            pClient->pDip = pClientDip;
     920
     921            mutex_enter(&g_VBoxUSBMonSolarisMtx);
     922            pClient->pNext = g_pVBoxUSBMonSolarisClients;
     923            g_pVBoxUSBMonSolarisClients = pClient;
     924            mutex_exit(&g_VBoxUSBMonSolarisMtx);
     925
     926            LogFlow((DEVICE_NAME ":VBoxUSBMonSolarisRegisterClient registered. %d %s %s\n",
     927                        pClient->Info.Instance, pClient->Info.szClientPath, pClient->Info.szDeviceIdent));
     928
     929            return VINF_SUCCESS;
    924930        }
    925931        else
    926             return VERR_INTERNAL_ERROR;
     932            return VERR_NO_MEMORY;
    927933    }
    928934    else
    929         return VERR_INTERNAL_ERROR_2;
     935        return VERR_INVALID_STATE;
    930936}
    931937
     
    941947{
    942948    LogFlowFunc((DEVICE_NAME ":VBoxUSBMonSolarisUnregisterClient pClientDip=%p\n", pClientDip));
     949    AssertReturn(pClientDip, VERR_INVALID_PARAMETER);
    943950
    944951    if (RT_LIKELY(g_pDip))
    945952    {
    946         vboxusbmon_state_t *pState = ddi_get_driver_private(g_pDip);
    947 
    948         if (RT_LIKELY(pState))
    949         {
    950             mutex_enter(&g_VBoxUSBMonSolarisMtx);
    951 
    952             vboxusbmon_client_t *pCur = g_pVBoxUSBMonSolarisClients;
    953             vboxusbmon_client_t *pPrev = NULL;
    954             while (pCur)
     953        mutex_enter(&g_VBoxUSBMonSolarisMtx);
     954
     955        vboxusbmon_client_t *pCur = g_pVBoxUSBMonSolarisClients;
     956        vboxusbmon_client_t *pPrev = NULL;
     957        while (pCur)
     958        {
     959            if (pCur->pDip == pClientDip)
    955960            {
    956                 if (pCur->pDip == pClientDip)
    957                 {
    958                     if (pPrev)
    959                         pPrev->pNext = pCur->pNext;
    960                     else
    961                         g_pVBoxUSBMonSolarisClients = pCur->pNext;
    962 
    963                     mutex_exit(&g_VBoxUSBMonSolarisMtx);
    964 
    965                     LogFlow((DEVICE_NAME ":VBoxUSBMonSolarisUnregisterClient unregistered. %d %s %s\n",
    966                                 pCur->Info.Instance, pCur->Info.szClientPath, pCur->Info.szDeviceIdent));
    967                     RTMemFree(pCur);
    968                     pCur = NULL;
    969                     return VINF_SUCCESS;
    970                 }
    971                 pPrev = pCur;
    972                 pCur = pCur->pNext;
     961                if (pPrev)
     962                    pPrev->pNext = pCur->pNext;
     963                else
     964                    g_pVBoxUSBMonSolarisClients = pCur->pNext;
     965
     966                mutex_exit(&g_VBoxUSBMonSolarisMtx);
     967
     968                LogFlow((DEVICE_NAME ":VBoxUSBMonSolarisUnregisterClient unregistered. %d %s %s\n",
     969                            pCur->Info.Instance, pCur->Info.szClientPath, pCur->Info.szDeviceIdent));
     970                RTMemFree(pCur);
     971                pCur = NULL;
     972                return VINF_SUCCESS;
    973973            }
    974 
    975             mutex_exit(&g_VBoxUSBMonSolarisMtx);
    976 
    977             LogRel((DEVICE_NAME ":VBoxUSBMonSolarisUnregisterClient Failed to find registered client %p\n", pClientDip));
    978             return VERR_SEARCH_ERROR;
    979         }
    980         else
    981             return VERR_INTERNAL_ERROR;
     974            pPrev = pCur;
     975            pCur = pCur->pNext;
     976        }
     977
     978        mutex_exit(&g_VBoxUSBMonSolarisMtx);
     979
     980        LogRel((DEVICE_NAME ":VBoxUSBMonSolarisUnregisterClient Failed to find registered client %p\n", pClientDip));
     981        return VERR_NOT_FOUND;
    982982    }
    983983    else
    984         return VERR_INTERNAL_ERROR_2;
     984        return VERR_INVALID_STATE;
    985985}
    986986
  • trunk/src/VBox/Installer/solaris/vboxconfig.sh

    r37792 r38016  
    562562        # For VirtualBox 3.1 the new USB code requires Nevada > 123
    563563        if test "$HOST_OS_MINORVERSION" -gt 123; then
     564            # Add a group "vboxuser" (8-character limit) for USB access.
     565            # All users which need host USB-passthrough support will have to be added to this group.
     566            groupadd vboxuser >/dev/null 2>&1
     567
    564568            add_driver "$MOD_VBOXUSBMON" "$DESC_VBOXUSBMON" "$FATALOP" "not-$NULLOP" "'* 0666 root sys'"
    565569            load_module "drv/$MOD_VBOXUSBMON" "$DESC_VBOXUSBMON" "$FATALOP"
     570
     571            chown root:vboxuser "/devices/pseudo/vboxusbmon@0:vboxusbmon"
    566572
    567573            # Add vboxusbmon to devlink.tab
  • trunk/src/VBox/Main/src-server/solaris/USBProxyServiceSolaris.cpp

    r37599 r38016  
    161161}
    162162
    163 #if 0
    164 static int solarisWalkMinor(di_node_t Node, di_minor_t Minor, void *pvArg)
    165 {
    166     char *pszDevFsPath = di_devfs_path(Node);
    167     char *pszMinorName = di_minor_name(Minor);
    168     PUSBDEVICE pDev = (PUSBDEVICE)pvArg;
    169 
    170     AssertRelease(pDev);
    171 
    172     if (!pszDevFsPath || !pszMinorName)
    173         return DI_WALK_CONTINUE;
    174 
    175     RTStrAPrintf(&pDev->pszApId, "/devices%s:%s", pszDevFsPath, pszMinorName);
    176     di_devfs_path_free(pszDevFsPath);
    177 
    178     syslog(LOG_ERR, "VBoxUsbApId:%s\n", pDev->pszApId);
    179     return DI_WALK_TERMINATE;
    180 }
    181 
    182 static bool solarisGetApId(PUSBDEVICE pDev, char *pszDevicePath, di_node_t RootNode)
    183 {
    184     pDev->pszApId = NULL;
    185 
    186     /* Skip "/devices" prefix if any */
    187     char achDevicesDir[] = "/devices/";
    188     if (strncmp(pszDevicePath, achDevicesDir, sizeof(achDevicesDir)) == 0)
    189         pszDevicePath += sizeof(achDevicesDir);
    190 
    191     char *pszPhysical = RTStrDup(pszDevicePath);
    192     char *pszTmp = NULL;
    193 
    194     /* Remove dynamic component "::" if any */
    195     if ((pszTmp = strstr(pszPhysical, "::")) != NULL)
    196         *pszTmp = '\0';
    197 
    198     /* Remove minor name if any */
    199     if ((pszTmp = strrchr(pszPhysical, ':')) != NULL)
    200         *pszTmp = '\0';
    201 
    202     /* Walk device tree */
    203 //    di_node_t RootNode = di_init("/", DINFOCPYALL);
    204 //    if (RootNode != DI_NODE_NIL)
    205 //    {
    206 //        di_node_t MinorNode = di_lookup_node(RootNode, pszPhysical);
    207 //        if (MinorNode != DI_NODE_NIL)
    208         {
    209             di_walk_minor(RootNode, NULL, DI_CHECK_ALIAS | DI_CHECK_INTERNAL_PATH, pDev, solarisWalkMinor);
    210             return true;
    211         }
    212 //        di_fini(RootNode);
    213 //    }
    214 
    215     return false;
    216 }
    217 #endif
    218163
    219164static int solarisWalkDeviceNode(di_node_t Node, void *pvArg)
     
    316261                pCur->bPort = 0;
    317262
    318 #if 0
    319             /*
    320              * Obtain the dev_t of the device.
    321              */
    322             di_minor_t Minor = di_minor_next(Node, DI_MINOR_NIL);
    323             AssertBreak(Minor != DI_MINOR_NIL);
    324             dev_t DeviceNum = di_minor_devt(Minor);
    325 
    326             int DevInstance = 0;
    327             rc = solarisUSBGetInstance(pszDevicePath, &DevInstance);
    328 
    329             char szAddress[PATH_MAX + 128];
    330             RTStrPrintf(szAddress, sizeof(szAddress), "/dev/usb/%x.%x|%s", pCur->idVendor, pCur->idProduct, pszDevicePath);
    331             /* @todo after binding ugen we need to append the instance number to the address. Not yet sure how we can update PUSBDEVICE at that time. */
    332 
    333             pCur->pszAddress = RTStrDup(szAddress);
    334             AssertBreak(pCur->pszAddress);
    335 #endif
    336 
    337263            char pathBuf[PATH_MAX];
    338264            RTStrPrintf(pathBuf, sizeof(pathBuf), "%s", pszDevicePath);
     
    368294            pCur->enmState = solarisDetermineUSBDeviceState(pCur, Node);
    369295
    370 //            fValidDevice = solarisGetApId(pCur, pszDevicePath, Node);
    371             fValidDevice = true;
    372 
    373296            /*
    374297             * Valid device, add it to the list.
    375298             */
    376             if (fValidDevice)
    377             {
    378                 pCur->pPrev = pList->pTail;
    379                 if (pList->pTail)
    380                     pList->pTail = pList->pTail->pNext = pCur;
    381                 else
    382                     pList->pTail = pList->pHead = pCur;
    383             }
     299            fValidDevice = true;
     300            pCur->pPrev = pList->pTail;
     301            if (pList->pTail)
     302                pList->pTail = pList->pTail->pNext = pCur;
     303            else
     304                pList->pTail = pList->pHead = pCur;
     305
    384306            rc = DI_WALK_CONTINUE;
    385307        } while(0);
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