From 4ea0a7e64bcad454f56c83815e9dd6a248da19f0 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Tue, 18 May 2021 02:46:40 -0400 Subject: [PATCH] import spice-gtk-0.38-6.el8 --- .gitignore | 2 + .spice-gtk.metadata | 2 + ...hannel-main-Avoid-macro-side-effects.patch | 34 + ...ck-proper-size-and-caps-handling-VD_.patch | 77 +++ ...sys-bump-polkit-requirement-to-0.101.patch | 94 +++ ...ad-all-available-data-from-SASL-buff.patch | 47 ++ .../0005-meson-add-wayland-protocols.patch | 160 +++++ ...and-add-wayland-extensions-functions.patch | 321 ++++++++++ ...ve-mouse-button-state-on-mouse-click.patch | 77 +++ ...ayland-fix-mouse-lock-in-server-mode.patch | 181 ++++++ ...dle-some-detailed-error-for-VD_AGENT.patch | 54 ++ ...ve-some-data-to-start-decoding-quic-.patch | 34 + ...heck-image-size-in-quic_decode_begin.patch | 48 ++ SOURCES/0012-quic-Check-RLE-lengths.patch | 35 ++ ...sible-buffer-overflow-in-find_bucket.patch | 35 ++ ...-warnings-from-Clang-static-analyzer.patch | 74 +++ ...ot-check-IP-if-we-fail-to-resolve-it.patch | 66 ++ ...spice-usbredir-redirect-on-connect-o.patch | 37 ++ ...-empty_cd_clicked_cb-g_free-basename.patch | 33 + ...rse_usbids-verify-at-least-one-vendo.patch | 44 ++ ...e-do-not-keep-duration-in-a-variable.patch | 42 ++ ..._id-is-guint-assign-0-to-it-not-FALS.patch | 26 + ...te_emulated_device-assert-address-32.patch | 33 + ...ocate-ctx-after-g_return_val_if_fail.patch | 48 ++ .../0023-channel-main-Fix-indentation.patch | 118 ++++ .../0024-channel-main-Fix-indentation.patch | 40 ++ ...annel-main-Remove-unused-declaration.patch | 42 ++ ...issing-vdagent-capability-descriptio.patch | 26 + ...er-pre-condition-on-display-id-value.patch | 39 ++ ...-heap-and-reference-counting-for-spi.patch | 273 ++++++++ ...y-SpiceMigrationDstInfo-into-spice_m.patch | 71 +++ ...e-more-clear-that-host_data-and-cert.patch | 47 ++ ...dle-not-terminated-host_data-and-cer.patch | 38 ++ SOURCES/spice-gtk-0.38.tar.xz.sig | Bin 0 -> 566 bytes SPECS/spice-gtk.spec | 589 ++++++++++++++++++ 35 files changed, 2887 insertions(+) create mode 100644 .gitignore create mode 100644 .spice-gtk.metadata create mode 100644 SOURCES/0001-channel-main-Avoid-macro-side-effects.patch create mode 100644 SOURCES/0002-channel-main-Check-proper-size-and-caps-handling-VD_.patch create mode 100644 SOURCES/0003-build-sys-bump-polkit-requirement-to-0.101.patch create mode 100644 SOURCES/0004-spice-channel-Read-all-available-data-from-SASL-buff.patch create mode 100644 SOURCES/0005-meson-add-wayland-protocols.patch create mode 100644 SOURCES/0006-wayland-add-wayland-extensions-functions.patch create mode 100644 SOURCES/0007-spice-gtk-save-mouse-button-state-on-mouse-click.patch create mode 100644 SOURCES/0008-wayland-fix-mouse-lock-in-server-mode.patch create mode 100644 SOURCES/0009-channel-main-Handle-some-detailed-error-for-VD_AGENT.patch create mode 100644 SOURCES/0010-quic-Check-we-have-some-data-to-start-decoding-quic-.patch create mode 100644 SOURCES/0011-quic-Check-image-size-in-quic_decode_begin.patch create mode 100644 SOURCES/0012-quic-Check-RLE-lengths.patch create mode 100644 SOURCES/0013-quic-Avoid-possible-buffer-overflow-in-find_bucket.patch create mode 100644 SOURCES/0014-Remove-some-warnings-from-Clang-static-analyzer.patch create mode 100644 SOURCES/0015-ssl_verify-Do-not-check-IP-if-we-fail-to-resolve-it.patch create mode 100644 SOURCES/0016-usb-backend-Fix-spice-usbredir-redirect-on-connect-o.patch create mode 100644 SOURCES/0017-empty_cd_clicked_cb-g_free-basename.patch create mode 100644 SOURCES/0018-spice_usbutil_parse_usbids-verify-at-least-one-vendo.patch create mode 100644 SOURCES/0019-sink_event_probe-do-not-keep-duration-in-a-variable.patch create mode 100644 SOURCES/0020-mark_false_event_id-is-guint-assign-0-to-it-not-FALS.patch create mode 100644 SOURCES/0021-usb-backend-create_emulated_device-assert-address-32.patch create mode 100644 SOURCES/0022-spice-utils-allocate-ctx-after-g_return_val_if_fail.patch create mode 100644 SOURCES/0023-channel-main-Fix-indentation.patch create mode 100644 SOURCES/0024-channel-main-Fix-indentation.patch create mode 100644 SOURCES/0025-channel-main-Remove-unused-declaration.patch create mode 100644 SOURCES/0026-main-add-a-few-missing-vdagent-capability-descriptio.patch create mode 100644 SOURCES/0027-main-add-stricter-pre-condition-on-display-id-value.patch create mode 100644 SOURCES/0028-channel-main-Use-heap-and-reference-counting-for-spi.patch create mode 100644 SOURCES/0029-channel-main-Copy-SpiceMigrationDstInfo-into-spice_m.patch create mode 100644 SOURCES/0030-channel-main-Make-more-clear-that-host_data-and-cert.patch create mode 100644 SOURCES/0031-channel-main-Handle-not-terminated-host_data-and-cer.patch create mode 100644 SOURCES/spice-gtk-0.38.tar.xz.sig create mode 100644 SPECS/spice-gtk.spec diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..45a2fae --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +SOURCES/spice-gtk-0.38.tar.xz +SOURCES/victortoso-E37A484F.keyring diff --git a/.spice-gtk.metadata b/.spice-gtk.metadata new file mode 100644 index 0000000..9afc954 --- /dev/null +++ b/.spice-gtk.metadata @@ -0,0 +1,2 @@ +2d378aaeaecd0cb35c43b9ab216df840060d1baa SOURCES/spice-gtk-0.38.tar.xz +da7a529db1ea28a1540c5892ea9836abeb378c3e SOURCES/victortoso-E37A484F.keyring diff --git a/SOURCES/0001-channel-main-Avoid-macro-side-effects.patch b/SOURCES/0001-channel-main-Avoid-macro-side-effects.patch new file mode 100644 index 0000000..dabb8ad --- /dev/null +++ b/SOURCES/0001-channel-main-Avoid-macro-side-effects.patch @@ -0,0 +1,34 @@ +From d8922b93f52d08fb81cc66842b4df80d1d1d9a7e Mon Sep 17 00:00:00 2001 +From: Frediano Ziglio +Date: Thu, 19 Mar 2020 15:50:45 +0000 +Subject: [PATCH 1/9] channel-main: Avoid macro side effects + +In big endian system GUINT32_TO_LE macro uses the parameter +multiple time causing serial to be incremented multiple times +instead of one. +Avoid side effects using a temporary variable. + +Signed-off-by: Frediano Ziglio +Acked-by: Victor Toso +(cherry picked from commit 7363d1a0a640b6992d5967621e37c3376958d708) +--- + src/channel-main.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/channel-main.c b/src/channel-main.c +index 1e85a36..e89b813 100644 +--- a/src/channel-main.c ++++ b/src/channel-main.c +@@ -1384,7 +1384,8 @@ static void agent_clipboard_grab(SpiceMainChannel *channel, guint selection, + } + + if (test_agent_cap(channel, VD_AGENT_CAP_CLIPBOARD_GRAB_SERIAL)) { +- *(uint32_t *)grab = GUINT32_TO_LE(c->clipboard_serial[selection]++); ++ uint32_t serial = c->clipboard_serial[selection]++; ++ *(uint32_t *)grab = GUINT32_TO_LE(serial); + grab = (void *)grab + sizeof(uint32_t); + } + +-- +2.26.2 + diff --git a/SOURCES/0002-channel-main-Check-proper-size-and-caps-handling-VD_.patch b/SOURCES/0002-channel-main-Check-proper-size-and-caps-handling-VD_.patch new file mode 100644 index 0000000..8383ad7 --- /dev/null +++ b/SOURCES/0002-channel-main-Check-proper-size-and-caps-handling-VD_.patch @@ -0,0 +1,77 @@ +From 5324e83bf636b995522088d508e61ba5543777f4 Mon Sep 17 00:00:00 2001 +From: Frediano Ziglio +Date: Thu, 19 Mar 2020 06:07:39 +0000 +Subject: [PATCH 2/9] channel-main: Check proper size and caps handling + VD_AGENT_FILE_XFER_STATUS_NOT_ENOUGH_SPACE + +VDAgentFileXferStatusMessage message can or cannot contain detailed +information attached to it. +Detect this correctly checking capabilities and flags. +This fixes a small buffer overflow reading in case the details are +off the payload. + +Signed-off-by: Frediano Ziglio +Acked-by: Victor Toso +(cherry picked from commit b13fd0664075c951f5418f5828c0803408ad664d) +--- + meson.build | 2 +- + src/channel-main.c | 16 +++++++++++++--- + 2 files changed, 14 insertions(+), 4 deletions(-) + +diff --git a/meson.build b/meson.build +index 995268b..8098989 100644 +--- a/meson.build ++++ b/meson.build +@@ -81,7 +81,7 @@ endforeach + # + # check for mandatory dependencies + # +-spice_protocol_version='>= 0.14.1' ++spice_protocol_version='>= 0.14.2' + + glib_version = '2.46' + glib_version_info = '>= @0@'.format(glib_version) +diff --git a/src/channel-main.c b/src/channel-main.c +index e89b813..c4fe02b 100644 +--- a/src/channel-main.c ++++ b/src/channel-main.c +@@ -1891,6 +1891,7 @@ static void file_xfer_read_async_cb(GObject *source_object, + + /* coroutine context */ + static void main_agent_handle_xfer_status(SpiceMainChannel *channel, ++ const VDAgentMessage *msg_hdr, + VDAgentFileXferStatusMessage *msg) + { + SpiceFileTransferTask *xfer_task; +@@ -1917,8 +1918,17 @@ static void main_agent_handle_xfer_status(SpiceMainChannel *channel, + _("The spice agent reported an error during the file transfer")); + break; + case VD_AGENT_FILE_XFER_STATUS_NOT_ENOUGH_SPACE: { +- uint64_t *free_space = SPICE_ALIGNED_CAST(uint64_t *, msg->data); +- gchar *free_space_str = g_format_size(*free_space); ++ const VDAgentFileXferStatusNotEnoughSpace *err = ++ (VDAgentFileXferStatusNotEnoughSpace*) msg->data; ++ if (!test_agent_cap(channel, VD_AGENT_CAP_FILE_XFER_DETAILED_ERRORS) || ++ msg_hdr->size < sizeof(*msg) + sizeof(*err)) { ++ error = ++ g_error_new(SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED, ++ _("File transfer failed due to lack of free space on remote machine")); ++ break; ++ } ++ ++ gchar *free_space_str = g_format_size(err->disk_free_space); + gchar *file_size_str = g_format_size(spice_file_transfer_task_get_total_bytes(xfer_task)); + error = g_error_new(SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED, + _("File transfer failed due to lack of free space on remote machine " +@@ -2110,7 +2120,7 @@ static void main_agent_handle_msg(SpiceChannel *channel, + break; + } + case VD_AGENT_FILE_XFER_STATUS: +- main_agent_handle_xfer_status(self, payload); ++ main_agent_handle_xfer_status(self, msg, payload); + break; + default: + g_warning("unhandled agent message type: %u (%s), size %u", +-- +2.26.2 + diff --git a/SOURCES/0003-build-sys-bump-polkit-requirement-to-0.101.patch b/SOURCES/0003-build-sys-bump-polkit-requirement-to-0.101.patch new file mode 100644 index 0000000..991d977 --- /dev/null +++ b/SOURCES/0003-build-sys-bump-polkit-requirement-to-0.101.patch @@ -0,0 +1,94 @@ +From f036039b2ab3945940159342fb3880064f2611c9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Thu, 9 Apr 2020 01:05:00 +0200 +Subject: [PATCH 3/9] build-sys: bump polkit requirement to 0.101 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It was released on 2011-03-03, and is available in old debian stable +and all distros we care about. + +Signed-off-by: Marc-André Lureau +Acked-by: Frediano Ziglio +(cherry picked from commit 94a3375beff5df8c8add33cf2f1b74350185dce2) +--- + meson.build | 7 +----- + src/spice-client-glib-usb-acl-helper.c | 34 -------------------------- + 2 files changed, 1 insertion(+), 40 deletions(-) + +diff --git a/meson.build b/meson.build +index 8098989..c442a0d 100644 +--- a/meson.build ++++ b/meson.build +@@ -204,14 +204,9 @@ endif + + # polkit + spice_gtk_has_polkit = false +-d = dependency('polkit-gobject-1', version : '>= 0.96', required : get_option('polkit')) ++d = dependency('polkit-gobject-1', version : '>= 0.101', required : get_option('polkit')) + if d.found() + spice_gtk_policy_dir = d.get_pkgconfig_variable('policydir') +- foreach func : ['polkit_authority_get_sync', 'polkit_authorization_result_get_dismissed'] +- if compiler.has_function(func, dependencies : d) +- spice_gtk_config_data.set('HAVE_@0@'.format(func.to_upper()), '1') +- endif +- endforeach + + # TODO: With 'auto', we should just disable polkit support if this is missing. + if not compiler.has_function('acl_get_file') +diff --git a/src/spice-client-glib-usb-acl-helper.c b/src/spice-client-glib-usb-acl-helper.c +index f75e0fc..de9e605 100644 +--- a/src/spice-client-glib-usb-acl-helper.c ++++ b/src/spice-client-glib-usb-acl-helper.c +@@ -156,25 +156,6 @@ static void cleanup(void) + g_main_loop_quit(loop); + } + +-/* Not available in polkit < 0.101 */ +-#ifndef HAVE_POLKIT_AUTHORIZATION_RESULT_GET_DISMISSED +-static gboolean +-polkit_authorization_result_get_dismissed(PolkitAuthorizationResult *result) +-{ +- gboolean ret; +- PolkitDetails *details; +- +- g_return_val_if_fail(POLKIT_IS_AUTHORIZATION_RESULT(result), FALSE); +- +- ret = FALSE; +- details = polkit_authorization_result_get_details(result); +- if (details != NULL && polkit_details_lookup(details, "polkit.dismissed")) +- ret = TRUE; +- +- return ret; +-} +-#endif +- + static void check_authorization_cb(PolkitAuthority *authority, + GAsyncResult *res, gpointer data) + { +@@ -291,21 +272,6 @@ static void stdin_read_complete(GObject *src, GAsyncResult *res, gpointer data) + g_free(s); + } + +-/* Fix for polkit 0.97 and later */ +-#ifndef HAVE_POLKIT_AUTHORITY_GET_SYNC +-static PolkitAuthority * +-polkit_authority_get_sync (GCancellable *cancellable, GError **error) +-{ +- PolkitAuthority *authority; +- +- authority = polkit_authority_get (); +- if (!authority) +- g_set_error (error, 0, 0, "failed to get the PolicyKit authority"); +- +- return authority; +-} +-#endif +- + #ifndef HAVE_CLEARENV + extern char **environ; + +-- +2.26.2 + diff --git a/SOURCES/0004-spice-channel-Read-all-available-data-from-SASL-buff.patch b/SOURCES/0004-spice-channel-Read-all-available-data-from-SASL-buff.patch new file mode 100644 index 0000000..d703a6b --- /dev/null +++ b/SOURCES/0004-spice-channel-Read-all-available-data-from-SASL-buff.patch @@ -0,0 +1,47 @@ +From 1562755fd60ae79d595dd8be0d1ddf5b784729c2 Mon Sep 17 00:00:00 2001 +From: Gilmar Santos Jr +Date: Wed, 6 May 2020 12:58:51 -0300 +Subject: [PATCH 4/9] spice-channel: Read all available data from SASL buffer + +When SASL is in use, its buffer may contain remaining data from previously +received messages. The spice_channel_iterate_read should use it, even if c->in +socket is not readable. + +Fixes: https://gitlab.freedesktop.org/spice/spice-gtk/-/issues/126 + +Acked-by: Frediano Ziglio +(cherry picked from commit 80e9c852a406d93cad3fc7b845fe181d75356f11) +--- + src/spice-channel.c | 13 ++++++------- + 1 file changed, 6 insertions(+), 7 deletions(-) + +diff --git a/src/spice-channel.c b/src/spice-channel.c +index 315e287..5824fdd 100644 +--- a/src/spice-channel.c ++++ b/src/spice-channel.c +@@ -2345,16 +2345,15 @@ static void spice_channel_iterate_read(SpiceChannel *channel) + /* treat all incoming data (block on message completion) */ + while (!c->has_error && + c->state != SPICE_CHANNEL_STATE_MIGRATING && +- g_pollable_input_stream_is_readable(G_POLLABLE_INPUT_STREAM(c->in)) +- ) { do +- spice_channel_recv_msg(channel, +- (handler_msg_in)SPICE_CHANNEL_GET_CLASS(channel)->handle_msg, NULL); ++ (g_pollable_input_stream_is_readable(G_POLLABLE_INPUT_STREAM(c->in)) + #ifdef HAVE_SASL + /* flush the sasl buffer too */ +- while (c->sasl_decoded != NULL); +-#else +- while (FALSE); ++ || c->sasl_decoded != NULL + #endif ++ ) ++ ) { ++ spice_channel_recv_msg(channel, ++ (handler_msg_in)SPICE_CHANNEL_GET_CLASS(channel)->handle_msg, NULL); + } + + } +-- +2.26.2 + diff --git a/SOURCES/0005-meson-add-wayland-protocols.patch b/SOURCES/0005-meson-add-wayland-protocols.patch new file mode 100644 index 0000000..c9e8f73 --- /dev/null +++ b/SOURCES/0005-meson-add-wayland-protocols.patch @@ -0,0 +1,160 @@ +From 8d3731162c2b3aae518f8d8b2d7190c4deec9911 Mon Sep 17 00:00:00 2001 +From: Francesco Giudici +Date: Thu, 27 Feb 2020 11:55:15 +0100 +Subject: [PATCH 5/9] meson: add wayland protocols + +Generate wayland protocols: these will be used later for locking the +mouse pointer and getting relative mouse movements when using the mouse +in server mode in Wayland. +The meson build steps have been freely taken and adapted from Weston +source code: +https://gitlab.freedesktop.org/wayland/weston/-/blob/master/protocol/meson.build + +Signed-off-by: Francesco Giudici +Acked-by: Frediano Ziglio +(cherry picked from commit d70044ab49728524c68796dd371d2bf7d94d27e5) +--- + meson.build | 20 +++++++++++++++ + meson_options.txt | 4 +++ + src/meson.build | 62 +++++++++++++++++++++++++++++++++++++++++++++-- + 3 files changed, 84 insertions(+), 2 deletions(-) + +diff --git a/meson.build b/meson.build +index c442a0d..7426ea5 100644 +--- a/meson.build ++++ b/meson.build +@@ -31,6 +31,7 @@ spice_gtk_config_data = configuration_data() + spice_gtk_include = [include_directories('.')] + spice_glib_deps = [] + spice_gtk_deps = [] ++spice_wayland_deps = [] + spice_acl_deps = [] + + # +@@ -152,6 +153,25 @@ if d.found() + spice_gtk_has_gtk = true + endif + ++# wayland protocols ++spice_gtk_has_wayland_protocols = false ++# Check if gtk is enabled and supports the wayland backend ++if host_machine.system() != 'windows' and spice_gtk_has_gtk and compiler.has_header('gtk-3.0/gdk/gdkwayland.h') ++ d = dependency('wayland-protocols', version: '>= 1.17', required: get_option('wayland-protocols')) ++ if d.found() ++ spice_gtk_config_data.set('HAVE_WAYLAND_PROTOCOLS', '1') ++ dir_wp_base = d.get_pkgconfig_variable('pkgdatadir') ++ dep_scanner = dependency('wayland-scanner', native: true) ++ prog_scanner = find_program(dep_scanner.get_pkgconfig_variable('wayland_scanner')) ++ ++ wayland_libs_version_required = '1.17.0' ++ spice_wayland_deps += dependency('wayland-server', version : '>= @0@'.format(wayland_libs_version_required)) ++ spice_wayland_deps += dependency('wayland-cursor', version : '>= @0@'.format(wayland_libs_version_required)) ++ spice_wayland_deps += dependency('wayland-client', version : '>= @0@'.format(wayland_libs_version_required)) ++ spice_gtk_has_wayland_protocols = true ++ endif ++endif ++ + # webdav + spice_gtk_has_phodav = false + d = dependency('libphodav-2.0', required: get_option('webdav')) +diff --git a/meson_options.txt b/meson_options.txt +index 9804217..60b87ca 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -2,6 +2,10 @@ option('gtk', + type : 'feature', + description: 'Enable gtk+') + ++option('wayland-protocols', ++ type : 'feature', ++ description: 'Enable wayland protocols') ++ + option('webdav', + type : 'feature', + description: 'Enable webdav support') +diff --git a/src/meson.build b/src/meson.build +index 654dab5..bdd2239 100644 +--- a/src/meson.build ++++ b/src/meson.build +@@ -318,6 +318,64 @@ if spice_gtk_has_gtk + command : cmd) + endforeach + ++ # ++ # Wayland protocols ++ # ++ if spice_gtk_has_wayland_protocols ++ ++ generated_protocols = [ ++ [ 'pointer-constraints', 'v1' ], ++ [ 'relative-pointer', 'v1' ], ++ #[ 'input-method', 'v1' ], ++ #[ 'input-timestamps', 'v1' ], ++ #[ 'fullscreen-shell', 'v1' ], ++ #[ 'linux-dmabuf', 'v1' ], ++ #[ 'linux-explicit-synchronization', 'v1' ], ++ #[ 'presentation-time', 'stable' ], ++ #[ 'tablet', 'v2' ], ++ #[ 'text-input', 'v1' ], ++ #[ 'viewporter', 'stable' ], ++ #[ 'xdg-output', 'v1' ], ++ #[ 'xdg-shell', 'v6' ], ++ #[ 'xdg-shell', 'stable' ], ++ ] ++ ++ foreach proto: generated_protocols ++ proto_name = proto[0] ++ if proto[1] == 'internal' ++ base_file = proto_name ++ xml_path = '@0@.xml'.format(proto_name) ++ elif proto[1] == 'stable' ++ base_file = proto_name ++ xml_path = '@0@/stable/@1@/@1@.xml'.format(dir_wp_base, base_file) ++ else ++ base_file = '@0@-unstable-@1@'.format(proto_name, proto[1]) ++ xml_path = '@0@/unstable/@1@/@2@.xml'.format(dir_wp_base, proto_name, base_file) ++ endif ++ ++ foreach output_type: [ 'client-header', 'server-header', 'private-code' ] ++ if output_type == 'client-header' ++ output_file = '@0@-client-protocol.h'.format(base_file) ++ elif output_type == 'server-header' ++ output_file = '@0@-server-protocol.h'.format(base_file) ++ else ++ output_file = '@0@-protocol.c'.format(base_file) ++ if dep_scanner.version().version_compare('< 1.14.91') ++ output_type = 'code' ++ endif ++ endif ++ ++ spice_client_gtk_sources += custom_target( ++ '@0@ @1@'.format(base_file, output_type), ++ command: [ prog_scanner, output_type, '@INPUT@', '@OUTPUT@' ], ++ input: xml_path, ++ output: output_file, ++ ) ++ message('@0@ @1@: @2@ -> @3@'.format(prog_scanner, output_type, xml_path, output_file)) ++ endforeach ++ endforeach ++ endif ++ + # + # libspice-client-gtk.so + # +@@ -343,11 +401,11 @@ if spice_gtk_has_gtk + install : true, + link_args : [spice_gtk_version_script], + link_depends : spice_client_gtk_syms, +- dependencies : [spice_client_glib_dep, spice_gtk_deps]) ++ dependencies : [spice_client_glib_dep, spice_gtk_deps, spice_wayland_deps]) + + spice_client_gtk_dep = declare_dependency(sources : spice_widget_enums[1], + link_with : spice_client_gtk_lib, +- dependencies : [spice_client_glib_dep, spice_gtk_deps]) ++ dependencies : [spice_client_glib_dep, spice_gtk_deps, spice_wayland_deps]) + + if spice_gtk_has_introspection + # +-- +2.26.2 + diff --git a/SOURCES/0006-wayland-add-wayland-extensions-functions.patch b/SOURCES/0006-wayland-add-wayland-extensions-functions.patch new file mode 100644 index 0000000..b195ac2 --- /dev/null +++ b/SOURCES/0006-wayland-add-wayland-extensions-functions.patch @@ -0,0 +1,321 @@ +From 19e0922572cee7bda989a82407208eac8a41b47f Mon Sep 17 00:00:00 2001 +From: Francesco Giudici +Date: Tue, 28 Mar 2017 15:07:16 +0200 +Subject: [PATCH 6/9] wayland: add wayland-extensions functions + +add utilities to lock the pointer to a window and to get relative mouse +movement in Wayland. This is made possible thanks to the wayland +protocols introduced in the previous commit. + +Code freely taken and adapted from Christophe Fergeau branch: +https://gitlab.freedesktop.org/teuf/spice-gtk/-/tree/wayland + +Signed-off-by: Francesco Giudici +Acked-by: Frediano Ziglio +(cherry picked from commit 59d5c92c74da0f452b9104191bb752c33d26ec77) +--- + src/meson.build | 5 + + src/wayland-extensions.c | 235 +++++++++++++++++++++++++++++++++++++++ + src/wayland-extensions.h | 32 ++++++ + 3 files changed, 272 insertions(+) + create mode 100644 src/wayland-extensions.c + create mode 100644 src/wayland-extensions.h + +diff --git a/src/meson.build b/src/meson.build +index bdd2239..16810a7 100644 +--- a/src/meson.build ++++ b/src/meson.build +@@ -374,6 +374,11 @@ if spice_gtk_has_gtk + message('@0@ @1@: @2@ -> @3@'.format(prog_scanner, output_type, xml_path, output_file)) + endforeach + endforeach ++ ++ spice_client_gtk_sources += [ ++ 'wayland-extensions.c', ++ 'wayland-extensions.h', ++ ] + endif + + # +diff --git a/src/wayland-extensions.c b/src/wayland-extensions.c +new file mode 100644 +index 0000000..64b5139 +--- /dev/null ++++ b/src/wayland-extensions.c +@@ -0,0 +1,235 @@ ++/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ ++/* ++ Copyright (C) 2017 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 ++ ++#include ++ ++#include ++#include "pointer-constraints-unstable-v1-client-protocol.h" ++#include "relative-pointer-unstable-v1-client-protocol.h" ++ ++#include "wayland-extensions.h" ++ ++static void * ++gtk_wl_registry_bind(GtkWidget *widget, ++ uint32_t name, ++ const struct wl_interface *interface, ++ uint32_t version) ++{ ++ GdkDisplay *gdk_display = gtk_widget_get_display(widget); ++ struct wl_display *display; ++ struct wl_registry *registry; ++ ++ if (!GDK_IS_WAYLAND_DISPLAY(gdk_display)) { ++ return NULL; ++ } ++ ++ display = gdk_wayland_display_get_wl_display(gdk_display); ++ registry = wl_display_get_registry(display); ++ ++ return wl_registry_bind(registry, name, interface, version); ++} ++ ++static void ++gtk_wl_registry_add_listener(GtkWidget *widget, const struct wl_registry_listener *listener) ++{ ++ GdkDisplay *gdk_display = gtk_widget_get_display(widget); ++ struct wl_display *display; ++ struct wl_registry *registry; ++ ++ if (!GDK_IS_WAYLAND_DISPLAY(gdk_display)) { ++ return; ++ } ++ ++ display = gdk_wayland_display_get_wl_display(gdk_display); ++ registry = wl_display_get_registry(display); ++ wl_registry_add_listener(registry, listener, widget); ++ wl_display_roundtrip(display); ++} ++ ++ ++static void ++registry_handle_global(void *data, ++ struct wl_registry *registry, ++ uint32_t name, ++ const char *interface, ++ uint32_t version) ++{ ++ GtkWidget *widget = GTK_WIDGET(data); ++ ++ if (strcmp(interface, "zwp_relative_pointer_manager_v1") == 0) { ++ struct zwp_relative_pointer_manager_v1 *relative_pointer_manager; ++ relative_pointer_manager = gtk_wl_registry_bind(widget, name, ++ &zwp_relative_pointer_manager_v1_interface, ++ 1); ++ g_object_set_data_full(G_OBJECT(widget), ++ "zwp_relative_pointer_manager_v1", ++ relative_pointer_manager, ++ (GDestroyNotify)zwp_relative_pointer_manager_v1_destroy); ++ } else if (strcmp(interface, "zwp_pointer_constraints_v1") == 0) { ++ struct zwp_pointer_constraints_v1 *pointer_constraints; ++ pointer_constraints = gtk_wl_registry_bind(widget, name, ++ &zwp_pointer_constraints_v1_interface, ++ 1); ++ g_object_set_data_full(G_OBJECT(widget), ++ "zwp_pointer_constraints_v1", ++ pointer_constraints, ++ (GDestroyNotify)zwp_pointer_constraints_v1_destroy); ++ } ++} ++ ++static void ++registry_handle_global_remove(void *data, ++ struct wl_registry *registry, ++ uint32_t name) ++{ ++} ++ ++static const struct wl_registry_listener registry_listener = { ++ registry_handle_global, ++ registry_handle_global_remove ++}; ++ ++void ++spice_wayland_extensions_init(GtkWidget *widget) ++{ ++ g_return_if_fail(GTK_IS_WIDGET(widget)); ++ ++ gtk_wl_registry_add_listener(widget, ®istry_listener); ++} ++ ++ ++static GdkDevice * ++spice_gdk_window_get_pointing_device(GdkWindow *window) ++{ ++ GdkDisplay *gdk_display = gdk_window_get_display(window); ++ ++ return gdk_seat_get_pointer(gdk_display_get_default_seat(gdk_display)); ++} ++ ++static struct zwp_relative_pointer_v1_listener relative_pointer_listener; ++ ++// NOTE this API works only on a single widget per application ++int ++spice_wayland_extensions_enable_relative_pointer(GtkWidget *widget, ++ void (*cb)(void *, ++ struct zwp_relative_pointer_v1 *, ++ uint32_t, uint32_t, ++ wl_fixed_t, wl_fixed_t, wl_fixed_t, wl_fixed_t)) ++{ ++ struct zwp_relative_pointer_v1 *relative_pointer; ++ ++ g_return_val_if_fail(GTK_IS_WIDGET(widget), -1); ++ ++ relative_pointer = g_object_get_data(G_OBJECT(widget), "zwp_relative_pointer_v1"); ++ ++ if (relative_pointer == NULL) { ++ struct zwp_relative_pointer_manager_v1 *relative_pointer_manager; ++ GdkWindow *window = gtk_widget_get_window(widget); ++ struct wl_pointer *pointer; ++ ++ relative_pointer_manager = g_object_get_data(G_OBJECT(widget), "zwp_relative_pointer_manager_v1"); ++ if (relative_pointer_manager == NULL) ++ return -1; ++ ++ pointer = gdk_wayland_device_get_wl_pointer(spice_gdk_window_get_pointing_device(window)); ++ relative_pointer = zwp_relative_pointer_manager_v1_get_relative_pointer(relative_pointer_manager, ++ pointer); ++ ++ relative_pointer_listener.relative_motion = cb; ++ zwp_relative_pointer_v1_add_listener(relative_pointer, ++ &relative_pointer_listener, ++ widget); ++ ++ g_object_set_data_full(G_OBJECT(widget), ++ "zwp_relative_pointer_v1", ++ relative_pointer, ++ (GDestroyNotify)zwp_relative_pointer_v1_destroy); ++ } ++ ++ return 0; ++} ++ ++int spice_wayland_extensions_disable_relative_pointer(GtkWidget *widget) ++{ ++ g_return_val_if_fail(GTK_IS_WIDGET(widget), -1); ++ ++ /* This will call zwp_relative_pointer_v1_destroy() and stop relative ++ * movement */ ++ g_object_set_data(G_OBJECT(widget), "zwp_relative_pointer_v1", NULL); ++ ++ return 0; ++} ++ ++static struct zwp_locked_pointer_v1_listener locked_pointer_listener; ++ ++// NOTE this API works only on a single widget per application ++int ++spice_wayland_extensions_lock_pointer(GtkWidget *widget, ++ void (*lock_cb)(void *, struct zwp_locked_pointer_v1 *), ++ void (*unlock_cb)(void *, struct zwp_locked_pointer_v1 *)) ++{ ++ struct zwp_pointer_constraints_v1 *pointer_constraints; ++ struct zwp_locked_pointer_v1 *locked_pointer; ++ GdkWindow *window; ++ struct wl_pointer *pointer; ++ ++ g_return_val_if_fail(GTK_IS_WIDGET(widget), -1); ++ ++ pointer_constraints = g_object_get_data(G_OBJECT(widget), "zwp_pointer_constraints_v1"); ++ locked_pointer = g_object_get_data(G_OBJECT(widget), "zwp_locked_pointer_v1"); ++ if (locked_pointer != NULL) { ++ /* A previous lock already in place */ ++ return 0; ++ } ++ ++ window = gtk_widget_get_window(widget); ++ pointer = gdk_wayland_device_get_wl_pointer(spice_gdk_window_get_pointing_device(window)); ++ locked_pointer = zwp_pointer_constraints_v1_lock_pointer(pointer_constraints, ++ gdk_wayland_window_get_wl_surface(window), ++ pointer, ++ NULL, ++ ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT); ++ if (lock_cb || unlock_cb) { ++ locked_pointer_listener.locked = lock_cb; ++ locked_pointer_listener.unlocked = unlock_cb; ++ zwp_locked_pointer_v1_add_listener(locked_pointer, ++ &locked_pointer_listener, ++ widget); ++ } ++ g_object_set_data_full(G_OBJECT(widget), ++ "zwp_locked_pointer_v1", ++ locked_pointer, ++ (GDestroyNotify)zwp_locked_pointer_v1_destroy); ++ ++ return 0; ++} ++ ++int ++spice_wayland_extensions_unlock_pointer(GtkWidget *widget) ++{ ++ g_return_val_if_fail(GTK_IS_WIDGET(widget), -1); ++ ++ g_object_set_data(G_OBJECT(widget), "zwp_locked_pointer_v1", NULL); ++ ++ return 0; ++} +diff --git a/src/wayland-extensions.h b/src/wayland-extensions.h +new file mode 100644 +index 0000000..bf34044 +--- /dev/null ++++ b/src/wayland-extensions.h +@@ -0,0 +1,32 @@ ++/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ ++/* ++ Copyright (C) 2017 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 . ++*/ ++#pragma once ++ ++#include ++ ++void spice_wayland_extensions_init(GtkWidget *widget); ++int spice_wayland_extensions_enable_relative_pointer(GtkWidget *widget, ++ void (*cb)(void *, ++ struct zwp_relative_pointer_v1 *, ++ uint32_t, uint32_t, ++ wl_fixed_t, wl_fixed_t, wl_fixed_t, wl_fixed_t)); ++int spice_wayland_extensions_disable_relative_pointer(GtkWidget *widget); ++int spice_wayland_extensions_lock_pointer(GtkWidget *widget, ++ void (*lock_cb)(void *, struct zwp_locked_pointer_v1 *), ++ void (*unlock_cb)(void *, struct zwp_locked_pointer_v1 *)); ++int spice_wayland_extensions_unlock_pointer(GtkWidget *widget); +-- +2.26.2 + diff --git a/SOURCES/0007-spice-gtk-save-mouse-button-state-on-mouse-click.patch b/SOURCES/0007-spice-gtk-save-mouse-button-state-on-mouse-click.patch new file mode 100644 index 0000000..e3618ab --- /dev/null +++ b/SOURCES/0007-spice-gtk-save-mouse-button-state-on-mouse-click.patch @@ -0,0 +1,77 @@ +From 7e0f7bda8d5817c0cbfc56be4cf3727b98f223f4 Mon Sep 17 00:00:00 2001 +From: Francesco Giudici +Date: Mon, 20 Apr 2020 14:37:57 +0200 +Subject: [PATCH 7/9] spice-gtk: save mouse button state on mouse click + +This will be used later to couple it with relative mouse movement under +Wayland: we just get the mouse movement from the Wayland protocols +callback. + +Signed-off-by: Francesco Giudici +Acked-by: Frediano Ziglio +(cherry picked from commit 0fe70950524c28d383f34876c66107117581c72f) +--- + src/spice-widget-priv.h | 1 + + src/spice-widget.c | 22 +++++++++++++++++++++- + 2 files changed, 22 insertions(+), 1 deletion(-) + +diff --git a/src/spice-widget-priv.h b/src/spice-widget-priv.h +index 436c802..0b282f5 100644 +--- a/src/spice-widget-priv.h ++++ b/src/spice-widget-priv.h +@@ -96,6 +96,7 @@ struct _SpiceDisplayPrivate { + SpiceSmartcardChannel *smartcard; + + enum SpiceMouseMode mouse_mode; ++ int mouse_button_mask; + int mouse_grab_active; + bool mouse_have_pointer; + GdkCursor *mouse_cursor; +diff --git a/src/spice-widget.c b/src/spice-widget.c +index 8b91f52..7700f47 100644 +--- a/src/spice-widget.c ++++ b/src/spice-widget.c +@@ -1954,7 +1954,21 @@ static int button_gdk_to_spice(guint gdk) + }; + + if (gdk < SPICE_N_ELEMENTS(map)) { +- return map [ gdk ]; ++ return map[gdk]; ++ } ++ return 0; ++} ++ ++static int button_gdk_to_spice_mask(guint gdk) ++{ ++ static const int map[] = { ++ [1] = SPICE_MOUSE_BUTTON_MASK_LEFT, ++ [2] = SPICE_MOUSE_BUTTON_MASK_MIDDLE, ++ [3] = SPICE_MOUSE_BUTTON_MASK_RIGHT, ++ }; ++ ++ if (gdk < SPICE_N_ELEMENTS(map)) { ++ return map[gdk]; + } + return 0; + } +@@ -2160,11 +2174,17 @@ static gboolean button_event(GtkWidget *widget, GdkEventButton *button) + spice_inputs_channel_button_press(d->inputs, + button_gdk_to_spice(button->button), + button_mask_gdk_to_spice(button->state)); ++ /* Save the mouse button mask to couple it with Wayland movement */ ++ d->mouse_button_mask = button_mask_gdk_to_spice(button->state); ++ d->mouse_button_mask |= button_gdk_to_spice_mask(button->button); + break; + case GDK_BUTTON_RELEASE: + spice_inputs_channel_button_release(d->inputs, + button_gdk_to_spice(button->button), + button_mask_gdk_to_spice(button->state)); ++ /* Save the mouse button mask to couple it with Wayland movement */ ++ d->mouse_button_mask = button_mask_gdk_to_spice(button->state); ++ d->mouse_button_mask ^= button_gdk_to_spice_mask(button->button); + break; + default: + break; +-- +2.26.2 + diff --git a/SOURCES/0008-wayland-fix-mouse-lock-in-server-mode.patch b/SOURCES/0008-wayland-fix-mouse-lock-in-server-mode.patch new file mode 100644 index 0000000..5c5253e --- /dev/null +++ b/SOURCES/0008-wayland-fix-mouse-lock-in-server-mode.patch @@ -0,0 +1,181 @@ +From 16cdb3a8cdd60da9eef12d1d10a01d4eed21a5a7 Mon Sep 17 00:00:00 2001 +From: Francesco Giudici +Date: Mon, 20 Apr 2020 10:25:03 +0200 +Subject: [PATCH 8/9] wayland: fix mouse lock in server mode + +We can now properly manage mouse pointer lock by using the wayland protocols. +Includes fix from Frediano Ziglio to manage switching from mouse in +server mode to client mode without releasing the pointer +(see https://gitlab.freedesktop.org/fziglio/spice-gtk/-/commit/c14b047e45) + +Signed-off-by: Francesco Giudici +Acked-by: Frediano Ziglio +(cherry picked from commit dd7015d57ca936cc81060b1e2a09d3afc1478d4a) +--- + src/spice-widget.c | 85 +++++++++++++++++++++++++++++++++++----------- + 1 file changed, 66 insertions(+), 19 deletions(-) + +diff --git a/src/spice-widget.c b/src/spice-widget.c +index 7700f47..6cfc72f 100644 +--- a/src/spice-widget.c ++++ b/src/spice-widget.c +@@ -34,7 +34,13 @@ + #endif + #ifdef GDK_WINDOWING_WAYLAND + #include ++#ifdef HAVE_WAYLAND_PROTOCOLS ++#include "pointer-constraints-unstable-v1-client-protocol.h" ++#include "relative-pointer-unstable-v1-client-protocol.h" ++#include "wayland-extensions.h" + #endif ++#endif ++ + #ifdef G_OS_WIN32 + #include + #include +@@ -698,6 +704,11 @@ static void spice_display_init(SpiceDisplay *display) + + d->grabseq = spice_grab_sequence_new_from_string("Control_L+Alt_L"); + d->activeseq = g_new0(gboolean, d->grabseq->nkeysyms); ++ ++#ifdef HAVE_WAYLAND_PROTOCOLS ++ if GDK_IS_WAYLAND_DISPLAY(gtk_widget_get_display(widget)) ++ spice_wayland_extensions_init(widget); ++#endif + } + + static void +@@ -900,7 +911,7 @@ static void ungrab_keyboard(SpiceDisplay *display) + * We simply issue a gdk_seat_ungrab() followed immediately by another + * gdk_seat_grab() on the pointer if the pointer grab is to be kept. + */ +- if (GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default())) { ++ if (GDK_IS_WAYLAND_DISPLAY(gtk_widget_get_display(GTK_WIDGET(display)))) { + SpiceDisplayPrivate *d = display->priv; + + gdk_seat_ungrab(seat); +@@ -1055,15 +1066,49 @@ error: + } + #endif + ++#ifdef HAVE_WAYLAND_PROTOCOLS ++static void ++relative_pointer_handle_relative_motion(void *data, ++ struct zwp_relative_pointer_v1 *pointer, ++ uint32_t time_hi, ++ uint32_t time_lo, ++ wl_fixed_t dx_w, ++ wl_fixed_t dy_w, ++ wl_fixed_t dx_unaccel_w, ++ wl_fixed_t dy_unaccel_w) ++{ ++ SpiceDisplay *display = SPICE_DISPLAY(data); ++ GtkWidget *widget = GTK_WIDGET(display); ++ SpiceDisplayPrivate *d = display->priv; ++ ++ if (!d->inputs) ++ return; ++ if (d->disable_inputs) ++ return; ++ /* mode changed to client in the meantime */ ++ if (d->mouse_mode != SPICE_MOUSE_MODE_SERVER) { ++ spice_wayland_extensions_disable_relative_pointer(widget); ++ spice_wayland_extensions_unlock_pointer(widget); ++ return; ++ } ++ ++ spice_inputs_channel_motion(d->inputs, ++ wl_fixed_to_int(dx_unaccel_w), ++ wl_fixed_to_int(dy_unaccel_w), ++ d->mouse_button_mask); ++} ++#endif ++ + static gboolean do_pointer_grab(SpiceDisplay *display) + { ++ GtkWidget *widget = GTK_WIDGET(display); + SpiceDisplayPrivate *d = display->priv; +- GdkWindow *window = GDK_WINDOW(gtk_widget_get_window(GTK_WIDGET(display))); ++ GdkWindow *window = GDK_WINDOW(gtk_widget_get_window(widget)); + GdkGrabStatus status; + GdkCursor *blank = spice_display_get_blank_cursor(display); + gboolean grab_successful = FALSE; + +- if (!gtk_widget_get_realized(GTK_WIDGET(display))) ++ if (!gtk_widget_get_realized(widget)) + goto end; + + #ifdef G_OS_WIN32 +@@ -1080,6 +1125,14 @@ static gboolean do_pointer_grab(SpiceDisplay *display) + NULL, + NULL, + NULL); ++ ++#ifdef HAVE_WAYLAND_PROTOCOLS ++ if (GDK_IS_WAYLAND_DISPLAY(gtk_widget_get_display(widget))) { ++ spice_wayland_extensions_enable_relative_pointer(widget, relative_pointer_handle_relative_motion); ++ spice_wayland_extensions_lock_pointer(widget, NULL, NULL); ++ } ++#endif ++ + grab_successful = (status == GDK_GRAB_SUCCESS); + if (!grab_successful) { + d->mouse_grab_active = false; +@@ -1204,7 +1257,8 @@ static void ungrab_pointer(SpiceDisplay *display) + * immediately by another gdk_seat_grab() on the keyboard if the + * keyboard grab is to be kept. + */ +- if (GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default())) { ++ if (GDK_IS_WAYLAND_DISPLAY(gtk_widget_get_display(GTK_WIDGET(display)))) { ++ GtkWidget *widget = GTK_WIDGET(display); + SpiceDisplayPrivate *d = display->priv; + + gdk_seat_ungrab(seat); +@@ -1213,7 +1267,7 @@ static void ungrab_pointer(SpiceDisplay *display) + GdkGrabStatus status; + + status = gdk_seat_grab(seat, +- gtk_widget_get_window(GTK_WIDGET(display)), ++ gtk_widget_get_window(widget), + GDK_SEAT_CAPABILITY_KEYBOARD, + FALSE, + NULL, +@@ -1224,6 +1278,12 @@ static void ungrab_pointer(SpiceDisplay *display) + g_warning("keyboard grab failed %u", status); + d->keyboard_grab_active = false; + } ++#ifdef HAVE_WAYLAND_PROTOCOLS ++ if (d->mouse_mode == SPICE_MOUSE_MODE_SERVER) { ++ spice_wayland_extensions_disable_relative_pointer(widget); ++ spice_wayland_extensions_unlock_pointer(widget); ++ } ++#endif + } + + return; +@@ -1860,21 +1920,8 @@ static gboolean leave_event(GtkWidget *widget, GdkEventCrossing *crossing G_GNUC + + DISPLAY_DEBUG(display, "%s", __FUNCTION__); + +- if (d->mouse_grab_active) { +-#ifdef GDK_WINDOWING_WAYLAND +- /* On Wayland, there is no active pointer grab, so once the pointer +- * has left the window, the events are routed to the window with +- * pointer focus instead of ours, in which case we should just +- * ungrab to avoid nasty side effects. */ +- if (GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default())) { +- GdkWindow *window = gtk_widget_get_window(widget); +- +- if (window == crossing->window) +- try_mouse_ungrab(display); +- } +-#endif ++ if (d->mouse_grab_active) + return true; +- } + + d->mouse_have_pointer = false; + spice_gtk_session_set_mouse_has_pointer(d->gtk_session, false); +-- +2.26.2 + diff --git a/SOURCES/0009-channel-main-Handle-some-detailed-error-for-VD_AGENT.patch b/SOURCES/0009-channel-main-Handle-some-detailed-error-for-VD_AGENT.patch new file mode 100644 index 0000000..9f1255c --- /dev/null +++ b/SOURCES/0009-channel-main-Handle-some-detailed-error-for-VD_AGENT.patch @@ -0,0 +1,54 @@ +From 769465494c5e3e4299a2dfdf6e0c835be4e04ab7 Mon Sep 17 00:00:00 2001 +From: Frediano Ziglio +Date: Thu, 19 Mar 2020 06:12:34 +0000 +Subject: [PATCH 9/9] channel-main: Handle some detailed error for + VD_AGENT_FILE_XFER_STATUS_ERROR + +Detect presence of detail on VD_AGENT_FILE_XFER_STATUS_ERROR and +if the error is supported give more detailed information, otherwise +fallback to the old generic error. + +Signed-off-by: Frediano Ziglio +Acked-by: Victor Toso +(cherry picked from commit d79b05dcff83792c8415cafbb288d614de9d3101) +--- + src/channel-main.c | 22 +++++++++++++++++++--- + 1 file changed, 19 insertions(+), 3 deletions(-) + +diff --git a/src/channel-main.c b/src/channel-main.c +index c4fe02b..d845fda 100644 +--- a/src/channel-main.c ++++ b/src/channel-main.c +@@ -1913,10 +1913,26 @@ static void main_agent_handle_xfer_status(SpiceMainChannel *channel, + error = g_error_new_literal(SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED, + _("The spice agent cancelled the file transfer")); + break; +- case VD_AGENT_FILE_XFER_STATUS_ERROR: +- error = g_error_new_literal(SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED, +- _("The spice agent reported an error during the file transfer")); ++ case VD_AGENT_FILE_XFER_STATUS_ERROR: { ++ const VDAgentFileXferStatusError *err = (VDAgentFileXferStatusError *) msg->data; ++ if (test_agent_cap(channel, VD_AGENT_CAP_FILE_XFER_DETAILED_ERRORS) && ++ msg_hdr->size >= sizeof(*msg) + sizeof(*err) && ++ err->error_type == VD_AGENT_FILE_XFER_STATUS_ERROR_GLIB_IO) { ++ ++ switch (err->error_code) { ++ case G_IO_ERROR_INVALID_FILENAME: ++ error = g_error_new_literal(G_IO_ERROR, err->error_code, ++ _("Invalid filename of transferred file")); ++ break; ++ } ++ } ++ if (error == NULL) { ++ error = g_error_new_literal(SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED, ++ _("The spice agent reported an error " ++ "during the file transfer")); ++ } + break; ++ } + case VD_AGENT_FILE_XFER_STATUS_NOT_ENOUGH_SPACE: { + const VDAgentFileXferStatusNotEnoughSpace *err = + (VDAgentFileXferStatusNotEnoughSpace*) msg->data; +-- +2.26.2 + diff --git a/SOURCES/0010-quic-Check-we-have-some-data-to-start-decoding-quic-.patch b/SOURCES/0010-quic-Check-we-have-some-data-to-start-decoding-quic-.patch new file mode 100644 index 0000000..896bfbc --- /dev/null +++ b/SOURCES/0010-quic-Check-we-have-some-data-to-start-decoding-quic-.patch @@ -0,0 +1,34 @@ +From d9cc2d4659950df230dfe30e5445b91d4c15604e Mon Sep 17 00:00:00 2001 +From: Frediano Ziglio +Date: Wed, 29 Apr 2020 15:09:13 +0100 +Subject: [PATCH spice-common 1/4] quic: Check we have some data to start + decoding quic image + +All paths already pass some data to quic_decode_begin but for the +test check it, it's not that expensive test. +Checking for not 0 is enough, all other words will potentially be +read calling more_io_words but we need one to avoid a potential +initial buffer overflow or deferencing an invalid pointer. + +Signed-off-by: Frediano Ziglio +Acked-by: Uri Lublin +--- + common/quic.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/subprojects/spice-common/common/quic.c b/subprojects/spice-common/common/quic.c +index 55a5d6c..e03f3af 100644 +--- a/subprojects/spice-common/common/quic.c ++++ b/subprojects/spice-common/common/quic.c +@@ -1136,7 +1136,7 @@ int quic_decode_begin(QuicContext *quic, uint32_t *io_ptr, unsigned int num_io_w + int channels; + int bpc; + +- if (!encoder_reset(encoder, io_ptr, io_ptr_end)) { ++ if (!num_io_words || !encoder_reset(encoder, io_ptr, io_ptr_end)) { + return QUIC_ERROR; + } + +-- +2.25.4 + diff --git a/SOURCES/0011-quic-Check-image-size-in-quic_decode_begin.patch b/SOURCES/0011-quic-Check-image-size-in-quic_decode_begin.patch new file mode 100644 index 0000000..ea52954 --- /dev/null +++ b/SOURCES/0011-quic-Check-image-size-in-quic_decode_begin.patch @@ -0,0 +1,48 @@ +From 19cd6fe85610b424349db2d97e2dd0e2761a4a05 Mon Sep 17 00:00:00 2001 +From: Frediano Ziglio +Date: Wed, 29 Apr 2020 15:10:24 +0100 +Subject: [PATCH spice-common 2/4] quic: Check image size in quic_decode_begin + +Avoid some overflow in code due to images too big or +negative numbers. + +Signed-off-by: Frediano Ziglio +Acked-by: Uri Lublin +--- + common/quic.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/subprojects/spice-common/common/quic.c b/subprojects/spice-common/common/quic.c +index e03f3af..890f128 100644 +--- a/subprojects/spice-common/common/quic.c ++++ b/subprojects/spice-common/common/quic.c +@@ -56,6 +56,9 @@ typedef uint8_t BYTE; + #define MINwminext 1 + #define MAXwminext 100000000 + ++/* Maximum image size in pixels, mainly to avoid possible integer overflows */ ++#define SPICE_MAX_IMAGE_SIZE (512 * 1024 * 1024 - 1) ++ + typedef struct QuicFamily { + unsigned int nGRcodewords[MAXNUMCODES]; /* indexed by code number, contains number of + unmodified GR codewords in the code */ +@@ -1165,6 +1168,16 @@ int quic_decode_begin(QuicContext *quic, uint32_t *io_ptr, unsigned int num_io_w + height = encoder->io_word; + decode_eat32bits(encoder); + ++ if (width <= 0 || height <= 0) { ++ encoder->usr->warn(encoder->usr, "invalid size\n"); ++ return QUIC_ERROR; ++ } ++ ++ /* avoid too big images */ ++ if ((uint64_t) width * height > SPICE_MAX_IMAGE_SIZE) { ++ encoder->usr->error(encoder->usr, "image too large\n"); ++ } ++ + quic_image_params(encoder, type, &channels, &bpc); + + if (!encoder_reset_channels(encoder, channels, width, bpc)) { +-- +2.25.4 + diff --git a/SOURCES/0012-quic-Check-RLE-lengths.patch b/SOURCES/0012-quic-Check-RLE-lengths.patch new file mode 100644 index 0000000..aebad02 --- /dev/null +++ b/SOURCES/0012-quic-Check-RLE-lengths.patch @@ -0,0 +1,35 @@ +From d45a4954d73b41a255b8b4ec57c01ae87ec2936e Mon Sep 17 00:00:00 2001 +From: Frediano Ziglio +Date: Wed, 29 Apr 2020 15:11:38 +0100 +Subject: [PATCH spice-common 3/4] quic: Check RLE lengths + +Avoid buffer overflows decoding images. On compression we compute +lengths till end of line so it won't cause regressions. +Proved by fuzzing the code. + +Signed-off-by: Frediano Ziglio +Acked-by: Uri Lublin +--- + common/quic_tmpl.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/subprojects/spice-common/common/quic_tmpl.c b/subprojects/spice-common/common/quic_tmpl.c +index f0a4927..11e09f5 100644 +--- a/subprojects/spice-common/common/quic_tmpl.c ++++ b/subprojects/spice-common/common/quic_tmpl.c +@@ -570,7 +570,11 @@ static void FNAME_DECL(uncompress_row_seg)(const PIXEL * const prev_row, + do_run: + state->waitcnt = stopidx - i; + run_index = i; +- run_end = i + decode_state_run(encoder, state); ++ run_end = decode_state_run(encoder, state); ++ if (run_end < 0 || run_end > (end - i)) { ++ encoder->usr->error(encoder->usr, "wrong RLE\n"); ++ } ++ run_end += i; + + for (; i < run_end; i++) { + UNCOMPRESS_PIX_START(&cur_row[i]); +-- +2.25.4 + diff --git a/SOURCES/0013-quic-Avoid-possible-buffer-overflow-in-find_bucket.patch b/SOURCES/0013-quic-Avoid-possible-buffer-overflow-in-find_bucket.patch new file mode 100644 index 0000000..ca9f80f --- /dev/null +++ b/SOURCES/0013-quic-Avoid-possible-buffer-overflow-in-find_bucket.patch @@ -0,0 +1,35 @@ +From 57c6e6b00247ad289a27648213d7ad2306fe3931 Mon Sep 17 00:00:00 2001 +From: Frediano Ziglio +Date: Thu, 30 Apr 2020 10:19:09 +0100 +Subject: [PATCH spice-common 4/4] quic: Avoid possible buffer overflow in + find_bucket + +Proved by fuzzing the code. + +Signed-off-by: Frediano Ziglio +Acked-by: Uri Lublin +--- + common/quic_family_tmpl.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/subprojects/spice-common/common/quic_family_tmpl.c b/subprojects/spice-common/common/quic_family_tmpl.c +index 8a5f7d2..6cc051b 100644 +--- a/subprojects/spice-common/common/quic_family_tmpl.c ++++ b/subprojects/spice-common/common/quic_family_tmpl.c +@@ -103,7 +103,12 @@ static s_bucket *FNAME(find_bucket)(Channel *channel, const unsigned int val) + { + spice_extra_assert(val < (0x1U << BPC)); + +- return channel->_buckets_ptrs[val]; ++ /* The and (&) here is to avoid buffer overflows in case of garbage or malicious ++ * attempts. Is much faster then using comparisons and save us from such situations. ++ * Note that on normal build the check above won't be compiled as this code path ++ * is pretty hot and would cause speed regressions. ++ */ ++ return channel->_buckets_ptrs[val & ((1U << BPC) - 1)]; + } + + #undef FNAME +-- +2.25.4 + diff --git a/SOURCES/0014-Remove-some-warnings-from-Clang-static-analyzer.patch b/SOURCES/0014-Remove-some-warnings-from-Clang-static-analyzer.patch new file mode 100644 index 0000000..ccfb3d7 --- /dev/null +++ b/SOURCES/0014-Remove-some-warnings-from-Clang-static-analyzer.patch @@ -0,0 +1,74 @@ +From 95f6f22c4fee847cdf84465107561b94a5c10782 Mon Sep 17 00:00:00 2001 +From: Frediano Ziglio +Date: Thu, 27 Aug 2020 17:20:06 +0100 +Subject: [PATCH] Remove some warnings from Clang static analyzer + +qmp-port.c: +warning: Although the value stored to 'node' is used in the enclosing +expression, the value is never actually read from 'node' + +usb-backend.c: +warning: Value stored to 'done' is never read +warning: Use of memory after it is freed + +usb-device-cd.c: +warning: Value stored to 'error' is never read + +Signed-off-by: Frediano Ziglio +--- + src/qmp-port.c | 2 +- + src/usb-backend.c | 3 +-- + src/usb-device-cd.c | 2 +- + 3 files changed, 3 insertions(+), 4 deletions(-) + +diff --git a/src/qmp-port.c b/src/qmp-port.c +index 25ab1d1..f0cbbc7 100644 +--- a/src/qmp-port.c ++++ b/src/qmp-port.c +@@ -104,7 +104,7 @@ spice_qmp_dispatch_message(SpiceQmpPort *self) + return TRUE; + } + +- if ((node = json_object_get_member(obj, "error"))) { ++ if (json_object_get_member(obj, "error") != NULL) { + gint id = json_object_get_int_member(obj, "id"); + const gchar *desc = json_object_get_string_member(obj, "desc"); + +diff --git a/src/usb-backend.c b/src/usb-backend.c +index 5d3912b..a4a5f0a 100644 +--- a/src/usb-backend.c ++++ b/src/usb-backend.c +@@ -867,7 +867,6 @@ usbredir_control_packet(void *priv, uint64_t id, struct usb_redir_control_packet + + if (!done) { + device_ops(edev)->control_request(edev, data, data_len, &response, &out_buffer); +- done = TRUE; + } + + if (response.status) { +@@ -1367,8 +1366,8 @@ void spice_usb_backend_channel_delete(SpiceUsbBackendChannel *ch) + free(ch->rules); + } + ++ SPICE_DEBUG("%s << %p", __FUNCTION__, ch); + g_free(ch); +- SPICE_DEBUG("%s << %p", __FUNCTION__, ch); + } + + void +diff --git a/src/usb-device-cd.c b/src/usb-device-cd.c +index 1aa553a..b9fa317 100644 +--- a/src/usb-device-cd.c ++++ b/src/usb-device-cd.c +@@ -150,7 +150,7 @@ static int cd_device_load(SpiceCdLU *unit, gboolean load) + if (load) { + error = ioctl(fd, CDROMCLOSETRAY, 0); + } else { +- error = ioctl(fd, CDROM_LOCKDOOR, 0); ++ ioctl(fd, CDROM_LOCKDOOR, 0); + error = ioctl(fd, CDROMEJECT, 0); + } + if (error) { +-- +2.28.0 + diff --git a/SOURCES/0015-ssl_verify-Do-not-check-IP-if-we-fail-to-resolve-it.patch b/SOURCES/0015-ssl_verify-Do-not-check-IP-if-we-fail-to-resolve-it.patch new file mode 100644 index 0000000..3bc60d7 --- /dev/null +++ b/SOURCES/0015-ssl_verify-Do-not-check-IP-if-we-fail-to-resolve-it.patch @@ -0,0 +1,66 @@ +From c39cc1b1ef5165523f3394f06a65cc9a6c65b7ae Mon Sep 17 00:00:00 2001 +From: Frediano Ziglio +Date: Thu, 27 Aug 2020 17:57:36 +0100 +Subject: [PATCH] ssl_verify: Do not check IP if we fail to resolve it + +There's no point on checking an empty IP address, an IP +address is never empty. +This also solve some compiler warnings trying to possibly +pass a NULL pointer to memcmp or setting a variable without +reading it. + +Signed-off-by: Frediano Ziglio +Acked-by: Uri Lublin +--- + common/ssl_verify.c | 21 ++++++++++----------- + 1 file changed, 10 insertions(+), 11 deletions(-) + +diff --git a/subprojects/spice-common/common/ssl_verify.c b/subprojects/spice-common/common/ssl_verify.c +index dee719f..9ee8059 100644 +--- a/subprojects/spice-common/common/ssl_verify.c ++++ b/subprojects/spice-common/common/ssl_verify.c +@@ -196,21 +196,22 @@ static int verify_hostname(X509* cert, const char *hostname) + return 1; + } + } else if (name->type == GEN_IPADD) { +- GInetAddress * ip = NULL; +- const guint8 * ip_binary = NULL; +- int alt_ip_len = 0; +- int ip_len = 0; ++ GInetAddress * ip; ++ const guint8 * ip_binary; ++ int alt_ip_len; ++ int ip_len; + + found_dns_name = 1; + + ip = g_inet_address_new_from_string(hostname); +- if (ip != NULL) { +- ip_len = g_inet_address_get_native_size(ip); +- ip_binary = g_inet_address_to_bytes(ip); +- } else { ++ if (ip == NULL) { + spice_warning("Could not parse hostname: %s", hostname); ++ continue; + } + ++ ip_len = g_inet_address_get_native_size(ip); ++ ip_binary = g_inet_address_to_bytes(ip); ++ + alt_ip_len = ASN1_STRING_length(name->d.iPAddress); + + if ((ip_len == alt_ip_len) && +@@ -229,9 +230,7 @@ static int verify_hostname(X509* cert, const char *hostname) + GENERAL_NAMES_free(subject_alt_names); + return 1; + } +- if (ip != NULL) { +- g_object_unref(ip); +- } ++ g_object_unref(ip); + } + } + GENERAL_NAMES_free(subject_alt_names); +-- +2.28.0 + diff --git a/SOURCES/0016-usb-backend-Fix-spice-usbredir-redirect-on-connect-o.patch b/SOURCES/0016-usb-backend-Fix-spice-usbredir-redirect-on-connect-o.patch new file mode 100644 index 0000000..a948ca6 --- /dev/null +++ b/SOURCES/0016-usb-backend-Fix-spice-usbredir-redirect-on-connect-o.patch @@ -0,0 +1,37 @@ +From afc5872bff1eb327dd299bacdc4eec5e26d37a10 Mon Sep 17 00:00:00 2001 +From: Frediano Ziglio +Date: Wed, 23 Sep 2020 17:05:01 +0100 +Subject: [PATCH] usb-backend: Fix spice-usbredir-redirect-on-connect option + +After commit 3e20f17b90598e740c4e274b81d99f28187da800 (cfr +"usb-redir: extend USB backend to support emulated devices") +this option stopped working, as devices are not redirected. +Data for device to guest were not written during initialisation. + +With this fix both spice-usbredir-redirect-on-connect and +spice-share-cd are working (even together). + +This fixes https://bugzilla.redhat.com/show_bug.cgi?id=1874740. + +Signed-off-by: Frediano Ziglio +Acked-by: Uri Lublin +--- + src/usb-backend.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/usb-backend.c b/src/usb-backend.c +index a4a5f0a..857488e 100644 +--- a/src/usb-backend.c ++++ b/src/usb-backend.c +@@ -418,7 +418,7 @@ static void usbredir_write_flush_callback(void *user_data) + return; + } + if (is_channel_ready(ch->usbredir_channel)) { +- if (ch->state == USB_CHANNEL_STATE_HOST) { ++ if (ch->state != USB_CHANNEL_STATE_PARSER && ch->usbredirhost != NULL) { + SPICE_DEBUG("%s ch %p -> usbredirhost", __FUNCTION__, ch); + usbredirhost_write_guest_data(ch->usbredirhost); + } else { +-- +2.28.0 + diff --git a/SOURCES/0017-empty_cd_clicked_cb-g_free-basename.patch b/SOURCES/0017-empty_cd_clicked_cb-g_free-basename.patch new file mode 100644 index 0000000..18f855b --- /dev/null +++ b/SOURCES/0017-empty_cd_clicked_cb-g_free-basename.patch @@ -0,0 +1,33 @@ +From 20eebc549da508c82e139120b577b047c76964c3 Mon Sep 17 00:00:00 2001 +From: Uri Lublin +Date: Wed, 11 Nov 2020 14:12:19 +0200 +Subject: [PATCH 17/22] empty_cd_clicked_cb: g_free basename + +Fix the following static analyzer warning: + src/usb-device-widget.c:224: leaked_storage: Failing to save or free + storage allocated by "g_path_get_basename(filename)" leaks it. + +Signed-off-by: Uri Lublin +--- + src/usb-device-widget.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/usb-device-widget.c b/src/usb-device-widget.c +index 257e9e1..0ff4e52 100644 +--- a/src/usb-device-widget.c ++++ b/src/usb-device-widget.c +@@ -220,8 +220,10 @@ empty_cd_clicked_cb(GtkToggleButton *toggle, gpointer user_data) + + rc = spice_usb_device_manager_create_shared_cd_device(priv->manager, filename, &err); + if (!rc && err != NULL) { ++ const gchar *basename = g_path_get_basename(filename); + gchar *err_msg = g_strdup_printf(_("shared CD %s, %s"), +- g_path_get_basename(filename), err->message); ++ basename, err->message); ++ g_free((gpointer)basename); + + SPICE_DEBUG("Failed to create %s", err_msg); + spice_usb_device_widget_add_err_msg(self, err_msg); +-- +2.28.0 + diff --git a/SOURCES/0018-spice_usbutil_parse_usbids-verify-at-least-one-vendo.patch b/SOURCES/0018-spice_usbutil_parse_usbids-verify-at-least-one-vendo.patch new file mode 100644 index 0000000..299cd8c --- /dev/null +++ b/SOURCES/0018-spice_usbutil_parse_usbids-verify-at-least-one-vendo.patch @@ -0,0 +1,44 @@ +From 032ca202f839fe1c49cddfd2b0459f9fecc23c86 Mon Sep 17 00:00:00 2001 +From: Uri Lublin +Date: Wed, 11 Nov 2020 20:03:57 +0200 +Subject: [PATCH 18/22] spice_usbutil_parse_usbids: verify at least one vendor + and product + +Fixes the following clang warning: + src/usbutil.c:148:52: warning: Use of zero-allocated memory + ... + + product_info[product_count].product_id = id; + ^ + 146| while (isspace(line[0])) + 147| line++; + 148|-> product_info[product_count].product_id = id; + 149| snprintf(product_info[product_count].name, + 150| PRODUCT_NAME_LEN, "%s", line); + +Signed-off-by: Uri Lublin +--- + src/usbutil.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/src/usbutil.c b/src/usbutil.c +index 7d7f38a..f29302b 100644 +--- a/src/usbutil.c ++++ b/src/usbutil.c +@@ -113,6 +113,13 @@ static gboolean spice_usbutil_parse_usbids(gchar *path) + usbids_vendor_count++; + } + ++ if (usbids_vendor_info == 0 || product_count == 0) { ++ usbids_vendor_count = -1; ++ g_strfreev(lines); ++ g_free(contents); ++ return FALSE; ++ } ++ + usbids_vendor_info = g_new(usb_vendor_info, usbids_vendor_count); + product_info = g_new(usb_product_info, product_count); + +-- +2.28.0 + diff --git a/SOURCES/0019-sink_event_probe-do-not-keep-duration-in-a-variable.patch b/SOURCES/0019-sink_event_probe-do-not-keep-duration-in-a-variable.patch new file mode 100644 index 0000000..f27f04a --- /dev/null +++ b/SOURCES/0019-sink_event_probe-do-not-keep-duration-in-a-variable.patch @@ -0,0 +1,42 @@ +From bb4999f6e450aa1b1270ade7113966869fc4ed27 Mon Sep 17 00:00:00 2001 +From: Uri Lublin +Date: Wed, 11 Nov 2020 20:34:09 +0200 +Subject: [PATCH 19/22] sink_event_probe: do not keep duration in a variable + +If not ENABLE_RECORDER, then duration is assigned a value +but is never used - as the compiler optimizes it out. + +Fixes the following clang warning: + src/channel-display-gst.c:443:21: warning: Value stored to + 'duration' during its initialization is never read + +Signed-off-by: Uri Lublin +--- + src/channel-display-gst.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/channel-display-gst.c b/src/channel-display-gst.c +index c58a90f..36db3a3 100644 +--- a/src/channel-display-gst.c ++++ b/src/channel-display-gst.c +@@ -439,7 +439,6 @@ sink_event_probe(GstPad *pad, GstPadProbeInfo *info, gpointer data) + if (l) { + SpiceGstFrame *gstframe = l->data; + const SpiceFrame *frame = gstframe->encoded_frame; +- int64_t duration = g_get_monotonic_time() - frame->creation_time; + /* Note that queue_len (the length of the queue prior to adding + * this frame) is crucial to correctly interpret the decoding time: + * - Less than MAX_DECODED_FRAMES means nothing blocked the +@@ -450,7 +449,8 @@ sink_event_probe(GstPad *pad, GstPadProbeInfo *info, gpointer data) + record(frames_stats, + "frame mm_time %u size %u creation time %" PRId64 + " decoded time %" PRId64 " queue %u before %u", +- frame->mm_time, frame->size, frame->creation_time, duration, ++ frame->mm_time, frame->size, frame->creation_time, ++ g_get_monotonic_time() - frame->creation_time, + decoder->decoding_queue->length, gstframe->queue_len); + + if (!decoder->appsink) { +-- +2.28.0 + diff --git a/SOURCES/0020-mark_false_event_id-is-guint-assign-0-to-it-not-FALS.patch b/SOURCES/0020-mark_false_event_id-is-guint-assign-0-to-it-not-FALS.patch new file mode 100644 index 0000000..7984e75 --- /dev/null +++ b/SOURCES/0020-mark_false_event_id-is-guint-assign-0-to-it-not-FALS.patch @@ -0,0 +1,26 @@ +From df47365c32711bae5dfa163f8eba7b0f741326d6 Mon Sep 17 00:00:00 2001 +From: Uri Lublin +Date: Thu, 19 Nov 2020 19:30:54 +0200 +Subject: [PATCH 20/22] mark_false_event_id is guint, assign 0 to it not FALSE + +Signed-off-by: Uri Lublin +--- + src/channel-display.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/channel-display.c b/src/channel-display.c +index 023baa1..f52ef12 100644 +--- a/src/channel-display.c ++++ b/src/channel-display.c +@@ -1971,7 +1971,7 @@ static void display_handle_surface_create(SpiceChannel *channel, SpiceMsgIn *in) + create_canvas(channel, surface); + if (c->mark_false_event_id != 0) { + g_source_remove(c->mark_false_event_id); +- c->mark_false_event_id = FALSE; ++ c->mark_false_event_id = 0; + } + } else { + surface->primary = false; +-- +2.28.0 + diff --git a/SOURCES/0021-usb-backend-create_emulated_device-assert-address-32.patch b/SOURCES/0021-usb-backend-create_emulated_device-assert-address-32.patch new file mode 100644 index 0000000..f4df551 --- /dev/null +++ b/SOURCES/0021-usb-backend-create_emulated_device-assert-address-32.patch @@ -0,0 +1,33 @@ +From 35f6926328cd415f6ba24efe49c3f990e44a8948 Mon Sep 17 00:00:00 2001 +From: Uri Lublin +Date: Sun, 22 Nov 2020 16:21:00 +0200 +Subject: [PATCH 21/22] usb-backend: create_emulated_device: assert address < + 32 + +This may fix the following static analyzer issue: + src/usb-backend.c:1507: large_shift: In expression "1 << address", left + shifting by more than 31 bits has undefined behavior. + The shift amount, "address", is 32. + +Signed-off-by: Uri Lublin +--- + src/usb-backend.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/usb-backend.c b/src/usb-backend.c +index 857488e..c76d576 100644 +--- a/src/usb-backend.c ++++ b/src/usb-backend.c +@@ -1482,6 +1482,9 @@ spice_usb_backend_create_emulated_device(SpiceUsbBackend *be, + } + } + ++ // for static analyzers: it is already checked above ++ g_assert(address < 32); ++ + dev = g_new0(SpiceUsbDevice, 1); + dev->device_info.bus = BUS_NUMBER_FOR_EMULATED_USB; + dev->device_info.address = address; +-- +2.28.0 + diff --git a/SOURCES/0022-spice-utils-allocate-ctx-after-g_return_val_if_fail.patch b/SOURCES/0022-spice-utils-allocate-ctx-after-g_return_val_if_fail.patch new file mode 100644 index 0000000..ae8543f --- /dev/null +++ b/SOURCES/0022-spice-utils-allocate-ctx-after-g_return_val_if_fail.patch @@ -0,0 +1,48 @@ +From 1068e4d0e39f3d8f3390102863a02eaed7ee81b1 Mon Sep 17 00:00:00 2001 +From: Uri Lublin +Date: Mon, 23 Nov 2020 15:38:43 +0200 +Subject: [PATCH 22/22] spice-utils: allocate ctx after g_return_val_if_fail + +Fix the following issue: + Error: RESOURCE_LEAK + src/spice-util.c:235: alloc_fn: Storage is returned + from allocation function "whc_new". + src/spice-util.c:235: var_assign: Assigning: "ctx" = + storage returned from "whc_new(instance_obj, gobject)". + src/spice-util.c:237: leaked_storage: Variable "ctx" + going out of scope leaks the storage it points to. + + 235| WeakHandlerCtx *ctx = whc_new (instance_obj, gobject); + 236| + 237|-> g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); + 238| g_return_val_if_fail (detailed_signal != NULL, 0); + 239| g_return_val_if_fail (c_handler != NULL, 0); + +Signed-off-by: Uri Lublin +--- + src/spice-util.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/spice-util.c b/src/spice-util.c +index 1e49982..d0c56ba 100644 +--- a/src/spice-util.c ++++ b/src/spice-util.c +@@ -231,7 +231,6 @@ gulong spice_g_signal_connect_object (gpointer instance, + GConnectFlags connect_flags) + { + GObject *instance_obj = G_OBJECT (instance); +- WeakHandlerCtx *ctx = whc_new (instance_obj, gobject); + + g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); + g_return_val_if_fail (detailed_signal != NULL, 0); +@@ -240,6 +239,7 @@ gulong spice_g_signal_connect_object (gpointer instance, + g_return_val_if_fail ( + (connect_flags & ~(G_CONNECT_AFTER|G_CONNECT_SWAPPED)) == 0, 0); + ++ WeakHandlerCtx *ctx = whc_new (instance_obj, gobject); + if (connect_flags & G_CONNECT_SWAPPED) + ctx->closure = g_cclosure_new_object_swap (c_handler, gobject); + else +-- +2.28.0 + diff --git a/SOURCES/0023-channel-main-Fix-indentation.patch b/SOURCES/0023-channel-main-Fix-indentation.patch new file mode 100644 index 0000000..d1d7837 --- /dev/null +++ b/SOURCES/0023-channel-main-Fix-indentation.patch @@ -0,0 +1,118 @@ +From 1defa5c0f0107b8496b7696408aad064c65947a5 Mon Sep 17 00:00:00 2001 +From: Frediano Ziglio +Date: Tue, 17 Mar 2020 21:27:19 +0000 +Subject: [PATCH] channel-main: Fix indentation + +Signed-off-by: Frediano Ziglio +Acked-by: Victor Toso +--- + src/channel-main.c | 36 +++++++++++++++++++----------------- + 1 file changed, 19 insertions(+), 17 deletions(-) + +diff --git a/src/channel-main.c b/src/channel-main.c +index 1e85a36..0a0b9ca 100644 +--- a/src/channel-main.c ++++ b/src/channel-main.c +@@ -283,13 +283,13 @@ static void spice_main_get_property(GObject *object, + switch (prop_id) { + case PROP_MOUSE_MODE: + g_value_set_int(value, c->mouse_mode); +- break; ++ break; + case PROP_AGENT_CONNECTED: + g_value_set_boolean(value, c->agent_connected); +- break; ++ break; + case PROP_AGENT_CAPS_0: + g_value_set_int(value, c->agent_caps[0]); +- break; ++ break; + case PROP_DISPLAY_DISABLE_WALLPAPER: + g_value_set_boolean(value, c->display_disable_wallpaper); + break; +@@ -312,8 +312,8 @@ static void spice_main_get_property(GObject *object, + g_value_set_int(value, spice_main_get_max_clipboard(self)); + break; + default: +- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); +- break; ++ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); ++ break; + } + } + +@@ -346,8 +346,8 @@ static void spice_main_set_property(GObject *gobject, guint prop_id, + spice_main_set_max_clipboard(self, g_value_get_int(value)); + break; + default: +- G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec); +- break; ++ G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec); ++ break; + } + } + +@@ -2051,9 +2051,10 @@ static void main_agent_handle_msg(SpiceChannel *channel, + g_coroutine_signal_emit(self, signals[SPICE_MAIN_CLIPBOARD_SELECTION], 0, selection, + cb->type, cb->data, msg->size - sizeof(VDAgentClipboard)); + +- if (selection == VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD) +- g_coroutine_signal_emit(self, signals[SPICE_MAIN_CLIPBOARD], 0, +- cb->type, cb->data, msg->size - sizeof(VDAgentClipboard)); ++ if (selection == VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD) { ++ g_coroutine_signal_emit(self, signals[SPICE_MAIN_CLIPBOARD], 0, ++ cb->type, cb->data, msg->size - sizeof(VDAgentClipboard)); ++ } + break; + } + case VD_AGENT_CLIPBOARD_GRAB: +@@ -2075,10 +2076,11 @@ static void main_agent_handle_msg(SpiceChannel *channel, + } + + g_coroutine_signal_emit(self, signals[SPICE_MAIN_CLIPBOARD_SELECTION_GRAB], 0, selection, +- (guint8*)payload, msg->size / sizeof(uint32_t), &ret); +- if (selection == VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD) ++ (guint8*)payload, msg->size / sizeof(uint32_t), &ret); ++ if (selection == VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD) { + g_coroutine_signal_emit(self, signals[SPICE_MAIN_CLIPBOARD_GRAB], 0, +- payload, msg->size / sizeof(uint32_t), &ret); ++ payload, msg->size / sizeof(uint32_t), &ret); ++ } + break; + } + case VD_AGENT_CLIPBOARD_REQUEST: +@@ -2086,11 +2088,11 @@ static void main_agent_handle_msg(SpiceChannel *channel, + gboolean ret; + VDAgentClipboardRequest *req = payload; + g_coroutine_signal_emit(self, signals[SPICE_MAIN_CLIPBOARD_SELECTION_REQUEST], 0, selection, +- req->type, &ret); ++ req->type, &ret); + + if (selection == VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD) + g_coroutine_signal_emit(self, signals[SPICE_MAIN_CLIPBOARD_REQUEST], 0, +- req->type, &ret); ++ req->type, &ret); + break; + } + case VD_AGENT_CLIPBOARD_RELEASE: +@@ -2333,7 +2335,7 @@ static gboolean migrate_connect(gpointer data) + host = (char*)info->host_data; + + if (info->cert_subject_size == 0 || +- strlen((const char*)info->cert_subject_data) == 0) { ++ strlen((const char*)info->cert_subject_data) == 0) { + /* only verify hostname if no cert subject */ + g_object_set(mig->session, "verify", SPICE_SESSION_VERIFY_HOSTNAME, NULL); + } else { +@@ -2690,7 +2692,7 @@ void spice_main_update_display(SpiceMainChannel *channel, int id, + * Since: 0.35 + **/ + void spice_main_channel_update_display(SpiceMainChannel *channel, int id, int x, int y, int width, +- int height, gboolean update) ++ int height, gboolean update) + { + SpiceMainChannelPrivate *c; + +-- +2.28.0 + diff --git a/SOURCES/0024-channel-main-Fix-indentation.patch b/SOURCES/0024-channel-main-Fix-indentation.patch new file mode 100644 index 0000000..1079e96 --- /dev/null +++ b/SOURCES/0024-channel-main-Fix-indentation.patch @@ -0,0 +1,40 @@ +From 3c933f53bfa9b679750f5d0bbdc7707134d88598 Mon Sep 17 00:00:00 2001 +From: Frediano Ziglio +Date: Fri, 20 Mar 2020 05:19:49 +0000 +Subject: [PATCH] channel-main: Fix indentation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Some mistake in recent patch, thanks to Marc-André's eagle eyes. + +Signed-off-by: Frediano Ziglio +Acked-by: Victor Toso +--- + src/channel-main.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/channel-main.c b/src/channel-main.c +index d7669e8..6a1bb40 100644 +--- a/src/channel-main.c ++++ b/src/channel-main.c +@@ -283,13 +283,13 @@ static void spice_main_get_property(GObject *object, + switch (prop_id) { + case PROP_MOUSE_MODE: + g_value_set_int(value, c->mouse_mode); +- break; ++ break; + case PROP_AGENT_CONNECTED: + g_value_set_boolean(value, c->agent_connected); +- break; ++ break; + case PROP_AGENT_CAPS_0: + g_value_set_int(value, c->agent_caps[0]); +- break; ++ break; + case PROP_DISPLAY_DISABLE_WALLPAPER: + g_value_set_boolean(value, c->display_disable_wallpaper); + break; +-- +2.28.0 + diff --git a/SOURCES/0025-channel-main-Remove-unused-declaration.patch b/SOURCES/0025-channel-main-Remove-unused-declaration.patch new file mode 100644 index 0000000..ee8a4b3 --- /dev/null +++ b/SOURCES/0025-channel-main-Remove-unused-declaration.patch @@ -0,0 +1,42 @@ +From 41c8a60e5e9451080863d2f87bb0f5007a71cc34 Mon Sep 17 00:00:00 2001 +From: Frediano Ziglio +Date: Tue, 4 Aug 2020 15:50:03 +0100 +Subject: [PATCH] channel-main: Remove unused declaration + +OldRedMigrationBegin is not used. Last usage removed in + + commit f944ad6935f12efe47f78cbde1c5e6db31442597 + + More cleanup for old protocol support + + Support for protocol version 1 was dropped in commit f77a1d50. + +Signed-off-by: Frediano Ziglio +--- + src/channel-main.c | 10 ---------- + 1 file changed, 10 deletions(-) + +diff --git a/src/channel-main.c b/src/channel-main.c +index e944771..3dd94a2 100644 +--- a/src/channel-main.c ++++ b/src/channel-main.c +@@ -2326,16 +2326,6 @@ static gboolean main_migrate_handshake_done(gpointer data) + return FALSE; + } + +-#ifdef __GNUC__ +-typedef struct __attribute__ ((__packed__)) OldRedMigrationBegin { +-#else +-typedef struct __declspec(align(1)) OldRedMigrationBegin { +-#endif +- uint16_t port; +- uint16_t sport; +- char host[0]; +-} OldRedMigrationBegin; +- + /* main context */ + static gboolean migrate_connect(gpointer data) + { +-- +2.28.0 + diff --git a/SOURCES/0026-main-add-a-few-missing-vdagent-capability-descriptio.patch b/SOURCES/0026-main-add-a-few-missing-vdagent-capability-descriptio.patch new file mode 100644 index 0000000..8d08d54 --- /dev/null +++ b/SOURCES/0026-main-add-a-few-missing-vdagent-capability-descriptio.patch @@ -0,0 +1,26 @@ +From 8d60d4fc3fe0bd620f216091b24bbb8b72bb055a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Mon, 17 Aug 2020 14:36:05 +0400 +Subject: [PATCH] main: add a few missing vdagent capability descriptions + +Acked-by: Frediano Ziglio +--- + src/channel-main.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/channel-main.c b/src/channel-main.c +index 3dd94a2..671716a 100644 +--- a/src/channel-main.c ++++ b/src/channel-main.c +@@ -222,6 +222,8 @@ static const char *agent_caps[] = { + [ VD_AGENT_CAP_AUDIO_VOLUME_SYNC ] = "volume-sync", + [ VD_AGENT_CAP_MONITORS_CONFIG_POSITION ] = "monitors config position", + [ VD_AGENT_CAP_FILE_XFER_DISABLED ] = "file transfer disabled", ++ [ VD_AGENT_CAP_FILE_XFER_DETAILED_ERRORS ] = "file transfer detailed errors", ++ [ VD_AGENT_CAP_GRAPHICS_DEVICE_INFO ] = "graphics device info", + [ VD_AGENT_CAP_CLIPBOARD_NO_RELEASE_ON_REGRAB ] = "no release on re-grab", + [ VD_AGENT_CAP_CLIPBOARD_GRAB_SERIAL ] = "clipboard grab serial", + }; +-- +2.28.0 + diff --git a/SOURCES/0027-main-add-stricter-pre-condition-on-display-id-value.patch b/SOURCES/0027-main-add-stricter-pre-condition-on-display-id-value.patch new file mode 100644 index 0000000..60ec0f5 --- /dev/null +++ b/SOURCES/0027-main-add-stricter-pre-condition-on-display-id-value.patch @@ -0,0 +1,39 @@ +From e521ddee98961bb30a7a3d93c6c01dddb7da3662 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Tue, 15 Sep 2020 13:09:46 +0400 +Subject: [PATCH] main: add stricter pre-condition on display id value +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Marc-André Lureau +Acked-by: Frediano Ziglio +--- + 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 671716a..5fcf8e8 100644 +--- a/src/channel-main.c ++++ b/src/channel-main.c +@@ -2723,7 +2723,7 @@ void spice_main_channel_update_display(SpiceMainChannel *channel, int id, int x, + + c = SPICE_MAIN_CHANNEL(channel)->priv; + +- g_return_if_fail(id < SPICE_N_ELEMENTS(c->display)); ++ g_return_if_fail(id >= 0 && id < SPICE_N_ELEMENTS(c->display)); + + SpiceDisplayConfig display = { + .x = x, .y = y, .width = width, .height = height, +@@ -3040,7 +3040,7 @@ void spice_main_channel_update_display_enabled(SpiceMainChannel *channel, int id + c->display[i].display_state = display_state; + } + } else { +- g_return_if_fail(id < G_N_ELEMENTS(c->display)); ++ g_return_if_fail(id >= 0 && id < G_N_ELEMENTS(c->display)); + if (c->display[id].display_state == display_state) + return; + c->display[id].display_state = display_state; +-- +2.28.0 + diff --git a/SOURCES/0028-channel-main-Use-heap-and-reference-counting-for-spi.patch b/SOURCES/0028-channel-main-Use-heap-and-reference-counting-for-spi.patch new file mode 100644 index 0000000..1744443 --- /dev/null +++ b/SOURCES/0028-channel-main-Use-heap-and-reference-counting-for-spi.patch @@ -0,0 +1,273 @@ +From 8f1147b4119f920b69eb9c577121cbd5ac1e1d70 Mon Sep 17 00:00:00 2001 +From: Frediano Ziglio +Date: Mon, 10 Aug 2020 15:27:09 +0100 +Subject: [PATCH 28/31] channel-main: Use heap and reference counting for + spice_migrate + +Don't use the stack, it will potentially disappear (see mig +variable in main_migrate_connect). +For instance channels use this structure when they are freed. As +the free is done in delayed mode the initial coroutine could be +ended releasing the stack and causing a segmentation fault. + +This fixes https://bugzilla.redhat.com/show_bug.cgi?id=1867564. + +Signed-off-by: Frediano Ziglio +Acked-by: Uri Lublin +--- + src/channel-main.c | 110 ++++++++++++++++++++++++++++++++------------- + 1 file changed, 78 insertions(+), 32 deletions(-) + +diff --git a/src/channel-main.c b/src/channel-main.c +index 79fe63c..8caf727 100644 +--- a/src/channel-main.c ++++ b/src/channel-main.c +@@ -123,6 +123,7 @@ struct spice_migrate { + struct coroutine *from; + SpiceMigrationDstInfo *info; + SpiceSession *session; ++ int ref_count; + guint nchannels; + SpiceChannel *src_channel; + SpiceChannel *dst_channel; +@@ -175,8 +176,8 @@ static void channel_set_handlers(SpiceChannelClass *klass); + static void agent_send_msg_queue(SpiceMainChannel *channel); + static void agent_free_msg_queue(SpiceMainChannel *channel); + static void migrate_channel_event_cb(SpiceChannel *channel, SpiceChannelEvent event, +- gpointer data); +-static gboolean main_migrate_handshake_done(gpointer data); ++ spice_migrate *mig); ++static gboolean main_migrate_handshake_done(spice_migrate *mig); + static void spice_main_channel_send_migration_handshake(SpiceChannel *channel); + static void file_xfer_flushed(SpiceMainChannel *channel, gboolean success); + static void file_xfer_read_async_cb(GObject *source_object, +@@ -193,6 +194,7 @@ static void file_transfer_operation_task_finished(SpiceFileTransferTask *xfer_ta + GError *error, + gpointer userdata); + static void file_transfer_operation_send_progress(SpiceFileTransferTask *xfer_task); ++static void spice_migrate_unref(spice_migrate *mig); + + /* ------------------------------------------------------------------ */ + +@@ -387,6 +389,7 @@ static void spice_main_channel_finalize(GObject *obj) + { + SpiceMainChannelPrivate *c = SPICE_MAIN_CHANNEL(obj)->priv; + ++ spice_migrate_unref(c->migrate_data); + g_free(c->agent_msg_data); + agent_free_msg_queue(SPICE_MAIN_CHANNEL(obj)); + +@@ -2242,11 +2245,50 @@ static void main_handle_agent_token(SpiceChannel *channel, SpiceMsgIn *in) + agent_send_msg_queue(SPICE_MAIN_CHANNEL(channel)); + } + ++static spice_migrate* ++spice_migrate_ref(spice_migrate *mig) ++{ ++ if (mig != NULL) { ++ mig->ref_count++; ++ } ++ return mig; ++} ++ ++static void ++spice_migrate_unref(spice_migrate *mig) ++{ ++ if (mig != NULL && --mig->ref_count == 0) { ++ g_free(mig); ++ } ++} ++ ++static inline void ++spice_migrate_idle_add(gboolean (*func)(spice_migrate *mig), spice_migrate *mig) ++{ ++ g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, (GSourceFunc) func, spice_migrate_ref(mig), ++ (GDestroyNotify) spice_migrate_unref); ++} ++ ++static void ++spice_migrate_closure_unref(spice_migrate *mig, GClosure *closure) ++{ ++ spice_migrate_unref(mig); ++} ++ ++static gulong ++spice_migrate_signal_connect(gpointer instance, const gchar *detailed_signal, ++ GCallback func, spice_migrate *mig) ++{ ++ return g_signal_connect_data(instance, detailed_signal, func, spice_migrate_ref(mig), ++ (GClosureNotify) spice_migrate_closure_unref, ++ (GConnectFlags) 0); ++} ++ + /* main context */ +-static void migrate_channel_new_cb(SpiceSession *s, SpiceChannel *channel, gpointer data) ++static void migrate_channel_new_cb(SpiceSession *s, SpiceChannel *channel, spice_migrate *mig) + { +- g_signal_connect(channel, "channel-event", +- G_CALLBACK(migrate_channel_event_cb), data); ++ spice_migrate_signal_connect(channel, "channel-event", ++ G_CALLBACK(migrate_channel_event_cb), mig); + } + + static void +@@ -2267,7 +2309,7 @@ static void spice_main_channel_send_migration_handshake(SpiceChannel *channel) + + if (!spice_channel_test_capability(channel, SPICE_MAIN_CAP_SEAMLESS_MIGRATE)) { + c->migrate_data->do_seamless = false; +- g_idle_add(main_migrate_handshake_done, c->migrate_data); ++ spice_migrate_idle_add(main_migrate_handshake_done, c->migrate_data); + } else { + SpiceMsgcMainMigrateDstDoSeamless msg_data; + SpiceMsgOut *msg_out; +@@ -2282,13 +2324,12 @@ static void spice_main_channel_send_migration_handshake(SpiceChannel *channel) + + /* main context */ + static void migrate_channel_event_cb(SpiceChannel *channel, SpiceChannelEvent event, +- gpointer data) ++ spice_migrate *mig) + { +- spice_migrate *mig = data; + SpiceChannelPrivate *c = SPICE_CHANNEL(channel)->priv; + + g_return_if_fail(mig->nchannels > 0); +- g_signal_handlers_disconnect_by_func(channel, migrate_channel_event_cb, data); ++ g_signal_handlers_disconnect_by_func(channel, migrate_channel_event_cb, mig); + + switch (event) { + case SPICE_CHANNEL_OPENED: +@@ -2299,7 +2340,8 @@ static void migrate_channel_event_cb(SpiceChannel *channel, SpiceChannelEvent ev + + c->state = SPICE_CHANNEL_STATE_MIGRATION_HANDSHAKE; + mig->dst_channel = channel; +- main_priv->migrate_data = mig; ++ spice_migrate_unref(main_priv->migrate_data); ++ main_priv->migrate_data = spice_migrate_ref(mig); + } else { + c->state = SPICE_CHANNEL_STATE_MIGRATING; + mig->nchannels--; +@@ -2332,9 +2374,8 @@ static void migrate_channel_event_cb(SpiceChannel *channel, SpiceChannelEvent ev + } + + /* main context */ +-static gboolean main_migrate_handshake_done(gpointer data) ++static gboolean main_migrate_handshake_done(spice_migrate *mig) + { +- spice_migrate *mig = data; + SpiceChannelPrivate *c = SPICE_CHANNEL(mig->dst_channel)->priv; + + g_return_val_if_fail(c->channel_type == SPICE_CHANNEL_MAIN, FALSE); +@@ -2348,9 +2389,8 @@ static gboolean main_migrate_handshake_done(gpointer data) + } + + /* main context */ +-static gboolean migrate_connect(gpointer data) ++static gboolean migrate_connect(spice_migrate *mig) + { +- spice_migrate *mig = data; + SpiceChannelPrivate *c; + int port, sport; + const char *host; +@@ -2393,8 +2433,8 @@ static gboolean migrate_connect(gpointer data) + g_object_set(mig->session, "host", host, NULL); + spice_session_set_port(mig->session, port, FALSE); + spice_session_set_port(mig->session, sport, TRUE); +- g_signal_connect(mig->session, "channel-new", +- G_CALLBACK(migrate_channel_new_cb), mig); ++ spice_migrate_signal_connect(mig->session, "channel-new", ++ G_CALLBACK(migrate_channel_new_cb), mig); + + g_signal_emit(mig->src_channel, signals[SPICE_MIGRATION_STARTED], 0, + mig->session); +@@ -2414,50 +2454,56 @@ static void main_migrate_connect(SpiceChannel *channel, + { + SpiceMainChannelPrivate *main_priv = SPICE_MAIN_CHANNEL(channel)->priv; + int reply_type = SPICE_MSGC_MAIN_MIGRATE_CONNECT_ERROR; +- spice_migrate mig = { 0, }; ++ spice_migrate *mig; + SpiceMsgOut *out; + SpiceSession *session; + +- mig.src_channel = channel; +- mig.info = dst_info; +- mig.from = coroutine_self(); +- mig.do_seamless = do_seamless; +- mig.src_mig_version = src_mig_version; ++ mig = spice_new0(spice_migrate, 1); ++ mig->ref_count = 1; ++ mig->src_channel = channel; ++ mig->info = dst_info; ++ mig->from = coroutine_self(); ++ mig->do_seamless = do_seamless; ++ mig->src_mig_version = src_mig_version; + + CHANNEL_DEBUG(channel, "migrate connect"); + session = spice_channel_get_session(channel); +- mig.session = spice_session_new_from_session(session); +- if (mig.session == NULL) ++ mig->session = spice_session_new_from_session(session); ++ if (mig->session == NULL) { + goto end; +- if (!spice_session_set_migration_session(session, mig.session)) ++ } ++ if (!spice_session_set_migration_session(session, mig->session)) { + goto end; ++ } + +- main_priv->migrate_data = &mig; ++ spice_migrate_unref(main_priv->migrate_data); ++ main_priv->migrate_data = spice_migrate_ref(mig); + + /* no need to track idle, call is sync for this coroutine */ +- g_idle_add(migrate_connect, &mig); ++ spice_migrate_idle_add(migrate_connect, mig); + + /* switch to main loop and wait for connections */ + coroutine_yield(NULL); + +- if (mig.nchannels != 0) { ++ if (mig->nchannels != 0) { + CHANNEL_DEBUG(channel, "migrate failed: some channels failed to connect"); + spice_session_abort_migration(session); + } else { +- if (mig.do_seamless) { ++ if (mig->do_seamless) { + SPICE_DEBUG("migration (seamless): connections all ok"); + reply_type = SPICE_MSGC_MAIN_MIGRATE_CONNECTED_SEAMLESS; + } else { + SPICE_DEBUG("migration (semi-seamless): connections all ok"); + reply_type = SPICE_MSGC_MAIN_MIGRATE_CONNECTED; + } +- spice_session_start_migrating(session, mig.do_seamless); ++ spice_session_start_migrating(session, mig->do_seamless); + } + + end: + CHANNEL_DEBUG(channel, "migrate connect reply %d", reply_type); + out = spice_msg_out_new(channel, reply_type); + spice_msg_out_send(out); ++ spice_migrate_unref(mig); + } + + /* coroutine context */ +@@ -2489,7 +2535,7 @@ static void main_handle_migrate_dst_seamless_ack(SpiceChannel *channel, SpiceMsg + + g_return_if_fail(c->state == SPICE_CHANNEL_STATE_MIGRATION_HANDSHAKE); + main_priv->migrate_data->do_seamless = true; +- g_idle_add(main_migrate_handshake_done, main_priv->migrate_data); ++ spice_migrate_idle_add(main_migrate_handshake_done, main_priv->migrate_data); + } + + static void main_handle_migrate_dst_seamless_nack(SpiceChannel *channel, SpiceMsgIn *in) +@@ -2501,7 +2547,7 @@ static void main_handle_migrate_dst_seamless_nack(SpiceChannel *channel, SpiceMs + + g_return_if_fail(c->state == SPICE_CHANNEL_STATE_MIGRATION_HANDSHAKE); + main_priv->migrate_data->do_seamless = false; +- g_idle_add(main_migrate_handshake_done, main_priv->migrate_data); ++ spice_migrate_idle_add(main_migrate_handshake_done, main_priv->migrate_data); + } + + /* main context */ +-- +2.28.0 + diff --git a/SOURCES/0029-channel-main-Copy-SpiceMigrationDstInfo-into-spice_m.patch b/SOURCES/0029-channel-main-Copy-SpiceMigrationDstInfo-into-spice_m.patch new file mode 100644 index 0000000..29959c4 --- /dev/null +++ b/SOURCES/0029-channel-main-Copy-SpiceMigrationDstInfo-into-spice_m.patch @@ -0,0 +1,71 @@ +From ab42be2b00d12d0bc98c6ddea08a7f969e83b2ac Mon Sep 17 00:00:00 2001 +From: Frediano Ziglio +Date: Mon, 10 Aug 2020 15:35:26 +0100 +Subject: [PATCH 29/31] channel-main: Copy SpiceMigrationDstInfo into + spice_migrate + +The message could disappear while the structure is used. + +Signed-off-by: Frediano Ziglio +Acked-by: Uri Lublin +--- + src/channel-main.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +diff --git a/src/channel-main.c b/src/channel-main.c +index 8caf727..5f81975 100644 +--- a/src/channel-main.c ++++ b/src/channel-main.c +@@ -121,7 +121,7 @@ struct _SpiceMainChannelPrivate { + + struct spice_migrate { + struct coroutine *from; +- SpiceMigrationDstInfo *info; ++ SpiceMigrationDstInfo info; + SpiceSession *session; + int ref_count; + guint nchannels; +@@ -2258,6 +2258,8 @@ static void + spice_migrate_unref(spice_migrate *mig) + { + if (mig != NULL && --mig->ref_count == 0) { ++ g_free(mig->info.host_data); ++ g_free(mig->info.cert_subject_data); + g_free(mig); + } + } +@@ -2396,7 +2398,6 @@ static gboolean migrate_connect(spice_migrate *mig) + const char *host; + + g_return_val_if_fail(mig != NULL, FALSE); +- g_return_val_if_fail(mig->info != NULL, FALSE); + g_return_val_if_fail(mig->nchannels == 0, FALSE); + c = SPICE_CHANNEL(mig->src_channel)->priv; + g_return_val_if_fail(c != NULL, FALSE); +@@ -2404,7 +2405,7 @@ static gboolean migrate_connect(spice_migrate *mig) + + spice_session_set_migration_state(mig->session, SPICE_SESSION_MIGRATION_CONNECTING); + +- SpiceMigrationDstInfo *info = mig->info; ++ SpiceMigrationDstInfo *info = &mig->info; + SPICE_DEBUG("migrate_begin %u %s %d %d", + info->host_size, info->host_data, info->port, info->sport); + port = info->port; +@@ -2461,7 +2462,13 @@ static void main_migrate_connect(SpiceChannel *channel, + mig = spice_new0(spice_migrate, 1); + mig->ref_count = 1; + mig->src_channel = channel; +- mig->info = dst_info; ++ mig->info = *dst_info; ++ if (dst_info->host_data) { ++ mig->info.host_data = (void *) g_strdup((char*) dst_info->host_data); ++ } ++ if (dst_info->cert_subject_data) { ++ mig->info.cert_subject_data = (void *) g_strdup((char*) dst_info->cert_subject_data); ++ } + mig->from = coroutine_self(); + mig->do_seamless = do_seamless; + mig->src_mig_version = src_mig_version; +-- +2.28.0 + diff --git a/SOURCES/0030-channel-main-Make-more-clear-that-host_data-and-cert.patch b/SOURCES/0030-channel-main-Make-more-clear-that-host_data-and-cert.patch new file mode 100644 index 0000000..4010f4b --- /dev/null +++ b/SOURCES/0030-channel-main-Make-more-clear-that-host_data-and-cert.patch @@ -0,0 +1,47 @@ +From 1f2a7a079a42ac9bccc12749c5eac4fcdbd48b2e Mon Sep 17 00:00:00 2001 +From: Frediano Ziglio +Date: Wed, 16 Sep 2020 17:12:14 +0100 +Subject: [PATCH 30/31] channel-main: Make more clear that host_data and + cert_subject_data are C strings + +After commit ab42be2b00d12d0bc98c6ddea08a7f969e83b2ac ("channel-main: +Copy SpiceMigrationDstInfo into spice_migrate") host_data and +cert_subject_data fields in spice_migrate structure are proper +terminated C strings so: +- check pointer instead of related field; +- you don't need to terminate again. + +Signed-off-by: Frediano Ziglio +Acked-by: Uri Lublin +--- + src/channel-main.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +diff --git a/src/channel-main.c b/src/channel-main.c +index 5f81975..2881d59 100644 +--- a/src/channel-main.c ++++ b/src/channel-main.c +@@ -2412,18 +2412,14 @@ static gboolean migrate_connect(spice_migrate *mig) + sport = info->sport; + host = (char*)info->host_data; + +- if (info->cert_subject_size == 0 || ++ if (info->cert_subject_data == NULL || + strlen((const char*)info->cert_subject_data) == 0) { + /* only verify hostname if no cert subject */ + g_object_set(mig->session, "verify", SPICE_SESSION_VERIFY_HOSTNAME, NULL); + } else { +- gchar *subject = g_alloca(info->cert_subject_size + 1); +- strncpy(subject, (const char*)info->cert_subject_data, info->cert_subject_size); +- subject[info->cert_subject_size] = '\0'; +- + // session data are already copied + g_object_set(mig->session, +- "cert-subject", subject, ++ "cert-subject", info->cert_subject_data, + "verify", SPICE_SESSION_VERIFY_SUBJECT, + NULL); + } +-- +2.28.0 + diff --git a/SOURCES/0031-channel-main-Handle-not-terminated-host_data-and-cer.patch b/SOURCES/0031-channel-main-Handle-not-terminated-host_data-and-cer.patch new file mode 100644 index 0000000..7abc850 --- /dev/null +++ b/SOURCES/0031-channel-main-Handle-not-terminated-host_data-and-cer.patch @@ -0,0 +1,38 @@ +From 9b98e01c8f5d0dc8faaf3af7b8fc95768e1ff0ad Mon Sep 17 00:00:00 2001 +From: Frediano Ziglio +Date: Wed, 16 Sep 2020 15:50:33 +0100 +Subject: [PATCH 31/31] channel-main: Handle not terminated host_data and + cert_subject_data fields + +host_data and cert_subject_data fields from SPICE messages could be +not NUL terminated so using g_strdup can lead to some read overflow. + +This bug was discovered by Uri Lublin. + +Signed-off-by: Frediano Ziglio +Acked-by: Uri Lublin +--- + src/channel-main.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/channel-main.c b/src/channel-main.c +index 2881d59..5fefded 100644 +--- a/src/channel-main.c ++++ b/src/channel-main.c +@@ -2460,10 +2460,11 @@ static void main_migrate_connect(SpiceChannel *channel, + mig->src_channel = channel; + mig->info = *dst_info; + if (dst_info->host_data) { +- mig->info.host_data = (void *) g_strdup((char*) dst_info->host_data); ++ mig->info.host_data = (void *) g_strndup((char*) dst_info->host_data, dst_info->host_size); + } + if (dst_info->cert_subject_data) { +- mig->info.cert_subject_data = (void *) g_strdup((char*) dst_info->cert_subject_data); ++ mig->info.cert_subject_data = (void *) g_strndup((char*) dst_info->cert_subject_data, ++ dst_info->cert_subject_size); + } + mig->from = coroutine_self(); + mig->do_seamless = do_seamless; +-- +2.28.0 + diff --git a/SOURCES/spice-gtk-0.38.tar.xz.sig b/SOURCES/spice-gtk-0.38.tar.xz.sig new file mode 100644 index 0000000000000000000000000000000000000000..eab14d28501e8ce9510e3da92096c353d99bc087 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*6Z96qDR&P5FWpe44*%CeDdPq+N0$y))4gd-X5SQ5! zJ>z;vPig=U{ytKvSSF(-;o<`)$2G2|^6V%I)Tofd+BNMP9y)~ddJTOycR#HUqv6_x zo|||K5%8MxD9+@bg-`IkmZF25hzGgX12(=a= z!2*6g9YJ&EaRR)HbkWl9WH@%PxUtw3O(5^Wiaf)Sq%Hz&D*R7Dbur3C&96`O-vR$$ z7ZVHxrzrgm?Tm-!3I9%PglA7mnX_uirg1{)NL5SHF!Fs}0Sl${9m(yX@<3Z)A#ljM z>d-9vlIWRtOA(x7vO7A~>@zTo6WrdYxUD96-c8pcyb92I$MIE^@IE|1Ejg2WAOczz zcR>sk=N8ZB$$A#JUQLLSFSPx#VgDp_XTi^Nbh1KJ8}C+2PexVy7fOiVGp| z9q-3pDL;sw`k&<(Fna8sYvmN)5HsYQtWCw&z2TA^GFZm?0>VX-4#pGcLCx8=)bA;< zag#;Inc|FP=q#3(#)q2SLYF6#v+j0`5MYf~qK<~5MCEq?ewh2%wgP8+eD}I?cy!nM Eo)-BMeE= 0.7.1 +BuildRequires: libusb1-devel >= 1.0.21 +BuildRequires: libgudev1-devel +BuildRequires: pixman-devel libjpeg-turbo-devel +BuildRequires: celt051-devel pulseaudio-libs-devel opus-devel +BuildRequires: zlib-devel +BuildRequires: cyrus-sasl-devel +BuildRequires: libcacard-devel +BuildRequires: gobject-introspection-devel +BuildRequires: libacl-devel +BuildRequires: polkit-devel +BuildRequires: gtk-doc +BuildRequires: vala-tools +BuildRequires: usbutils +BuildRequires: libsoup-devel >= 2.49.91 +BuildRequires: lz4-devel +BuildRequires: gtk3-devel +BuildRequires: json-glib-devel +BuildRequires: spice-protocol >= 0.14.2 +BuildRequires: gstreamer1-devel >= 1.10.0 gstreamer1-plugins-base-devel >= 1.10.0 +BuildRequires: python3-devel python3-six python3-pyparsing +BuildRequires: wayland-protocols-devel >= 1.17 +BuildRequires: libwayland-server libwayland-cursor libwayland-client +Obsoletes: spice-gtk-python < 0.32 + +Requires: spice-glib%{?_isa} = %{version}-%{release} + +BuildRequires: openssl-devel + +%description +Client libraries for SPICE desktop servers. + +%package -n spice-glib +Summary: A GObject for communicating with Spice servers +Group: Development/Libraries + +%description -n spice-glib +spice-client-glib-2.0 is a SPICE client library for GLib2. + +%package -n spice-glib-devel +Summary: Development files to build Glib2 applications with spice-glib-2.0 +Group: Development/Libraries +Requires: spice-glib%{?_isa} = %{version}-%{release} +Requires: pkgconfig +Requires: glib2-devel + +%description -n spice-glib-devel +spice-client-glib-2.0 is a SPICE client library for GLib2. + +Libraries, includes, etc. to compile with the spice-glib-2.0 libraries + +%package -n spice-gtk3 +Summary: A GTK3 widget for SPICE clients +Group: Development/Libraries +Requires: spice-glib%{?_isa} = %{version}-%{release} + +%description -n spice-gtk3 +spice-client-glib-3.0 is a SPICE client library for Gtk3. + +%package -n spice-gtk3-devel +Summary: Development files to build GTK3 applications with spice-gtk-3.0 +Group: Development/Libraries +Requires: spice-gtk3%{?_isa} = %{version}-%{release} +Requires: spice-glib-devel%{?_isa} = %{version}-%{release} +Requires: pkgconfig +Requires: gtk3-devel +Obsoletes: spice-gtk-devel < 0.32 + +%description -n spice-gtk3-devel +spice-client-gtk-3.0 provides a SPICE viewer widget for GTK3. + +Libraries, includes, etc. to compile with the spice-gtk3 libraries + +%package -n spice-gtk3-vala +Summary: Vala bindings for the spice-gtk-3.0 library +Group: Development/Libraries +Requires: spice-gtk3%{?_isa} = %{version}-%{release} +Requires: spice-gtk3-devel%{?_isa} = %{version}-%{release} + +%description -n spice-gtk3-vala +A module allowing use of the spice-gtk-3.0 widget from vala + +%package tools +Summary: Spice-gtk tools +Group: Applications/Internet +Requires: spice-gtk3%{?_isa} = %{version}-%{release} +Requires: spice-glib%{?_isa} = %{version}-%{release} + +%description tools +Simple clients for interacting with SPICE servers. +spicy is a client to a SPICE desktop server. +spicy-screenshot is a tool to capture screen-shots of a SPICE desktop. + + +%prep +gpgv2 --quiet --keyring %{SOURCE2} %{SOURCE1} %{SOURCE0} +%autosetup -S git_am + +%build +%meson \ + -Dgtk_doc=enabled \ + -Dusb-acl-helper-dir=%{_libexecdir}/spice-gtk-%{_arch}/ \ + -Dlz4=enabled \ + -Dvapi=enabled \ + -Dcelt051=disabled \ + -Dwayland-protocols=enabled \ + -Dwebdav=disabled + +%meson_build + +%install +%meson_install + +%find_lang %{name} + +%ldconfig_scriptlets +%ldconfig_scriptlets -n spice-glib +%ldconfig_scriptlets -n spice-gtk3 + + +%files +%doc AUTHORS +%doc COPYING +%doc README.md +%doc CHANGELOG.md +%{_mandir}/man1/spice-client.1* + +%files -n spice-glib -f %{name}.lang +%{_libdir}/libspice-client-glib-2.0.so.* +%{_libdir}/girepository-1.0/SpiceClientGLib-2.0.typelib +%dir %{_libexecdir}/spice-gtk-%{_arch}/ +%attr(4755, root, root) %{_libexecdir}/spice-gtk-%{_arch}/spice-client-glib-usb-acl-helper +%{_datadir}/polkit-1/actions/org.spice-space.lowlevelusbaccess.policy + +%files -n spice-glib-devel +%{_libdir}/libspice-client-glib-2.0.so +%{_includedir}/spice-client-glib-2.0 +%{_libdir}/pkgconfig/spice-client-glib-2.0.pc +%{_datadir}/gir-1.0/SpiceClientGLib-2.0.gir +%doc %{_datadir}/gtk-doc/html/* + +%files -n spice-gtk3 +%{_libdir}/libspice-client-gtk-3.0.so.* +%{_libdir}/girepository-1.0/SpiceClientGtk-3.0.typelib + +%files -n spice-gtk3-devel +%{_libdir}/libspice-client-gtk-3.0.so +%{_includedir}/spice-client-gtk-3.0 +%{_libdir}/pkgconfig/spice-client-gtk-3.0.pc +%{_datadir}/gir-1.0/SpiceClientGtk-3.0.gir + +%files -n spice-gtk3-vala +%{_datadir}/vala/vapi/spice-client-glib-2.0.deps +%{_datadir}/vala/vapi/spice-client-glib-2.0.vapi +%{_datadir}/vala/vapi/spice-client-gtk-3.0.deps +%{_datadir}/vala/vapi/spice-client-gtk-3.0.vapi + +%files tools +%{_bindir}/spicy +%{_bindir}/spicy-screenshot +%{_bindir}/spicy-stats + +%changelog +* Sun Dec 13 2020 Uri Lublin - 0.38-6 +- Fix some migration issues + Related: rhbz#1867564 + +* Thu Dec 03 2020 Uri Lublin - 0.38-5 +- Fix more static analyzer issues + Resolves: rhbz#1839104 + +* Mon Nov 9 18:01:40 IST 2020 Uri Lublin - 0.38-4 +- Fix some static analyzer issues + Resolves: rhbz#1839104 +- Fix spice-usbredir-redirect-on-connect + Resolves: rhbz#1874740 + +* Mon Jun 1 2020 Frediano Ziglio - 0.38-3 +- Fix multiple buffer overflows in QUIC decoding code + Resolves: rhbz#1842472 + +* Wed May 20 2020 Victor Toso - 0.38-2 +- Brings some post releases fixes and disables celt051 that is + deprecated in spice-protocol 0.14.2 +- Possibly related to rhbz#1688737 rhbz#1746239 + Related: rhbz#1817471 +- Fix mouse pointer on relative mouse mode + Resolves: rhbz#1674311 +- Handle detailed errors from guest agent + Related: rhbz#1520393 + +* Tue May 05 2020 Victor Toso - 0.38-1 +- Update to 0.38 + Resolves: rhbz#1817471 + +* Fri May 17 2019 Victor Toso - 0.37-1 +- Update to 0.37 + Resolves: rhbz#1711370 +- Use gpg to check that tarball matches upstream release + +* Fri Oct 12 2018 Frediano Ziglio - 0.35-7 +- Check for overflows decoding LZ4 + Resolves: rhbz#1598242 + +* Wed Oct 10 2018 Frediano Ziglio - 0.35-6 +- Fix insufficient encoding checks for LZ + Resolves: rhbz#1598234 + +* Wed Aug 15 2018 Victor Toso - 0.35-4 +- Disable shared folders downstream (phodav) +- Resolves: rhbz#1615985 + +* Mon Aug 13 2018 Victor Toso - 0.35-3 +- Include python3-devel to not fail on rhel-8.0 builds +- Resolves: rhbz#1615571 + +* Mon Jul 30 2018 Florian Weimer - 0.35-2 +- Rebuild with fixed binutils + +* Mon Jul 30 2018 Victor Toso - 0.35-1 +- Update to 0.35 + +* Fri Feb 09 2018 Fedora Release Engineering - 0.34-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Sat Feb 03 2018 Igor Gnatenko - 0.34-3 +- Switch to %%ldconfig_scriptlets + +* Thu Aug 24 2017 Christophe Fergeau - 0.34-2 +- Build against OpenSSL 1.1.0 rather than the older 1.0 + +* Mon Jul 31 2017 Marc-André Lureau - 0.34-1 +- v0.34 release + +* Thu Jul 27 2017 Fedora Release Engineering - 0.33-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Tue Jun 20 2017 Cole Robinson - 0.33-5 +- channel-usbredir: Fix crash on channel-up. Resolves: rhbz#1399838 +- usbutils no longer ships usb.ids, it is hwdata now, set path manually. +- Backport fixes for "Couldn't find current GL or GLX context" Resolves: rhbz#1461802 + +* Sat Feb 11 2017 Fedora Release Engineering - 0.33-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Tue Oct 25 2016 Victor Toso - 0.33-2 +- Fix crash due clipboard failure with text conversion + Resolves: rhbz#1384676 + +* Fri Oct 07 2016 Marc-André Lureau - 0.33-1 +- Update to new 0.33 upstream release + +* Thu Oct 06 2016 Marc-André Lureau - 0.32-3 +- Fix display refresh unless scaling is forced (rhbz#1382325) + +* Mon Jul 11 2016 Christophe Fergeau 0.32-2 +- Add upstream patches fixing USB event thread leak + Resolves: rhbz#1217202 (virt-manager) + May help with rhbz#1338042 (gnome-boxes) + +* Tue Jun 21 2016 Marc-André Lureau 0.32-1 +- Update to new 0.32 upstream release + +* Fri Apr 15 2016 Christophe Fergeau - 0.31-2 +- Add upstream patch fixing flickering bug + Resolves: rhbz#1266484 + +* Fri Mar 11 2016 Marc-André Lureau 0.31-1 +- Update to new 0.31 upstream release + +* Fri Feb 05 2016 Fedora Release Engineering - 0.30-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Tue Oct 06 2015 Christophe Fergeau 0.30-1 +- Update to new 0.30 upstream release + +* Sat Sep 12 2015 Cole Robinson 0.29-4 +- Fix virt-manager default screen resolution and resolution across reboots +- Resolves: rhbz#1240721 + +* Tue Sep 08 2015 Christophe Fergeau 0.29-3 +- Don't crash on volume sync when there is no audio channel + Resolves: rhbz#1257210 + +* Fri Jun 19 2015 Fedora Release Engineering - 0.29-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Mon Jun 15 2015 Marc-Andre Lureau 0.29-1 +- Update to spice-gtk v0.29 + +* Mon May 11 2015 Marc-Andre Lureau 0.28-3 +- Fix audio and usb channels with GNOME Boxes. + Resolves: rhbz#1220026 + +* Tue Mar 31 2015 Christophe Fergeau 0.28-2 +- Add upstream patch fixing an USB redirection crash + Resolves: rhbz#1182226 +- Adjust build requires to new naming of phodav package + +* Wed Mar 4 2015 Marc-André Lureau 0.28-1 +- Update to spice-gtk v0.28 + +* Mon Feb 23 2015 Christophe Fergeau 0.27-6 +- Rebuild for phodav soname bump + +* Tue Jan 27 2015 Marc-André Lureau 0.27-5 +- Fix reconnection on same session regressions introduced in 27-2. + +* Tue Dec 30 2014 Christophe Fergeau 0.27-4 +- Enable lz4 support + +* Mon Dec 22 2014 Marc-André Lureau 0.27-3 +- Fix usbredir crash on disconnection. + +* Tue Dec 16 2014 Marc-André Lureau 0.27-2 +- Fix authentication error handling regression. + +* Thu Dec 11 2014 Marc-André Lureau 0.27-1 +- Update to spice-gtk v0.27 + +* Wed Oct 29 2014 Christophe Fergeau 0.26-1 +- Update to spice-gtk v0.26 + +* Wed Sep 24 2014 Christophe Fergeau 0.25-6 +- Run make install in gtk3 build after doing so in gtk2 build, otherwise + we'll end up packaging gtk2 builds of spicy et al in spice-client-tools + instead of gtk3 ones (#1145829) + +* Wed Aug 20 2014 Kalev Lember - 0.25-5 +- Rebuilt for rpm dependency generator failure (#1131892) + +* Mon Aug 18 2014 Fedora Release Engineering - 0.25-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Tue Jul 22 2014 Kalev Lember - 0.25-3 +- Rebuilt for gobject-introspection 1.41.4 + +* Sun Jun 08 2014 Fedora Release Engineering - 0.25-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Tue Feb 25 2014 Marc-André Lureau - 0.25-1 +- Update to upstream release v0.25 +- Added phodav dependency + +* Tue Feb 25 2014 Marc-André Lureau - 0.23-2 +- Fix crash on finishing display rhbz#1069546 + +* Mon Feb 10 2014 Marc-André Lureau - 0.23-1 +- Update to spice-gtk 0.23 + +* Wed Nov 27 2013 Marc-André Lureau - 0.22-1 +- Update to spice-gtk 0.22 + +* Sun Nov 17 2013 Cole Robinson - 0.21-5 +- Fix grub graphical corruption after VM reboot (bz #1017955) + +* Mon Oct 21 2013 Alon Levy - 0.21-4 +- Fix mono invert only cursor contract. rhbz#998529 + +* Thu Oct 3 2013 Marc-André Lureau - 0.21-3 +- Fix palette cache regression. rhbz#1011936 + +* Mon Sep 30 2013 Marc-André Lureau - 0.21-2 +- Fix usbredir being broken in 0.21 release + +* Wed Sep 18 2013 Marc-André Lureau - 0.21-1 +- Update to spice-gtk 0.21 + +* Fri Sep 13 2013 Christophe Fergeau 0.20-6 +- Add misc upstream patches fixing various 0.20 bugs + +* Wed Aug 28 2013 Alon Levy - 0.20-5 +- Fix wrong mono cursor local rendering (rhbz#998529) + +* Wed Aug 28 2013 Hans de Goede - 0.20-4 +- Fix the spice-client-glib-usb-acl-helper no longer being suid root + +* Sun Aug 04 2013 Fedora Release Engineering - 0.20-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Sat Jul 6 2013 Marc-André Lureau - 0.20-2 +- Fix spice_channel_string_to_type symbol visibility (rhbz#981815) + +* Wed Jun 26 2013 Marc-André Lureau - 0.20-1 +- Update to spice-gtk 0.20 + +* Thu Apr 11 2013 Marc-André Lureau - 0.19-1 +- Update to spice-gtk 0.19 + +* Thu Mar 14 2013 Hans de Goede - 0.18-2 +- Fix "Warning no automount-inhibiting implementation available" warnings + +* Wed Feb 13 2013 Marc-André Lureau - 0.18-1 +- Update to spice-gtk 0.18 + +* Wed Feb 6 2013 Marc-André Lureau - 0.17-1 +- Update to spice-gtk 0.17 + +* Thu Jan 31 2013 Marc-André Lureau - 0.16-2 +- Remove perl-text-csv build requirement. (rhbz#873174) + +* Sat Jan 12 2013 Marc-André Lureau - 0.16-1 +- Update to spice-gtk 0.16 + +* Mon Dec 31 2012 Marc-André Lureau - 0.15.3-1 +- Update to spice-gtk 0.15.3, fixes TLS & password regressions + +* Fri Dec 21 2012 Christophe Fergeau - 0.15-2 +- Update to spice-gtk 0.15 + +* Thu Oct 25 2012 Christophe Fergeau - 0.14-2 +- Add various upstream patches + +* Fri Sep 21 2012 Christophe Fergeau - 0.14-1 +- Update to 0.14 release + +* Fri Sep 14 2012 Christophe Fergeau - 0.13.29-4 +- Add patch fixing CVE 2012-4425 + +* Thu Sep 13 2012 Christophe Fergeau - 0.13.29-3 +- Run autoreconf after applying patch 2 as it only modifies Makefile.am + +* Tue Sep 11 2012 Christophe Fergeau - 0.13.29-2 +- Add patch to fix symbol versioning + +* Fri Sep 7 2012 Hans de Goede - 0.13.29-1 +- Update to the spice-gtk 0.13.29 development release +- Rebuild for new usbredir + +* Mon Sep 03 2012 Christophe Fergeau - 0.13-2 +- Update to spice-gtk 0.13 + +* Tue Aug 07 2012 Christophe Fergeau - 0.12.101-1 +- Update to the spice-gtk 0.12.101 development release (needed by Boxes + 3.5.5) + +* Sat Jul 21 2012 Fedora Release Engineering - 0.12-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Tue May 15 2012 Marc-André Lureau - 0.12-4 +- re-Add back spice-protocol BuildRequires to help some deps magic happen + +* Thu May 10 2012 Marc-André Lureau - 0.12-3 +- Fix Spice.Audio constructor Python binding + https://bugzilla.redhat.com/show_bug.cgi?id=820335 + +* Wed May 2 2012 Marc-André Lureau - 0.12-2 +- Fix virt-manager console not showing up, rhbz#818169 + +* Tue Apr 24 2012 Marc-André Lureau - 0.12-1 +- New upstream release 0.12 + +* Tue Apr 10 2012 Christophe Fergeau - 0.11-5 +- Fix build on PPC +- Remove ExclusiveArch. While spice-gtk will build on ARM and PPC, it + hasn't been tested on these arch, so there may be some bugs. + +* Tue Mar 20 2012 Hans de Goede - 0.11-4 +- Add missing BuildRequires: usbutils, so that we get proper USB device + descriptions in the USB device selection menu + +* Wed Mar 14 2012 Hans de Goede - 0.11-3 +- Fix a crash triggered when trying to view a usbredir enabled vm from + virt-manager + +* Mon Mar 12 2012 Hans de Goede - 0.11-2 +- Add back spice-protocol BuildRequires to help some deps magic happen + +* Fri Mar 9 2012 Hans de Goede - 0.11-1 +- New upstream release 0.11 +- Fix multilib conflict in spice-glib + +* Thu Feb 23 2012 Marc-André Lureau - 0.10-1 +- New upstream release 0.10 + +* Mon Jan 30 2012 Hans de Goede - 0.9-1 +- New upstream release 0.9 + +* Mon Jan 16 2012 Hans de Goede - 0.8-1 +- New upstream release 0.8 +- Various small specfile improvements +- Enable vala bindings + +* Sat Jan 14 2012 Fedora Release Engineering - 0.7.39-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Mon Nov 14 2011 Adam Jackson 0.7.39-2 +- Rebuild to break bogus libpng dependency +- Fix summaries for gtk3 subpackages to not talk about gtk2 + +* Fri Sep 2 2011 Hans de Goede - 0.7.39-1 +- Update to git snapshot 0.7.39-ab64, to add usbredir support + +* Tue Jul 26 2011 Marc-André Lureau - 0.7.1-1 +- Upstream version 0.7.1-d5a8 (fix libtool versionning) + +* Tue Jul 19 2011 Marc-André Lureau - 0.7-1 +- Upstream release 0.7 + +* Wed May 25 2011 Christophe Fergeau - 0.6-1 +- Upstream release 0.6 + +* Tue Mar 1 2011 Hans de Goede - 0.5-6 +- Fix spice-glib requires in .pc file (#680314) + +* Fri Feb 11 2011 Matthias Clasen - 0.5-5 +- Fix build against glib 2.28 + +* Thu Feb 10 2011 Matthias Clasen - 0.5-4 +- Rebuild against newer gtk + +* Wed Feb 09 2011 Fedora Release Engineering - 0.5-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Wed Feb 2 2011 Matthias Clasen - 0.5-2 +- Rebuild against newer gtk + +* Thu Jan 27 2011 Marc-André Lureau - 0.5-1 +- Upstream release 0.5 + +* Fri Jan 14 2011 Daniel P. Berrange - 0.4-2 +- Add support for parallel GTK3 build + +* Mon Jan 10 2011 Dan Horák - 0.4-2 +- add ExclusiveArch as only x86 is supported + +* Sun Jan 09 2011 Marc-André Lureau - 0.4-1 +- Upstream release 0.4 +- Initial release (#657403) + +* Thu Nov 25 2010 Marc-André Lureau - 0.1.0-1 +- Initial packaging