VirtualBox

Changeset 36958 in vbox


Ignore:
Timestamp:
May 4, 2011 2:50:32 PM (14 years ago)
Author:
vboxsync
Message:

Main/linux/USB: better permissions checking and code cleanup

Location:
trunk/src/VBox
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/USBGetDevices.h

    r34341 r36958  
    7575RT_C_DECLS_BEGIN
    7676
    77 /** List of well-known USB device tree locations */
    78 typedef struct USBDEVTREELOCATION
    79 {
    80     /** The root of the device tree for this location. */
    81     char szDevicesRoot[256];
    82     /** Whether this location requires device enumeration using sysfs. */
    83     bool fUseSysfs;
    84 } USBDEVTREELOCATION, *PUSBDEVTREELOCATION;
    85 typedef const USBDEVTREELOCATION *PCUSBDEVTREELOCATION;
    86 
    8777/**
    88  * Get the USB device tree root
    89  * @param  fPreferSysfs  whether we wish to use sysfs over usbfs for
    90  *                       enumeration if we have the choice
    91  * @note   returns a pointer into a static array so it will stay valid
     78 * Check whether a USB device tree root is usable
     79 * @param pcszRoot        the path to the root of the device tree
     80 * @param fIsDeviceNodes  whether this is a device node (or usbfs) tree
     81 * @note  returns a pointer into a static array so it will stay valid
    9282 */
    93 extern PCUSBDEVTREELOCATION USBProxyLinuxGetDeviceRoot(bool fPreferSysfs);
     83extern bool USBProxyLinuxCheckDeviceRoot(const char *pcszRoot,
     84                                         bool fIsDeviceNodes);
    9485
    9586/**
     
    9788 * @a deviceFree or something equivalent.
    9889 * @param pcszDevicesRoot  the path to the root of the device tree
    99  * @param fUseSysfs       whether to use sysfs (or usbfs) for enumeration
     90 * @param fUseSysfs        whether to use sysfs (or usbfs) for enumeration
    10091 */
    10192extern PUSBDEVICE USBProxyLinuxGetDevices(const char *pcszDevicesRoot,
  • trunk/src/VBox/Main/src-server/linux/USBGetDevices.cpp

    r36417 r36958  
    9393    { "s",  1, 1000,       0 },
    9494    { "",   0,    0,       0 }  /* term */
    95 };
    96 
    97 /**
    98  * List of well-known USB device tree locations.
    99  */
    100 static const USBDEVTREELOCATION s_aTreeLocations[] =
    101 {
    102     { "/dev/vboxusb",  true },
    103     { "/proc/bus/usb", false },
    10495};
    10596
     
    14011392/** Is inotify available and working on this system?  This is a requirement
    14021393 * for using USB with sysfs */
    1403 /** @todo test the "inotify in glibc but not in the kernel" case. */
    14041394static bool inotifyAvailable(void)
    14051395{
     
    14161406}
    14171407
    1418 PCUSBDEVTREELOCATION USBProxyLinuxGetDeviceRoot(bool fPreferSysfs)
    1419 {
    1420     PCUSBDEVTREELOCATION pcBestUsbfs = NULL;
    1421     PCUSBDEVTREELOCATION pcBestSysfs = NULL;
    1422 
    1423     bool fHaveInotify = inotifyAvailable();
    1424     for (unsigned i = 0; i < RT_ELEMENTS(s_aTreeLocations); ++i)
    1425         if (!s_aTreeLocations[i].fUseSysfs)
    1426         {
    1427             if (!pcBestUsbfs)
    1428             {
    1429                 PUSBDEVICE pDevices;
    1430 
    1431                 pDevices = getDevicesFromUsbfs(s_aTreeLocations[i].szDevicesRoot,
    1432                                                true);
    1433                 if (pDevices)
    1434                 {
    1435                     pcBestUsbfs = &s_aTreeLocations[i];
    1436                     deviceListFree(&pDevices);
    1437                 }
    1438             }
    1439         }
    1440         else
    1441         {
    1442             if (   fHaveInotify
    1443                 && !pcBestSysfs
    1444                 && RTPathExists(s_aTreeLocations[i].szDevicesRoot))
    1445                 pcBestSysfs = &s_aTreeLocations[i];
    1446         }
    1447     if (pcBestUsbfs && !fPreferSysfs)
    1448         return pcBestUsbfs;
    1449     return pcBestSysfs;
     1408bool USBProxyLinuxCheckDeviceRoot(const char *pcszRoot, bool fIsDeviceNodes)
     1409{
     1410    bool fOK = false;
     1411    if (!fIsDeviceNodes)  /* usbfs */
     1412    {
     1413        PUSBDEVICE pDevices;
     1414
     1415        pDevices = getDevicesFromUsbfs(pcszRoot, true);
     1416        if (pDevices)
     1417        {
     1418            PUSBDEVICE pDevice;
     1419           
     1420            fOK = true;
     1421            for (pDevice = pDevices; pDevice && fOK; pDevice = pDevice->pNext)
     1422                if (access(pDevice->pszAddress, R_OK | W_OK))
     1423                    fOK = false;
     1424            deviceListFree(&pDevices);
     1425        }
     1426    }
     1427    else  /* device nodes */
     1428        if (inotifyAvailable() && !access(pcszRoot, R_OK | X_OK))
     1429            fOK = true;
     1430    return fOK;
    14501431}
    14511432
  • trunk/src/VBox/Main/src-server/linux/USBProxyServiceLinux.cpp

    r36727 r36958  
    3232#include <iprt/assert.h>
    3333#include <iprt/ctype.h>
     34#include <iprt/dir.h>
    3435#include <iprt/env.h>
    3536#include <iprt/file.h>
     
    8283    /*
    8384     * We have two methods available for getting host USB device data - using
    84      * USBFS and using sysfs/hal.  The default choice depends on build-time
     85     * USBFS and using sysfs.  The default choice depends on build-time
    8586     * settings and an environment variable; if the default is not available
    8687     * we fall back to the second.
     
    8889     * will be presented to the user.
    8990     */
    90 #ifdef VBOX_WITH_SYSFS_BY_DEFAULT
    91     bool fUseSysfs = true;
    92 #else
    93     bool fUseSysfs = false;
    94 #endif
     91    bool fUseSysfs;
    9592    const char *pcszUsbFromEnv = RTEnvGet("VBOX_USB");
    9693    const char *pcszUsbRoot = NULL;
     
    121118    if (!pcszUsbRoot)
    122119    {
    123         PCUSBDEVTREELOCATION pLocation;
    124         pLocation = USBProxyLinuxGetDeviceRoot(fUseSysfs);
    125         if (pLocation)
    126         {
    127             pcszUsbRoot = pLocation->szDevicesRoot;
    128             fUseSysfs = pLocation->fUseSysfs;
     120        if (USBProxyLinuxCheckDeviceRoot("/dev/vboxusb", true))
     121        {
     122            fUseSysfs = true;
     123            pcszUsbRoot = "/dev/vboxusb";
     124        }
     125        else if (USBProxyLinuxCheckDeviceRoot("/proc/bus/usb", false))
     126        {
     127            fUseSysfs = false;
     128            pcszUsbRoot = "/proc/bus/usb";
    129129        }
    130130    }
     
    141141    }
    142142    else
    143         mLastError = VERR_NOT_FOUND;
     143        /** @todo fix this, preferably in the next fifteen minutes. */
     144        mLastError =   RTDirExists("/dev/vboxusb") ? VERR_PERMISSION_DENIED
     145                     : RTFileExists("/proc/bus/usb/devices") ? VERR_VUSB_USBFS_PERMISSION
     146                     : VERR_NOT_FOUND;
    144147    return S_OK;
    145148}
  • trunk/src/VBox/Main/testcase/tstHostHardwareLinux.cpp

    r36348 r36958  
    128128        RTPrintf ("\n");
    129129    }
    130     PCUSBDEVTREELOCATION pcLocation = USBProxyLinuxGetDeviceRoot(false);
    131     if (pcLocation && !pcLocation->fUseSysfs)
     130    RTPrintf("NOTE: checking for usbfs at /dev/bus/usb, not /proc/bus/usb!!!\n");
     131    if (USBProxyLinuxCheckDeviceRoot("/dev/bus/usb", false))
    132132    {
    133         PUSBDEVICE pDevice = USBProxyLinuxGetDevices(pcLocation->szDevicesRoot,
     133        PUSBDEVICE pDevice = USBProxyLinuxGetDevices("/dev/bus/usb",
    134134                                                     false);
    135         printDevices(pDevice, pcLocation->szDevicesRoot, "usbfs");
     135        printDevices(pDevice, "/dev/bus/usb", "usbfs");
    136136        freeDevices(pDevice);
    137137    }
     138    else
     139        RTPrintf("-> not found\n");
    138140#ifdef VBOX_USB_WITH_SYSFS
    139     pcLocation = USBProxyLinuxGetDeviceRoot(true);
    140     if (pcLocation && pcLocation->fUseSysfs)
     141    RTPrintf("Testing for USB devices at /dev/vboxusb\n");
     142    if (USBProxyLinuxCheckDeviceRoot("/dev/vboxusb", true))
    141143    {
    142         PUSBDEVICE pDevice = USBProxyLinuxGetDevices(pcLocation->szDevicesRoot,
     144        PUSBDEVICE pDevice = USBProxyLinuxGetDevices("/dev/vboxusb",
    143145                                                     true);
    144         printDevices(pDevice, pcLocation->szDevicesRoot, "sysfs");
     146        printDevices(pDevice, "/dev/vboxusb", "sysfs");
    145147        freeDevices(pDevice);
    146148    }
    147     VBoxMainHotplugWaiter waiter(pcLocation->szDevicesRoot);
     149    else
     150        RTPrintf("-> not found\n");
     151    VBoxMainHotplugWaiter waiter("/dev/vboxusb");
    148152    RTPrintf ("Waiting for a hotplug event for five seconds...\n");
    149153    doHotplugEvent(&waiter, 5000);
  • trunk/src/VBox/Main/testcase/tstUSBProxyLinux.cpp

    r36419 r36958  
    6262}
    6363
    64 static USBDEVTREELOCATION s_deviceRoot = { "", false };
    65 static bool s_fGetDeviceRootPreferSysfs = false;
     64static const char *s_pcszDeviceRoot = "";
     65static bool s_fIsDeviceNodes = false;
    6666
    67 PCUSBDEVTREELOCATION USBProxyLinuxGetDeviceRoot(bool fPreferSysfs)
     67bool USBProxyLinuxCheckDeviceRoot(const char *pcszRoot,
     68                                  bool fIsDeviceNodes)
    6869{
    69     s_fGetDeviceRootPreferSysfs = fPreferSysfs;
    70     return &s_deviceRoot;
     70    return (   (!strcmp(s_pcszDeviceRoot, pcszRoot))
     71            && (s_fIsDeviceNodes == fIsDeviceNodes));
    7172}
    7273
     
    153154        else
    154155            RTEnvUnset("VBOX_USB_ROOT");
    155         strcpy(s_deviceRoot.szDevicesRoot,
    156                s_testEnvironment[i].pcszReturnedRoot);
    157         s_deviceRoot.fUseSysfs = s_testEnvironment[i].fReturnedUseSysfs;
     156        s_pcszDeviceRoot = s_testEnvironment[i].pcszReturnedRoot;
     157        s_fIsDeviceNodes = s_testEnvironment[i].fReturnedUseSysfs;
    158158        RTTESTI_CHECK(test.init() == S_OK);
    159159        test.getDevices();
  • trunk/src/VBox/RDP/client/vrdp/rdpusb.c

    r36409 r36958  
    888888rdpusb_init(void)
    889889{
    890         PCUSBDEVTREELOCATION pcLocation = USBProxyLinuxGetDeviceRoot(false);
    891         g_fUseSysfs       = pcLocation->fUseSysfs;
    892         g_pcszDevicesRoot = pcLocation->szDevicesRoot;
     890    /** @todo re-use the proxy service code */
     891        if (USBProxyLinuxCheckDeviceRoot("/dev/vboxusb", true))
     892        {
     893            g_fUseSysfs       = true;
     894            g_pcszDevicesRoot = "/dev/vboxusb";
     895        }
     896        else
     897        {
     898            g_fUseSysfs       = false;
     899            g_pcszDevicesRoot = "/proc/bus/usb";
     900        }
    893901        rdpusb_channel =
    894902                channel_register("vrdpusb", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,
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