[Spice-commits] 2 commits - gtk/spice-util-priv.h gtk/usbutil.c

Marc-André Lureau elmarco at kemper.freedesktop.org
Wed Jul 11 06:13:15 PDT 2012


 gtk/spice-util-priv.h |    1 
 gtk/usbutil.c         |   89 +++++++++++++++++++++++++++++++++++---------------
 2 files changed, 65 insertions(+), 25 deletions(-)

New commits:
commit 748b42ecc4fffaf158c8355107f269a355955aa8
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date:   Wed Jul 11 14:41:26 2012 +0200

    usbutil: fix crash on windows
    
    vendor_count is the last access index, the actually count is +1.
    
    On Windows, it crashes later on because of corrupted memory.
    
    Thanks to valgrind for this precious help:
    
    ==4535== Invalid write of size 2
    ==4535==    at 0x40197E: spice_usbutil_parse_usbids (usbutil.c:170)
    ==4535==    by 0x401CEC: spice_usbutil_load_usbids (usbutil.c:241)
    ==4535==    by 0x4020C6: main (usbutil.c:322)
    ==4535==  Address 0x56b740c is 12 bytes after a block of size 348,160 alloc'd
    ==4535==    at 0x4A0884D: malloc (vg_replace_malloc.c:263)
    ==4535==    by 0x4EAAEBE: g_malloc (gmem.c:159)
    ==4535==    by 0x401847: spice_usbutil_parse_usbids (usbutil.c:156)
    ==4535==    by 0x401CEC: spice_usbutil_load_usbids (usbutil.c:241)
    ==4535==    by 0x4020C6: main (usbutil.c:322)
    ==4535==

diff --git a/gtk/usbutil.c b/gtk/usbutil.c
index 3bd7660..0649794 100644
--- a/gtk/usbutil.c
+++ b/gtk/usbutil.c
@@ -19,7 +19,9 @@
    License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */
 
-#include "config.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
 
 #include <glib-object.h>
 #include <glib/gi18n.h>
@@ -149,7 +151,7 @@ static gboolean spice_usbutil_parse_usbids(gchar *path)
         usbids_vendor_count++;
     }
 
-    usbids_vendor_info = g_new(usb_vendor_info, usbids_vendor_count);
+    usbids_vendor_info = g_new(usb_vendor_info, usbids_vendor_count + 1);
     product_info = g_new(usb_product_info, product_count);
 
     usbids_vendor_count = 0;
@@ -162,6 +164,7 @@ static gboolean spice_usbutil_parse_usbids(gchar *path)
         id = strtoul(line, &line, 16);
         while (isspace(line[0]))
             line++;
+
         usbids_vendor_info[usbids_vendor_count].vendor_id = id;
         snprintf(usbids_vendor_info[usbids_vendor_count].name,
                  VENDOR_NAME_LEN, "%s", line);
@@ -309,3 +312,13 @@ void spice_usb_util_get_device_strings(int bus, int address,
 }
 
 #endif
+
+#ifdef USBUTIL_TEST
+int main()
+{
+    if (spice_usbutil_load_usbids())
+        exit(0);
+
+    exit(1);
+}
+#endif
commit 2a54f19a64a3d4d661f63a7afa4d767b92b1f8c8
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date:   Wed Jul 11 13:22:12 2012 +0200

    usbutil: look up usb.ids under g_get_system_data_dirs() by default
    
    Simplify a little bit the portability by looking up usb.ids file
    under g_get_system_data_dirs(). This is how most resources are
    found under other OS, looking up files under various places, since
    installation location may vary.

diff --git a/gtk/spice-util-priv.h b/gtk/spice-util-priv.h
index 7449667..c2022a3 100644
--- a/gtk/spice-util-priv.h
+++ b/gtk/spice-util-priv.h
@@ -19,6 +19,7 @@
 #define SPICE_UTIL_PRIV_H
 
 #include <glib.h>
+#include "spice-util.h"
 
 G_BEGIN_DECLS
 
diff --git a/gtk/usbutil.c b/gtk/usbutil.c
index 704f973..3bd7660 100644
--- a/gtk/usbutil.c
+++ b/gtk/usbutil.c
@@ -36,8 +36,8 @@
 #include <sys/stat.h>
 #endif
 #include "usbutil.h"
+#include "spice-util-priv.h"
 
-#ifdef WITH_USBIDS
 #define VENDOR_NAME_LEN (122 - sizeof(void *))
 #define PRODUCT_NAME_LEN 126
 
@@ -53,10 +53,9 @@ typedef struct _usb_vendor_info {
     char name[VENDOR_NAME_LEN];
 } usb_vendor_info;
 
