Accepting request 459243 from home:michals:boo1012215
Add endian swapping to run on BE guests (boo#1012215). OBS-URL: https://build.opensuse.org/request/show/459243 OBS-URL: https://build.opensuse.org/package/show/Virtualization/spice-vdagent?expand=0&rev=19
This commit is contained in:
parent
ecc6f57b61
commit
ca67a006d4
@ -1,3 +1,8 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Mon Feb 20 13:56:35 UTC 2017 - msuchanek@suse.com
|
||||||
|
|
||||||
|
- Add endian swapping to run on BE guests (boo#1012215).
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Fri Nov 25 18:53:15 UTC 2016 - zaitor@opensuse.org
|
Fri Nov 25 18:53:15 UTC 2016 - zaitor@opensuse.org
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# spec file for package spice-vdagent
|
# spec file for package spice-vdagent
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany.
|
# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
|
||||||
# Copyright (c) 2014 B1 Systems GmbH, Vohburg, Germany.
|
# Copyright (c) 2014 B1 Systems GmbH, Vohburg, Germany.
|
||||||
#
|
#
|
||||||
# All modifications and additions to the file contributed by third parties
|
# All modifications and additions to the file contributed by third parties
|
||||||
@ -26,6 +26,7 @@ Group: Applications/System
|
|||||||
Url: http://spice-space.org/
|
Url: http://spice-space.org/
|
||||||
Source0: http://spice-space.org/download/releases/%{name}-%{version}.tar.bz2
|
Source0: http://spice-space.org/download/releases/%{name}-%{version}.tar.bz2
|
||||||
Patch0: spice-vdagent-var_run.patch
|
Patch0: spice-vdagent-var_run.patch
|
||||||
|
Patch1: vdagentd-do-endian-swapping.patch
|
||||||
BuildRequires: alsa-devel >= 1.0.22
|
BuildRequires: alsa-devel >= 1.0.22
|
||||||
BuildRequires: desktop-file-utils
|
BuildRequires: desktop-file-utils
|
||||||
BuildRequires: glib2-devel
|
BuildRequires: glib2-devel
|
||||||
@ -57,6 +58,7 @@ Features:
|
|||||||
%prep
|
%prep
|
||||||
%setup -q
|
%setup -q
|
||||||
%patch0 -p1
|
%patch0 -p1
|
||||||
|
%patch1 -p1
|
||||||
|
|
||||||
%build
|
%build
|
||||||
%configure \
|
%configure \
|
||||||
|
719
vdagentd-do-endian-swapping.patch
Normal file
719
vdagentd-do-endian-swapping.patch
Normal file
@ -0,0 +1,719 @@
|
|||||||
|
From 1c0c3a0d32d71f2b3890b39b245981c3f32777c5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michal Suchanek <msuchanek@suse.de>
|
||||||
|
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 <msuchanek@suse.de>
|
||||||
|
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
|
||||||
|
---
|
||||||
|
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 <msuchanek@suse.de>
|
||||||
|
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 <msuchanek@suse.de>
|
||||||
|
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
|
||||||
|
---
|
||||||
|
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 <me@victortoso.com>
|
||||||
|
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 <victortoso@redhat.com>
|
||||||
|
Signed-off-by: Michal Suchanek <msuchanek@suse.de>
|
||||||
|
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
|
||||||
|
---
|
||||||
|
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 <cfergeau@redhat.com>
|
||||||
|
Date: Mon, 30 Jan 2017 12:57:55 +0100
|
||||||
|
Subject: [PATCH] vdagentd: Add missing size checks
|
||||||
|
|
||||||
|
Acked-by: Victor Toso <victortoso@redhat.com>
|
||||||
|
---
|
||||||
|
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 <cfergeau@redhat.com>
|
||||||
|
Date: Mon, 30 Jan 2017 12:58:06 +0100
|
||||||
|
Subject: [PATCH] vdagentd: Adjust size checks
|
||||||
|
|
||||||
|
Acked-by: Victor Toso <victortoso@redhat.com>
|
||||||
|
---
|
||||||
|
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 <msuchanek@suse.de>
|
||||||
|
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 <msuchanek@suse.de>
|
||||||
|
Signed-off-by: Victor Toso <me@victortoso.com>
|
||||||
|
---
|
||||||
|
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 <sys/select.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
+#include <glib.h>
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user