From 0ec6ec5de68bd1d3c4c74cac19490b6a8de3bb4488d6a66ac4ad3d4534b67ea3 Mon Sep 17 00:00:00 2001 From: Bruce Rogers Date: Fri, 17 May 2019 22:21:17 +0000 Subject: [PATCH] Accepting request 703813 from home:bfrogers:branches:Virtualization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Update to 0.19.0 * Add libdrm dependency * Fix file descriptor leak on failed connections * Handle new VD_AGENT_GRAPHICS_DEVICE_INFO message advertised by VD_AGENT_CAP_GRAPHICS_DEVICE_INFO capability * Session agent autostart changed to WindowManager ([rhbz#1623947]) This fixes possible race with xdg-user-dirs * Fix of sending empty screen resolution messages ([rhbz#1641723]) * Fix 'Dependency failed for Activation socket' with systemd ([rhbz#1545212]) * Fix error messages about on selecting text on host ([rhbz#1594876]) this was also fixed with Gtk backend * Update paths from /var/run → /run * Fix Session agent restart * Add test for file creation * Prefer GLib memory functions stdlib.h ones * Several code and logs improvements * Add GTK+ framework to handle x11 backend such as clipboard * Deprecate X11 backend in favor of GTK+ framework * Ask pkg-config to appropriate directory to install udev rules * Fix leak of udscs's file descriptor * Better quote directory path when calling xdg-open to save file transfer * Bump GLib to 2.34 * Add systemd socket activation (rhbz#1340160) * Add support to detailed errors on file transfers * Add check for available free space in guest before starting a file transfer * Use better names for duplicated files on file transfer * Improve support on big endian guests (#5) * Use IdleHint to check if a session is locked over console-kit (rhbz#1412673) * Fixes double free on errors over udscs by improving memory ownership * Hide autostart file on Unity * Improve command line messages for vdagentd * Fix typo in --enable-static-uinput configure option * Code repository moved to gitlab.freedesktop.org - Add keyring and tarball signature files - obsoleted patches removed: 8ba17481-quote-save-dir-before-passing-to-shell.patch vdagentd-do-endian-swapping.patch OBS-URL: https://build.opensuse.org/request/show/703813 OBS-URL: https://build.opensuse.org/package/show/Virtualization/spice-vdagent?expand=0&rev=26 --- ...ote-save-dir-before-passing-to-shell.patch | 48 -- spice-vdagent-0.17.0.tar.bz2 | 3 - spice-vdagent-0.19.0.tar.bz2 | 3 + spice-vdagent-0.19.0.tar.bz2.sig | Bin 0 -> 566 bytes spice-vdagent-var_run.patch | 19 +- spice-vdagent.changes | 41 + spice-vdagent.keyring | 386 +++++++++ spice-vdagent.spec | 39 +- vdagentd-do-endian-swapping.patch | 750 ------------------ 9 files changed, 452 insertions(+), 837 deletions(-) delete mode 100644 8ba17481-quote-save-dir-before-passing-to-shell.patch delete mode 100644 spice-vdagent-0.17.0.tar.bz2 create mode 100644 spice-vdagent-0.19.0.tar.bz2 create mode 100644 spice-vdagent-0.19.0.tar.bz2.sig create mode 100644 spice-vdagent.keyring delete mode 100644 vdagentd-do-endian-swapping.patch diff --git a/8ba17481-quote-save-dir-before-passing-to-shell.patch b/8ba17481-quote-save-dir-before-passing-to-shell.patch deleted file mode 100644 index 21cfa2e..0000000 --- a/8ba17481-quote-save-dir-before-passing-to-shell.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 8ba174816d245757e743e636df357910e1d5eb61 Mon Sep 17 00:00:00 2001 -From: Jonathon Jongsma -Date: Wed, 25 Oct 2017 10:33:11 -0500 -Subject: [PATCH] Quote the save directory before passing to shell - -Thanks to a report from Seth Arnold : -- vdagent_file_xfers_data() does not escape xfers->save_dir before giving - it to the shell -- vdagent_file_xfers_data() does not check snprintf() return code; a - too-long xfers->save_dir could cause the & or ' or any number of other - characters to go missing. - -To fix these issues, we use g_spawn_async(). This avoids the need to -quote the filename and also avoids the snprintf issue. - -In the case that the spawn fails, we also print a warning to the syslog -now. - -Signed-off-by: Jonathon Jongsma -Acked-by: Frediano Ziglio ---- - src/vdagent/file-xfers.c | 13 ++++++++++--- - 1 file changed, 10 insertions(+), 3 deletions(-) - -Index: spice-vdagent-0.17.0/src/vdagent-file-xfers.c -=================================================================== ---- spice-vdagent-0.17.0.orig/src/vdagent-file-xfers.c -+++ spice-vdagent-0.17.0/src/vdagent-file-xfers.c -@@ -293,9 +293,16 @@ void vdagent_file_xfers_data(struct vdag - if (xfers->open_save_dir && - task->file_xfer_nr == task->file_xfer_total && - g_hash_table_size(xfers->xfers) == 1) { -- char buf[PATH_MAX]; -- snprintf(buf, PATH_MAX, "xdg-open '%s'&", xfers->save_dir); -- status = system(buf); -+ GError *error = NULL; -+ gchar *argv[] = { "xdg-open", xfers->save_dir, NULL }; -+ if (!g_spawn_async(NULL, argv, NULL, -+ G_SPAWN_SEARCH_PATH, -+ NULL, NULL, NULL, &error)) { -+ syslog(LOG_WARNING, -+ "file-xfer: failed to open save directory: %s", -+ error->message); -+ g_error_free(error); -+ } - } - status = VD_AGENT_FILE_XFER_STATUS_SUCCESS; - } else { diff --git a/spice-vdagent-0.17.0.tar.bz2 b/spice-vdagent-0.17.0.tar.bz2 deleted file mode 100644 index 68924fa..0000000 --- a/spice-vdagent-0.17.0.tar.bz2 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f14a8bd8cdee10641aabd9ba32461a5844eab0fddb2a10c1d31386e7a9f7b33d -size 130413 diff --git a/spice-vdagent-0.19.0.tar.bz2 b/spice-vdagent-0.19.0.tar.bz2 new file mode 100644 index 0000000..07e8ae9 --- /dev/null +++ b/spice-vdagent-0.19.0.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:63a77c611c84f8120519a78a30256e43e159085831ac82de71643db643972f65 +size 151356 diff --git a/spice-vdagent-0.19.0.tar.bz2.sig b/spice-vdagent-0.19.0.tar.bz2.sig new file mode 100644 index 0000000000000000000000000000000000000000000000000000000000000000..df4851efc395cf9dc458118d6283dfe869db136adc908bc590affe8fad198ba9 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*6Z96qDR&P5FWpe44*%CeDdPq+N0$i}9UH}RS5SQ5! zJ>z;vPsZyH|3v_-0fy>?ri;PtK98WqL{THW@Ggn!ylseNG)~T4kgKkyJ1ycO7 zL3|*DKmZVnEQw`GH8kbbJGFu!?H5#1Su*pbq@8&35=!W&2e~}gjOc2!O}O-Ug~*pd z-e_@}mo?y68l^0T6>CfUxIzSSELj=lV{aUk@WH~$pmf33yh)G>%G`mMx|IUq>5ZIe zS&gY+;P8!*9XydE#~&N^CkICMa6Gic@NqHMM$;?Cg?N~eM}sS8#q=>uI30@BUC}+& zkB-Z;9BG$O5y?u(S0vu#$o_Ytdyg>d+4l7OIXP|7dE4%p1;}P#B?|5m4wn1K(UX?s zj=x{|#MKxN%;@sM~afJZ3z?xcAa#Qfwt)j?VP1*C?*O /dev/null 2>&1 -+ mkdir -p /var/run/spice-vdagentd ++ mkdir -p /run/spice-vdagentd # In case the previous running vdagentd crashed - rm -f /var/run/spice-vdagentd/spice-vdagent-sock + rm -f /run/spice-vdagentd/spice-vdagent-sock echo -n $"Starting $prog: " diff --git a/spice-vdagent.changes b/spice-vdagent.changes index 18bf4b3..3ea0eba 100644 --- a/spice-vdagent.changes +++ b/spice-vdagent.changes @@ -1,3 +1,44 @@ +------------------------------------------------------------------- +Fri May 17 20:34:45 UTC 2019 - Bruce Rogers + +- Update to 0.19.0 + * Add libdrm dependency + * Fix file descriptor leak on failed connections + * Handle new VD_AGENT_GRAPHICS_DEVICE_INFO message advertised by + VD_AGENT_CAP_GRAPHICS_DEVICE_INFO capability + * Session agent autostart changed to WindowManager ([rhbz#1623947]) + This fixes possible race with xdg-user-dirs + * Fix of sending empty screen resolution messages ([rhbz#1641723]) + * Fix 'Dependency failed for Activation socket' with systemd ([rhbz#1545212]) + * Fix error messages about on selecting text on host ([rhbz#1594876]) + this was also fixed with Gtk backend + * Update paths from /var/run → /run + * Fix Session agent restart + * Add test for file creation + * Prefer GLib memory functions stdlib.h ones + * Several code and logs improvements + * Add GTK+ framework to handle x11 backend such as clipboard + * Deprecate X11 backend in favor of GTK+ framework + * Ask pkg-config to appropriate directory to install udev rules + * Fix leak of udscs's file descriptor + * Better quote directory path when calling xdg-open to save file transfer + * Bump GLib to 2.34 + * Add systemd socket activation (rhbz#1340160) + * Add support to detailed errors on file transfers + * Add check for available free space in guest before starting a file transfer + * Use better names for duplicated files on file transfer + * Improve support on big endian guests (#5) + * Use IdleHint to check if a session is locked over console-kit (rhbz#1412673) + * Fixes double free on errors over udscs by improving memory ownership + * Hide autostart file on Unity + * Improve command line messages for vdagentd + * Fix typo in --enable-static-uinput configure option + * Code repository moved to gitlab.freedesktop.org +- Add keyring and tarball signature files +- obsoleted patches removed: + 8ba17481-quote-save-dir-before-passing-to-shell.patch + vdagentd-do-endian-swapping.patch + ------------------------------------------------------------------- Tue Dec 5 16:12:24 UTC 2017 - cbosdonnat@suse.com diff --git a/spice-vdagent.keyring b/spice-vdagent.keyring new file mode 100644 index 0000000..7b78fa0 --- /dev/null +++ b/spice-vdagent.keyring @@ -0,0 +1,386 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: SKS 1.1.6 +Comment: Hostname: pgpkeys.co.uk + +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 +=DMP2 +-----END PGP PUBLIC KEY BLOCK----- diff --git a/spice-vdagent.spec b/spice-vdagent.spec index 87e2430..fafd558 100644 --- a/spice-vdagent.spec +++ b/spice-vdagent.spec @@ -1,7 +1,7 @@ # # spec file for package spice-vdagent # -# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. # Copyright (c) 2014 B1 Systems GmbH, Vohburg, Germany. # # All modifications and additions to the file contributed by third parties @@ -13,34 +13,36 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org/ # Name: spice-vdagent -Version: 0.17.0 +Version: 0.19.0 Release: 0 Summary: Agent for Spice guests -License: GPL-3.0+ -Group: Applications/System +License: GPL-3.0-or-later +Group: System/Daemons Url: http://spice-space.org/ -Source0: http://spice-space.org/download/releases/%{name}-%{version}.tar.bz2 +Source: http://spice-space.org/download/releases/%{name}-%{version}.tar.bz2 +Source1: http://spice-space.org/download/releases/%{name}-%{version}.tar.bz2.sig +Source2: %{name}.keyring Patch0: spice-vdagent-var_run.patch -Patch1: vdagentd-do-endian-swapping.patch -Patch2: 8ba17481-quote-save-dir-before-passing-to-shell.patch BuildRequires: alsa-devel >= 1.0.22 BuildRequires: desktop-file-utils BuildRequires: glib2-devel BuildRequires: libXfixes-devel BuildRequires: libXinerama-devel BuildRequires: libXrandr-devel +BuildRequires: libdrm-devel BuildRequires: libpciaccess-devel BuildRequires: libtool BuildRequires: spice-protocol-devel >= 0.12.8 BuildRequires: systemd BuildRequires: systemd-devel BuildRequires: pkgconfig(dbus-1) -BuildRequires: pkgconfig(glib-2.0) >= 2.28 +BuildRequires: pkgconfig(glib-2.0) >= 2.34 +BuildRequires: pkgconfig(udev) Supplements: modalias(xorg-x11-server:virtio:d00000003v*) %{?systemd_requires} @@ -59,8 +61,6 @@ Features: %prep %setup -q %patch0 -p1 -%patch1 -p1 -%patch2 -p1 %build %configure \ @@ -70,9 +70,6 @@ make %{?_smp_mflags} V=2 %install make install DESTDIR=%{buildroot} V=2 -# move udev role -mv %{buildroot}/lib/udev %{buildroot}%{_prefix}/lib -rmdir %{buildroot}/lib # remove rsyslogd config rm -rf %{buildroot}%{_sysconfdir}/rsyslog.d # create rc symlink @@ -85,32 +82,34 @@ rm -fr %{buildroot}%{_datadir}/gdm/autostart %pre %service_add_pre spice-vdagentd.service -%service_add_pre spice-vdagentd.target +%service_add_pre spice-vdagentd.socket %post %service_add_post spice-vdagentd.service if [ "$1" -eq 1 ]; then systemctl -q enable spice-vdagentd.service || : fi -%service_add_post spice-vdagentd.target +%service_add_post spice-vdagentd.socket %tmpfiles_create %_tmpfilesdir/spice-vdagentd.conf %preun %service_del_preun spice-vdagentd.service -%service_del_preun spice-vdagentd.target +%service_del_preun spice-vdagentd.socket %postun %service_del_postun spice-vdagentd.service -%service_del_postun spice-vdagentd.target +%service_del_postun spice-vdagentd.socket %files %defattr(-,root,root) -%doc COPYING ChangeLog README TODO +%doc CHANGELOG.md README.md +%license COPYING %dir %{_libexecdir}/udev %dir %{_libexecdir}/udev/rules.d +%ghost /run/spice-vdagentd %{_libexecdir}/udev/rules.d/70-spice-vdagentd.rules %{_unitdir}/spice-vdagentd.service -%{_unitdir}/spice-vdagentd.target +%{_unitdir}/spice-vdagentd.socket %{_libexecdir}/tmpfiles.d/spice-vdagentd.conf %{_bindir}/spice-vdagent %{_sbindir}/spice-vdagentd diff --git a/vdagentd-do-endian-swapping.patch b/vdagentd-do-endian-swapping.patch deleted file mode 100644 index 327e904..0000000 --- a/vdagentd-do-endian-swapping.patch +++ /dev/null @@ -1,750 +0,0 @@ -From 1c0c3a0d32d71f2b3890b39b245981c3f32777c5 Mon Sep 17 00:00:00 2001 -From: Michal Suchanek -Date: Mon, 23 Jan 2017 14:53:53 +0100 -Subject: [PATCH] Move mouse-specific handling out of virtio_port_read_complete - -Move some mouse-specific code from the start of -virtio_port_read_complete to a separate helper -as is the case with other message types. - -Signed-off-by: Michal Suchanek -Acked-by: Christophe Fergeau ---- - src/vdagentd.c | 43 ++++++++++++++++++++++++------------------- - 1 file changed, 24 insertions(+), 19 deletions(-) - -diff --git a/src/vdagentd.c b/src/vdagentd.c -index a699681..4d587d1 100644 ---- a/src/vdagentd.c -+++ b/src/vdagentd.c -@@ -118,6 +118,29 @@ static void do_client_disconnect(void) - } - } - -+void do_client_mouse(struct vdagentd_uinput **uinputp, VDAgentMouseState *mouse) -+{ -+ vdagentd_uinput_do_mouse(uinputp, mouse); -+ if (!*uinputp) { -+ /* Try to re-open the tablet */ -+ struct agent_data *agent_data = -+ udscs_get_user_data(active_session_conn); -+ if (agent_data) -+ *uinputp = vdagentd_uinput_create(uinput_device, -+ agent_data->width, -+ agent_data->height, -+ agent_data->screen_info, -+ agent_data->screen_count, -+ debug > 1, -+ uinput_fake); -+ if (!*uinputp) { -+ syslog(LOG_CRIT, "Fatal uinput error"); -+ retval = 1; -+ quit = 1; -+ } -+ } -+} -+ - static void do_client_monitors(struct vdagent_virtio_port *vport, int port_nr, - VDAgentMessage *message_header, VDAgentMonitorsConfig *new_monitors) - { -@@ -333,25 +356,7 @@ static int virtio_port_read_complete( - case VD_AGENT_MOUSE_STATE: - if (message_header->size != sizeof(VDAgentMouseState)) - goto size_error; -- vdagentd_uinput_do_mouse(&uinput, (VDAgentMouseState *)data); -- if (!uinput) { -- /* Try to re-open the tablet */ -- struct agent_data *agent_data = -- udscs_get_user_data(active_session_conn); -- if (agent_data) -- uinput = vdagentd_uinput_create(uinput_device, -- agent_data->width, -- agent_data->height, -- agent_data->screen_info, -- agent_data->screen_count, -- debug > 1, -- uinput_fake); -- if (!uinput) { -- syslog(LOG_CRIT, "Fatal uinput error"); -- retval = 1; -- quit = 1; -- } -- } -+ do_client_mouse(&uinput, (VDAgentMouseState *)data); - break; - case VD_AGENT_MONITORS_CONFIG: - if (message_header->size < sizeof(VDAgentMonitorsConfig)) --- -2.10.2 - -From a430acfb779f9cfcc01aaa18a656c8d5a7042a27 Mon Sep 17 00:00:00 2001 -From: Michal Suchanek -Date: Fri, 27 Jan 2017 18:53:38 +0100 -Subject: [PATCH] vdagentd: Quiet uninitialized variable warning. - -With gcc 6.2.1 I cannot build vdagentd because gcc detects msg_type as -potentially uninitialized and vdagentd is built with -Werror. - -gcc 4.8.5 does not detect the issue and gcc 7 should be able to tell -that do_client_file_xfer is called only with values of -message_header->type handled in the switch. - -Signed-off-by: Michal Suchanek -Acked-by: Christophe Fergeau ---- - src/vdagentd.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/src/vdagentd.c b/src/vdagentd.c -index 4d587d1..0e0d4a3 100644 ---- a/src/vdagentd.c -+++ b/src/vdagentd.c -@@ -328,6 +328,8 @@ static void do_client_file_xfer(struct vdagent_virtio_port *vport, - id = d->id; - break; - } -+ default: -+ g_return_if_reached(); /* quiet uninitialized variable warning */ - } - - conn = g_hash_table_lookup(active_xfers, GUINT_TO_POINTER(id)); --- -2.10.2 - -From dd8ac5e041ab3f8d8c9b3f53e7564566ee183c20 Mon Sep 17 00:00:00 2001 -From: Victor Toso -Date: Mon, 23 Jan 2017 14:53:54 +0100 -Subject: [PATCH] vdagentd: early return on bad message size - -The payload size for each message should be the size of the expected -struct or bigger when it contain arrays of no fixed size. - -This patch creates: - * vdagent_message_min_size[] static array with the expected size for - each message; - * vdagent_message_check_size() which checks the size of message's - payload based on the type of message and by using - vdagent_message_min_size[] as reference" - -Signed-off-by: Victor Toso -Signed-off-by: Michal Suchanek -Acked-by: Christophe Fergeau ---- - src/vdagentd.c | 133 +++++++++++++++++++++++++++++++++++++++------------------ - 1 file changed, 91 insertions(+), 42 deletions(-) - -diff --git a/src/vdagentd.c b/src/vdagentd.c -index 0e0d4a3..579446a 100644 ---- a/src/vdagentd.c -+++ b/src/vdagentd.c -@@ -341,34 +341,109 @@ static void do_client_file_xfer(struct vdagent_virtio_port *vport, - udscs_write(conn, msg_type, 0, 0, data, message_header->size); - } - -+static gsize vdagent_message_min_size[] = -+{ -+ -1, /* Does not exist */ -+ sizeof(VDAgentMouseState), /* VD_AGENT_MOUSE_STATE */ -+ sizeof(VDAgentMonitorsConfig), /* VD_AGENT_MONITORS_CONFIG */ -+ sizeof(VDAgentReply), /* VD_AGENT_REPLY */ -+ sizeof(VDAgentClipboard), /* VD_AGENT_CLIPBOARD */ -+ sizeof(VDAgentDisplayConfig), /* VD_AGENT_DISPLAY_CONFIG */ -+ sizeof(VDAgentAnnounceCapabilities), /* VD_AGENT_ANNOUNCE_CAPABILITIES */ -+ sizeof(VDAgentClipboardGrab), /* VD_AGENT_CLIPBOARD_GRAB */ -+ sizeof(VDAgentClipboardRequest), /* VD_AGENT_CLIPBOARD_REQUEST */ -+ sizeof(VDAgentClipboardRelease), /* VD_AGENT_CLIPBOARD_RELEASE */ -+ sizeof(VDAgentFileXferStartMessage), /* VD_AGENT_FILE_XFER_START */ -+ sizeof(VDAgentFileXferStatusMessage), /* VD_AGENT_FILE_XFER_STATUS */ -+ sizeof(VDAgentFileXferDataMessage), /* VD_AGENT_FILE_XFER_DATA */ -+ 0, /* VD_AGENT_CLIENT_DISCONNECTED */ -+ sizeof(VDAgentMaxClipboard), /* VD_AGENT_MAX_CLIPBOARD */ -+ sizeof(VDAgentAudioVolumeSync), /* VD_AGENT_AUDIO_VOLUME_SYNC */ -+}; -+ -+static gboolean vdagent_message_check_size(const VDAgentMessage *message_header) -+{ -+ uint32_t min_size = 0; -+ -+ if (message_header->protocol != VD_AGENT_PROTOCOL) { -+ syslog(LOG_ERR, "message with wrong protocol version ignoring"); -+ return FALSE; -+ } -+ -+ if (!message_header->type || -+ message_header->type >= G_N_ELEMENTS(vdagent_message_min_size)) { -+ syslog(LOG_WARNING, "unknown message type %d, ignoring", -+ message_header->type); -+ return FALSE; -+ } -+ -+ min_size = vdagent_message_min_size[message_header->type]; -+ if (VD_AGENT_HAS_CAPABILITY(capabilities, capabilities_size, -+ VD_AGENT_CAP_CLIPBOARD_SELECTION)) { -+ switch (message_header->type) { -+ case VD_AGENT_CLIPBOARD_GRAB: -+ case VD_AGENT_CLIPBOARD_REQUEST: -+ case VD_AGENT_CLIPBOARD: -+ case VD_AGENT_CLIPBOARD_RELEASE: -+ min_size += 4; -+ } -+ } -+ -+ switch (message_header->type) { -+ case VD_AGENT_MONITORS_CONFIG: -+ case VD_AGENT_CLIPBOARD: -+ case VD_AGENT_CLIPBOARD_GRAB: -+ case VD_AGENT_CLIPBOARD_REQUEST: -+ case VD_AGENT_CLIPBOARD_RELEASE: -+ case VD_AGENT_AUDIO_VOLUME_SYNC: -+ case VD_AGENT_ANNOUNCE_CAPABILITIES: -+ if (message_header->size < min_size) { -+ syslog(LOG_ERR, "read: invalid message size: %u for message type: %u", -+ message_header->size, message_header->type); -+ return FALSE; -+ } -+ break; -+ case VD_AGENT_MOUSE_STATE: -+ case VD_AGENT_MAX_CLIPBOARD: -+ if (message_header->size != min_size) { -+ syslog(LOG_ERR, "read: invalid message size: %u for message type: %u", -+ message_header->size, message_header->type); -+ return FALSE; -+ } -+ break; -+ case VD_AGENT_FILE_XFER_START: -+ case VD_AGENT_FILE_XFER_DATA: -+ case VD_AGENT_FILE_XFER_STATUS: -+ case VD_AGENT_CLIENT_DISCONNECTED: -+ /* No size checks for these at the moment */ -+ break; -+ case VD_AGENT_DISPLAY_CONFIG: -+ case VD_AGENT_REPLY: -+ default: -+ g_warn_if_reached(); -+ return FALSE; -+ } -+ return TRUE; -+} -+ - static int virtio_port_read_complete( - struct vdagent_virtio_port *vport, - int port_nr, - VDAgentMessage *message_header, - uint8_t *data) - { -- uint32_t min_size = 0; -- -- if (message_header->protocol != VD_AGENT_PROTOCOL) { -- syslog(LOG_ERR, "message with wrong protocol version ignoring"); -+ if (!vdagent_message_check_size(message_header)) - return 0; -- } - - switch (message_header->type) { - case VD_AGENT_MOUSE_STATE: -- if (message_header->size != sizeof(VDAgentMouseState)) -- goto size_error; - do_client_mouse(&uinput, (VDAgentMouseState *)data); - break; - case VD_AGENT_MONITORS_CONFIG: -- if (message_header->size < sizeof(VDAgentMonitorsConfig)) -- goto size_error; - do_client_monitors(vport, port_nr, message_header, - (VDAgentMonitorsConfig *)data); - break; - case VD_AGENT_ANNOUNCE_CAPABILITIES: -- if (message_header->size < sizeof(VDAgentAnnounceCapabilities)) -- goto size_error; - do_client_capabilities(vport, message_header, - (VDAgentAnnounceCapabilities *)data); - break; -@@ -376,21 +451,6 @@ static int virtio_port_read_complete( - case VD_AGENT_CLIPBOARD_REQUEST: - case VD_AGENT_CLIPBOARD: - case VD_AGENT_CLIPBOARD_RELEASE: -- switch (message_header->type) { -- case VD_AGENT_CLIPBOARD_GRAB: -- min_size = sizeof(VDAgentClipboardGrab); break; -- case VD_AGENT_CLIPBOARD_REQUEST: -- min_size = sizeof(VDAgentClipboardRequest); break; -- case VD_AGENT_CLIPBOARD: -- min_size = sizeof(VDAgentClipboard); break; -- } -- if (VD_AGENT_HAS_CAPABILITY(capabilities, capabilities_size, -- VD_AGENT_CAP_CLIPBOARD_SELECTION)) { -- min_size += 4; -- } -- if (message_header->size < min_size) { -- goto size_error; -- } - do_client_clipboard(vport, message_header, data); - break; - case VD_AGENT_FILE_XFER_START: -@@ -402,31 +462,20 @@ static int virtio_port_read_complete( - vdagent_virtio_port_reset(vport, VDP_CLIENT_PORT); - do_client_disconnect(); - break; -- case VD_AGENT_MAX_CLIPBOARD: -- if (message_header->size != sizeof(VDAgentMaxClipboard)) -- goto size_error; -- VDAgentMaxClipboard *msg = (VDAgentMaxClipboard *)data; -- syslog(LOG_DEBUG, "Set max clipboard: %d", msg->max); -- max_clipboard = msg->max; -+ case VD_AGENT_MAX_CLIPBOARD: { -+ max_clipboard = ((VDAgentMaxClipboard *)data)->max; -+ syslog(LOG_DEBUG, "Set max clipboard: %d", max_clipboard); - break; -+ } - case VD_AGENT_AUDIO_VOLUME_SYNC: -- if (message_header->size < sizeof(VDAgentAudioVolumeSync)) -- goto size_error; -- - do_client_volume_sync(vport, port_nr, message_header, - (VDAgentAudioVolumeSync *)data); - break; - default: -- syslog(LOG_WARNING, "unknown message type %d, ignoring", -- message_header->type); -+ g_warn_if_reached(); - } - - return 0; -- --size_error: -- syslog(LOG_ERR, "read: invalid message size: %u for message type: %u", -- message_header->size, message_header->type); -- return 0; - } - - static void virtio_write_clipboard(uint8_t selection, uint32_t msg_type, --- -2.10.2 - -From 3102dca497aae947c29455876cad5ba882613224 Mon Sep 17 00:00:00 2001 -From: Christophe Fergeau -Date: Mon, 30 Jan 2017 12:57:55 +0100 -Subject: [PATCH] vdagentd: Add missing size checks - -Acked-by: Victor Toso ---- - src/vdagentd.c | 14 ++++++-------- - 1 file changed, 6 insertions(+), 8 deletions(-) - -diff --git a/src/vdagentd.c b/src/vdagentd.c -index 579446a..ffafba9 100644 ---- a/src/vdagentd.c -+++ b/src/vdagentd.c -@@ -391,6 +391,8 @@ static gboolean vdagent_message_check_size(const VDAgentMessage *message_header) - - switch (message_header->type) { - case VD_AGENT_MONITORS_CONFIG: -+ case VD_AGENT_FILE_XFER_START: -+ case VD_AGENT_FILE_XFER_DATA: - case VD_AGENT_CLIPBOARD: - case VD_AGENT_CLIPBOARD_GRAB: - case VD_AGENT_CLIPBOARD_REQUEST: -@@ -404,21 +406,17 @@ static gboolean vdagent_message_check_size(const VDAgentMessage *message_header) - } - break; - case VD_AGENT_MOUSE_STATE: -+ case VD_AGENT_FILE_XFER_STATUS: -+ case VD_AGENT_DISPLAY_CONFIG: -+ case VD_AGENT_REPLY: - case VD_AGENT_MAX_CLIPBOARD: -+ case VD_AGENT_CLIENT_DISCONNECTED: - if (message_header->size != min_size) { - syslog(LOG_ERR, "read: invalid message size: %u for message type: %u", - message_header->size, message_header->type); - return FALSE; - } - break; -- case VD_AGENT_FILE_XFER_START: -- case VD_AGENT_FILE_XFER_DATA: -- case VD_AGENT_FILE_XFER_STATUS: -- case VD_AGENT_CLIENT_DISCONNECTED: -- /* No size checks for these at the moment */ -- break; -- case VD_AGENT_DISPLAY_CONFIG: -- case VD_AGENT_REPLY: - default: - g_warn_if_reached(); - return FALSE; --- -2.10.2 - -From 1b59bd11ebc3edce1957bfaaaeb90e559171e4ad Mon Sep 17 00:00:00 2001 -From: Christophe Fergeau -Date: Mon, 30 Jan 2017 12:58:06 +0100 -Subject: [PATCH] vdagentd: Adjust size checks - -Acked-by: Victor Toso ---- - src/vdagentd.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/vdagentd.c b/src/vdagentd.c -index ffafba9..a1bbf71 100644 ---- a/src/vdagentd.c -+++ b/src/vdagentd.c -@@ -395,8 +395,6 @@ static gboolean vdagent_message_check_size(const VDAgentMessage *message_header) - case VD_AGENT_FILE_XFER_DATA: - case VD_AGENT_CLIPBOARD: - case VD_AGENT_CLIPBOARD_GRAB: -- case VD_AGENT_CLIPBOARD_REQUEST: -- case VD_AGENT_CLIPBOARD_RELEASE: - case VD_AGENT_AUDIO_VOLUME_SYNC: - case VD_AGENT_ANNOUNCE_CAPABILITIES: - if (message_header->size < min_size) { -@@ -409,6 +407,8 @@ static gboolean vdagent_message_check_size(const VDAgentMessage *message_header) - case VD_AGENT_FILE_XFER_STATUS: - case VD_AGENT_DISPLAY_CONFIG: - case VD_AGENT_REPLY: -+ case VD_AGENT_CLIPBOARD_REQUEST: -+ case VD_AGENT_CLIPBOARD_RELEASE: - case VD_AGENT_MAX_CLIPBOARD: - case VD_AGENT_CLIENT_DISCONNECTED: - if (message_header->size != min_size) { --- -2.10.2 - -From 44b2511b2dd621ca6267f73c4f29fccfb0302bc6 Mon Sep 17 00:00:00 2001 -From: Michal Suchanek -Date: Fri, 27 Jan 2017 18:53:40 +0100 -Subject: [PATCH] vdagentd: Do endian swapping. - -This allows running big endian and little endian guest side by side using -cut & paste between them. - -There is a general design idea that swapping should come as close to -virtio_read/virtio_write as possible. In particular, the protocol -between vdagent and vdagentd is guest-specific and in native endian. -With muliple layers of headers this is a bit tricky. A few message types -have to be swapped fully before passing through vdagentd. - -Signed-off-by: Michal Suchanek -Signed-off-by: Victor Toso ---- - src/vdagent-virtio-port.c | 36 +++++++++------ - src/vdagentd.c | 109 +++++++++++++++++++++++++++++++++++++++++----- - 2 files changed, 120 insertions(+), 25 deletions(-) - -diff --git a/src/vdagent-virtio-port.c b/src/vdagent-virtio-port.c -index 6267c74..2d1ee5b 100644 ---- a/src/vdagent-virtio-port.c -+++ b/src/vdagent-virtio-port.c -@@ -28,6 +28,7 @@ - #include - #include - #include -+#include - - #include "vdagent-virtio-port.h" - -@@ -216,16 +217,16 @@ int vdagent_virtio_port_write_start( - return -1; - } - -- chunk_header.port = port_nr; -- chunk_header.size = sizeof(message_header) + data_size; -+ chunk_header.port = GUINT32_TO_LE(port_nr); -+ chunk_header.size = GUINT32_TO_LE(sizeof(message_header) + data_size); - memcpy(new_wbuf->buf + new_wbuf->write_pos, &chunk_header, - sizeof(chunk_header)); - new_wbuf->write_pos += sizeof(chunk_header); - -- message_header.protocol = VD_AGENT_PROTOCOL; -- message_header.type = message_type; -- message_header.opaque = message_opaque; -- message_header.size = data_size; -+ message_header.protocol = GUINT32_TO_LE(VD_AGENT_PROTOCOL); -+ message_header.type = GUINT32_TO_LE(message_type); -+ message_header.opaque = GUINT64_TO_LE(message_opaque); -+ message_header.size = GUINT32_TO_LE(data_size); - memcpy(new_wbuf->buf + new_wbuf->write_pos, &message_header, - sizeof(message_header)); - new_wbuf->write_pos += sizeof(message_header); -@@ -309,13 +310,20 @@ static void vdagent_virtio_port_do_chunk(struct vdagent_virtio_port **vportp) - memcpy((uint8_t *)&port->message_header + port->message_header_read, - vport->chunk_data, read); - port->message_header_read += read; -- if (port->message_header_read == sizeof(port->message_header) && -- port->message_header.size) { -- port->message_data = malloc(port->message_header.size); -- if (!port->message_data) { -- syslog(LOG_ERR, "out of memory, disconnecting virtio"); -- vdagent_virtio_port_destroy(vportp); -- return; -+ if (port->message_header_read == sizeof(port->message_header)) { -+ -+ port->message_header.protocol = GUINT32_FROM_LE(port->message_header.protocol); -+ port->message_header.type = GUINT32_FROM_LE(port->message_header.type); -+ port->message_header.opaque = GUINT64_FROM_LE(port->message_header.opaque); -+ port->message_header.size = GUINT32_FROM_LE(port->message_header.size); -+ -+ if (port->message_header.size) { -+ port->message_data = malloc(port->message_header.size); -+ if (!port->message_data) { -+ syslog(LOG_ERR, "out of memory, disconnecting virtio"); -+ vdagent_virtio_port_destroy(vportp); -+ return; -+ } - } - } - pos = read; -@@ -420,6 +428,8 @@ static void vdagent_virtio_port_do_read(struct vdagent_virtio_port **vportp) - if (vport->chunk_header_read < sizeof(vport->chunk_header)) { - vport->chunk_header_read += n; - if (vport->chunk_header_read == sizeof(vport->chunk_header)) { -+ vport->chunk_header.size = GUINT32_FROM_LE(vport->chunk_header.size); -+ vport->chunk_header.port = GUINT32_FROM_LE(vport->chunk_header.port); - if (vport->chunk_header.size > VD_AGENT_MAX_DATA_SIZE) { - syslog(LOG_ERR, "chunk size %u too large", - vport->chunk_header.size); -diff --git a/src/vdagentd.c b/src/vdagentd.c -index a1bbf71..5ea98eb 100644 ---- a/src/vdagentd.c -+++ b/src/vdagentd.c -@@ -78,6 +78,34 @@ static int client_connected = 0; - static int max_clipboard = -1; - - /* utility functions */ -+static void virtio_msg_uint32_to_le(uint8_t *_msg, uint32_t size, uint32_t offset) -+{ -+ uint32_t i, *msg = (uint32_t *)(_msg + offset); -+ -+ /* offset - size % 4 should be 0 - extra bytes are ignored */ -+ for (i = 0; i < (size - offset) / 4; i++) -+ msg[i] = GUINT32_TO_LE(msg[i]); -+} -+ -+static void virtio_msg_uint32_from_le(uint8_t *_msg, uint32_t size, uint32_t offset) -+{ -+ uint32_t i, *msg = (uint32_t *)(_msg + offset); -+ -+ /* offset - size % 4 should be 0 - extra bytes are ignored */ -+ for (i = 0; i < (size - offset) / 4; i++) -+ msg[i] = GUINT32_FROM_LE(msg[i]); -+} -+ -+static void virtio_msg_uint16_from_le(uint8_t *_msg, uint32_t size, uint32_t offset) -+{ -+ uint32_t i; -+ uint16_t *msg = (uint16_t *)(_msg + offset); -+ -+ /* offset - size % 2 should be 0 - extra bytes are ignored */ -+ for (i = 0; i < (size - offset) / 2; i++) -+ msg[i] = GUINT16_FROM_LE(msg[i]); -+} -+ - /* vdagentd <-> spice-client communication handling */ - static void send_capabilities(struct vdagent_virtio_port *vport, - uint32_t request) -@@ -102,6 +130,7 @@ static void send_capabilities(struct vdagent_virtio_port *vport, - VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_GUEST_LINEEND_LF); - VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_MAX_CLIPBOARD); - VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_AUDIO_VOLUME_SYNC); -+ virtio_msg_uint32_to_le((uint8_t *)caps, size, 0); - - vdagent_virtio_port_write(vport, VDP_CLIENT_PORT, - VD_AGENT_ANNOUNCE_CAPABILITIES, 0, -@@ -174,8 +203,8 @@ static void do_client_monitors(struct vdagent_virtio_port *vport, int port_nr, - (uint8_t *)mon_config, size); - - /* Acknowledge reception of monitors config to spice server / client */ -- reply.type = VD_AGENT_MONITORS_CONFIG; -- reply.error = VD_AGENT_SUCCESS; -+ reply.type = GUINT32_TO_LE(VD_AGENT_MONITORS_CONFIG); -+ reply.error = GUINT32_TO_LE(VD_AGENT_SUCCESS); - vdagent_virtio_port_write(vport, port_nr, VD_AGENT_REPLY, 0, - (uint8_t *)&reply, sizeof(reply)); - } -@@ -278,8 +307,8 @@ static void send_file_xfer_status(struct vdagent_virtio_port *vport, - const char *msg, uint32_t id, uint32_t xfer_status) - { - VDAgentFileXferStatusMessage status = { -- .id = id, -- .result = xfer_status, -+ .id = GUINT32_TO_LE(id), -+ .result = GUINT32_TO_LE(xfer_status), - }; - syslog(LOG_WARNING, msg, id); - if (vport) -@@ -361,6 +390,50 @@ static gsize vdagent_message_min_size[] = - sizeof(VDAgentAudioVolumeSync), /* VD_AGENT_AUDIO_VOLUME_SYNC */ - }; - -+static void vdagent_message_clipboard_from_le(VDAgentMessage *message_header, -+ uint8_t *data) -+{ -+ gsize min_size = vdagent_message_min_size[message_header->type]; -+ uint32_t *data_type = (uint32_t *) data; -+ -+ if (VD_AGENT_HAS_CAPABILITY(capabilities, capabilities_size, -+ VD_AGENT_CAP_CLIPBOARD_SELECTION)) { -+ min_size += 4; -+ data_type++; -+ } -+ -+ switch (message_header->type) { -+ case VD_AGENT_CLIPBOARD_REQUEST: -+ case VD_AGENT_CLIPBOARD: -+ *data_type = GUINT32_FROM_LE(*data_type); -+ break; -+ case VD_AGENT_CLIPBOARD_GRAB: -+ virtio_msg_uint32_from_le(data, message_header->size, min_size); -+ break; -+ default: -+ g_warn_if_reached(); -+ } -+} -+ -+static void vdagent_message_file_xfer_from_le(VDAgentMessage *message_header, -+ uint8_t *data) -+{ -+ uint32_t *id = (uint32_t *)data; -+ *id = GUINT32_FROM_LE(*id); -+ id++; /* status */ -+ -+ switch (message_header->type) { -+ case VD_AGENT_FILE_XFER_DATA: { -+ VDAgentFileXferDataMessage *msg = (VDAgentFileXferDataMessage *)data; -+ msg->size = GUINT64_FROM_LE(msg->size); -+ break; -+ } -+ case VD_AGENT_FILE_XFER_STATUS: -+ *id = GUINT32_FROM_LE(*id); /* status */ -+ break; -+ } -+} -+ - static gboolean vdagent_message_check_size(const VDAgentMessage *message_header) - { - uint32_t min_size = 0; -@@ -435,13 +508,16 @@ static int virtio_port_read_complete( - - switch (message_header->type) { - case VD_AGENT_MOUSE_STATE: -+ virtio_msg_uint32_from_le(data, message_header->size, 0); - do_client_mouse(&uinput, (VDAgentMouseState *)data); - break; - case VD_AGENT_MONITORS_CONFIG: -+ virtio_msg_uint32_from_le(data, message_header->size, 0); - do_client_monitors(vport, port_nr, message_header, - (VDAgentMonitorsConfig *)data); - break; - case VD_AGENT_ANNOUNCE_CAPABILITIES: -+ virtio_msg_uint32_from_le(data, message_header->size, 0); - do_client_capabilities(vport, message_header, - (VDAgentAnnounceCapabilities *)data); - break; -@@ -449,11 +525,13 @@ static int virtio_port_read_complete( - case VD_AGENT_CLIPBOARD_REQUEST: - case VD_AGENT_CLIPBOARD: - case VD_AGENT_CLIPBOARD_RELEASE: -+ vdagent_message_clipboard_from_le(message_header, data); - do_client_clipboard(vport, message_header, data); - break; - case VD_AGENT_FILE_XFER_START: - case VD_AGENT_FILE_XFER_STATUS: - case VD_AGENT_FILE_XFER_DATA: -+ vdagent_message_file_xfer_from_le(message_header, data); - do_client_file_xfer(vport, message_header, data); - break; - case VD_AGENT_CLIENT_DISCONNECTED: -@@ -461,14 +539,18 @@ static int virtio_port_read_complete( - do_client_disconnect(); - break; - case VD_AGENT_MAX_CLIPBOARD: { -- max_clipboard = ((VDAgentMaxClipboard *)data)->max; -+ max_clipboard = GUINT32_FROM_LE(((VDAgentMaxClipboard *)data)->max); - syslog(LOG_DEBUG, "Set max clipboard: %d", max_clipboard); - break; - } -- case VD_AGENT_AUDIO_VOLUME_SYNC: -- do_client_volume_sync(vport, port_nr, message_header, -- (VDAgentAudioVolumeSync *)data); -+ case VD_AGENT_AUDIO_VOLUME_SYNC: { -+ VDAgentAudioVolumeSync *vdata = (VDAgentAudioVolumeSync *)data; -+ virtio_msg_uint16_from_le((uint8_t *)vdata, message_header->size, -+ offsetof(VDAgentAudioVolumeSync, volume)); -+ -+ do_client_volume_sync(vport, port_nr, message_header, vdata); - break; -+ } - default: - g_warn_if_reached(); - } -@@ -477,7 +559,7 @@ static int virtio_port_read_complete( - } - - static void virtio_write_clipboard(uint8_t selection, uint32_t msg_type, -- uint32_t data_type, const uint8_t *data, uint32_t data_size) -+ uint32_t data_type, uint8_t *data, uint32_t data_size) - { - uint32_t size = data_size; - -@@ -498,15 +580,18 @@ static void virtio_write_clipboard(uint8_t selection, uint32_t msg_type, - vdagent_virtio_port_write_append(virtio_port, sel, 4); - } - if (data_type != -1) { -+ data_type = GUINT32_TO_LE(data_type); - vdagent_virtio_port_write_append(virtio_port, (uint8_t*)&data_type, 4); - } - -+ if (msg_type == VD_AGENT_CLIPBOARD_GRAB) -+ virtio_msg_uint32_to_le(data, data_size, 0); - vdagent_virtio_port_write_append(virtio_port, data, data_size); - } - - /* vdagentd <-> vdagent communication handling */ - static int do_agent_clipboard(struct udscs_connection *conn, -- struct udscs_message_header *header, const uint8_t *data) -+ struct udscs_message_header *header, uint8_t *data) - { - uint8_t selection = header->arg1; - uint32_t msg_type = 0, data_type = -1, size = header->size; -@@ -820,8 +905,8 @@ static void agent_read_complete(struct udscs_connection **connp, - break; - case VDAGENTD_FILE_XFER_STATUS:{ - VDAgentFileXferStatusMessage status; -- status.id = header->arg1; -- status.result = header->arg2; -+ status.id = GUINT32_TO_LE(header->arg1); -+ status.result = GUINT32_TO_LE(header->arg2); - vdagent_virtio_port_write(virtio_port, VDP_CLIENT_PORT, - VD_AGENT_FILE_XFER_STATUS, 0, - (uint8_t *)&status, sizeof(status)); --- -2.10.2 - -From 69e5fd82bf5d9282a640ae8f4069e3cd1bf6abb8 Mon Sep 17 00:00:00 2001 -From: Pavel Grunt -Date: Thu, 23 Mar 2017 12:26:28 +0100 -Subject: [PATCH] vdagentd: Handle VD_AGENT_CLIPBOARD_RELEASE - -In fact do nothing but avoid a runtime warning - vdagent_message_clipboard_from_le: code should not be reached - -Introduced in 99d9d3583143aef7143ec986cebe2980fdeeb776 - -Acked-by: Victor Toso ---- - src/vdagentd/vdagentd.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/src/vdagentd.c b/src/vdagentd.c -index 954bba12cca8..aef5b9616318 100644 ---- a/src/vdagentd.c -+++ b/src/vdagentd.c -@@ -410,6 +410,8 @@ static void vdagent_message_clipboard_from_le(VDAgentMessage *message_header, - case VD_AGENT_CLIPBOARD_GRAB: - virtio_msg_uint32_from_le(data, message_header->size, min_size); - break; -+ case VD_AGENT_CLIPBOARD_RELEASE: -+ break; - default: - g_warn_if_reached(); - } --- -2.10.2 -