-GStaticMutex usbids_parse_mutex = G_STATIC_MUTEX_INIT;
-int usbids_vendor_count;
-usb_vendor_info *usbids_vendor_info;
-#endif
+static GStaticMutex usbids_load_mutex = G_STATIC_MUTEX_INIT;
+static int usbids_vendor_count;
+static usb_vendor_info *usbids_vendor_info;
 
 G_GNUC_INTERNAL
 const char *spice_usbutil_libusb_strerror(enum libusb_error error_code)
@@ -121,21 +120,17 @@ static gchar *spice_usbutil_get_sysfs_attribute(int bus, int address,
 }
 #endif
 
-#ifdef WITH_USBIDS
-static void spice_usbutil_parse_usbids(void)
+static gboolean spice_usbutil_parse_usbids(gchar *path)
 {
     gchar *contents, *line, **lines;
     usb_product_info *product_info;
     int i, j, id, product_count = 0;
 
-    g_static_mutex_lock(&usbids_parse_mutex);
-    if (usbids_vendor_count)
-        goto leave;
-
-    if (!g_file_get_contents(USB_IDS, &contents, NULL, NULL)) {
+    if (!g_file_get_contents(path, &contents, NULL, NULL)) {
         usbids_vendor_count = -1;
-        goto leave;
+        return FALSE;
     }
+
     lines = g_strsplit(contents, "\n", -1);
 
     for (i = 0; lines[i]; i++) {
@@ -165,7 +160,7 @@ static void spice_usbutil_parse_usbids(void)
             continue;
 
         id = strtoul(line, &line, 16);
-        while(isspace(line[0]))
+        while (isspace(line[0]))
             line++;
         usbids_vendor_info[usbids_vendor_count].vendor_id = id;
         snprintf(usbids_vendor_info[usbids_vendor_count].name,
@@ -182,7 +177,7 @@ static void spice_usbutil_parse_usbids(void)
                 continue;
 
             id = strtoul(line + 1, &line, 16);
-            while(isspace(line[0]))
+            while (isspace(line[0]))
                 line++;
             product_info[product_count].product_id = id;
             snprintf(product_info[product_count].name,
@@ -212,20 +207,52 @@ static void spice_usbutil_parse_usbids(void)
         }
     }
 #endif
-leave:
-    g_static_mutex_unlock(&usbids_parse_mutex);
+
+    return TRUE;
 }
+
+static gboolean spice_usbutil_load_usbids(void)
+{
+    gboolean success = FALSE;
+
+    g_static_mutex_lock(&usbids_load_mutex);
+    if (usbids_vendor_count) {
+        success = TRUE;
+        goto leave;
+    }
+
+#ifdef WITH_USBIDS
+    success = spice_usbutil_parse_usbids(USB_IDS);
+#else
+    {
+        const gchar * const *dirs = g_get_system_data_dirs();
+        gchar *path = NULL;
+        int i;
+
+        for (i = 0; dirs[i]; ++i) {
+            path = g_build_filename(dirs[i], "hwdata", "usb.ids", NULL);
+            success = spice_usbutil_parse_usbids(path);
+            SPICE_DEBUG("loading %s success: %s", path, spice_yes_no(success));
+            g_free(path);
+
+            if (success)
+                goto leave;
+        }
+    }
 #endif
 
+leave:
+    g_static_mutex_unlock(&usbids_load_mutex);
+    return success;
+}
+
 G_GNUC_INTERNAL
 void spice_usb_util_get_device_strings(int bus, int address,
                                        int vendor_id, int product_id,
                                        gchar **manufacturer, gchar **product)
 {
-#ifdef WITH_USBIDS
     usb_product_info *product_info;
     int i, j;
-#endif
 
     g_return_if_fail(manufacturer != NULL);
     g_return_if_fail(product != NULL);
@@ -238,9 +265,8 @@ void spice_usb_util_get_device_strings(int bus, int address,
     *product = spice_usbutil_get_sysfs_attribute(bus, address, "product");
 #endif
 
-#ifdef WITH_USBIDS
-    if (!*manufacturer || !*product) {
-        spice_usbutil_parse_usbids();
+    if ((!*manufacturer || !*product) &&
+        spice_usbutil_load_usbids()) {
 
         for (i = 0; i < usbids_vendor_count; i++) {
             if ((int)usbids_vendor_info[i].vendor_id != vendor_id)
@@ -262,7 +288,7 @@ void spice_usb_util_get_device_strings(int bus, int address,
             break;
         }
     }
-#endif
+
     if (!*manufacturer)
         *manufacturer = g_strdup(_("USB"));
     if (!*product)


More information about the Spice-commits mailing list