[Spice-commits] src/channel-usbredir.c

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Aug 22 08:14:03 UTC 2018


 src/channel-usbredir.c |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

New commits:
commit 558c967ecd230fa6ddde553f6206b1bfd86b40e7
Author: Jorge Olmos <jorge.olmos at flexvdi.com>
Date:   Fri Aug 17 15:12:35 2018 +0200

    Avoid passing libusb functions as callbacks
    
    When building spice-gtk for windows:
    - libusb uses __stdcall calling convention when compiled for win32. It does
    not include an option to be compiled with __cdecl calling convention.
    Directly calling libusb functions works fine. But it is a problem when its
    functions are passed as callbacks to a function that expects other calling
    convention.
    - glib uses __cdecl calling convention and expects the functions it
    receives as parameters to follow __cdecl convention.
    
    So the lines included in spice-gtk like:
         g_clear_pointer(&priv->device, libusb_unref_device);
    cause libusb_unref_device (compiled with _stdcall convention) to be called
    with __cdecl convention. This causes stack corruption, and hence crashes.
    
    Related: https://gitlab.gnome.org/GNOME/glib/issues/1494
    Acked-by: Victor Toso <victortoso at redhat.com>

diff --git a/src/channel-usbredir.c b/src/channel-usbredir.c
index 6ffe546..1d9c380 100644
--- a/src/channel-usbredir.c
+++ b/src/channel-usbredir.c
@@ -352,7 +352,8 @@ static void spice_usbredir_channel_open_acl_cb(
         spice_usbredir_channel_open_device(channel, &err);
     }
     if (err) {
-        g_clear_pointer(&priv->device, libusb_unref_device);
+        libusb_unref_device(priv->device);
+        priv->device = NULL;
         g_boxed_free(spice_usb_device_get_type(), priv->spice_device);
         priv->spice_device = NULL;
         priv->state  = STATE_DISCONNECTED;
@@ -383,7 +384,8 @@ _open_device_async_cb(GTask *task,
     spice_usbredir_channel_lock(channel);
 
     if (!spice_usbredir_channel_open_device(channel, &err)) {
-        g_clear_pointer(&priv->device, libusb_unref_device);
+        libusb_unref_device(priv->device);
+        priv->device = NULL;
         g_boxed_free(spice_usb_device_get_type(), priv->spice_device);
         priv->spice_device = NULL;
     }
@@ -504,7 +506,8 @@ void spice_usbredir_channel_disconnect_device(SpiceUsbredirChannel *channel)
 
         /* This also closes the libusb handle we passed from open_device */
         usbredirhost_set_device(priv->host, NULL);
-        g_clear_pointer(&priv->device, libusb_unref_device);
+        libusb_unref_device(priv->device);
+        priv->device = NULL;
         g_boxed_free(spice_usb_device_get_type(), priv->spice_device);
         priv->spice_device = NULL;
         priv->state  = STATE_DISCONNECTED;


More information about the Spice-commits mailing list