diff --git a/.gitignore b/.gitignore index d71b4b7..d47ad7b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/spice-gtk-0.26.tar.bz2 +SOURCES/spice-gtk-0.31.tar.bz2 diff --git a/.spice-gtk.metadata b/.spice-gtk.metadata index 37bdda9..44b5e33 100644 --- a/.spice-gtk.metadata +++ b/.spice-gtk.metadata @@ -1 +1 @@ -c84ffe620cc5b7c9f91ffaef4e4371636b472fa1 SOURCES/spice-gtk-0.26.tar.bz2 +949d99191fae7c5f4e54a303384616ce2c40162f SOURCES/spice-gtk-0.31.tar.bz2 diff --git a/SOURCES/0001-display-Lower-level-of-warning-for-empty-monitor-con.patch b/SOURCES/0001-display-Lower-level-of-warning-for-empty-monitor-con.patch new file mode 100644 index 0000000..917c3f6 --- /dev/null +++ b/SOURCES/0001-display-Lower-level-of-warning-for-empty-monitor-con.patch @@ -0,0 +1,37 @@ +From bfdde4d94759666c2bd2da5632620e95da8c9214 Mon Sep 17 00:00:00 2001 +From: Pavel Grunt +Date: Wed, 16 Mar 2016 14:46:51 +0100 +Subject: [PATCH 1/5] display: Lower level of warning for empty monitor config + +It is a valid case when a guest requests to turn off monitors, eg: + xrandr --output Virtual-0 --off + +Related: +https://bugzilla.redhat.com/show_bug.cgi?id=1061942 + +Acked-by: Frediano Ziglio +(cherry picked from commit c0c721bbaae50d3ad1991d22df1c4397f24f7acb) +--- + src/channel-display.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/src/channel-display.c b/src/channel-display.c +index 442642a..0ae84a0 100644 +--- a/src/channel-display.c ++++ b/src/channel-display.c +@@ -1846,7 +1846,11 @@ static void display_handle_monitors_config(SpiceChannel *channel, SpiceMsgIn *in + guint i; + + g_return_if_fail(config != NULL); +- g_return_if_fail(config->count > 0); ++ ++ if (config->count == 0) { ++ CHANNEL_DEBUG(channel, "received empty monitor config"); ++ return; ++ } + + CHANNEL_DEBUG(channel, "received new monitors config from guest: n: %d/%d", config->count, config->max_allowed); + +-- +2.8.1 + diff --git a/SOURCES/0001-smartcard-connect-object-signal-handlers-with-spice-.patch b/SOURCES/0001-smartcard-connect-object-signal-handlers-with-spice-.patch deleted file mode 100644 index 7c2a4db..0000000 --- a/SOURCES/0001-smartcard-connect-object-signal-handlers-with-spice-.patch +++ /dev/null @@ -1,43 +0,0 @@ -From b9b9a6913a7322610869307442e82eaee41cbefa Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= -Date: Tue, 24 Mar 2015 18:57:53 +0100 -Subject: [PATCH] smartcard: connect object signal handlers with spice helper - -The smartcard manager may outlive the smartcard channels. Make sure the -channel handlers are disconnected when the channel is free by using -spice_g_signal_connect_object() helper. This fixes crashes when -dispatching smartcard events on deleted channels. - -Related bug: -https://bugzilla.redhat.com/show_bug.cgi?id=1205171 ---- - gtk/channel-smartcard.c | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - -diff --git a/gtk/channel-smartcard.c b/gtk/channel-smartcard.c -index d27360c..627b9aa 100644 ---- a/gtk/channel-smartcard.c -+++ b/gtk/channel-smartcard.c -@@ -140,14 +140,14 @@ static void spice_smartcard_channel_constructed(GObject *object) - SpiceSmartcardChannel *channel = SPICE_SMARTCARD_CHANNEL(object); - SpiceSmartcardManager *manager = spice_smartcard_manager_get(); - -- g_signal_connect(G_OBJECT(manager), "reader-added", -- (GCallback)reader_added_cb, channel); -- g_signal_connect(G_OBJECT(manager), "reader-removed", -- (GCallback)reader_removed_cb, channel); -- g_signal_connect(G_OBJECT(manager), "card-inserted", -- (GCallback)card_inserted_cb, channel); -- g_signal_connect(G_OBJECT(manager), "card-removed", -- (GCallback)card_removed_cb, channel); -+ spice_g_signal_connect_object(G_OBJECT(manager), "reader-added", -+ (GCallback)reader_added_cb, channel, 0); -+ spice_g_signal_connect_object(G_OBJECT(manager), "reader-removed", -+ (GCallback)reader_removed_cb, channel, 0); -+ spice_g_signal_connect_object(G_OBJECT(manager), "card-inserted", -+ (GCallback)card_inserted_cb, channel, 0); -+ spice_g_signal_connect_object(G_OBJECT(manager), "card-removed", -+ (GCallback)card_removed_cb, channel, 0); - } - #endif - diff --git a/SOURCES/0002-fix-16-bpp-LZ-image-decompression.patch b/SOURCES/0002-fix-16-bpp-LZ-image-decompression.patch new file mode 100644 index 0000000..76a8a17 --- /dev/null +++ b/SOURCES/0002-fix-16-bpp-LZ-image-decompression.patch @@ -0,0 +1,165 @@ +From e8d016187810f9c038370da14c24d744ed250e14 Mon Sep 17 00:00:00 2001 +From: Frediano Ziglio +Date: Thu, 14 Apr 2016 17:56:40 +0100 +Subject: [PATCH 2/5] fix 16 bpp LZ image decompression + +LZ image decompression was broken for 16 bpp: +- stride was computed not computed correctly (as width*4). This caused + also a buffer underflow; +- stride in pixman is always multiple of 4 bytes (so for 16 bpp is + ALIGN(width*2, 4)) so image decompressed by lz_decode as some missing + bytes to be fixed. + +The alignment code is reused from LZ4 function. + +This fix also https://bugzilla.redhat.com/show_bug.cgi?id=1285469. + +Signed-off-by: Frediano Ziglio +Acked-by: Pavel Grunt +--- + spice-common/common/canvas_base.c | 54 +++++++++++++++++++++++---------------- + 1 file changed, 32 insertions(+), 22 deletions(-) + +diff --git a/spice-common/common/canvas_base.c b/spice-common/common/canvas_base.c +index fa4d373..45dd75f 100644 +--- a/spice-common/common/canvas_base.c ++++ b/spice-common/common/canvas_base.c +@@ -515,13 +515,30 @@ static pixman_image_t *canvas_get_jpeg(CanvasBase *canvas, SpiceImage *image) + return surface; + } + ++static void canvas_fix_alignment(uint8_t *bits, ++ int stride_encoded, int stride_pixman, ++ int height) ++{ ++ if (stride_pixman > stride_encoded) { ++ // Fix the row alignment ++ int row; ++ uint8_t *dest = bits; ++ for (row = height - 1; row > 0; --row) { ++ uint32_t *dest_aligned, *dest_misaligned; ++ dest_aligned = (uint32_t *)(dest + stride_pixman*row); ++ dest_misaligned = (uint32_t*)(dest + stride_encoded*row); ++ memmove(dest_aligned, dest_misaligned, stride_encoded); ++ } ++ } ++} ++ + #ifdef USE_LZ4 + static pixman_image_t *canvas_get_lz4(CanvasBase *canvas, SpiceImage *image) + { + pixman_image_t *surface = NULL; + int dec_size, enc_size, available; + int stride, stride_abs, stride_encoded; +- uint8_t *dest, *data, *data_end; ++ uint8_t *dest, *data, *data_end, *bits; + int width, height, top_down; + LZ4_streamDecode_t *stream; + uint8_t spice_format; +@@ -576,6 +593,7 @@ static pixman_image_t *canvas_get_lz4(CanvasBase *canvas, SpiceImage *image) + if (!top_down) { + dest -= (stride_abs * (height - 1)); + } ++ bits = dest; + + do { + // Read next compressed block +@@ -594,20 +612,7 @@ static pixman_image_t *canvas_get_lz4(CanvasBase *canvas, SpiceImage *image) + data += enc_size; + } while (data < data_end); + +- if (stride_abs > stride_encoded) { +- // Fix the row alignment +- int row; +- dest = (uint8_t *)pixman_image_get_data(surface); +- if (!top_down) { +- dest -= (stride_abs * (height - 1)); +- } +- for (row = height - 1; row > 0; --row) { +- uint32_t *dest_aligned, *dest_misaligned; +- dest_aligned = (uint32_t *)(dest + stride_abs*row); +- dest_misaligned = (uint32_t*)(dest + stride_encoded*row); +- memmove(dest_aligned, dest_misaligned, stride_encoded); +- } +- } ++ canvas_fix_alignment(bits, stride_encoded, stride_abs, height); + + LZ4_freeStreamDecode(stream); + return surface; +@@ -782,7 +787,6 @@ static pixman_image_t *canvas_get_lz(CanvasBase *canvas, SpiceImage *image, + uint8_t *comp_buf = NULL; + int comp_size; + uint8_t *decomp_buf = NULL; +- uint8_t *src; + pixman_format_code_t pixman_format; + LzImageType type, as_type; + SpicePalette *palette; +@@ -790,6 +794,7 @@ static pixman_image_t *canvas_get_lz(CanvasBase *canvas, SpiceImage *image, + int width; + int height; + int top_down; ++ int stride_encoded; + int stride; + int free_palette; + +@@ -818,10 +823,12 @@ static pixman_image_t *canvas_get_lz(CanvasBase *canvas, SpiceImage *image, + lz_decode_begin(lz_data->lz, comp_buf, comp_size, &type, + &width, &height, &n_comp_pixels, &top_down, palette); + ++ stride_encoded = width; + switch (type) { + case LZ_IMAGE_TYPE_RGBA: + as_type = LZ_IMAGE_TYPE_RGBA; + pixman_format = PIXMAN_LE_a8r8g8b8; ++ stride_encoded *= 4; + break; + case LZ_IMAGE_TYPE_RGB32: + case LZ_IMAGE_TYPE_RGB24: +@@ -832,6 +839,7 @@ static pixman_image_t *canvas_get_lz(CanvasBase *canvas, SpiceImage *image, + case LZ_IMAGE_TYPE_PLT8: + as_type = LZ_IMAGE_TYPE_RGB32; + pixman_format = PIXMAN_LE_x8r8g8b8; ++ stride_encoded *= 4; + break; + case LZ_IMAGE_TYPE_A8: + as_type = LZ_IMAGE_TYPE_A8; +@@ -843,9 +851,11 @@ static pixman_image_t *canvas_get_lz(CanvasBase *canvas, SpiceImage *image, + canvas->format == SPICE_SURFACE_FMT_32_ARGB)) { + as_type = LZ_IMAGE_TYPE_RGB32; + pixman_format = PIXMAN_LE_x8r8g8b8; ++ stride_encoded *= 4; + } else { + as_type = LZ_IMAGE_TYPE_RGB16; + pixman_format = PIXMAN_x1r5g5b5; ++ stride_encoded *= 2; + } + break; + default: +@@ -865,18 +875,18 @@ static pixman_image_t *canvas_get_lz(CanvasBase *canvas, SpiceImage *image, + alloc_lz_image_surface(&lz_data->decode_data, pixman_format, + width, height, n_comp_pixels, top_down); + +- src = (uint8_t *)pixman_image_get_data(lz_data->decode_data.out_surface); ++ stride = pixman_image_get_stride(lz_data->decode_data.out_surface); ++ stride = abs(stride); + +- stride = (n_comp_pixels / height) * 4; ++ decomp_buf = (uint8_t *)pixman_image_get_data(lz_data->decode_data.out_surface); + if (!top_down) { +- stride = -stride; +- decomp_buf = src + stride * (height - 1); +- } else { +- decomp_buf = src; ++ decomp_buf -= stride * (height - 1); + } + + lz_decode(lz_data->lz, as_type, decomp_buf); + ++ canvas_fix_alignment(decomp_buf, stride_encoded, stride, height); ++ + if (free_palette) { + free(palette); + } +-- +2.8.1 + diff --git a/SOURCES/0002-smartcard-add-reader-and-cards-on-channel-up.patch b/SOURCES/0002-smartcard-add-reader-and-cards-on-channel-up.patch deleted file mode 100644 index 3ead626..0000000 --- a/SOURCES/0002-smartcard-add-reader-and-cards-on-channel-up.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 8a4846ae9c155a09c3bb996281fe45967360943e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= -Date: Wed, 25 Mar 2015 00:06:33 +0100 -Subject: [PATCH] smartcard: add reader and cards on channel up - -The smartcard manager reports reader/card events on insertion and -removal. If a smartcard channel is created after those events, the -channel state will not be in sync with the current reader/card state. -Sync the state when the channel is up. - -Fixes: -https://bugzilla.redhat.com/show_bug.cgi?id=1205171 ---- - gtk/channel-smartcard.c | 25 ++++++++++++++++++++++++- - 1 file changed, 24 insertions(+), 1 deletion(-) - -diff --git a/gtk/channel-smartcard.c b/gtk/channel-smartcard.c -index 627b9aa..fc23626 100644 ---- a/gtk/channel-smartcard.c -+++ b/gtk/channel-smartcard.c -@@ -400,6 +400,10 @@ static void reader_added_cb(SpiceSmartcardManager *manager, VReader *reader, - SpiceSmartcardChannel *channel = SPICE_SMARTCARD_CHANNEL(user_data); - const char *reader_name = vreader_get_name(reader); - -+ if (vreader_get_id(reader) != -1 || -+ g_list_find(channel->priv->pending_reader_additions, reader)) -+ return; -+ - channel->priv->pending_reader_additions = - g_list_append(channel->priv->pending_reader_additions, reader); - -@@ -457,14 +461,33 @@ static void spice_smartcard_channel_up_cb(GObject *source_object, - g_return_if_fail(SPICE_IS_SESSION(source_object)); - - if (!spice_channel_get_session(SPICE_CHANNEL(channel))->priv->migration_copy) { -+ SpiceSmartcardManager *manager = spice_smartcard_manager_get(); -+ GList *l, *list = NULL; - GError *error = NULL; - - spice_smartcard_manager_init_finish(SPICE_SESSION(source_object), - res, &error); -- if (error) -+ if (error) { - g_warning("%s", error->message); -+ goto end; -+ } -+ -+ list = spice_smartcard_manager_get_readers(manager); -+ for (l = list; l != NULL; l = l->next) { -+ VReader *reader = l->data; -+ gboolean has_card = vreader_card_is_present(reader) == VREADER_OK; -+ -+ reader_added_cb(manager, reader, channel); -+ if (has_card) -+ card_inserted_cb(manager, reader, channel); -+ -+ g_boxed_free(SPICE_TYPE_SMARTCARD_READER, reader); -+ } -+end: -+ g_list_free(list); - g_clear_error(&error); - } -+ - } - - static void spice_smartcard_channel_up(SpiceChannel *channel) diff --git a/SOURCES/0003-channel-smartcard-Add-missing-USE_SMARTCARD-checks.patch b/SOURCES/0003-channel-smartcard-Add-missing-USE_SMARTCARD-checks.patch deleted file mode 100644 index e8b13a6..0000000 --- a/SOURCES/0003-channel-smartcard-Add-missing-USE_SMARTCARD-checks.patch +++ /dev/null @@ -1,45 +0,0 @@ -From bf584f60cbdc755258f8311a4a4f7f4266d1c421 Mon Sep 17 00:00:00 2001 -From: Christophe Fergeau -Date: Fri, 10 Apr 2015 19:34:04 +0200 -Subject: [PATCH] channel-smartcard: Add missing USE_SMARTCARD checks - -In order to enable build without smartcard support ---- - gtk/channel-smartcard.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/gtk/channel-smartcard.c b/gtk/channel-smartcard.c -index fc23626..2f40979 100644 ---- a/gtk/channel-smartcard.c -+++ b/gtk/channel-smartcard.c -@@ -461,8 +461,10 @@ static void spice_smartcard_channel_up_cb(GObject *source_object, - g_return_if_fail(SPICE_IS_SESSION(source_object)); - - if (!spice_channel_get_session(SPICE_CHANNEL(channel))->priv->migration_copy) { -+#ifdef USE_SMARTCARD - SpiceSmartcardManager *manager = spice_smartcard_manager_get(); - GList *l, *list = NULL; -+#endif - GError *error = NULL; - - spice_smartcard_manager_init_finish(SPICE_SESSION(source_object), -@@ -472,6 +474,7 @@ static void spice_smartcard_channel_up_cb(GObject *source_object, - goto end; - } - -+#ifdef USE_SMARTCARD - list = spice_smartcard_manager_get_readers(manager); - for (l = list; l != NULL; l = l->next) { - VReader *reader = l->data; -@@ -483,8 +486,11 @@ static void spice_smartcard_channel_up_cb(GObject *source_object, - - g_boxed_free(SPICE_TYPE_SMARTCARD_READER, reader); - } -+#endif - end: -+#ifdef USE_SMARTCARD - g_list_free(list); -+#endif - g_clear_error(&error); - } - diff --git a/SOURCES/0003-egl-fix-leak-when-display-is-unrealize.patch b/SOURCES/0003-egl-fix-leak-when-display-is-unrealize.patch new file mode 100644 index 0000000..63357d8 --- /dev/null +++ b/SOURCES/0003-egl-fix-leak-when-display-is-unrealize.patch @@ -0,0 +1,177 @@ +From 3355a08e286bc2430692239e47367c59d6ac8109 Mon Sep 17 00:00:00 2001 +From: Victor Toso +Date: Tue, 29 Mar 2016 15:09:22 +0200 +Subject: [PATCH 3/5] egl: fix leak when display is unrealize +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +eglTerminate should be called on unrealize. This not yet fix all the +leaks but reduces it significantly from 318kb to 74kb as definitely lost +and around 1mb to 8kb as indirectly lost. + +4,096 bytes in 1 blocks are definitely lost in loss record +9,762 of 9,882 + at 0x35B19E40: drm_intel_gem_bo_map (intel_bufmgr_gem.c:1454) + by 0x35688320: can_write_oacontrol (intel_extensions.c:121) + by 0x35688320: intelInitExtensions (intel_extensions.c:279) + by 0x35651380: brwCreateContext (brw_context.c:875) + by 0x35602720: driCreateContextAttribs (dri_util.c:426) + by 0xF0C48B1: dri2_create_context (egl_dri2.c:1072) + by 0xF0BE727: eglCreateContext (eglapi.c:638) + by 0x5461D27: spice_egl_init (spice-widget-egl.c:256) + by 0x545B885: drawing_area_realize (spice-widget.c:581) + by 0xB431784: g_closure_invoke (gclosure.c:804) + by 0xB443A40: signal_emit_unlocked_R (gsignal.c:3629) + by 0xB44C92E: g_signal_emit_valist (gsignal.c:3385) + by 0xB44CC51: g_signal_emit (gsignal.c:3441) + +4,856 (32 direct, 4,824 indirect) bytes in 1 blocks are definitely lost +in loss record 9,779 of 9,882 + at 0x4C2A988: calloc (vg_replace_malloc.c:711) + by 0xF0BEEF7: _eglCreateArray (eglarray.c:71) + by 0xF0BF420: _eglLinkConfig (eglconfig.c:90) + by 0xF0C4F8D: dri2_add_config (egl_dri2.c:307) + by 0xF0C66EE: dri2_x11_add_configs_for_visuals (platform_x11.c:766) + by 0xF0C80EC: dri2_initialize_x11_dri3 (platform_x11.c:1319) + by 0xF0C80EC: dri2_initialize_x11 (platform_x11.c:1464) + by 0xF0C18FE: _eglMatchAndInitialize (egldriver.c:261) + by 0xF0C19B8: _eglMatchDriver (egldriver.c:292) + by 0xF0BDD31: eglInitialize (eglapi.c:482) + by 0x5461A76: spice_egl_init (spice-widget-egl.c:226) + by 0x545B885: drawing_area_realize (spice-widget.c:581) + by 0xB431784: g_closure_invoke (gclosure.c:804) + +5,921 (472 direct, 5,449 indirect) bytes in 1 blocks are definitely lost +in loss record 9,794 of 9,882 + at 0x4C2A988: calloc (vg_replace_malloc.c:711) + by 0xF0C7E0E: dri2_initialize_x11_dri3 (platform_x11.c:1267) + by 0xF0C7E0E: dri2_initialize_x11 (platform_x11.c:1464) + by 0xF0C18FE: _eglMatchAndInitialize (egldriver.c:261) + by 0xF0C19B8: _eglMatchDriver (egldriver.c:292) + by 0xF0BDD31: eglInitialize (eglapi.c:482) + by 0x5461A76: spice_egl_init (spice-widget-egl.c:226) + by 0x545B885: drawing_area_realize (spice-widget.c:581) + by 0xB431784: g_closure_invoke (gclosure.c:804) + by 0xB443A40: signal_emit_unlocked_R (gsignal.c:3629) + by 0xB44C92E: g_signal_emit_valist (gsignal.c:3385) + by 0xB44CC51: g_signal_emit (gsignal.c:3441) + by 0x5D2C9DB: gtk_widget_realize (gtkwidget.c:5454) + +16,384 bytes in 4 blocks are definitely lost in loss record 9,854 of 9,882 + at 0x35B19E40: drm_intel_gem_bo_map (intel_bufmgr_gem.c:1454) + by 0x3568AB30: intel_miptree_map_raw (intel_mipmap_tree.c:2149) + by 0x3568CEE6: intel_miptree_map_gtt (intel_mipmap_tree.c:2182) + by 0x3568CEE6: intel_miptree_map (intel_mipmap_tree.c:2774) + by 0x35692851: intel_map_texture_image (intel_tex.c:227) + by 0x35447C3B: store_texsubimage (texstore.c:1069) + by 0x35447E9F: _mesa_store_teximage (texstore.c:1125) + by 0x3543D9BA: _mesa_get_fallback_texture (texobj.c:1056) + by 0x35443E1E: UnknownInlinedFun (texstate.c:562) + by 0x35443E1E: update_program_texture_state (texstate.c:587) + by 0x35443E1E: UnknownInlinedFun (texstate.c:726) + by 0x35443E1E: _mesa_update_texture (texstate.c:757) + by 0x35420809: _mesa_update_state_locked (state.c:430) + by 0x35420ED0: _mesa_update_state (state.c:504) + by 0x3535BF87: _mesa_Clear (clear.c:172) + by 0x546214F: spice_egl_update_display (spice-widget-egl.c:514) + +32,768 bytes in 1 blocks are definitely lost in loss record 9,864 of 9,882 + at 0x35B19E40: drm_intel_gem_bo_map (intel_bufmgr_gem.c:1454) + by 0x35683E3C: intel_batchbuffer_reset (intel_batchbuffer.c:68) + by 0x35684052: brw_new_batch (intel_batchbuffer.c:164) + by 0x35684052: _intel_batchbuffer_flush.part.2 (intel_batchbuffer.c:397) + by 0x3568853B: can_write_oacontrol (intel_extensions.c:153) + by 0x3568853B: intelInitExtensions (intel_extensions.c:279) + by 0x35651380: brwCreateContext (brw_context.c:875) + by 0x35602720: driCreateContextAttribs (dri_util.c:426) + by 0xF0C48B1: dri2_create_context (egl_dri2.c:1072) + by 0xF0BE727: eglCreateContext (eglapi.c:638) + by 0x5461D27: spice_egl_init (spice-widget-egl.c:256) + by 0x545B885: drawing_area_realize (spice-widget.c:581) + by 0xB431784: g_closure_invoke (gclosure.c:804) + by 0xB443A40: signal_emit_unlocked_R (gsignal.c:3629) + +32,768 bytes in 1 blocks are definitely lost in loss record 9,865 of 9,882 + at 0x35B19E40: drm_intel_gem_bo_map (intel_bufmgr_gem.c:1454) + by 0x35683E3C: intel_batchbuffer_reset (intel_batchbuffer.c:68) + by 0x35684052: brw_new_batch (intel_batchbuffer.c:164) + by 0x35684052: _intel_batchbuffer_flush.part.2 (intel_batchbuffer.c:397) + by 0x356887F3: can_do_pipelined_register_writes (intel_extensions.c:88) + by 0x356887F3: intelInitExtensions (intel_extensions.c:338) + by 0x35651380: brwCreateContext (brw_context.c:875) + by 0x35602720: driCreateContextAttribs (dri_util.c:426) + by 0xF0C48B1: dri2_create_context (egl_dri2.c:1072) + by 0xF0BE727: eglCreateContext (eglapi.c:638) + by 0x5461D27: spice_egl_init (spice-widget-egl.c:256) + by 0x545B885: drawing_area_realize (spice-widget.c:581) + by 0xB431784: g_closure_invoke (gclosure.c:804) + by 0xB443A40: signal_emit_unlocked_R (gsignal.c:3629) + +98,304 bytes in 3 blocks are definitely lost in loss record 9,872 of 9,882 + at 0x35B19E40: drm_intel_gem_bo_map (intel_bufmgr_gem.c:1454) + by 0x35683E3C: intel_batchbuffer_reset (intel_batchbuffer.c:68) + by 0x35684052: brw_new_batch (intel_batchbuffer.c:164) + by 0x35684052: _intel_batchbuffer_flush.part.2 (intel_batchbuffer.c:397) + by 0x3564F834: intel_glFlush (brw_context.c:259) + by 0xF0C3DA0: dri2_make_current (egl_dri2.c:1189) + by 0xF0BAB1B: eglMakeCurrent (eglapi.c:703) + by 0x546274E: spice_widget_init_egl_win (spice-widget-egl.c:316) + by 0x546274E: spice_egl_realize_display (spice-widget-egl.c:333) + by 0x545B89F: drawing_area_realize (spice-widget.c:586) + by 0xB431784: g_closure_invoke (gclosure.c:804) + by 0xB443A40: signal_emit_unlocked_R (gsignal.c:3629) + by 0xB44C92E: g_signal_emit_valist (gsignal.c:3385) + by 0xB44CC51: g_signal_emit (gsignal.c:3441) + +131,072 bytes in 4 blocks are definitely lost in loss record 9,874 of 9,882 + at 0x35B19E40: drm_intel_gem_bo_map (intel_bufmgr_gem.c:1454) + by 0x35683E3C: intel_batchbuffer_reset (intel_batchbuffer.c:68) + by 0x356848E8: intel_batchbuffer_init (intel_batchbuffer.c:45) + by 0x35651337: brwCreateContext (brw_context.c:848) + by 0x35602720: driCreateContextAttribs (dri_util.c:426) + by 0xF0C48B1: dri2_create_context (egl_dri2.c:1072) + by 0xF0BE727: eglCreateContext (eglapi.c:638) + by 0x5461D27: spice_egl_init (spice-widget-egl.c:256) + by 0x545B885: drawing_area_realize (spice-widget.c:581) + by 0xB431784: g_closure_invoke (gclosure.c:804) + by 0xB443A40: signal_emit_unlocked_R (gsignal.c:3629) + by 0xB44C92E: g_signal_emit_valist (gsignal.c:3385) + +1,080,655 (284 direct, 1,080,371 indirect) bytes in 1 blocks are +definitely lost in loss record 9,881 of 9,882 + at 0x4C2A988: calloc (vg_replace_malloc.c:711) + by 0x355A2221: ralloc_size (ralloc.c:113) + by 0x355A227D: rzalloc_size (ralloc.c:134) + by 0x355A2BEE: ra_alloc_reg_set (register_allocate.c:196) + by 0x356D79AA: brw_alloc_reg_set(brw_compiler*, int) (brw_fs_reg_allocate.cpp:159) + by 0x356D817D: brw_fs_alloc_reg_sets (brw_fs_reg_allocate.cpp:305) + by 0x356FDACC: brw_compiler_create (brw_shader.cpp:84) + by 0x35691995: intelInitScreen2 (intel_screen.c:1495) + by 0x35602A5E: driCreateNewScreen2 (dri_util.c:144) + by 0xF0C547B: dri2_create_screen (egl_dri2.c:674) + by 0xF0C808F: dri2_initialize_x11_dri3 (platform_x11.c:1303) + by 0xF0C808F: dri2_initialize_x11 (platform_x11.c:1464) + by 0xF0C18FE: _eglMatchAndInitialize (egldriver.c:261) + +Acked-by: Marc-André Lureau +(cherry picked from commit 181ec2511902483df5c02ecf12db437d9975a53b) +--- + src/spice-widget-egl.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/spice-widget-egl.c b/src/spice-widget-egl.c +index 1748189..7c2fdfb 100644 +--- a/src/spice-widget-egl.c ++++ b/src/spice-widget-egl.c +@@ -360,6 +360,7 @@ void spice_egl_unrealize_display(SpiceDisplay *display) + + eglMakeCurrent(d->egl.display, EGL_NO_SURFACE, EGL_NO_SURFACE, + EGL_NO_CONTEXT); ++ eglTerminate(d->egl.display); + } + + G_GNUC_INTERNAL +-- +2.8.1 + diff --git a/SOURCES/0004-Ensure-that-file-transfers-get-cancelled.patch b/SOURCES/0004-Ensure-that-file-transfers-get-cancelled.patch new file mode 100644 index 0000000..a7a18dd --- /dev/null +++ b/SOURCES/0004-Ensure-that-file-transfers-get-cancelled.patch @@ -0,0 +1,61 @@ +From 8f74b35fa15fa08054e6f14612219f3818224f7b Mon Sep 17 00:00:00 2001 +From: Jonathon Jongsma +Date: Thu, 7 Apr 2016 15:42:14 -0500 +Subject: [PATCH 4/5] Ensure that file transfers get cancelled + +When canceling a file transfer task in spicy, the client would often +stop sending additional data, but it would not send a "CANCELLED" +message to the guest. Because of this, the partial file would remain in +the guest's downloads folder until the spice client disconnected, at +which point the vdagent would remove the unfinshed file. + +This CANCELLED status message was only being sent if the task was +canceled during the async file read operation. If you cancel a task, +it's quite likely that it will happen during other operations +(e.g. file_xfer_flush_async(), etc). In order to handle these scenarios +(and make sure that the file gets canceled properly), send the +FILE_XFER_STATUS message in spice_file_transfer_task_completed(). + +(cherry picked from commit 4da4d9201cc3f86e38f00388cdd6157fe70e3328) +--- + src/channel-main.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +diff --git a/src/channel-main.c b/src/channel-main.c +index e5a70af..67fce5b 100644 +--- a/src/channel-main.c ++++ b/src/channel-main.c +@@ -1919,13 +1919,6 @@ static void file_xfer_read_cb(GObject *source_object, + file_xfer_data_flushed_cb, self); + self->priv->pending = TRUE; + } else if (error) { +- VDAgentFileXferStatusMessage msg = { +- .id = self->priv->id, +- .result = error->code == G_IO_ERROR_CANCELLED ? +- VD_AGENT_FILE_XFER_STATUS_CANCELLED : VD_AGENT_FILE_XFER_STATUS_ERROR, +- }; +- agent_msg_queue_many(self->priv->channel, VD_AGENT_FILE_XFER_STATUS, +- &msg, sizeof(msg), NULL); + spice_channel_wakeup(SPICE_CHANNEL(self->priv->channel), FALSE); + spice_file_transfer_task_completed(self, error); + } +@@ -2946,6 +2939,16 @@ static void spice_file_transfer_task_completed(SpiceFileTransferTask *self, + self->priv->error = error; + } + ++ if (self->priv->error) { ++ VDAgentFileXferStatusMessage msg = { ++ .id = self->priv->id, ++ .result = error->code == G_IO_ERROR_CANCELLED ? ++ VD_AGENT_FILE_XFER_STATUS_CANCELLED : VD_AGENT_FILE_XFER_STATUS_ERROR, ++ }; ++ agent_msg_queue_many(self->priv->channel, VD_AGENT_FILE_XFER_STATUS, ++ &msg, sizeof(msg), NULL); ++ } ++ + if (self->priv->pending) + return; + +-- +2.8.1 + diff --git a/SOURCES/0004-session-disable-default-socket-proxy.patch b/SOURCES/0004-session-disable-default-socket-proxy.patch deleted file mode 100644 index 783085c..0000000 --- a/SOURCES/0004-session-disable-default-socket-proxy.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 5c161c56ec7568b6eeb698be5d5e18970c8146a3 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= -Date: Thu, 9 Jul 2015 18:49:09 +0200 -Subject: [PATCH] Subject: [PATCH] session: disable default socket proxy - -GSocketClient uses the system proxy by default, and it may end up using -the system HTTP proxy with bad results if CONNECT is not -supported. spice-gtk uses it's own SPICE_PROXY instead, and doesn't rely -on GSocketClient default proxy but GProxyAddress instead. Disabling the -default proxy solve a wrong proxy from being used. - -It may be worth to revisit this change if GSocketClient can be told to -ignore proxies that are not eligible for Spice connections. (HTTP could -be though, in which case it would be a user configuration issue) - -Fixes: -https://bugzilla.redhat.com/show_bug.cgi?id=1040679 ---- - gtk/spice-session.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/gtk/spice-session.c b/gtk/spice-session.c -index 0663380..7d84c07 100644 ---- a/gtk/spice-session.c -+++ b/gtk/spice-session.c -@@ -1895,6 +1895,7 @@ GSocketConnection* spice_session_channel_open_host(SpiceSession *session, SpiceC - - open_host.client = g_socket_client_new(); - #if GLIB_CHECK_VERSION(2,26,0) -+ g_socket_client_set_enable_proxy(open_host.client, FALSE); - g_socket_client_set_timeout(open_host.client, SOCKET_TIMEOUT); - #else - open_host.timeout_id = --- -2.4.4 - diff --git a/SOURCES/0005-channel-main-fix-leak-on-volume-sync.patch b/SOURCES/0005-channel-main-fix-leak-on-volume-sync.patch new file mode 100644 index 0000000..42de81b --- /dev/null +++ b/SOURCES/0005-channel-main-fix-leak-on-volume-sync.patch @@ -0,0 +1,62 @@ +From abec5822455c76d353e40d5e2748ddce7c5219d9 Mon Sep 17 00:00:00 2001 +From: Victor Toso +Date: Wed, 23 Mar 2016 15:40:50 +0100 +Subject: [PATCH 5/5] channel-main: fix leak on volume-sync + +7 bytes in 1 blocks are definitely lost in loss record 128 of 10,009 + at 0x4C2A988: calloc (vg_replace_malloc.c:711) + by 0xB6C3200: g_malloc0 (gmem.c:124) + by 0x740BD5F: audio_playback_volume_info_cb (channel-main.c:1216) + by 0xB11D488: g_task_return_now (gtask.c:1107) + by 0xB11DCBD: g_task_return (gtask.c:1165) + by 0x742D1F5: spice_pulse_complete_all_async_tasks (spice-pulse.c:1034) + by 0x8B6B57C: ext_stream_restore_read_cb (ext-stream-restore.c:141) + by 0x10BA63C0: run_action (pdispatch.c:284) + by 0x10BA6722: pa_pdispatch_run (pdispatch.c:337) + by 0x8B6520D: pstream_packet_callback (context.c:338) + by 0x10BA8D7E: do_read (pstream.c:879) + by 0x10BAB39A: do_pstream_read_write (pstream.c:189) + +7 bytes in 1 blocks are definitely lost in loss record 129 of 10,009 + at 0x4C2A988: calloc (vg_replace_malloc.c:711) + by 0xB6C3200: g_malloc0 (gmem.c:124) + by 0x740BFBF: audio_record_volume_info_cb (channel-main.c:1273) + by 0xB11D488: g_task_return_now (gtask.c:1107) + by 0xB11DCBD: g_task_return (gtask.c:1165) + by 0x742D1F5: spice_pulse_complete_all_async_tasks (spice-pulse.c:1034) + by 0x8B6B57C: ext_stream_restore_read_cb (ext-stream-restore.c:141) + by 0x10BA63C0: run_action (pdispatch.c:284) + by 0x10BA6722: pa_pdispatch_run (pdispatch.c:337) + by 0x8B6520D: pstream_packet_callback (context.c:338) + by 0x10BA8D7E: do_read (pstream.c:879) + by 0x10BAB39A: do_pstream_read_write (pstream.c:189) + +Acked-by: Christophe Fergeau +(cherry picked from commit e47075093d5d78b05a2b34fa7aee43dd6818f6ab) +--- + src/channel-main.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/channel-main.c b/src/channel-main.c +index 67fce5b..2ad1ece 100644 +--- a/src/channel-main.c ++++ b/src/channel-main.c +@@ -1234,6 +1234,7 @@ static void audio_playback_volume_info_cb(GObject *object, GAsyncResult *res, gp + g_free(volume); + agent_msg_queue(main_channel, VD_AGENT_AUDIO_VOLUME_SYNC, + sizeof(VDAgentAudioVolumeSync) + array_size, avs); ++ g_free (avs); + } + + static void agent_sync_audio_playback(SpiceMainChannel *main_channel) +@@ -1291,6 +1292,7 @@ static void audio_record_volume_info_cb(GObject *object, GAsyncResult *res, gpoi + g_free(volume); + agent_msg_queue(main_channel, VD_AGENT_AUDIO_VOLUME_SYNC, + sizeof(VDAgentAudioVolumeSync) + array_size, avs); ++ g_free (avs); + } + + static void agent_sync_audio_record(SpiceMainChannel *main_channel) +-- +2.8.1 + diff --git a/SOURCES/0005-spice-widget-Do-not-update-display-when-resize-guest.patch b/SOURCES/0005-spice-widget-Do-not-update-display-when-resize-guest.patch deleted file mode 100644 index 68b26a2..0000000 --- a/SOURCES/0005-spice-widget-Do-not-update-display-when-resize-guest.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 459ba2b0db481a8188b36120e2ad777b2f17e67c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= -Date: Wed, 3 Jun 2015 22:16:36 +0200 -Subject: [PATCH 05/11] spice-widget: Do not update display when resize-guest - is disabled - -Updating the display causes weird behaviors in virt-viewer, like -re-resizing to a previous monitor config when, after changing the -display resolution (through System > PReferences > Displays). the agent -reconnects. -It is not perfect yet, because when the agent reconnects the guest -resizes to the previous config and switch to the proper one, but this -seems more like an agent bug than a spice-gtk one. ---- - gtk/spice-widget.c | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c -index 62a98dc..be1e936 100644 ---- a/gtk/spice-widget.c -+++ b/gtk/spice-widget.c -@@ -293,10 +293,6 @@ static void update_monitor_area(SpiceDisplay *display) - goto whole; - } - -- if (!d->resize_guest_enable) -- spice_main_update_display(d->main, get_display_id(display), -- c->x, c->y, c->width, c->height, FALSE); -- - update_area(display, c->x, c->y, c->width, c->height); - g_clear_pointer(&monitors, g_array_unref); - return; --- -2.4.3 - diff --git a/SOURCES/0006-Send-monitor-config-if-at-least-one-monitor-has-dime.patch b/SOURCES/0006-Send-monitor-config-if-at-least-one-monitor-has-dime.patch deleted file mode 100644 index 8a1710f..0000000 --- a/SOURCES/0006-Send-monitor-config-if-at-least-one-monitor-has-dime.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 6e7c20543ac57197841e0badac1bd52fb5bdf9b1 Mon Sep 17 00:00:00 2001 -From: Pavel Grunt -Date: Fri, 10 Jul 2015 10:37:27 +0200 -Subject: [PATCH 06/11] Send monitor config if at least one monitor has - dimensions - -If a client (virt-manager, spicy) is not setting display dimensions -and the "resize-guest" property is disabled, spice-gtk sends a wrong -monitor config message where all the monitors have width = heigh = 0 -when the agent connects. This message can confuse the guest, in that -case the guest will change the resolution of its monitor. - -Regression since 28312b8d1e287a320851e8828825f2ca138d8b0b - -Resolves: -https://bugzilla.redhat.com/show_bug.cgi?id=1240721 ---- - gtk/channel-main.c | 21 +++++++++++++++++++++ - 1 file changed, 21 insertions(+) - -diff --git a/gtk/channel-main.c b/gtk/channel-main.c -index 1ad090f..7ab3407 100644 ---- a/gtk/channel-main.c -+++ b/gtk/channel-main.c -@@ -1282,6 +1282,22 @@ static void agent_clipboard_release(SpiceMainChannel *channel, guint selection) - agent_msg_queue(channel, VD_AGENT_CLIPBOARD_RELEASE, msgsize, msg); - } - -+static gboolean any_display_has_dimensions(SpiceMainChannel *channel) -+{ -+ SpiceMainChannelPrivate *c; -+ guint i; -+ -+ g_return_if_fail(SPICE_IS_MAIN_CHANNEL(channel)); -+ c = channel->priv; -+ -+ for (i = 0; i < MAX_DISPLAY; i++) { -+ if (c->display[i].width > 0 && c->display[i].height > 0) -+ return TRUE; -+ } -+ -+ return FALSE; -+} -+ - /* main context*/ - static gboolean timer_set_display(gpointer data) - { -@@ -1294,6 +1310,11 @@ static gboolean timer_set_display(gpointer data) - if (!c->agent_connected) - return FALSE; - -+ if (!any_display_has_dimensions(channel)) { -+ SPICE_DEBUG("Not sending monitors config, at least one monitor must have dimensions"); -+ return FALSE; -+ } -+ - session = spice_channel_get_session(SPICE_CHANNEL(channel)); - - /* ensure we have an explicit monitor configuration at least for --- -2.4.3 - diff --git a/SOURCES/0006-channel-Abort-migration-in-delayed-unref.patch b/SOURCES/0006-channel-Abort-migration-in-delayed-unref.patch new file mode 100644 index 0000000..057e894 --- /dev/null +++ b/SOURCES/0006-channel-Abort-migration-in-delayed-unref.patch @@ -0,0 +1,50 @@ +From 71789361f05fbdcca1c91b28eba9dbca5d1af249 Mon Sep 17 00:00:00 2001 +From: Pavel Grunt +Date: Fri, 22 Apr 2016 16:47:48 +0200 +Subject: [PATCH] channel: Abort migration in delayed unref + +When channel is unref'ed during migration migrate_channel_event_cb +is called causing a crash by coroutine yielding to nonexistent channel. + +The delayed_unref happens for the target host channel and will only occur +when the migration process fails. + +As comment in spice_channel_coroutine says: + Co-routine exits now - the SpiceChannel object may no longer exist, + so don't do anything else now unless you like SEGVs + +Related: rhbz#1318574 +Acked-by: Victor Toso +--- + src/spice-channel.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/src/spice-channel.c b/src/spice-channel.c +index d8a4ed6..e52a6a9 100644 +--- a/src/spice-channel.c ++++ b/src/spice-channel.c +@@ -2306,6 +2306,7 @@ static gboolean spice_channel_delayed_unref(gpointer data) + SpiceChannel *channel = SPICE_CHANNEL(data); + SpiceChannelPrivate *c = channel->priv; + gboolean was_ready = c->state == SPICE_CHANNEL_STATE_READY; ++ SpiceSession *session; + + CHANNEL_DEBUG(channel, "Delayed unref channel %p", channel); + +@@ -2313,6 +2314,13 @@ static gboolean spice_channel_delayed_unref(gpointer data) + + c->state = SPICE_CHANNEL_STATE_UNCONNECTED; + ++ session = spice_channel_get_session(channel); ++ if (spice_session_is_for_migration(session)) { ++ /* error during migration - abort migration */ ++ spice_session_abort_migration(session); ++ return FALSE; ++ } ++ + if (c->event != SPICE_CHANNEL_NONE) { + g_coroutine_signal_emit(channel, signals[SPICE_CHANNEL_EVENT], 0, c->event); + c->event = SPICE_CHANNEL_NONE; +-- +2.8.1 + diff --git a/SOURCES/0007-Notify-about-existence-of-monitor-for-all-display-ch.patch b/SOURCES/0007-Notify-about-existence-of-monitor-for-all-display-ch.patch deleted file mode 100644 index 3e38bd2..0000000 --- a/SOURCES/0007-Notify-about-existence-of-monitor-for-all-display-ch.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 22196a745281c28e2d21327a9229b84d64c3e0ea Mon Sep 17 00:00:00 2001 -From: Pavel Grunt -Date: Thu, 30 Jul 2015 13:51:44 +0200 -Subject: [PATCH 07/11] Notify about existence of monitor for all display - channels - -Windows guest can have disabled display on the display chanel #0, in -that case it will not be listed in virt-viewer's "View->Displays" menu - -Resolves: -https://bugs.freedesktop.org/show_bug.cgi?id=91489 ---- - gtk/channel-display.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/gtk/channel-display.c b/gtk/channel-display.c -index 1e1312c..aca7118 100644 ---- a/gtk/channel-display.c -+++ b/gtk/channel-display.c -@@ -805,10 +805,8 @@ static void spice_display_channel_up(SpiceChannel *channel) - out->marshallers->msgc_display_init(out->marshaller, &init); - spice_msg_out_send_internal(out); - -- /* if we are not using monitors config, notify of existence of -- this monitor */ -- if (channel->priv->channel_id != 0) -- g_coroutine_object_notify(G_OBJECT(channel), "monitors"); -+ /* notify of existence of this monitor */ -+ g_coroutine_object_notify(G_OBJECT(channel), "monitors"); - } - - #define DRAW(type) { \ --- -2.4.3 - diff --git a/SOURCES/0007-file-xfer-fix-segfault-on-agent-disconnection.patch b/SOURCES/0007-file-xfer-fix-segfault-on-agent-disconnection.patch new file mode 100644 index 0000000..bbdc2bf --- /dev/null +++ b/SOURCES/0007-file-xfer-fix-segfault-on-agent-disconnection.patch @@ -0,0 +1,65 @@ +From 51fa9b5b1d1c322206f7056d56bb74b1759a8161 Mon Sep 17 00:00:00 2001 +From: Victor Toso +Date: Thu, 12 May 2016 22:18:44 +0200 +Subject: [PATCH 07/15] file-xfer: fix segfault on agent disconnection +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We are checking self->priv->error but accessing the argument GError * +which is NULL and leads to a segfault. + +Program received signal SIGSEGV, Segmentation fault. +spice_file_transfer_task_completed (self=self@entry=0x7fffd0006f00, error=0x0) at channel-main.c:2963 +2963 VDAgentFileXferStatusMessage msg = { +(gdb) bt + #0 spice_file_transfer_task_completed (self=self@entry=0x7fffd0006f00, error=0x0) at channel-main.c:2963 + #1 in file_xfer_data_flushed_cb (source_object=0x7cc1d0, res=0x953390, user_data=user_data@entry=0x7fffd0006f00) at channel-main.c:1857 + #2 in g_task_return_now (task=0x953390) at gtask.c:1108 + #3 in g_task_return (task=0x953390, type=) at gtask.c:1166 + #4 in flush_foreach_remove (key=, value=, user_data=) at channel-main.c:928 + #5 in g_hash_table_foreach_remove_or_steal (hash_table=0x70cea0, func=func@entry=0x7ffff5616f10 , user_data=user_data@entry=0x0, notify=notify@entry=1) at ghash.c:1492 + #6 in g_hash_table_foreach_remove (hash_table=, func=func@entry=0x7ffff5616f10 , user_data=user_data@entry=0x0) at ghash.c:1538 + #7 in file_xfer_flushed (success=0, channel=0x7cc1d0) at channel-main.c:936 + #8 spice_main_channel_reset_agent (channel=0x7cc1d0) at channel-main.c:466 + #9 set_agent_connected (channel=0x7cc1d0, connected=connected@entry=0) at channel-main.c:1572 + #10 in spice_main_channel_reset (channel=0x7cc1d0, migrating=0) at channel-main.c:485 + #11 in spice_channel_coroutine (data=0x7cc1d0) at spice-channel.c:2564 + #12 in coroutine_trampoline (cc=0x7cb860) at coroutine_ucontext.c:63 + #13 in continuation_trampoline (i0=, i1=) at continuation.c:55 + #14 in ?? () from /lib64/libc.so.6 + #15 in ?? () + #16 in ?? () +Backtrace stopped: Cannot access memory at address + +Acked-by: Fabiano Fidêncio +(cherry picked from commit a61c1ff0ac34fded8f71e528594c3f548479cd44) +--- + src/channel-main.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/channel-main.c b/src/channel-main.c +index 2ad1ece..7f4d0b3 100644 +--- a/src/channel-main.c ++++ b/src/channel-main.c +@@ -2944,7 +2944,7 @@ static void spice_file_transfer_task_completed(SpiceFileTransferTask *self, + if (self->priv->error) { + VDAgentFileXferStatusMessage msg = { + .id = self->priv->id, +- .result = error->code == G_IO_ERROR_CANCELLED ? ++ .result = self->priv->error->code == G_IO_ERROR_CANCELLED ? + VD_AGENT_FILE_XFER_STATUS_CANCELLED : VD_AGENT_FILE_XFER_STATUS_ERROR, + }; + agent_msg_queue_many(self->priv->channel, VD_AGENT_FILE_XFER_STATUS, +@@ -2966,7 +2966,7 @@ static void spice_file_transfer_task_completed(SpiceFileTransferTask *self, + self); + self->priv->pending = TRUE; + signal: +- g_signal_emit(self, task_signals[SIGNAL_FINISHED], 0, error); ++ g_signal_emit(self, task_signals[SIGNAL_FINISHED], 0, self->priv->error); + } + + +-- +2.5.5 + diff --git a/SOURCES/0008-Handle-single-headed-monitors-that-have-a-non-zero-x.patch b/SOURCES/0008-Handle-single-headed-monitors-that-have-a-non-zero-x.patch deleted file mode 100644 index a3925b0..0000000 --- a/SOURCES/0008-Handle-single-headed-monitors-that-have-a-non-zero-x.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 228e25c587ba0359aaf61192853e373441971170 Mon Sep 17 00:00:00 2001 -From: Sandy Stutsman -Date: Wed, 24 Jun 2015 14:46:59 -0400 -Subject: [PATCH 08/11] Handle single headed monitors that have a non-zero x, y - config - -Each monitor on a Windows guest is represented as a separate, single-headed -device with its own framebuffer. When there are multiple monitors, all -monitors but one will have a non-zero xy config position. But even in -these cases the whole area (frame-buffer) of each monitor should be -updated. - -Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1202419 ---- - gtk/spice-widget.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c -index be1e936..37e0caf 100644 ---- a/gtk/spice-widget.c -+++ b/gtk/spice-widget.c -@@ -293,7 +293,12 @@ static void update_monitor_area(SpiceDisplay *display) - goto whole; - } - -- update_area(display, c->x, c->y, c->width, c->height); -+ /* If only one head on this monitor, update the whole area */ -+ if(monitors->len == 1) { -+ update_area(display, 0, 0, c->width, c->height); -+ } else { -+ update_area(display, c->x, c->y, c->width, c->height); -+ } - g_clear_pointer(&monitors, g_array_unref); - return; - --- -2.4.3 - diff --git a/SOURCES/0008-tests-Add-test-for-SpiceURI.patch b/SOURCES/0008-tests-Add-test-for-SpiceURI.patch new file mode 100644 index 0000000..6ab4844 --- /dev/null +++ b/SOURCES/0008-tests-Add-test-for-SpiceURI.patch @@ -0,0 +1,145 @@ +From 087bba6bbc4d47e3e068c8b5ee902637de04bc7e Mon Sep 17 00:00:00 2001 +From: Pavel Grunt +Date: Wed, 1 Jun 2016 10:04:44 +0200 +Subject: [PATCH 08/15] tests: Add test for SpiceURI + +Related: rhbz#1335239 +(cherry picked from commit dab190d8d2cb93f85f1858135354dd4e93ff48f8) +--- + tests/Makefile.am | 2 ++ + tests/uri.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 105 insertions(+) + create mode 100644 tests/uri.c + +diff --git a/tests/Makefile.am b/tests/Makefile.am +index c1d95c1..9517431 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -4,6 +4,7 @@ noinst_PROGRAMS = + TESTS = coroutine \ + util \ + session \ ++ test-spice-uri \ + $(NULL) + + if WITH_PHODAV +@@ -35,6 +36,7 @@ util_SOURCES = util.c + coroutine_SOURCES = coroutine.c + session_SOURCES = session.c + pipe_SOURCES = pipe.c ++test_spice_uri_SOURCES = uri.c + usb_acl_helper_SOURCES = usb-acl-helper.c + usb_acl_helper_CFLAGS = -DTESTDIR=\"$(abs_builddir)\" + mock_acl_helper_SOURCES = mock-acl-helper.c +diff --git a/tests/uri.c b/tests/uri.c +new file mode 100644 +index 0000000..b68f159 +--- /dev/null ++++ b/tests/uri.c +@@ -0,0 +1,103 @@ ++/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ ++/* ++ Copyright (C) 2016 Red Hat, Inc. ++ ++ This library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ This library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with this library; if not, see . ++*/ ++#include ++#include ++#include "spice-uri-priv.h" ++ ++struct test_case { ++ gchar *uri; ++ gchar *scheme; ++ gchar *hostname; ++ guint port; ++ gchar *user; ++ gchar *password; ++ gchar *error_msg; ++}; ++ ++static void test_spice_uri_bad(const struct test_case invalid_test_cases[], const guint cases_cnt) ++{ ++ guint i; ++ ++ SpiceURI *uri = spice_uri_new(); ++ g_assert_nonnull(uri); ++ ++ for (i = 0; i < cases_cnt; i++) { ++ GError *error = NULL; ++ g_assert_false(spice_uri_parse(uri, invalid_test_cases[i].uri, &error)); ++ g_assert_error(error, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED); ++ g_assert_cmpstr(error->message, ==, invalid_test_cases[i].error_msg); ++ g_error_free(error); ++ } ++ ++ g_object_unref(uri); ++} ++ ++static void test_spice_uri_good(const struct test_case valid_test_cases[], const guint cases_cnt) ++{ ++ guint i; ++ ++ SpiceURI *uri = spice_uri_new(); ++ g_assert_nonnull(uri); ++ ++ for (i = 0; i < cases_cnt; i++) { ++ GError *error = NULL; ++ g_assert_true(spice_uri_parse(uri, valid_test_cases[i].uri, &error)); ++ g_assert_cmpstr(spice_uri_get_scheme(uri), ==, valid_test_cases[i].scheme); ++ g_assert_cmpstr(spice_uri_get_hostname(uri), ==, valid_test_cases[i].hostname); ++ g_assert_cmpstr(spice_uri_get_user(uri), ==, valid_test_cases[i].user); ++ g_assert_cmpstr(spice_uri_get_password(uri), ==, valid_test_cases[i].password); ++ g_assert_cmpuint(spice_uri_get_port(uri), ==, valid_test_cases[i].port); ++ g_assert_no_error(error); ++ } ++ ++ g_object_unref(uri); ++} ++ ++static void test_spice_uri_ipv4_bad(void) ++{ ++ const struct test_case invalid_test_cases[] = { ++ {"http://:80", "http", NULL, 80, NULL, NULL, "Invalid hostname in uri address"}, ++ {"http://", "http", NULL, 3128, NULL, NULL, "Invalid hostname in uri address"}, ++ {"http://127.0.0.1:port", "http", "127.0.0.1", 3128, NULL, NULL, ++ "Invalid uri port: port"}, ++ }; ++ ++ test_spice_uri_bad(invalid_test_cases, G_N_ELEMENTS(invalid_test_cases)); ++} ++ ++static void test_spice_uri_ipv4_good(void) ++{ ++ const struct test_case valid_test_cases[] = { ++ {"http://127.0.0.1/", "http", "127.0.0.1", 3128, NULL, NULL, NULL}, ++ {"https://127.0.0.1", "https", "127.0.0.1", 3129, NULL, NULL, NULL}, ++ {"127.0.0.1", "http", "127.0.0.1", 3128, NULL, NULL, NULL}, ++ {"http://user:password@host:80", "http", "host", 80, "user", "password", NULL}, ++ }; ++ ++ test_spice_uri_good(valid_test_cases, G_N_ELEMENTS(valid_test_cases)); ++} ++ ++int main(int argc, char* argv[]) ++{ ++ g_test_init(&argc, &argv, NULL); ++ ++ g_test_add_func("/spice_uri/ipv4/bad-uri", test_spice_uri_ipv4_bad); ++ g_test_add_func("/spice_uri/ipv4/good-uri", test_spice_uri_ipv4_good); ++ ++ return g_test_run(); ++} +-- +2.5.5 + diff --git a/SOURCES/0009-This-adds-reference-counting-to-cached-images.patch b/SOURCES/0009-This-adds-reference-counting-to-cached-images.patch deleted file mode 100644 index 8afcfaf..0000000 --- a/SOURCES/0009-This-adds-reference-counting-to-cached-images.patch +++ /dev/null @@ -1,172 +0,0 @@ -From cf7027a0b0a5f5c11277b24fda4c23b0d7c49159 Mon Sep 17 00:00:00 2001 -From: Sandy Stutsman -Date: Thu, 9 Jul 2015 10:10:06 -0400 -Subject: [PATCH 09/11] This adds reference counting to cached images. - -Windows guests with multi-monitors will often send down the same image -via different channels. If these instances are not counted, one channel -can delete an image before all the rest of the channels are finished with -it. In this case, the client will hang. - -This can happen, for instance, when the Windows guest is updating the -monitor's wallpaper. There is a driver instance for each monitor, so each -one is sending down its own copy of the same image with the same id. As -one channel may be busier than another, the order that the client executes -commands may not be the same order as the server issued them. Here's what -can happen: - - On the server side: - Monitor 1 sends image A - Monitor 1 sends multiple rendering commands for image A - Monitor 1 removes image A - Monitor 2 sends image A - Monitor 2 sends rendering commands for image A - On the client side: - Monitor 1 adds image A to the cache - Monitor 1 starts rendering with image A - Monitor 2 adds image A to the cache - has same id, so image is replaced - Monitor 1 removes image A - image A is completely removed from cache - Monitor 2 render command hangs waiting for image A - -Addresses bug: https://bugzilla.redhat.com/show_bug.cgi?id=1194354 ---- - gtk/spice-channel-cache.h | 60 ++++++++++++++++++++++++++++++++++++----------- - gtk/spice-session.c | 2 +- - 2 files changed, 47 insertions(+), 15 deletions(-) - -diff --git a/gtk/spice-channel-cache.h b/gtk/spice-channel-cache.h -index 17775e6..6e2d084 100644 ---- a/gtk/spice-channel-cache.h -+++ b/gtk/spice-channel-cache.h -@@ -27,15 +27,20 @@ G_BEGIN_DECLS - typedef struct display_cache_item { - guint64 id; - gboolean lossy; -+ guint32 ref_count; - } display_cache_item; - --typedef GHashTable display_cache; -+typedef struct display_cache { -+ GHashTable *table; -+ gboolean ref_counted; -+}display_cache; - - static inline display_cache_item* cache_item_new(guint64 id, gboolean lossy) - { - display_cache_item *self = g_slice_new(display_cache_item); - self->id = id; - self->lossy = lossy; -+ self->ref_count = 1; - return self; - } - -@@ -46,18 +51,24 @@ static inline void cache_item_free(display_cache_item *self) - - static inline display_cache* cache_new(GDestroyNotify value_destroy) - { -- GHashTable* self; -- -- self = g_hash_table_new_full(g_int64_hash, g_int64_equal, -- (GDestroyNotify)cache_item_free, -- value_destroy); -- -+ display_cache * self = g_slice_new(display_cache); -+ self->table = g_hash_table_new_full(g_int64_hash, g_int64_equal, -+ (GDestroyNotify) cache_item_free, -+ value_destroy); -+ self->ref_counted = FALSE; - return self; - } - -+static inline display_cache * cache_image_new(GDestroyNotify value_destroy) -+{ -+ display_cache * self = cache_new(value_destroy); -+ self->ref_counted = TRUE; -+ return self; -+}; -+ - static inline gpointer cache_find(display_cache *cache, uint64_t id) - { -- return g_hash_table_lookup(cache, &id); -+ return g_hash_table_lookup(cache->table, &id); - } - - static inline gpointer cache_find_lossy(display_cache *cache, uint64_t id, gboolean *lossy) -@@ -65,7 +76,7 @@ static inline gpointer cache_find_lossy(display_cache *cache, uint64_t id, gbool - gpointer value; - display_cache_item *item; - -- if (!g_hash_table_lookup_extended(cache, &id, (gpointer*)&item, &value)) -+ if (!g_hash_table_lookup_extended(cache->table, &id, (gpointer*)&item, &value)) - return NULL; - - *lossy = item->lossy; -@@ -77,8 +88,17 @@ static inline void cache_add_lossy(display_cache *cache, uint64_t id, - gpointer value, gboolean lossy) - { - display_cache_item *item = cache_item_new(id, lossy); -- -- g_hash_table_replace(cache, item, value); -+ display_cache_item *current_item; -+ gpointer current_image; -+ -+ //If image is currently in the table add its reference count before replacing it -+ if(cache->ref_counted) { -+ if(g_hash_table_lookup_extended(cache->table, &id, (gpointer*) ¤t_item, -+ (gpointer*) ¤t_image)) { -+ item->ref_count = current_item->ref_count + 1; -+ } -+ } -+ g_hash_table_replace(cache->table, item, value); - } - - static inline void cache_add(display_cache *cache, uint64_t id, gpointer value) -@@ -88,17 +108,29 @@ static inline void cache_add(display_cache *cache, uint64_t id, gpointer value) - - static inline gboolean cache_remove(display_cache *cache, uint64_t id) - { -- return g_hash_table_remove(cache, &id); -+ display_cache_item * item; -+ gpointer value; -+ -+ if( g_hash_table_lookup_extended(cache->table, &id, (gpointer*) &item, &value)) { -+ --item->ref_count; -+ if(!cache->ref_counted || item->ref_count == 0 ) { -+ return g_hash_table_remove(cache->table, &id); -+ } -+ } -+ else { -+ return FALSE; -+ } -+ return TRUE; - } - - static inline void cache_clear(display_cache *cache) - { -- g_hash_table_remove_all(cache); -+ g_hash_table_remove_all(cache->table); - } - - static inline void cache_unref(display_cache *cache) - { -- g_hash_table_unref(cache); -+ g_hash_table_unref(cache->table); - } - - G_END_DECLS -diff --git a/gtk/spice-session.c b/gtk/spice-session.c -index 7d84c07..2a53230 100644 ---- a/gtk/spice-session.c -+++ b/gtk/spice-session.c -@@ -165,7 +165,7 @@ static void spice_session_init(SpiceSession *session) - g_free(channels); - - ring_init(&s->channels); -- s->images = cache_new((GDestroyNotify)pixman_image_unref); -+ s->images = cache_image_new((GDestroyNotify)pixman_image_unref); - s->glz_window = glz_decoder_window_new(); - update_proxy(session, NULL); - } --- -2.4.3 - diff --git a/SOURCES/0009-spice-uri-Reset-SpiceURI-before-parsing.patch b/SOURCES/0009-spice-uri-Reset-SpiceURI-before-parsing.patch new file mode 100644 index 0000000..2eaf421 --- /dev/null +++ b/SOURCES/0009-spice-uri-Reset-SpiceURI-before-parsing.patch @@ -0,0 +1,71 @@ +From 92a12ce39b7b49ab4f992066dcafeab98680232f Mon Sep 17 00:00:00 2001 +From: Pavel Grunt +Date: Wed, 1 Jun 2016 10:04:45 +0200 +Subject: [PATCH 09/15] spice-uri: Reset SpiceURI before parsing + +Avoid using old values after parsing a new uri. + +Related: rhbz#1335239 +(cherry picked from commit 024eccefba506f57fbff837c6d75864c51ed2add) +--- + src/spice-uri.c | 17 +++++++++++++---- + tests/uri.c | 1 + + 2 files changed, 14 insertions(+), 4 deletions(-) + +diff --git a/src/spice-uri.c b/src/spice-uri.c +index e2c5c9a..1684328 100644 +--- a/src/spice-uri.c ++++ b/src/spice-uri.c +@@ -68,6 +68,15 @@ SpiceURI* spice_uri_new(void) + return self; + } + ++static void spice_uri_reset(SpiceURI *self) ++{ ++ g_clear_pointer(&self->scheme, g_free); ++ g_clear_pointer(&self->hostname, g_free); ++ g_clear_pointer(&self->user, g_free); ++ g_clear_pointer(&self->password, g_free); ++ self->port = 0; ++} ++ + G_GNUC_INTERNAL + gboolean spice_uri_parse(SpiceURI *self, const gchar *_uri, GError **error) + { +@@ -76,6 +85,9 @@ gboolean spice_uri_parse(SpiceURI *self, const gchar *_uri, GError **error) + size_t len; + + g_return_val_if_fail(self != NULL, FALSE); ++ ++ spice_uri_reset(self); ++ + g_return_val_if_fail(_uri != NULL, FALSE); + + uri = dup = g_strdup(_uri); +@@ -304,10 +316,7 @@ static void spice_uri_finalize(GObject* obj) + SpiceURI *self; + + self = G_TYPE_CHECK_INSTANCE_CAST(obj, SPICE_TYPE_URI, SpiceURI); +- g_free(self->scheme); +- g_free(self->hostname); +- g_free(self->user); +- g_free(self->password); ++ spice_uri_reset(self); + + G_OBJECT_CLASS (spice_uri_parent_class)->finalize (obj); + } +diff --git a/tests/uri.c b/tests/uri.c +index b68f159..d57f072 100644 +--- a/tests/uri.c ++++ b/tests/uri.c +@@ -87,6 +87,7 @@ static void test_spice_uri_ipv4_good(void) + {"https://127.0.0.1", "https", "127.0.0.1", 3129, NULL, NULL, NULL}, + {"127.0.0.1", "http", "127.0.0.1", 3128, NULL, NULL, NULL}, + {"http://user:password@host:80", "http", "host", 80, "user", "password", NULL}, ++ {"https://host:42", "https", "host", 42, NULL, NULL, NULL}, /* tests resetting of username & password */ + }; + + test_spice_uri_good(valid_test_cases, G_N_ELEMENTS(valid_test_cases)); +-- +2.5.5 + diff --git a/SOURCES/0010-glib-compat-Add-g_format_size.patch b/SOURCES/0010-glib-compat-Add-g_format_size.patch deleted file mode 100644 index 6ff195d..0000000 --- a/SOURCES/0010-glib-compat-Add-g_format_size.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 3a9910bb3b70dc09ddb60d4c2d1130072754cb7d Mon Sep 17 00:00:00 2001 -From: Pavel Grunt -Date: Fri, 28 Aug 2015 02:40:48 +0200 -Subject: [PATCH 10/11] glib-compat: Add g_format_size - -g_format_size_for_display is deprecated since glib 2.30. See glib commit -afd1e3697065c1bd23fe9a1cacf43d8744d0bc9b - -g_format_size will be used in the following commit - -Acked-by: Frediano Ziglio ---- - gtk/glib-compat.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ - gtk/glib-compat.h | 1 + - 2 files changed, 63 insertions(+) - -diff --git a/gtk/glib-compat.c b/gtk/glib-compat.c -index 9d1165e..930ef31 100644 ---- a/gtk/glib-compat.c -+++ b/gtk/glib-compat.c -@@ -25,6 +25,68 @@ - #if !GLIB_CHECK_VERSION(2,26,0) - G_DEFINE_BOXED_TYPE (GError, spice_error, g_error_copy, g_error_free) - -+#define KILOBYTE_FACTOR (G_GOFFSET_CONSTANT (1000)) -+#define MEGABYTE_FACTOR (KILOBYTE_FACTOR * KILOBYTE_FACTOR) -+#define GIGABYTE_FACTOR (MEGABYTE_FACTOR * KILOBYTE_FACTOR) -+#define TERABYTE_FACTOR (GIGABYTE_FACTOR * KILOBYTE_FACTOR) -+#define PETABYTE_FACTOR (TERABYTE_FACTOR * KILOBYTE_FACTOR) -+#define EXABYTE_FACTOR (PETABYTE_FACTOR * KILOBYTE_FACTOR) -+ -+/** -+ * g_format_size: -+ * @size: a size in bytes -+ * -+ * Formats a size (for example the size of a file) into a human readable -+ * string. Sizes are rounded to the nearest size prefix (kB, MB, GB) -+ * and are displayed rounded to the nearest tenth. E.g. the file size -+ * 3292528 bytes will be converted into the string "3.2 MB". -+ * -+ * The prefix units base is 1000 (i.e. 1 kB is 1000 bytes). -+ * -+ * This string should be freed with g_free() when not needed any longer. -+ * -+ * See g_format_size_full() for more options about how the size might be -+ * formatted. -+ * -+ * Returns: a newly-allocated formatted string containing a human readable -+ * file size -+ * -+ * Since: 2.30 -+ */ -+gchar * -+g_format_size (guint64 size) -+{ -+ GString *string; -+ -+ string = g_string_new (NULL); -+ -+ if (size < KILOBYTE_FACTOR) -+ { -+ g_string_printf (string, -+ g_dngettext(GETTEXT_PACKAGE, "%u byte", "%u bytes", (guint) size), -+ (guint) size); -+ } -+ -+ else if (size < MEGABYTE_FACTOR) -+ g_string_printf (string, _("%.1f kB"), (gdouble) size / (gdouble) KILOBYTE_FACTOR); -+ -+ else if (size < GIGABYTE_FACTOR) -+ g_string_printf (string, _("%.1f MB"), (gdouble) size / (gdouble) MEGABYTE_FACTOR); -+ -+ else if (size < TERABYTE_FACTOR) -+ g_string_printf (string, _("%.1f GB"), (gdouble) size / (gdouble) GIGABYTE_FACTOR); -+ else if (size < PETABYTE_FACTOR) -+ g_string_printf (string, _("%.1f TB"), (gdouble) size / (gdouble) TERABYTE_FACTOR); -+ -+ else if (size < EXABYTE_FACTOR) -+ g_string_printf (string, _("%.1f PB"), (gdouble) size / (gdouble) PETABYTE_FACTOR); -+ -+ else -+ g_string_printf (string, _("%.1f EB"), (gdouble) size / (gdouble) EXABYTE_FACTOR); -+ -+ return g_string_free (string, FALSE); -+} -+ - /** - * g_key_file_set_uint64: - * @key_file: a #GKeyFile -diff --git a/gtk/glib-compat.h b/gtk/glib-compat.h -index 45d961e..81d27c4 100644 ---- a/gtk/glib-compat.h -+++ b/gtk/glib-compat.h -@@ -108,6 +108,7 @@ g_slist_free_full(GSList *list, - #if !GLIB_CHECK_VERSION(2,30,0) - #define G_TYPE_MAIN_CONTEXT (spice_main_context_get_type ()) - GType spice_main_context_get_type (void) G_GNUC_CONST; -+gchar *g_format_size (guint64 size); - #endif - - #if !GLIB_CHECK_VERSION(2,32,0) --- -2.4.3 - diff --git a/SOURCES/0010-spice-uri-Do-not-allow-empty-port-string.patch b/SOURCES/0010-spice-uri-Do-not-allow-empty-port-string.patch new file mode 100644 index 0000000..aa8d188 --- /dev/null +++ b/SOURCES/0010-spice-uri-Do-not-allow-empty-port-string.patch @@ -0,0 +1,43 @@ +From d2ea50359a5a646d3958bf2afdacebc20794b375 Mon Sep 17 00:00:00 2001 +From: Pavel Grunt +Date: Wed, 1 Jun 2016 10:04:46 +0200 +Subject: [PATCH 10/15] spice-uri: Do not allow empty port string + +Related: rhbz#1335239 + +Acked-by: Victor Toso +(cherry picked from commit 85051b06c1f04b206c00bb7f674a9a29bfb19594) +--- + src/spice-uri.c | 3 +++ + tests/uri.c | 1 + + 2 files changed, 4 insertions(+) + +diff --git a/src/spice-uri.c b/src/spice-uri.c +index 1684328..ce99f49 100644 +--- a/src/spice-uri.c ++++ b/src/spice-uri.c +@@ -147,6 +147,9 @@ gboolean spice_uri_parse(SpiceURI *self, const gchar *_uri, GError **error) + g_set_error(error, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED, + "Invalid uri port: %s", uri_port); + goto end; ++ } else if (endptr == uri_port) { ++ g_set_error(error, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED, "Missing uri port"); ++ goto end; + } + spice_uri_set_port(self, port); + } +diff --git a/tests/uri.c b/tests/uri.c +index d57f072..ee3d061 100644 +--- a/tests/uri.c ++++ b/tests/uri.c +@@ -75,6 +75,7 @@ static void test_spice_uri_ipv4_bad(void) + {"http://", "http", NULL, 3128, NULL, NULL, "Invalid hostname in uri address"}, + {"http://127.0.0.1:port", "http", "127.0.0.1", 3128, NULL, NULL, + "Invalid uri port: port"}, ++ {"http://127.0.0.1:", "http", "127.0.0.1", 3128, NULL, NULL, "Missing uri port"}, + }; + + test_spice_uri_bad(invalid_test_cases, G_N_ELEMENTS(invalid_test_cases)); +-- +2.5.5 + diff --git a/SOURCES/0011-file-xfer-Add-debug-messages-about-a-file-transfer-p.patch b/SOURCES/0011-file-xfer-Add-debug-messages-about-a-file-transfer-p.patch deleted file mode 100644 index 7991f10..0000000 --- a/SOURCES/0011-file-xfer-Add-debug-messages-about-a-file-transfer-p.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 4a4afa2901f8b71eb4e999a62746188d65e73864 Mon Sep 17 00:00:00 2001 -From: Pavel Grunt -Date: Tue, 25 Aug 2015 16:32:47 +0200 -Subject: [PATCH 11/11] file-xfer: Add debug messages about a file transfer - progress - -During the file transfer debug messages about the progress are printed -every 20 seconds for each of the file transfer tasks. - -Fixes: -https://bugzilla.redhat.com/show_bug.cgi?id=1140512 - -Acked-by: Frediano Ziglio ---- - gtk/channel-main.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 46 insertions(+) - -diff --git a/gtk/channel-main.c b/gtk/channel-main.c -index 7ab3407..ae22333 100644 ---- a/gtk/channel-main.c -+++ b/gtk/channel-main.c -@@ -70,6 +70,8 @@ typedef struct SpiceFileXferTask { - char buffer[FILE_XFER_CHUNK_SIZE]; - uint64_t read_bytes; - uint64_t file_size; -+ GDateTime *start_time; -+ GDateTime *last_update; - GError *error; - } SpiceFileXferTask; - -@@ -1559,6 +1561,10 @@ static void file_xfer_task_free(SpiceFileXferTask *task) - g_clear_object(&task->channel); - g_clear_object(&task->file); - g_clear_object(&task->file_stream); -+ if (spice_util_get_debug()) { -+ g_date_time_unref(task->start_time); -+ g_date_time_unref(task->last_update); -+ } - g_free(task); - } - -@@ -1594,6 +1600,23 @@ static void file_xfer_close_cb(GObject *object, - g_simple_async_result_set_op_res_gboolean(res, FALSE); - } else { - g_simple_async_result_set_op_res_gboolean(res, TRUE); -+ if (spice_util_get_debug()) { -+ GDateTime *now = g_date_time_new_now_local(); -+ gchar *basename = g_file_get_basename(task->file); -+ double seconds = -+ (double) g_date_time_difference(now, task->start_time) / G_TIME_SPAN_SECOND; -+ gchar *file_size_str = g_format_size(task->file_size); -+ gchar *transfer_speed_str = g_format_size(task->file_size / seconds); -+ -+ g_warn_if_fail(task->read_bytes == task->file_size); -+ SPICE_DEBUG("transferred file %s of %s size in %.1f seconds (%s/s)", -+ basename, file_size_str, seconds, transfer_speed_str); -+ -+ g_free(basename); -+ g_free(file_size_str); -+ g_free(transfer_speed_str); -+ g_date_time_unref(now); -+ } - } - g_simple_async_result_complete_in_idle(res); - g_object_unref(res); -@@ -1616,6 +1639,21 @@ static void file_xfer_data_flushed_cb(GObject *source_object, - return; - } - -+ if (spice_util_get_debug()) { -+ const GTimeSpan interval = 20 * G_TIME_SPAN_SECOND; -+ GDateTime *now = g_date_time_new_now_local(); -+ -+ if (interval < g_date_time_difference(now, task->last_update)) { -+ gchar *basename = g_file_get_basename(task->file); -+ g_date_time_unref(task->last_update); -+ task->last_update = g_date_time_ref(now); -+ SPICE_DEBUG("transferred %.2f%% of the file %s", -+ 100.0 * task->read_bytes / task->file_size, basename); -+ g_free(basename); -+ } -+ g_date_time_unref(now); -+ } -+ - if (task->progress_callback) - task->progress_callback(task->read_bytes, task->file_size, - task->progress_callback_data); -@@ -2775,6 +2813,14 @@ static void file_xfer_send_start_msg_async(SpiceMainChannel *channel, - task->callback = callback; - task->user_data = user_data; - -+ if (spice_util_get_debug()) { -+ gchar *basename = g_file_get_basename(task->file); -+ task->start_time = g_date_time_new_now_local(); -+ task->last_update = g_date_time_ref(task->start_time); -+ -+ SPICE_DEBUG("transfer of file %s has started", basename); -+ g_free(basename); -+ } - CHANNEL_DEBUG(task->channel, "Insert a xfer task:%d to task list", task->id); - g_hash_table_insert(c->file_xfer_tasks, GUINT_TO_POINTER(task->id), task); - --- -2.4.3 - diff --git a/SOURCES/0011-spice-uri-Check-if-port-is-in-allowed-range.patch b/SOURCES/0011-spice-uri-Check-if-port-is-in-allowed-range.patch new file mode 100644 index 0000000..30bd646 --- /dev/null +++ b/SOURCES/0011-spice-uri-Check-if-port-is-in-allowed-range.patch @@ -0,0 +1,59 @@ +From fabbac1b93acb2ffd406e30092b0cecdfed04dd7 Mon Sep 17 00:00:00 2001 +From: Pavel Grunt +Date: Wed, 1 Jun 2016 10:04:47 +0200 +Subject: [PATCH 11/15] spice-uri: Check if port is in allowed range + +Use g_ascii_strtoll because it helps to detect overflow. + +Related: rhbz#1335239 + +Acked-by: Victor Toso +(cherry picked from commit eacbe261d48979f72585225107d00bba76623e8e) +--- + src/spice-uri.c | 8 ++++++-- + tests/uri.c | 3 +++ + 2 files changed, 9 insertions(+), 2 deletions(-) + +diff --git a/src/spice-uri.c b/src/spice-uri.c +index ce99f49..51a6d34 100644 +--- a/src/spice-uri.c ++++ b/src/spice-uri.c +@@ -141,8 +141,8 @@ gboolean spice_uri_parse(SpiceURI *self, const gchar *_uri, GError **error) + uri_port = uriv[1]; + + if (uri_port != NULL) { +- char *endptr; +- guint port = strtoul(uri_port, &endptr, 10); ++ gchar *endptr; ++ gint64 port = g_ascii_strtoll(uri_port, &endptr, 10); + if (*endptr != '\0') { + g_set_error(error, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED, + "Invalid uri port: %s", uri_port); +@@ -151,6 +151,10 @@ gboolean spice_uri_parse(SpiceURI *self, const gchar *_uri, GError **error) + g_set_error(error, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED, "Missing uri port"); + goto end; + } ++ if (port <= 0 || port > 65535) { ++ g_set_error(error, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED, "Port out of range"); ++ goto end; ++ } + spice_uri_set_port(self, port); + } + +diff --git a/tests/uri.c b/tests/uri.c +index ee3d061..34569ec 100644 +--- a/tests/uri.c ++++ b/tests/uri.c +@@ -76,6 +76,9 @@ static void test_spice_uri_ipv4_bad(void) + {"http://127.0.0.1:port", "http", "127.0.0.1", 3128, NULL, NULL, + "Invalid uri port: port"}, + {"http://127.0.0.1:", "http", "127.0.0.1", 3128, NULL, NULL, "Missing uri port"}, ++ {"http://127.0.0.1:-80", "http", "127.0.0.1", 3128, NULL, NULL, "Port out of range"}, ++ {"http://127.0.0.1:4294967396", "http", "127.0.0.1", 3128, NULL, NULL, "Port out of range"}, ++ {"http://127.0.0.1:12345678901234", "http", "127.0.0.1", 3128, NULL, NULL, "Port out of range"}, + }; + + test_spice_uri_bad(invalid_test_cases, G_N_ELEMENTS(invalid_test_cases)); +-- +2.5.5 + diff --git a/SOURCES/0012-session-Enable-proxy-when-requested.patch b/SOURCES/0012-session-Enable-proxy-when-requested.patch deleted file mode 100644 index 951a02d..0000000 --- a/SOURCES/0012-session-Enable-proxy-when-requested.patch +++ /dev/null @@ -1,27 +0,0 @@ -From bec4fee3966dc78e7214c4bb00c06b4f4ea3cb49 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= -Date: Tue, 1 Sep 2015 13:29:15 +0200 -Subject: [PATCH 13/13] session: Enable proxy when requested - -Disabling the proxy avoids usage of GProxyResolver to determine -the necessary proxy protocol and to do the proxy negotiation ---- - gtk/spice-session.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/gtk/spice-session.c b/gtk/spice-session.c -index 2a53230..4e41ced 100644 ---- a/gtk/spice-session.c -+++ b/gtk/spice-session.c -@@ -1895,7 +1895,7 @@ GSocketConnection* spice_session_channel_open_host(SpiceSession *session, SpiceC - - open_host.client = g_socket_client_new(); - #if GLIB_CHECK_VERSION(2,26,0) -- g_socket_client_set_enable_proxy(open_host.client, FALSE); -+ g_socket_client_set_enable_proxy(open_host.client, s->proxy != NULL); - g_socket_client_set_timeout(open_host.client, SOCKET_TIMEOUT); - #else - open_host.timeout_id = --- -2.4.3 - diff --git a/SOURCES/0012-spice-uri-Validate-uri-scheme.patch b/SOURCES/0012-spice-uri-Validate-uri-scheme.patch new file mode 100644 index 0000000..c2cc0c7 --- /dev/null +++ b/SOURCES/0012-spice-uri-Validate-uri-scheme.patch @@ -0,0 +1,92 @@ +From 0da3d2768c544cc3c1146b00b9f1481c32010c91 Mon Sep 17 00:00:00 2001 +From: Pavel Grunt +Date: Wed, 1 Jun 2016 10:04:48 +0200 +Subject: [PATCH 12/15] spice-uri: Validate uri scheme + +Related: rhbz#1335239 + +Acked-by: Victor Toso +(cherry picked from commit 8dcb4129acde2aed353cd66e28678408e7d1257c) +--- + src/spice-uri.c | 26 ++++++++++++++++---------- + tests/uri.c | 2 ++ + 2 files changed, 18 insertions(+), 10 deletions(-) + +diff --git a/src/spice-uri.c b/src/spice-uri.c +index 51a6d34..c452db3 100644 +--- a/src/spice-uri.c ++++ b/src/spice-uri.c +@@ -80,7 +80,9 @@ static void spice_uri_reset(SpiceURI *self) + G_GNUC_INTERNAL + gboolean spice_uri_parse(SpiceURI *self, const gchar *_uri, GError **error) + { +- gchar *dup, *uri; ++ gchar *dup, *uri, **uriv = NULL; ++ const gchar *uri_port = NULL; ++ char *uri_scheme = NULL; + gboolean success = FALSE; + size_t len; + +@@ -93,17 +95,21 @@ gboolean spice_uri_parse(SpiceURI *self, const gchar *_uri, GError **error) + uri = dup = g_strdup(_uri); + /* FIXME: use GUri when it is ready... only support http atm */ + /* the code is voluntarily not parsing thoroughly the uri */ +- if (g_ascii_strncasecmp("http://", uri, 7) == 0) { +- uri += 7; ++ uri_scheme = g_uri_parse_scheme(uri); ++ if (uri_scheme == NULL) { + spice_uri_set_scheme(self, "http"); ++ } else { ++ spice_uri_set_scheme(self, uri_scheme); ++ uri += strlen(uri_scheme) + 3; /* scheme + "://" */ ++ } ++ if (g_ascii_strcasecmp(spice_uri_get_scheme(self), "http") == 0) { + spice_uri_set_port(self, 3128); +- } else if (g_ascii_strncasecmp("https://", uri, 8) == 0) { +- uri += 8; +- spice_uri_set_scheme(self, "https"); ++ } else if (g_ascii_strcasecmp(spice_uri_get_scheme(self), "https") == 0) { + spice_uri_set_port(self, 3129); + } else { +- spice_uri_set_scheme(self, "http"); +- spice_uri_set_port(self, 3128); ++ g_set_error(error, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED, ++ "Invalid uri scheme for proxy: %s", spice_uri_get_scheme(self)); ++ goto end; + } + /* remove trailing slash */ + len = strlen(uri); +@@ -127,8 +133,7 @@ gboolean spice_uri_parse(SpiceURI *self, const gchar *_uri, GError **error) + } + + /* max 2 parts, host:port */ +- gchar **uriv = g_strsplit(uri, ":", 2); +- const gchar *uri_port = NULL; ++ uriv = g_strsplit(uri, ":", 2); + + if (uriv[0] == NULL || strlen(uriv[0]) == 0) { + g_set_error(error, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED, +@@ -161,6 +166,7 @@ gboolean spice_uri_parse(SpiceURI *self, const gchar *_uri, GError **error) + success = TRUE; + + end: ++ free(uri_scheme); + g_free(dup); + g_strfreev(uriv); + return success; +diff --git a/tests/uri.c b/tests/uri.c +index 34569ec..80b00f4 100644 +--- a/tests/uri.c ++++ b/tests/uri.c +@@ -79,6 +79,8 @@ static void test_spice_uri_ipv4_bad(void) + {"http://127.0.0.1:-80", "http", "127.0.0.1", 3128, NULL, NULL, "Port out of range"}, + {"http://127.0.0.1:4294967396", "http", "127.0.0.1", 3128, NULL, NULL, "Port out of range"}, + {"http://127.0.0.1:12345678901234", "http", "127.0.0.1", 3128, NULL, NULL, "Port out of range"}, ++ {"scheme://192.168.1.1:3128", "http", "127.0.0.1", 3128, NULL, NULL, ++ "Invalid uri scheme for proxy: scheme"}, + }; + + test_spice_uri_bad(invalid_test_cases, G_N_ELEMENTS(invalid_test_cases)); +-- +2.5.5 + diff --git a/SOURCES/0013-spice-uri-Add-ipv6-support.patch b/SOURCES/0013-spice-uri-Add-ipv6-support.patch new file mode 100644 index 0000000..382aa77 --- /dev/null +++ b/SOURCES/0013-spice-uri-Add-ipv6-support.patch @@ -0,0 +1,109 @@ +From e25a335f18c8138fd64e762d24afb512ca13583f Mon Sep 17 00:00:00 2001 +From: Pavel Grunt +Date: Wed, 1 Jun 2016 10:04:49 +0200 +Subject: [PATCH 13/15] spice-uri: Add ipv6 support + +Just basic support - http://user:password@[host]:port + +Resolves: rhbz#1335239 +(cherry picked from commit b542dfa2d58cd352dc596318a1e50f074865ef5e) +--- + src/spice-uri.c | 24 ++++++++++++++++++++---- + tests/uri.c | 33 +++++++++++++++++++++++++++++++++ + 2 files changed, 53 insertions(+), 4 deletions(-) + +diff --git a/src/spice-uri.c b/src/spice-uri.c +index c452db3..99431d0 100644 +--- a/src/spice-uri.c ++++ b/src/spice-uri.c +@@ -132,8 +132,26 @@ gboolean spice_uri_parse(SpiceURI *self, const gchar *_uri, GError **error) + uri = next; + } + +- /* max 2 parts, host:port */ +- uriv = g_strsplit(uri, ":", 2); ++ if (*uri == '[') { /* ipv6 address */ ++ uriv = g_strsplit(uri + 1, "]", 2); ++ if (uriv[1] == NULL) { ++ g_set_error(error, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED, ++ "Missing ']' in ipv6 uri"); ++ goto end; ++ } ++ if (*uriv[1] == ':') { ++ uri_port = uriv[1] + 1; ++ } else if (strlen(uriv[1]) > 0) { /* invalid string after the hostname */ ++ g_set_error(error, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED, ++ "Invalid uri address"); ++ goto end; ++ } ++ } else { ++ /* max 2 parts, host:port */ ++ uriv = g_strsplit(uri, ":", 2); ++ if (uriv[0] != NULL) ++ uri_port = uriv[1]; ++ } + + if (uriv[0] == NULL || strlen(uriv[0]) == 0) { + g_set_error(error, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED, +@@ -142,8 +160,6 @@ gboolean spice_uri_parse(SpiceURI *self, const gchar *_uri, GError **error) + } + + spice_uri_set_hostname(self, uriv[0]); +- if (uriv[0] != NULL) +- uri_port = uriv[1]; + + if (uri_port != NULL) { + gchar *endptr; +diff --git a/tests/uri.c b/tests/uri.c +index 80b00f4..ea8b794 100644 +--- a/tests/uri.c ++++ b/tests/uri.c +@@ -99,12 +99,45 @@ static void test_spice_uri_ipv4_good(void) + test_spice_uri_good(valid_test_cases, G_N_ELEMENTS(valid_test_cases)); + } + ++static void test_spice_uri_ipv6_bad(void) ++{ ++ const struct test_case invalid_test_cases[] = { ++ {"http://[]:80", "http", NULL, 80, NULL, NULL, "Invalid hostname in uri address"}, ++ {"http://[::1", "http", NULL, 3128, NULL, NULL, "Missing ']' in ipv6 uri"}, ++ {"http://[host]1234", "http", "host", 3128, NULL, NULL, "Invalid uri address"}, ++ {"http://[host]foo/", "http", "host", 3128, NULL, NULL, "Invalid uri address"}, ++ {"http://[::1]:port", "http", "::1", 3128, NULL, NULL, "Invalid uri port: port"}, ++ {"http://[::127.0.0.1]:", "http", "::127.0.0.1", 3128, NULL, NULL, "Missing uri port"}, ++ {"http://[::127.0.0.1]:-42", "http", "::127.0.0.1", 3128, NULL, NULL, "Port out of range"}, ++ {"[3ffe:2a00:100:7031::1]:42000000", "http", "3ffe:2a00:100:7031::1", 3128, NULL, NULL, "Port out of range"}, ++ {"scheme://[3ffe::192.168.1.1]:3128", "http", "3ffe::192.168.1.1", 3128, NULL, NULL, ++ "Invalid uri scheme for proxy: scheme"}, ++ }; ++ ++ test_spice_uri_bad(invalid_test_cases, G_N_ELEMENTS(invalid_test_cases)); ++} ++ ++static void test_spice_uri_ipv6_good(void) ++{ ++ const struct test_case valid_test_cases[] = { ++ {"http://user:password@[host]:80/", "http", "host", 80, "user", "password", NULL}, ++ {"http://user@[1080:0:0:0:8:800:200C:4171]:100", "http", "1080:0:0:0:8:800:200C:4171", 100, ++ "user", NULL, NULL}, ++ {"https://[1080::8:800:200C:417A]", "https", "1080::8:800:200C:417A", 3129, NULL, NULL, NULL}, ++ {"[3ffe:2a00:100:7031::1]", "http", "3ffe:2a00:100:7031::1", 3128, NULL, NULL, NULL}, ++ }; ++ ++ test_spice_uri_good(valid_test_cases, G_N_ELEMENTS(valid_test_cases)); ++} ++ + int main(int argc, char* argv[]) + { + g_test_init(&argc, &argv, NULL); + + g_test_add_func("/spice_uri/ipv4/bad-uri", test_spice_uri_ipv4_bad); + g_test_add_func("/spice_uri/ipv4/good-uri", test_spice_uri_ipv4_good); ++ g_test_add_func("/spice_uri/ipv6/bad-uri", test_spice_uri_ipv6_bad); ++ g_test_add_func("/spice_uri/ipv6/good-uri", test_spice_uri_ipv6_good); + + return g_test_run(); + } +-- +2.5.5 + diff --git a/SOURCES/0014-Explicitly-specify-size-of-SpiceMsgSmartcardData.patch b/SOURCES/0014-Explicitly-specify-size-of-SpiceMsgSmartcardData.patch new file mode 100644 index 0000000..966c740 --- /dev/null +++ b/SOURCES/0014-Explicitly-specify-size-of-SpiceMsgSmartcardData.patch @@ -0,0 +1,51 @@ +From e45a8b586d19e7eb36f4fa72c2457947e5abb5de Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= +Date: Tue, 7 Jun 2016 01:56:21 +0200 +Subject: [PATCH 14/15] Explicitly specify size of SpiceMsgSmartcardData + +Without this, the demarshalling code does not know we expect exactly +SpiceMsgSmartcardData::length bytes, and has to guess it from the +amount of data which was sent + +Signed-off-by: Frediano Ziglio +Acked-by: Christophe Fergeau +--- + spice-common/common/generated_client_demarshallers.c | 8 +++++++- + spice-common/common/generated_server_marshallers.c | 2 +- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/spice-common/common/generated_client_demarshallers.c b/spice-common/common/generated_client_demarshallers.c +index e1393e7..62ef234 100644 +--- a/spice-common/common/generated_client_demarshallers.c ++++ b/spice-common/common/generated_client_demarshallers.c +@@ -7854,7 +7854,13 @@ static uint8_t * parse_msg_smartcard_data(uint8_t *message_start, uint8_t *messa + SpiceMsgSmartcard *out; + + { /* data */ +- data__nelements = message_end - (start + 12); ++ uint32_t length__value; ++ pos = start + 8; ++ if (SPICE_UNLIKELY(pos + 4 > message_end)) { ++ goto error; ++ } ++ length__value = read_uint32(pos); ++ data__nelements = length__value; + + data__nw_size = data__nelements; + data__mem_size = sizeof(uint8_t) * data__nelements; +diff --git a/spice-common/common/generated_server_marshallers.c b/spice-common/common/generated_server_marshallers.c +index c00de5e..0f4978d 100644 +--- a/spice-common/common/generated_server_marshallers.c ++++ b/spice-common/common/generated_server_marshallers.c +@@ -1358,7 +1358,7 @@ void spice_marshall_msg_smartcard_data(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPI + spice_marshaller_add_uint32(m, src->type); + spice_marshaller_add_uint32(m, src->reader_id); + spice_marshaller_add_uint32(m, src->length); +- /* Remaining data must be appended manually */ ++ /* Don't marshall @nomarshal data */ + } + + #endif /* USE_SMARTCARD */ +-- +2.5.5 + diff --git a/SOURCES/0015-main-Don-t-delay-update_display_timer-0-for-up-to-1-.patch b/SOURCES/0015-main-Don-t-delay-update_display_timer-0-for-up-to-1-.patch new file mode 100644 index 0000000..51b7ce0 --- /dev/null +++ b/SOURCES/0015-main-Don-t-delay-update_display_timer-0-for-up-to-1-.patch @@ -0,0 +1,70 @@ +From 6dc79d9ffdb91784fd33c030de94b9b2c37be595 Mon Sep 17 00:00:00 2001 +From: Christophe Fergeau +Date: Wed, 25 May 2016 18:14:47 +0200 +Subject: [PATCH 15/15] main: Don't delay update_display_timer(0) for up to 1 + second + +When using remote-viewer --full-screen with a VM/client with multiple +monitors, a race can be observed during auto-configuration. First, the +client monitors config is sent to the guest: +(remote-viewer:19480): GSpice-DEBUG: channel-main.c:1166 main-1:0: sending new monitors config to guest +(remote-viewer:19480): GSpice-DEBUG: channel-main.c:1183 main-1:0: monitor #0: 1920x1080+0+0 @ 32 bpp +(remote-viewer:19480): GSpice-DEBUG: channel-main.c:1183 main-1:0: monitor #1: 1920x1080+1920+0 @ 32 bpp + +Then we receive messages from the agent which trigger a call to +update_display_timer(0) + +This should cause the current monitors state to be sent to the server +very soon after this call. However, in the racy case, this is delayed +for nearly a second, and timer_set_display() ends up being called at the +wrong time, when information about the first display channel have been +received from the server, but not the second one. + +When this happens, we inform the server that only one monitor is active, +then the server sends a MonitorsConfig message with 2 monitors (first +request we sent), and then with just 1 monitor (second request we sent). + +This causes remote-viewer to show one fullscreen black window indicating +"Connected to server" on one monitor and a working fullscreen window on +the second monitor. + +update_display_timer(0) schedules a timeout to be run with +g_timeout_add_seconds(0). However, g_timeout_add_seconds() schedules +timers with a granularity of a second, so the timeout we scheduled with +g_timeout_add_seconds() may fire up to 1 second later than when we +called it, while we really wanted it to fire as soon as possible. +Special-casing update_display_timer(0) and using g_timeout_add() in that +case avoid this issue. In theory, the race could probably still happen +with a very very bad timing, but in practice I don't think it will be +possible to trigger it after this change. + +https://bugzilla.redhat.com/show_bug.cgi?id=1323092 +--- + src/channel-main.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/src/channel-main.c b/src/channel-main.c +index 7f4d0b3..702ffa8 100644 +--- a/src/channel-main.c ++++ b/src/channel-main.c +@@ -1562,7 +1562,16 @@ static void update_display_timer(SpiceMainChannel *channel, guint seconds) + if (c->timer_id) + g_source_remove(c->timer_id); + +- c->timer_id = g_timeout_add_seconds(seconds, timer_set_display, channel); ++ if (seconds != 0) { ++ c->timer_id = g_timeout_add_seconds(seconds, timer_set_display, channel); ++ } else { ++ /* We need to special case 0, as we want the callback to fire as soon ++ * as possible. g_timeout_add_seconds(0) would set up a timer which would fire ++ * at the next second boundary, which might be nearly 1 full second later. ++ */ ++ c->timer_id = g_timeout_add(0, timer_set_display, channel); ++ } ++ + } + + /* coroutine context */ +-- +2.5.5 + diff --git a/SOURCES/0016-sasl-fix-SASL-GSSAPI-by-allowing-NULL-username.patch b/SOURCES/0016-sasl-fix-SASL-GSSAPI-by-allowing-NULL-username.patch new file mode 100644 index 0000000..865f0c3 --- /dev/null +++ b/SOURCES/0016-sasl-fix-SASL-GSSAPI-by-allowing-NULL-username.patch @@ -0,0 +1,43 @@ +From e65dbb732d4f110dd6b55b510a754cffe0472b10 Mon Sep 17 00:00:00 2001 +From: Alexander Bokovoy +Date: Mon, 6 Jun 2016 18:04:59 +0200 +Subject: [PATCH 16/17] sasl: fix SASL GSSAPI by allowing NULL username +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +SASL GSSAPI module will try to negotiate authentication based on the +credentials in the default credentials cache. It does not matter if +SPICE knows username or not as SASL negotiation will pass through the +discovered name from the GSSAPI module. + +Signed-off-by: Alexander Bokovoy +Acked-by: Fabiano Fidêncio +(cherry picked from commit fb8e51667b9fa63497e413fb4fd484d23b772788) +--- + src/spice-channel.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/src/spice-channel.c b/src/spice-channel.c +index e52a6a9..fdc0e97 100644 +--- a/src/spice-channel.c ++++ b/src/spice-channel.c +@@ -1389,11 +1389,10 @@ spice_channel_gather_sasl_credentials(SpiceChannel *channel, + switch (interact[ninteract].id) { + case SASL_CB_AUTHNAME: + case SASL_CB_USER: +- if (spice_session_get_username(c->session) == NULL) +- return FALSE; +- +- interact[ninteract].result = spice_session_get_username(c->session); +- interact[ninteract].len = strlen(interact[ninteract].result); ++ if (spice_session_get_username(c->session) != NULL) { ++ interact[ninteract].result = spice_session_get_username(c->session); ++ interact[ninteract].len = strlen(interact[ninteract].result); ++ } + break; + + case SASL_CB_PASS: +-- +2.9.0 + diff --git a/SOURCES/0017-session-Keep-brackets-around-ipv6-hostname.patch b/SOURCES/0017-session-Keep-brackets-around-ipv6-hostname.patch new file mode 100644 index 0000000..cf20949 --- /dev/null +++ b/SOURCES/0017-session-Keep-brackets-around-ipv6-hostname.patch @@ -0,0 +1,36 @@ +From c5c4b2f5535977b0aec7567cfb016a5419d65873 Mon Sep 17 00:00:00 2001 +From: Pavel Grunt +Date: Tue, 21 Jun 2016 15:13:31 +0200 +Subject: [PATCH 17/17] session: Keep brackets around ipv6 hostname +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +According to rfc2732: +"To use a literal IPv6 address in a URL, the literal address should be +enclosed in "[" and "]" characters." + +Resolves: rhbz#1331777 + +Acked-by: Marc-André Lureau +(cherry picked from commit ea37f06eaa11b6307c797895aeb85d87d142625a) +--- + src/spice-session.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/spice-session.c b/src/spice-session.c +index f77487a..cc4b614 100644 +--- a/src/spice-session.c ++++ b/src/spice-session.c +@@ -479,7 +479,7 @@ static int spice_parse_uri(SpiceSession *session, const char *original_uri) + } + tmp[0] = '\0'; + tmp++; +- host = g_strdup(authority + 1); ++ host = g_strdup_printf("[%s]", authority + 1); + if (tmp[0] == ':') + port = g_strdup(tmp + 1); + } else { +-- +2.9.0 + diff --git a/SOURCES/0018-session-Fix-IPv6-by-using-g_network_address_parse.patch b/SOURCES/0018-session-Fix-IPv6-by-using-g_network_address_parse.patch new file mode 100644 index 0000000..af72a0f --- /dev/null +++ b/SOURCES/0018-session-Fix-IPv6-by-using-g_network_address_parse.patch @@ -0,0 +1,32 @@ +From 482156c8fce4dce3ce9e098d808c515fa9ea2d87 Mon Sep 17 00:00:00 2001 +From: Pavel Grunt +Date: Fri, 29 Jul 2016 14:16:03 +0200 +Subject: [PATCH 18/19] session: Fix IPv6 by using g_network_address_parse + +It supports quoting the address with [] + +Regression since ea37f06eaa11b6307c797895aeb85d87d142625a + +Fixes: +https://bugzilla.redhat.com/show_bug.cgi?id=1361478 +(cherry picked from commit 5a301b201be77c0ece71640ba99e92733a93f950) +--- + src/spice-session.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/spice-session.c b/src/spice-session.c +index cc4b614..860461f 100644 +--- a/src/spice-session.c ++++ b/src/spice-session.c +@@ -2125,7 +2125,7 @@ static gboolean open_host_idle_cb(gpointer data) + #endif + } else { + SPICE_DEBUG("open host %s:%d", s->host, open_host->port); +- address = g_network_address_new(s->host, open_host->port); ++ address = g_network_address_parse(s->host, open_host->port, &open_host->error); + } + + if (address == NULL || open_host->error != NULL) { +-- +2.9.2 + diff --git a/SOURCES/0019-channel-check-if-channel-has-a-session.patch b/SOURCES/0019-channel-check-if-channel-has-a-session.patch new file mode 100644 index 0000000..f534946 --- /dev/null +++ b/SOURCES/0019-channel-check-if-channel-has-a-session.patch @@ -0,0 +1,38 @@ +From 0cb2f7634a5ddaefc115181ba76702378007b5c4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Fri, 20 May 2016 15:45:43 +0200 +Subject: [PATCH 19/19] channel: check if channel has a session +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Since 8943d2329, the channel may be disconnected from the session +before it's destroyed. In this case, session is NULL. + +Fixes some critical with virt-manager when closing a display: + +(virt-manager:20451): GSpice-CRITICAL **: spice_session_is_for_migration: assertion 'SPICE_IS_SESSION(session)' failed + +Signed-off-by: Marc-André Lureau +Acked-by: Pavel Grunt +(cherry picked from commit 73564cc1007a7c14e6c79dec67e99458de359898) +--- + src/spice-channel.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/spice-channel.c b/src/spice-channel.c +index fdc0e97..0d9e85a 100644 +--- a/src/spice-channel.c ++++ b/src/spice-channel.c +@@ -2314,7 +2314,7 @@ static gboolean spice_channel_delayed_unref(gpointer data) + c->state = SPICE_CHANNEL_STATE_UNCONNECTED; + + session = spice_channel_get_session(channel); +- if (spice_session_is_for_migration(session)) { ++ if (session && spice_session_is_for_migration(session)) { + /* error during migration - abort migration */ + spice_session_abort_migration(session); + return FALSE; +-- +2.9.2 + diff --git a/SOURCES/0020-clipboard-Add-fixup_clipboard_text-helper.patch b/SOURCES/0020-clipboard-Add-fixup_clipboard_text-helper.patch new file mode 100644 index 0000000..7b551b1 --- /dev/null +++ b/SOURCES/0020-clipboard-Add-fixup_clipboard_text-helper.patch @@ -0,0 +1,103 @@ +From a11888af13a4cfab5ded7dec47dfb904dfb65fcb Mon Sep 17 00:00:00 2001 +From: Christophe Fergeau +Date: Wed, 10 Aug 2016 11:17:35 +0200 +Subject: [PATCH 20/23] clipboard: Add fixup_clipboard_text helper + +This makes clipboard_received_cb a bit shorter, and will be useful +in the next commit. + +(cherry picked from commit b0a2ff4f205e39f87e9b54d658a27d415ee3d055) +--- + src/spice-gtk-session.c | 69 +++++++++++++++++++++++++++++++------------------ + 1 file changed, 44 insertions(+), 25 deletions(-) + +diff --git a/src/spice-gtk-session.c b/src/spice-gtk-session.c +index 4201ee0..6b1bcf6 100644 +--- a/src/spice-gtk-session.c ++++ b/src/spice-gtk-session.c +@@ -883,6 +883,49 @@ static gboolean check_clipboard_size_limits(SpiceGtkSession *session, + return TRUE; + } + ++/* This will convert line endings if needed (between Windows/Unix conventions), ++ * and will make sure 'len' does not take into account any trailing \0 as this could ++ * cause some confusion guest side. ++ * The 'len' argument will be modified by this function to the length of the modified ++ * string ++ */ ++static char *fixup_clipboard_text(SpiceGtkSession *self, const char *text, int *len) ++{ ++ char *conv = NULL; ++ int new_len = *len; ++ ++ ++ if (spice_main_agent_test_capability(self->priv->main, VD_AGENT_CAP_GUEST_LINEEND_CRLF)) { ++ GError *err = NULL; ++ ++ conv = spice_unix2dos(text, *len, &err); ++ if (err) { ++ g_warning("Failed to convert text line ending: %s", err->message); ++ g_clear_error(&err); ++ return NULL; ++ } ++ ++ new_len = strlen(conv); ++ } else { ++ /* On Windows, with some versions of gtk+, GtkSelectionData::length ++ * will include the final '\0'. When a string with this trailing '\0' ++ * is pasted in some linux applications, it will be pasted as or ++ * as an invisible character, which is unwanted. Ensure the length we ++ * send to the agent does not include any trailing '\0' ++ * This is gtk+ bug https://bugzilla.gnome.org/show_bug.cgi?id=734670 ++ */ ++ new_len = strlen(text); ++ } ++ ++ if (!check_clipboard_size_limits(self, new_len)) { ++ g_free(conv); ++ return NULL; ++ } ++ ++ *len = new_len; ++ return conv; ++} ++ + static void clipboard_received_cb(GtkClipboard *clipboard, + GtkSelectionData *selection_data, + gpointer user_data) +@@ -932,31 +975,7 @@ static void clipboard_received_cb(GtkClipboard *clipboard, + + /* gtk+ internal utf8 newline is always LF, even on windows */ + if (type == VD_AGENT_CLIPBOARD_UTF8_TEXT) { +- if (spice_main_agent_test_capability(s->main, VD_AGENT_CAP_GUEST_LINEEND_CRLF)) { +- GError *err = NULL; +- +- conv = spice_unix2dos((gchar*)data, len, &err); +- if (err) { +- g_warning("Failed to convert text line ending: %s", err->message); +- g_clear_error(&err); +- return; +- } +- +- len = strlen(conv); +- } else { +- /* On Windows, with some versions of gtk+, GtkSelectionData::length +- * will include the final '\0'. When a string with this trailing '\0' +- * is pasted in some linux applications, it will be pasted as or +- * as an invisible character, which is unwanted. Ensure the length we +- * send to the agent does not include any trailing '\0' +- * This is gtk+ bug https://bugzilla.gnome.org/show_bug.cgi?id=734670 +- */ +- len = strlen((const char *)data); +- } +- if (!check_clipboard_size_limits(self, len)) { +- g_free(conv); +- return; +- } ++ conv = fixup_clipboard_text(self, (gchar *)data, &len); + } + + spice_main_clipboard_selection_notify(s->main, selection, type, +-- +2.10.0 + diff --git a/SOURCES/0021-clipboard-Use-gtk_clipboard_request_text-for-text-da.patch b/SOURCES/0021-clipboard-Use-gtk_clipboard_request_text-for-text-da.patch new file mode 100644 index 0000000..5e0d1d5 --- /dev/null +++ b/SOURCES/0021-clipboard-Use-gtk_clipboard_request_text-for-text-da.patch @@ -0,0 +1,125 @@ +From 9b575d2eefbbbc5a308648f99fcc0be5e1f03d87 Mon Sep 17 00:00:00 2001 +From: Christophe Fergeau +Date: Wed, 10 Aug 2016 12:04:30 +0200 +Subject: [PATCH 21/23] clipboard: Use gtk_clipboard_request_text for text data + +Currently, when the agent asks us for VD_AGENT_CLIPBOARD_UTF8_TEXT data, +spice-gtk looks up for the first X11 target which would provide it with +UTF8_TEXT data, and uses that for the clipboard request. This means we +will use UTF8_STRING as the target for gtk_clipboard_request_contents(). + +However, some applications who can copy and paste text do not +necessarily support the UTF8_STRING target. This is the case for Motif +applications which support the STRING target however. It turns out gtk+ +also provides a gtk_clipboard_request_text() method which will try +several targets (UTF8_TEXT, COMPOUND_TEXT, TEXT), and will ensure the +returned string is UTF-8, so we can use that when the agent asks us for +some text data. + +This fixes https://bugzilla.redhat.com/show_bug.cgi?id=1348624 + +(cherry picked from commit 7b0de6217670e0f668aff2949fba174ed3cc0b50) +--- + src/spice-gtk-session.c | 67 ++++++++++++++++++++++++++++++++++++++----------- + 1 file changed, 52 insertions(+), 15 deletions(-) + +diff --git a/src/spice-gtk-session.c b/src/spice-gtk-session.c +index 6b1bcf6..3ab1465 100644 +--- a/src/spice-gtk-session.c ++++ b/src/spice-gtk-session.c +@@ -926,6 +926,40 @@ static char *fixup_clipboard_text(SpiceGtkSession *self, const char *text, int * + return conv; + } + ++static void clipboard_received_text_cb(GtkClipboard *clipboard, ++ const gchar *text, ++ gpointer user_data) ++{ ++ WeakRef *weakref = user_data; ++ SpiceGtkSession *self = (SpiceGtkSession*)weakref->object; ++ char *conv = NULL; ++ int len = 0; ++ int selection; ++ ++ weak_unref(weakref); ++ ++ if (self == NULL) ++ return; ++ ++ g_return_if_fail(SPICE_IS_GTK_SESSION(self)); ++ ++ selection = get_selection_from_clipboard(self->priv, clipboard); ++ g_return_if_fail(selection != -1); ++ ++ len = strlen(text); ++ if (!check_clipboard_size_limits(self, len)) { ++ return; ++ } ++ ++ /* gtk+ internal utf8 newline is always LF, even on windows */ ++ conv = fixup_clipboard_text(self, text, &len); ++ ++ spice_main_clipboard_selection_notify(self->priv->main, selection, ++ VD_AGENT_CLIPBOARD_UTF8_TEXT, ++ (guchar *)(conv ?: text), len); ++ g_free(conv); ++} ++ + static void clipboard_received_cb(GtkClipboard *clipboard, + GtkSelectionData *selection_data, + gpointer user_data) +@@ -971,16 +1005,14 @@ static void clipboard_received_cb(GtkClipboard *clipboard, + } + + const guchar *data = gtk_selection_data_get_data(selection_data); +- gpointer conv = NULL; + +- /* gtk+ internal utf8 newline is always LF, even on windows */ +- if (type == VD_AGENT_CLIPBOARD_UTF8_TEXT) { +- conv = fixup_clipboard_text(self, (gchar *)data, &len); +- } ++ /* text should be handled through clipboard_received_text_cb(), not ++ * clipboard_received_cb(). ++ */ ++ g_warn_if_fail(type != VD_AGENT_CLIPBOARD_UTF8_TEXT); + + spice_main_clipboard_selection_notify(s->main, selection, type, +- conv ?: data, len); +- g_free(conv); ++ data, len); + } + + static gboolean clipboard_request(SpiceMainChannel *main, guint selection, +@@ -1003,16 +1035,21 @@ static gboolean clipboard_request(SpiceMainChannel *main, guint selection, + cb = get_clipboard_from_selection(s, selection); + g_return_val_if_fail(cb != NULL, FALSE); + +- for (m = 0; m < SPICE_N_ELEMENTS(atom2agent); m++) { +- if (atom2agent[m].vdagent == type) +- break; +- } ++ if (type == VD_AGENT_CLIPBOARD_UTF8_TEXT) { ++ gtk_clipboard_request_text(cb, clipboard_received_text_cb, ++ weak_ref(G_OBJECT(self))); ++ } else { ++ for (m = 0; m < SPICE_N_ELEMENTS(atom2agent); m++) { ++ if (atom2agent[m].vdagent == type) ++ break; ++ } + +- g_return_val_if_fail(m < SPICE_N_ELEMENTS(atom2agent), FALSE); ++ g_return_val_if_fail(m < SPICE_N_ELEMENTS(atom2agent), FALSE); + +- atom = gdk_atom_intern_static_string(atom2agent[m].xatom); +- gtk_clipboard_request_contents(cb, atom, clipboard_received_cb, +- weak_ref(G_OBJECT(self))); ++ atom = gdk_atom_intern_static_string(atom2agent[m].xatom); ++ gtk_clipboard_request_contents(cb, atom, clipboard_received_cb, ++ weak_ref(G_OBJECT(self))); ++ } + + return TRUE; + } +-- +2.10.0 + diff --git a/SOURCES/0022-util-Remove-unused-GError-parameter.patch b/SOURCES/0022-util-Remove-unused-GError-parameter.patch new file mode 100644 index 0000000..f36029b --- /dev/null +++ b/SOURCES/0022-util-Remove-unused-GError-parameter.patch @@ -0,0 +1,228 @@ +From f3092d6d61b7095517960faa967bd4c0c2ab4cb8 Mon Sep 17 00:00:00 2001 +From: Pavel Grunt +Date: Fri, 2 Sep 2016 11:24:43 +0200 +Subject: [PATCH 22/23] util: Remove unused GError parameter +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The parameter is removed from functions: + get_line + spice_convert_newlines + spice_unix2dos + spice_dos2unix + +It was introduced in 75f1ea3ee9c4dbd6c5f27896caee07792bbdbba4 +but never used + +Acked-by: Marc-André Lureau +Acked-by: Christophe Fergeau +(cherry picked from commit b708989b12122af39144b856576c2dd234130b9c) +--- + src/spice-gtk-session.c | 22 ++-------------------- + src/spice-util-priv.h | 4 ++-- + src/spice-util.c | 28 ++++++++-------------------- + tests/util.c | 14 ++++---------- + 4 files changed, 16 insertions(+), 52 deletions(-) + +diff --git a/src/spice-gtk-session.c b/src/spice-gtk-session.c +index 3ab1465..5ebc7c2 100644 +--- a/src/spice-gtk-session.c ++++ b/src/spice-gtk-session.c +@@ -708,15 +708,7 @@ static void clipboard_got_from_guest(SpiceMainChannel *main, guint selection, + /* on windows, gtk+ would already convert to LF endings, but + not on unix */ + if (spice_main_agent_test_capability(s->main, VD_AGENT_CAP_GUEST_LINEEND_CRLF)) { +- GError *err = NULL; +- +- conv = spice_dos2unix((gchar*)data, size, &err); +- if (err) { +- g_warning("Failed to convert text line ending: %s", err->message); +- g_clear_error(&err); +- goto end; +- } +- ++ conv = spice_dos2unix((gchar*)data, size); + size = strlen(conv); + } + +@@ -727,7 +719,6 @@ static void clipboard_got_from_guest(SpiceMainChannel *main, guint selection, + 8, data, size); + } + +-end: + if (g_main_loop_is_running (ri->loop)) + g_main_loop_quit (ri->loop); + +@@ -894,17 +885,8 @@ static char *fixup_clipboard_text(SpiceGtkSession *self, const char *text, int * + char *conv = NULL; + int new_len = *len; + +- + if (spice_main_agent_test_capability(self->priv->main, VD_AGENT_CAP_GUEST_LINEEND_CRLF)) { +- GError *err = NULL; +- +- conv = spice_unix2dos(text, *len, &err); +- if (err) { +- g_warning("Failed to convert text line ending: %s", err->message); +- g_clear_error(&err); +- return NULL; +- } +- ++ conv = spice_unix2dos(text, *len); + new_len = strlen(conv); + } else { + /* On Windows, with some versions of gtk+, GtkSelectionData::length +diff --git a/src/spice-util-priv.h b/src/spice-util-priv.h +index c0ea8d9..10a3d48 100644 +--- a/src/spice-util-priv.h ++++ b/src/spice-util-priv.h +@@ -28,8 +28,8 @@ G_BEGIN_DECLS + gboolean spice_strv_contains(const GStrv strv, const gchar *str); + const gchar* spice_yes_no(gboolean value); + guint16 spice_make_scancode(guint scancode, gboolean release); +-gchar* spice_unix2dos(const gchar *str, gssize len, GError **error); +-gchar* spice_dos2unix(const gchar *str, gssize len, GError **error); ++gchar* spice_unix2dos(const gchar *str, gssize len); ++gchar* spice_dos2unix(const gchar *str, gssize len); + void spice_mono_edge_highlight(unsigned width, unsigned hight, + const guint8 *and, const guint8 *xor, guint8 *dest); + +diff --git a/src/spice-util.c b/src/spice-util.c +index fd97ee7..2b9cb2f 100644 +--- a/src/spice-util.c ++++ b/src/spice-util.c +@@ -292,8 +292,7 @@ typedef enum { + } NewlineType; + + static gssize get_line(const gchar *str, gsize len, +- NewlineType type, gsize *nl_len, +- GError **error) ++ NewlineType type, gsize *nl_len) + { + const gchar *p, *endl; + gsize nl = 0; +@@ -312,19 +311,15 @@ static gssize get_line(const gchar *str, gsize len, + + static gchar* spice_convert_newlines(const gchar *str, gssize len, + NewlineType from, +- NewlineType to, +- GError **error) ++ NewlineType to) + { +- GError *err = NULL; + gssize length; + gsize nl; + GString *output; +- gboolean free_segment = FALSE; + gint i; + + g_return_val_if_fail(str != NULL, NULL); + g_return_val_if_fail(len >= -1, NULL); +- g_return_val_if_fail(error == NULL || *error == NULL, NULL); + /* only 2 supported combinations */ + g_return_val_if_fail((from == NEWLINE_TYPE_LF && + to == NEWLINE_TYPE_CR_LF) || +@@ -345,7 +340,7 @@ static gchar* spice_convert_newlines(const gchar *str, gssize len, + output = g_string_sized_new(len * 2 + 1); + + for (i = 0; i < len; i += length + nl) { +- length = get_line(str + i, len - i, from, &nl, &err); ++ length = get_line(str + i, len - i, from, &nl); + if (length < 0) + break; + +@@ -361,30 +356,23 @@ static gchar* spice_convert_newlines(const gchar *str, gssize len, + } + } + +- if (err) { +- g_propagate_error(error, err); +- free_segment = TRUE; +- } +- +- return g_string_free(output, free_segment); ++ return g_string_free(output, FALSE); + } + + G_GNUC_INTERNAL +-gchar* spice_dos2unix(const gchar *str, gssize len, GError **error) ++gchar* spice_dos2unix(const gchar *str, gssize len) + { + return spice_convert_newlines(str, len, + NEWLINE_TYPE_CR_LF, +- NEWLINE_TYPE_LF, +- error); ++ NEWLINE_TYPE_LF); + } + + G_GNUC_INTERNAL +-gchar* spice_unix2dos(const gchar *str, gssize len, GError **error) ++gchar* spice_unix2dos(const gchar *str, gssize len) + { + return spice_convert_newlines(str, len, + NEWLINE_TYPE_LF, +- NEWLINE_TYPE_CR_LF, +- error); ++ NEWLINE_TYPE_CR_LF); + } + + static bool buf_is_ones(unsigned size, const guint8 *data) +diff --git a/tests/util.c b/tests/util.c +index b9b9535..14862a5 100644 +--- a/tests/util.c ++++ b/tests/util.c +@@ -34,7 +34,6 @@ static const struct { + + static void test_dos2unix(void) + { +- GError *err = NULL; + gchar *tmp; + unsigned int i; + +@@ -42,22 +41,19 @@ static void test_dos2unix(void) + if (!(dosunix[i].flags & DOS2UNIX)) + continue; + +- tmp = spice_dos2unix(dosunix[i].d, -1, &err); ++ tmp = spice_dos2unix(dosunix[i].d, -1); + g_assert_cmpstr(tmp, ==, dosunix[i].u); +- g_assert_no_error(err); + g_free(tmp); + + /* including ending \0 */ +- tmp = spice_dos2unix(dosunix[i].d, strlen(dosunix[i].d) + 1, &err); ++ tmp = spice_dos2unix(dosunix[i].d, strlen(dosunix[i].d) + 1); + g_assert_cmpstr(tmp, ==, dosunix[i].u); +- g_assert_no_error(err); + g_free(tmp); + } + } + + static void test_unix2dos(void) + { +- GError *err = NULL; + gchar *tmp; + unsigned int i; + +@@ -65,15 +61,13 @@ static void test_unix2dos(void) + if (!(dosunix[i].flags & UNIX2DOS)) + continue; + +- tmp = spice_unix2dos(dosunix[i].u, -1, &err); ++ tmp = spice_unix2dos(dosunix[i].u, -1); + g_assert_cmpstr(tmp, ==, dosunix[i].d); +- g_assert_no_error(err); + g_free(tmp); + + /* including ending \0 */ +- tmp = spice_unix2dos(dosunix[i].u, strlen(dosunix[i].u) + 1, &err); ++ tmp = spice_unix2dos(dosunix[i].u, strlen(dosunix[i].u) + 1); + g_assert_cmpstr(tmp, ==, dosunix[i].d); +- g_assert_no_error(err); + g_free(tmp); + } + } +-- +2.10.0 + diff --git a/SOURCES/0023-clipboard-Return-early-if-check_clipboard_size_limit.patch b/SOURCES/0023-clipboard-Return-early-if-check_clipboard_size_limit.patch new file mode 100644 index 0000000..6cd126b --- /dev/null +++ b/SOURCES/0023-clipboard-Return-early-if-check_clipboard_size_limit.patch @@ -0,0 +1,47 @@ +From 601c9212631f682580d8e90e1c6dcd2850adcc3b Mon Sep 17 00:00:00 2001 +From: Pavel Grunt +Date: Fri, 2 Sep 2016 14:03:26 +0200 +Subject: [PATCH 23/23] clipboard: Return early if + check_clipboard_size_limits() fails + +b0a2ff4 "clipboard: Add fixup_clipboard_text helper" +mistakenly removed some early returns when text conversion fails for +some reason. This commit readds it. + +Signed-off-by: Christophe Fergeau +Signed-off-by: Pavel Grunt +(cherry picked from commit 24fe1387f966193c60d5f2c72a0f551b7ed593f1) +--- + src/spice-gtk-session.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/src/spice-gtk-session.c b/src/spice-gtk-session.c +index 5ebc7c2..f04d5e8 100644 +--- a/src/spice-gtk-session.c ++++ b/src/spice-gtk-session.c +@@ -899,11 +899,6 @@ static char *fixup_clipboard_text(SpiceGtkSession *self, const char *text, int * + new_len = strlen(text); + } + +- if (!check_clipboard_size_limits(self, new_len)) { +- g_free(conv); +- return NULL; +- } +- + *len = new_len; + return conv; + } +@@ -935,6 +930,10 @@ static void clipboard_received_text_cb(GtkClipboard *clipboard, + + /* gtk+ internal utf8 newline is always LF, even on windows */ + conv = fixup_clipboard_text(self, text, &len); ++ if (!check_clipboard_size_limits(self, len)) { ++ g_free(conv); ++ return; ++ } + + spice_main_clipboard_selection_notify(self->priv->main, selection, + VD_AGENT_CLIPBOARD_UTF8_TEXT, +-- +2.10.0 + diff --git a/SOURCES/1000-gtk-Makefile.am-add-PIE-flags-to-libspice-client-gli.patch b/SOURCES/1000-gtk-Makefile.am-add-PIE-flags-to-libspice-client-gli.patch index 8a4ce6f..58ba391 100644 --- a/SOURCES/1000-gtk-Makefile.am-add-PIE-flags-to-libspice-client-gli.patch +++ b/SOURCES/1000-gtk-Makefile.am-add-PIE-flags-to-libspice-client-gli.patch @@ -4,14 +4,14 @@ Date: Wed, 6 May 2015 09:04:02 -0400 Subject: [PATCH] gtk/Makefile.am: add PIE flags to libspice-client-glib --- - gtk/Makefile.am | 5 +++++ - gtk/Makefile.in | 5 +++++ + src/Makefile.am | 5 +++++ + src/Makefile.in | 5 +++++ 2 files changed, 10 insertions(+) -diff --git a/gtk/Makefile.am b/gtk/Makefile.am +diff --git a/src/Makefile.am b/src/Makefile.am index 7bc5842..f2256cc 100644 ---- a/gtk/Makefile.am -+++ b/gtk/Makefile.am +--- a/src/Makefile.am ++++ b/src/Makefile.am @@ -189,6 +189,11 @@ libspice_client_glib_2_0_la_LDFLAGS = \ -version-info 13:0:5 \ -no-undefined \ @@ -24,10 +24,10 @@ index 7bc5842..f2256cc 100644 $(NULL) libspice_client_glib_2_0_la_LIBADD = \ -diff --git a/gtk/Makefile.in b/gtk/Makefile.in +diff --git a/src/Makefile.in b/src/Makefile.in index 9686995..ef8bcc5 100644 ---- a/gtk/Makefile.in -+++ b/gtk/Makefile.in +--- a/src/Makefile.in ++++ b/src/Makefile.in @@ -848,6 +848,11 @@ libspice_client_glib_2_0_la_LDFLAGS = \ -version-info 13:0:5 \ -no-undefined \ diff --git a/SPECS/spice-gtk.spec b/SPECS/spice-gtk.spec index 02b0d1c..59af088 100644 --- a/SPECS/spice-gtk.spec +++ b/SPECS/spice-gtk.spec @@ -12,8 +12,8 @@ #define _version_suffix Name: spice-gtk -Version: 0.26 -Release: 5%{?dist} +Version: 0.31 +Release: 6%{?dist} Summary: A GTK+ widget for SPICE clients Group: System Environment/Libraries @@ -21,23 +21,34 @@ License: LGPLv2+ URL: http://spice-space.org/page/Spice-Gtk #VCS: git:git://anongit.freedesktop.org/spice/spice-gtk Source0: http://www.spice-space.org/download/gtk/%{name}-%{version}%{?_version_suffix}.tar.bz2 -Patch0001: 0001-smartcard-connect-object-signal-handlers-with-spice-.patch -Patch0002: 0002-smartcard-add-reader-and-cards-on-channel-up.patch -Patch0003: 0003-channel-smartcard-Add-missing-USE_SMARTCARD-checks.patch -Patch0004: 0004-session-disable-default-socket-proxy.patch -Patch0005: 0005-spice-widget-Do-not-update-display-when-resize-guest.patch -Patch0006: 0006-Send-monitor-config-if-at-least-one-monitor-has-dime.patch -Patch0007: 0007-Notify-about-existence-of-monitor-for-all-display-ch.patch -Patch0008: 0008-Handle-single-headed-monitors-that-have-a-non-zero-x.patch -Patch0009: 0009-This-adds-reference-counting-to-cached-images.patch -Patch0010: 0010-glib-compat-Add-g_format_size.patch -Patch0011: 0011-file-xfer-Add-debug-messages-about-a-file-transfer-p.patch -Patch0012: 0012-session-Enable-proxy-when-requested.patch +Patch0001: 0001-display-Lower-level-of-warning-for-empty-monitor-con.patch +Patch0002: 0002-fix-16-bpp-LZ-image-decompression.patch +Patch0003: 0003-egl-fix-leak-when-display-is-unrealize.patch +Patch0004: 0004-Ensure-that-file-transfers-get-cancelled.patch +Patch0005: 0005-channel-main-fix-leak-on-volume-sync.patch +Patch0006: 0006-channel-Abort-migration-in-delayed-unref.patch +Patch0007: 0007-file-xfer-fix-segfault-on-agent-disconnection.patch +Patch0008: 0008-tests-Add-test-for-SpiceURI.patch +Patch0009: 0009-spice-uri-Reset-SpiceURI-before-parsing.patch +Patch0010: 0010-spice-uri-Do-not-allow-empty-port-string.patch +Patch0011: 0011-spice-uri-Check-if-port-is-in-allowed-range.patch +Patch0012: 0012-spice-uri-Validate-uri-scheme.patch +Patch0013: 0013-spice-uri-Add-ipv6-support.patch +Patch0014: 0014-Explicitly-specify-size-of-SpiceMsgSmartcardData.patch +Patch0015: 0015-main-Don-t-delay-update_display_timer-0-for-up-to-1-.patch +Patch0016: 0016-sasl-fix-SASL-GSSAPI-by-allowing-NULL-username.patch +Patch0017: 0017-session-Keep-brackets-around-ipv6-hostname.patch +Patch0018: 0018-session-Fix-IPv6-by-using-g_network_address_parse.patch +Patch0019: 0019-channel-check-if-channel-has-a-session.patch +Patch0020: 0020-clipboard-Add-fixup_clipboard_text-helper.patch +Patch0021: 0021-clipboard-Use-gtk_clipboard_request_text-for-text-da.patch +Patch0022: 0022-util-Remove-unused-GError-parameter.patch +Patch0023: 0023-clipboard-Return-early-if-check_clipboard_size_limit.patch Patch1000: 1000-gtk-Makefile.am-add-PIE-flags-to-libspice-client-gli.patch BuildRequires: intltool BuildRequires: gtk2-devel >= 2.14 -BuildRequires: usbredir-devel >= 0.5.2 +BuildRequires: usbredir-devel >= 0.6-8 BuildRequires: libusb1-devel >= 1.0.9 BuildRequires: libgudev1-devel BuildRequires: pixman-devel openssl-devel libjpeg-turbo-devel @@ -52,13 +63,14 @@ BuildRequires: polkit-devel BuildRequires: gtk-doc BuildRequires: vala-tools BuildRequires: usbutils +BuildRequires: libepoxy-devel %if %{with_gtk3} BuildRequires: gtk3-devel %endif # FIXME: should ship the generated files.. BuildRequires: pyparsing # keep me to get gendeps magic happen -BuildRequires: spice-protocol +BuildRequires: spice-protocol >= 0.12.11-1 # Hack because of bz #613466 BuildRequires: libtool Requires: spice-glib%{?_isa} = %{version}-%{release} @@ -83,6 +95,9 @@ Libraries, includes, etc. to compile with the spice-gtk2 libraries %package -n spice-glib Summary: A GObject for communicating with Spice servers Group: Development/Libraries +Requires: usbredir >= 0.6-8 +Requires: spice-protocol >= 0.12.11-1 +Requires: nss %description -n spice-glib spice-client-glib-2.0 is a SPICE client library for GLib2. @@ -136,6 +151,7 @@ A module allowing use of the spice-gtk-3.0 widget from vala Summary: Python bindings for the spice-gtk-2.0 library Group: Development/Libraries Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: spice-glib = %{version}-%{release} %description python SpiceClientGtk module provides a SPICE viewer widget for GTK2. @@ -146,6 +162,7 @@ A module allowing use of the spice-gtk-2.0 widget from python Summary: Spice-gtk tools Group: Applications/Internet Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: spice-glib = %{version}-%{release} %description tools Simple clients for interacting with SPICE servers. @@ -172,6 +189,17 @@ pushd spice-gtk-%{version} %patch0010 -p1 %patch0011 -p1 %patch0012 -p1 +%patch0013 -p1 +%patch0014 -p1 +%patch0015 -p1 +%patch0016 -p1 +%patch0017 -p1 +%patch0018 -p1 +%patch0019 -p1 +%patch0020 -p1 +%patch0021 -p1 +%patch0022 -p1 +%patch0023 -p1 %patch1000 -p1 find . -name '*.stamp' | xargs touch popd @@ -184,13 +212,13 @@ cp -a spice-gtk-%{version} spice-gtk3-%{version} %build cd spice-gtk-%{version} -%configure --with-gtk=2.0 --enable-gtk-doc --with-usb-acl-helper-dir=%{_libexecdir}/spice-gtk-%{_arch}/ +%configure --with-gtk=2.0 --enable-gtk-doc --disable-epoxy --with-usb-acl-helper-dir=%{_libexecdir}/spice-gtk-%{_arch}/ make %{?_smp_mflags} cd .. %if %{with_gtk3} cd spice-gtk3-%{version} -%configure --with-gtk=3.0 --enable-vala --with-usb-acl-helper-dir=%{_libexecdir}/spice-gtk-%{_arch}/ +%configure --with-gtk=3.0 --enable-vala --disable-epoxy --with-usb-acl-helper-dir=%{_libexecdir}/spice-gtk-%{_arch}/ make %{?_smp_mflags} cd .. %endif @@ -295,6 +323,74 @@ rm -rf %{buildroot}%{_datadir}/pkgconfig/spice-protocol.pc %{_bindir}/spicy-stats %changelog +* Fri Sep 9 2016 Pavel Grunt - 0.31-6 +- Improve clipboard handling for motif applications + Resolves: rhbz#1348624 + +* Wed Aug 3 2016 Pavel Grunt - 0.31-5 +- Allow to connect to ipv6 without proxy + Resolves: rhbz#1361478 +- Silence a critical when migrating + Resolves: rhbz#1356162 +- Disable EPOXY / EGL usage + Resolves: rhbz#1362460 + +* Fri Jul 1 2016 Pavel Grunt - 0.31-4 +- Fix SASL GSSAPI (kerberos authentication) + Resolves: rhbz#1343361 +- Allow to connect to ipv6 behind proxy + Resolves: rhbz#1331777 + +* Wed Jun 8 2016 Victor Toso - 0.31-3 +- Fix client's crash when agent is killed + Resolves: rhbz#1336321 +- Parse ipv6 address + Resolves: rhbz#1335239 +- Improving parsing of Smartcard messages + Resolves: rhbz#1338727 +- Fix hangs with "Connected to graphic server" + Resolves: rhbz#1323092 + +* Mon May 2 2016 Pavel Grunt - 0.31-2 +- Rebase to 0.31, add back the PIE/relro patch. + Resolves: rhbz#1329973 + +* Mon May 2 2016 Pavel Grunt - 0.31-1 +- Rebase to 0.31 + Resolves: rhbz#1329973 +- Fix crash when migration fails + Resolves: rhbz#1318574 + +* Mon Apr 18 2016 Pavel Grunt - 0.26-8 +- Check runtime usbredir version + Resolves: rhbz#1320827 +- Allow connection to password protected guests + Resolves: rhbz#1320806 +- Fix runtime warnings related to shared folders and usb redirection + Resolves: rhbz#1319405 +- Change runtime warning for empty monitor config to debug message + Resolves: rhbz#1319405 +- Fix 16 bpp LZ image decompression + Resolves: rhbz#1285469 + +* Fri Mar 18 2016 Pavel Grunt - 0.26-7 +- Improve message for number of usb channels in usb device widget + Resolves: rhbz#1299931 +- Fix usbredir leak when redirecting a webcam + Resolves: rhbz#1270363 + +* Thu Mar 17 2016 Victor Toso - 0.26-6 +- Implements volume-sync from guest to client + Resolves: rhbz#1264105 +- Avoid crash in virt-manager + Resolves: rhbz#1301863 +- Fix focus in fullscreen mode + Resolves: rhbz#1275231 +- Add Client capability for Windows monitor_config message + Resolves: rhbz#1248189 +- Fix error message for file transfer + Resolves: rhbz#1265562 + * Mon Aug 31 2015 Fabiano Fidêncio - 0.26-5 - Connecting to VM changes its resolution Resolves: rhbz#1242602