Accepting request 863394 from home:bfrogers:branches:Virtualization

- Update to version 0.21.0
* Changes include:
* Security fixes:
  CVE-2020-25650, CVE-2020-25651, CVE-2020-25652, CVE-2020-25653
* Fix shutdown issue due to incompatible thread/fork uses with GLib
* Fix mouse pointer issues under Wayland
* Fix a crash when running without dbus (e.g: within containers)
* !9  - Introduce optional GTK4 support for monitor management
* !13 - Enable copying files from client using webdav
* Bump spice-protocol dependency to v0.14.3
* Drop all patches, since they are in base tarball now:
  Add-a-test-for-session_info.patch
  Avoids-unchecked-file-transfer-IDs-allocation-and-us.patch
  Avoids-uncontrolled-active_xfers-allocations.patch
  Avoids-unlimited-agent-connections.patch
  Avoids-user-session-hijacking.patch
  Better-check-for-sessions.patch
  cleanup-active_xfers-when-the-client-disconnects.patch
  systemd-login-Avoid-a-crash-on-container.patch
  vdagent-connection-Pass-err-to-g_credentials_get_uni.patch
  vdagentd-Automatically-release-agent_data.patch
  vdagentd-Avoid-calling-chmod.patch
  vdagentd-Better-check-for-vdagent_connection_get_pee.patch
  vdagentd-Limit-number-of-agents-per-session-to-1.patch
  vdagentd-Use-bool-for-agent_owns_clipboard-and-clien.patch
  vdagentd-do-not-allow-to-use-an-already-used-file-xf.patch
  vdagentd-init-static-uinput-before-fork.patch
  vdagentd-work-around-GLib-s-fork-issues.patch

OBS-URL: https://build.opensuse.org/request/show/863394
OBS-URL: https://build.opensuse.org/package/show/Virtualization/spice-vdagent?expand=0&rev=43
This commit is contained in:
Bruce Rogers 2021-01-15 17:48:26 +00:00 committed by Git OBS Bridge
parent 6ff184c434
commit efb30eb1c1
24 changed files with 74 additions and 1711 deletions

View File

@ -1,132 +0,0 @@
From a77b09e5d77e5cf1d4fdd38d018ecf164cd01df9 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <freddy77@gmail.com>
Date: Tue, 20 Oct 2020 16:38:37 +0100
Subject: [PATCH 10/10] Add a test for session_info
References: bsc#1173749
Test from Uri, integrated in test suite.
Signed-off-by: Uri Lublin <uril@redhat.com>
Signed-off-by: Frediano Ziglio <freddy77@gmail.com>
---
Makefile.am | 30 ++++++++++++++++++++
tests/test-session-info.c | 58 +++++++++++++++++++++++++++++++++++++++
2 files changed, 88 insertions(+)
create mode 100644 tests/test-session-info.c
diff --git a/Makefile.am b/Makefile.am
index 575ba52..f4c65b4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -109,13 +109,43 @@ src_spice_vdagentd_SOURCES = \
src/vdagentd/virtio-port.h \
$(NULL)
+tests_test_session_info_CFLAGS = \
+ $(DBUS_CFLAGS) \
+ $(LIBSYSTEMD_DAEMON_CFLAGS) \
+ $(LIBSYSTEMD_LOGIN_CFLAGS) \
+ $(SPICE_CFLAGS) \
+ $(GIO2_CFLAGS) \
+ -I$(srcdir)/src \
+ -I$(srcdir)/src/vdagentd \
+ -DUDSCS_NO_SERVER \
+ $(NULL)
+
+tests_test_session_info_LDADD = \
+ $(DBUS_LIBS) \
+ $(LIBSYSTEMD_DAEMON_LIBS) \
+ $(LIBSYSTEMD_LOGIN_LIBS) \
+ $(SPICE_LIBS) \
+ $(GIO2_LIBS) \
+ $(NULL)
+
+tests_test_session_info_SOURCES = \
+ $(common_sources) \
+ src/vdagentd/session-info.h \
+ tests/test-session-info.c \
+ $(NULL)
+
+check_PROGRAMS += tests/test-session-info
+
if HAVE_CONSOLE_KIT
src_spice_vdagentd_SOURCES += src/vdagentd/console-kit.c
+tests_test_session_info_SOURCES += src/vdagentd/console-kit.c
else
if HAVE_LIBSYSTEMD_LOGIN
src_spice_vdagentd_SOURCES += src/vdagentd/systemd-login.c
+tests_test_session_info_SOURCES += src/vdagentd/systemd-login.c
else
src_spice_vdagentd_SOURCES += src/vdagentd/dummy-session-info.c
+tests_test_session_info_SOURCES += src/vdagentd/dummy-session-info.c
endif
endif
diff --git a/tests/test-session-info.c b/tests/test-session-info.c
new file mode 100644
index 0000000..dae3ec6
--- /dev/null
+++ b/tests/test-session-info.c
@@ -0,0 +1,58 @@
+/* test-session-info.c - test session info
+
+ Copyright 2020 Red Hat, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+#include <config.h>
+
+#undef NDEBUG
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "session-info.h"
+
+int main(int argc, char *argv[])
+{
+ int pid, uid, ck_uid;
+
+ pid = (int)getpid();
+
+ struct session_info *session_info = session_info_create(1);
+ if (session_info == NULL) {
+ return 1;
+ }
+
+ char *session = session_info_session_for_pid(session_info, pid);
+ if (session == NULL) {
+ session_info_destroy(session_info);
+ return 2;
+ }
+ ck_uid = session_info_uid_for_session(session_info, session);
+
+ free(session);
+ session_info_destroy(session_info);
+
+ uid = getuid();
+ printf("MAIN: uid is %d, ck_uid is %d\n", uid, ck_uid);
+
+ if (uid != ck_uid) {
+ fprintf(stderr, "MAIN: uid (%d) does not match console-kit uid %d\n", uid, ck_uid);
+ return 3;
+ }
+
+ return 0;
+}
--
2.28.0

View File

@ -1,86 +0,0 @@
From e4a5f60ecbb0248159bc915613359d8f45b49134 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <freddy77@gmail.com>
Date: Sat, 19 Sep 2020 15:13:42 +0100
Subject: [PATCH 02/10] Avoids unchecked file transfer IDs allocation and usage
References: bsc#1173749
Avoid agents allocating file transfers.
The "active_xfers" entries are now inserted when client start sending
files.
Also different agents cannot mess with other agent transfers as a
transfer is bound to a single agent.
This issue was reported by SUSE security team.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Uri Lublin <uril@redhat.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
src/vdagentd/vdagentd.c | 28 ++++++++++++++++++++++------
1 file changed, 22 insertions(+), 6 deletions(-)
diff --git a/src/vdagentd/vdagentd.c b/src/vdagentd/vdagentd.c
index a2b74bb..f15989d 100644
--- a/src/vdagentd/vdagentd.c
+++ b/src/vdagentd/vdagentd.c
@@ -381,9 +381,11 @@ static void do_client_file_xfer(VirtioPort *vport,
s->id, VD_AGENT_FILE_XFER_STATUS_SESSION_LOCKED, NULL, 0);
return;
}
- udscs_write(active_session_conn, VDAGENTD_FILE_XFER_START, 0, 0,
- data, message_header->size);
- return;
+ msg_type = VDAGENTD_FILE_XFER_START;
+ id = s->id;
+ // associate the id with the active connection
+ g_hash_table_insert(active_xfers, GUINT_TO_POINTER(id), active_session_conn);
+ break;
}
case VD_AGENT_FILE_XFER_STATUS: {
VDAgentFileXferStatusMessage *s = (VDAgentFileXferStatusMessage *)data;
@@ -408,6 +410,12 @@ static void do_client_file_xfer(VirtioPort *vport,
return;
}
udscs_write(conn, msg_type, 0, 0, data, message_header->size);
+
+ // client told that transfer is ended, agents too stop the transfer
+ // and release resources
+ if (message_header->type == VD_AGENT_FILE_XFER_STATUS) {
+ g_hash_table_remove(active_xfers, GUINT_TO_POINTER(id));
+ }
}
static void forward_data_to_session_agent(uint32_t type, uint8_t *data, size_t size)
@@ -1012,6 +1020,15 @@ static void do_agent_file_xfer_status(UdscsConnection *conn,
const gchar *log_msg = NULL;
guint data_size = 0;
+ UdscsConnection *task_conn = g_hash_table_lookup(active_xfers, task_id);
+ if (task_conn == NULL || task_conn != conn) {
+ // Protect against misbehaving agent.
+ // Ignore the message, but do not disconnect the agent, to protect against
+ // a misbehaving client that tries to disconnect a good agent
+ // e.g. by sending a new task and immediately cancelling it.
+ return;
+ }
+
/* header->arg1 = file xfer task id, header->arg2 = file xfer status */
switch (header->arg2) {
case VD_AGENT_FILE_XFER_STATUS_NOT_ENOUGH_SPACE:
@@ -1026,10 +1043,9 @@ static void do_agent_file_xfer_status(UdscsConnection *conn,
send_file_xfer_status(virtio_port, log_msg, header->arg1, header->arg2,
data, data_size);
- if (header->arg2 == VD_AGENT_FILE_XFER_STATUS_CAN_SEND_DATA)
- g_hash_table_insert(active_xfers, task_id, conn);
- else
+ if (header->arg2 != VD_AGENT_FILE_XFER_STATUS_CAN_SEND_DATA) {
g_hash_table_remove(active_xfers, task_id);
+ }
}
static void agent_read_complete(UdscsConnection *conn,
--
2.28.0

View File

@ -1,63 +0,0 @@
From 53a5266e90ea09a5522f5ed867150a75c74052c3 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <freddy77@gmail.com>
Date: Fri, 2 Oct 2020 12:27:59 +0100
Subject: [PATCH 03/10] Avoids uncontrolled "active_xfers" allocations
References: bsc#1173749
Limit the number of active file transfers possibly causing DoSes
consuming memory in "active_xfers".
This issue was reported by SUSE security team.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Uri Lublin <uril@redhat.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
src/vdagentd/vdagentd.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/src/vdagentd/vdagentd.c b/src/vdagentd/vdagentd.c
index f15989d..8462889 100644
--- a/src/vdagentd/vdagentd.c
+++ b/src/vdagentd/vdagentd.c
@@ -47,6 +47,14 @@
#define DEFAULT_UINPUT_DEVICE "/dev/uinput"
+// Maximum number of transfers active at any time.
+// Avoid DoS from client.
+// As each transfer could likely end up taking a file descriptor
+// it is good to have a limit less than the number of file descriptors
+// in the process (by default 1024). The daemon do not open file
+// descriptors for the transfers but the agents do.
+#define MAX_ACTIVE_TRANSFERS 128
+
struct agent_data {
char *session;
int width;
@@ -380,6 +388,21 @@ static void do_client_file_xfer(VirtioPort *vport,
"Cancelling client file-xfer request %u",
s->id, VD_AGENT_FILE_XFER_STATUS_SESSION_LOCKED, NULL, 0);
return;
+ } else if (g_hash_table_size(active_xfers) >= MAX_ACTIVE_TRANSFERS) {
+ VDAgentFileXferStatusError error = {
+ GUINT32_TO_LE(VD_AGENT_FILE_XFER_STATUS_ERROR_GLIB_IO),
+ GUINT32_TO_LE(G_IO_ERROR_TOO_MANY_OPEN_FILES),
+ };
+ size_t detail_size = sizeof(error);
+ if (!VD_AGENT_HAS_CAPABILITY(capabilities, capabilities_size,
+ VD_AGENT_CAP_FILE_XFER_DETAILED_ERRORS)) {
+ detail_size = 0;
+ }
+ send_file_xfer_status(vport,
+ "Too many transfers ongoing. "
+ "Cancelling client file-xfer request %u",
+ s->id, VD_AGENT_FILE_XFER_STATUS_ERROR, (void*) &error, detail_size);
+ return;
}
msg_type = VDAGENTD_FILE_XFER_START;
id = s->id;
--
2.28.0

View File

@ -1,53 +0,0 @@
From e0ba1d640e2cac883ed1a0065aaea8764501b07c Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <freddy77@gmail.com>
Date: Sun, 20 Sep 2020 08:05:37 +0100
Subject: [PATCH 04/10] Avoids unlimited agent connections
References: bsc#1173749
Limit the number of agents that can be connected.
Avoids reaching the maximum number of files in a process.
Beside one file descriptor per agent the daemon open just some
other fixed number of files.
This issue was reported by SUSE security team.
Signed-off-by: Frediano Ziglio <freddy77@gmail.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
src/udscs.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/src/udscs.c b/src/udscs.c
index 7c99eed..3df67b3 100644
--- a/src/udscs.c
+++ b/src/udscs.c
@@ -30,6 +30,12 @@
#include "vdagentd-proto-strings.h"
#include "vdagent-connection.h"
+// Maximum number of connected agents.
+// Avoid DoS from agents.
+// As each connection end up taking a file descriptor is good to have a limit
+// less than the number of file descriptors in the process (by default 1024).
+#define MAX_CONNECTED_AGENTS 128
+
struct _UdscsConnection {
VDAgentConnection parent_instance;
int debug;
@@ -254,6 +260,12 @@ static gboolean udscs_server_accept_cb(GSocketService *service,
struct udscs_server *server = user_data;
UdscsConnection *new_conn;
+ /* prevents DoS having too many agents attached */
+ if (g_list_length(server->connections) >= MAX_CONNECTED_AGENTS) {
+ syslog(LOG_ERR, "Too many agents connected");
+ return TRUE;
+ }
+
new_conn = g_object_new(UDSCS_TYPE_CONNECTION, NULL);
new_conn->debug = server->debug;
new_conn->read_callback = server->read_callback;
--
2.28.0

View File

@ -1,147 +0,0 @@
From 9d011f9787e93e3ceb5541ddcb242f5fba9ac2e6 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <freddy77@gmail.com>
Date: Sun, 20 Sep 2020 08:06:16 +0100
Subject: [PATCH 05/10] Avoids user session hijacking
References: bsc#1173749
Avoids user hijacking sessions by reusing PID.
In theory an attacker could:
- open a connection to the daemon;
- fork and exit the process but keep the file descriptor open
(inheriting or duplicating it in forked process);
- force OS to recycle the initial PID, by creating many short lived
processes.
Daemon would detect the old PID as having the new session.
Check the user to avoid such replacements.
This issue was reported by SUSE security team.
Signed-off-by: Frediano Ziglio <freddy77@gmail.com>
Acked-by: Uri Lublin <uril@redhat.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
src/vdagent-connection.c | 13 +++++++------
src/vdagent-connection.h | 13 +++++++++----
src/vdagentd/vdagentd.c | 31 +++++++++++++++++++++++++++----
3 files changed, 43 insertions(+), 14 deletions(-)
diff --git a/src/vdagent-connection.c b/src/vdagent-connection.c
index ff8b88d..8e47e79 100644
--- a/src/vdagent-connection.c
+++ b/src/vdagent-connection.c
@@ -142,24 +142,25 @@ void vdagent_connection_destroy(gpointer p)
g_object_unref(self);
}
-gint vdagent_connection_get_peer_pid(VDAgentConnection *self,
- GError **err)
+PidUid vdagent_connection_get_peer_pid_uid(VDAgentConnection *self,
+ GError **err)
{
VDAgentConnectionPrivate *priv = vdagent_connection_get_instance_private(self);
GSocket *sock;
GCredentials *cred;
- gint pid = -1;
+ PidUid pid_uid = { -1, -1 };
- g_return_val_if_fail(G_IS_SOCKET_CONNECTION(priv->io_stream), pid);
+ g_return_val_if_fail(G_IS_SOCKET_CONNECTION(priv->io_stream), pid_uid);
sock = g_socket_connection_get_socket(G_SOCKET_CONNECTION(priv->io_stream));
cred = g_socket_get_credentials(sock, err);
if (cred) {
- pid = g_credentials_get_unix_pid(cred, err);
+ pid_uid.pid = g_credentials_get_unix_pid(cred, err);
+ pid_uid.uid = g_credentials_get_unix_user(cred, err);
g_object_unref(cred);
}
- return pid;
+ return pid_uid;
}
/* Performs single write operation,
diff --git a/src/vdagent-connection.h b/src/vdagent-connection.h
index 9d5a212..c515a79 100644
--- a/src/vdagent-connection.h
+++ b/src/vdagent-connection.h
@@ -92,10 +92,15 @@ void vdagent_connection_write(VDAgentConnection *self,
/* Synchronously write all queued messages to the output stream. */
void vdagent_connection_flush(VDAgentConnection *self);
-/* Returns the PID of the foreign process connected to the socket
- * or -1 with @err set. */
-gint vdagent_connection_get_peer_pid(VDAgentConnection *self,
- GError **err);
+typedef struct PidUid {
+ pid_t pid;
+ uid_t uid;
+} PidUid;
+
+/* Returns the PID and UID of the foreign process connected to the socket
+ * or fill @err set. */
+PidUid vdagent_connection_get_peer_pid_uid(VDAgentConnection *self,
+ GError **err);
G_END_DECLS
diff --git a/src/vdagentd/vdagentd.c b/src/vdagentd/vdagentd.c
index 8462889..fc22338 100644
--- a/src/vdagentd/vdagentd.c
+++ b/src/vdagentd/vdagentd.c
@@ -952,16 +952,28 @@ static gboolean remove_active_xfers(gpointer key, gpointer value, gpointer conn)
return 0;
}
+/* Check a given process has a given UID */
+static bool check_uid_of_pid(pid_t pid, uid_t uid)
+{
+ char fn[128];
+ struct stat st;
+
+ snprintf(fn, sizeof(fn), "/proc/%u/status", (unsigned) pid);
+ if (stat(fn, &st) != 0 || st.st_uid != uid) {
+ return false;
+ }
+ return true;
+}
+
static void agent_connect(UdscsConnection *conn)
{
struct agent_data *agent_data;
agent_data = g_new0(struct agent_data, 1);
GError *err = NULL;
- gint pid;
if (session_info) {
- pid = vdagent_connection_get_peer_pid(VDAGENT_CONNECTION(conn), &err);
- if (err || pid <= 0) {
+ PidUid pid_uid = vdagent_connection_get_peer_pid_uid(VDAGENT_CONNECTION(conn), &err);
+ if (err || pid_uid.pid <= 0) {
static const char msg[] = "Could not get peer PID, disconnecting new client";
if (err) {
syslog(LOG_ERR, "%s: %s", msg, err->message);
@@ -974,7 +986,18 @@ static void agent_connect(UdscsConnection *conn)
return;
}
- agent_data->session = session_info_session_for_pid(session_info, pid);
+ agent_data->session = session_info_session_for_pid(session_info, pid_uid.pid);
+
+ /* Check that the UID of the PID did not change, this should be done after
+ * computing the session to avoid race conditions.
+ * This can happen as vdagent_connection_get_peer_pid_uid get information
+ * from the time of creating the socket, but the process in the meantime
+ * have been replaced */
+ if (!check_uid_of_pid(pid_uid.pid, pid_uid.uid)) {
+ agent_data_destroy(agent_data);
+ udscs_server_destroy_connection(server, conn);
+ return;
+ }
}
g_object_set_data_full(G_OBJECT(conn), "agent_data", agent_data,
--
2.28.0

View File

@ -1,167 +0,0 @@
From 438aaef5f308b6c0a8bd184db776d415ededcc73 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <freddy77@gmail.com>
Date: Mon, 21 Sep 2020 07:06:09 +0100
Subject: [PATCH 06/10] Better check for sessions
References: bsc#1173749
Do not allow other users to hijack a session checking that
the process is launched by the owner of the session.
Signed-off-by: Frediano Ziglio <freddy77@gmail.com>
Acked-by: Uri Lublin <uril@redhat.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
src/vdagentd/console-kit.c | 67 +++++++++++++++++++++++++++++++
src/vdagentd/dummy-session-info.c | 5 +++
src/vdagentd/session-info.h | 3 ++
src/vdagentd/systemd-login.c | 9 +++++
src/vdagentd/vdagentd.c | 10 ++++-
5 files changed, 93 insertions(+), 1 deletion(-)
diff --git a/src/vdagentd/console-kit.c b/src/vdagentd/console-kit.c
index fcdb0b6..77429bc 100644
--- a/src/vdagentd/console-kit.c
+++ b/src/vdagentd/console-kit.c
@@ -568,3 +568,70 @@ exit:
}
return ret;
}
+
+uid_t session_info_uid_for_session(struct session_info *info, const char *session)
+{
+ DBusError error;
+ DBusMessage *message = NULL;
+ DBusMessage *reply = NULL;
+ uint32_t uid;
+ uid_t ret = -1;
+ const char *err_msg;
+
+ g_return_val_if_fail(info != NULL, ret);
+ g_return_val_if_fail(info->connection != NULL, ret);
+ g_return_val_if_fail(info->active_session != NULL, ret);
+
+ dbus_error_init(&error);
+
+ err_msg = "(console-kit) Unable to create dbus message for GetUnixUser";
+ message = dbus_message_new_method_call(INTERFACE_CONSOLE_KIT,
+ session,
+ INTERFACE_CONSOLE_KIT_SESSION,
+ "GetUnixUser");
+ if (message == NULL) {
+ goto exit;
+ }
+
+ err_msg = "(console-kit) GetUnixUser failed";
+ reply = dbus_connection_send_with_reply_and_block(info->connection,
+ message,
+ -1,
+ &error);
+ if (reply == NULL || dbus_error_is_set(&error)) {
+ goto exit;
+ }
+
+ dbus_error_init(&error);
+ err_msg = "(console-kit) fail to get session-type from reply";
+ if (!dbus_message_get_args(reply,
+ &error,
+ DBUS_TYPE_UINT32, &uid,
+ DBUS_TYPE_INVALID)) {
+ goto exit;
+ }
+
+ if (info->verbose) {
+ syslog(LOG_DEBUG, "(console-kit) unix user is '%u'", (unsigned) uid);
+ }
+
+ err_msg = NULL;
+ ret = uid;
+
+exit:
+ if (err_msg) {
+ if (dbus_error_is_set(&error)) {
+ syslog(LOG_ERR, "%s: %s", err_msg, error.message);
+ dbus_error_free(&error);
+ } else {
+ syslog(LOG_ERR, "%s", err_msg);
+ }
+ }
+ if (reply != NULL) {
+ dbus_message_unref(reply);
+ }
+ if (message != NULL) {
+ dbus_message_unref(message);
+ }
+ return ret;
+}
diff --git a/src/vdagentd/dummy-session-info.c b/src/vdagentd/dummy-session-info.c
index 7fd1eea..137c01a 100644
--- a/src/vdagentd/dummy-session-info.c
+++ b/src/vdagentd/dummy-session-info.c
@@ -55,3 +55,8 @@ gboolean session_info_session_is_locked(G_GNUC_UNUSED struct session_info *si)
{
return FALSE;
}
+
+uid_t session_info_uid_for_session(struct session_info *si, const char *session)
+{
+ return -1;
+}
diff --git a/src/vdagentd/session-info.h b/src/vdagentd/session-info.h
index c8edb86..96aa8d3 100644
--- a/src/vdagentd/session-info.h
+++ b/src/vdagentd/session-info.h
@@ -40,4 +40,7 @@ char *session_info_session_for_pid(struct session_info *ck, uint32_t pid);
gboolean session_info_session_is_locked(struct session_info *si);
gboolean session_info_is_user(struct session_info *si);
+/* get owner of a given session */
+uid_t session_info_uid_for_session(struct session_info *si, const char *session);
+
#endif
diff --git a/src/vdagentd/systemd-login.c b/src/vdagentd/systemd-login.c
index 2d2311c..42ccc5f 100644
--- a/src/vdagentd/systemd-login.c
+++ b/src/vdagentd/systemd-login.c
@@ -394,3 +394,12 @@ gboolean session_info_is_user(struct session_info *si)
return ret;
}
+
+uid_t session_info_uid_for_session(struct session_info *si, const char *session)
+{
+ uid_t ret = -1;
+ if (sd_session_get_uid(session, &ret) < 0) {
+ return -1;
+ }
+ return ret;
+}
diff --git a/src/vdagentd/vdagentd.c b/src/vdagentd/vdagentd.c
index fc22338..59aa523 100644
--- a/src/vdagentd/vdagentd.c
+++ b/src/vdagentd/vdagentd.c
@@ -988,12 +988,20 @@ static void agent_connect(UdscsConnection *conn)
agent_data->session = session_info_session_for_pid(session_info, pid_uid.pid);
+ uid_t session_uid = session_info_uid_for_session(session_info, agent_data->session);
+
/* Check that the UID of the PID did not change, this should be done after
* computing the session to avoid race conditions.
* This can happen as vdagent_connection_get_peer_pid_uid get information
* from the time of creating the socket, but the process in the meantime
* have been replaced */
- if (!check_uid_of_pid(pid_uid.pid, pid_uid.uid)) {
+ if (!check_uid_of_pid(pid_uid.pid, pid_uid.uid) ||
+ /* Check that the user launching the Agent is the same as session one
+ * or root user.
+ * This prevents session hijacks from other users. */
+ (pid_uid.uid != 0 && pid_uid.uid != session_uid)) {
+ syslog(LOG_ERR, "UID mismatch: UID=%u PID=%u suid=%u", pid_uid.uid,
+ pid_uid.pid, session_uid);
agent_data_destroy(agent_data);
udscs_server_destroy_connection(server, conn);
return;
--
2.28.0

View File

@ -1,29 +0,0 @@
From 2e7760735696beab903d14bfe17202d60dd3b043 Mon Sep 17 00:00:00 2001
From: Uri Lublin <uril@redhat.com>
Date: Wed, 7 Oct 2020 19:34:57 +0300
Subject: [PATCH 08/10] cleanup active_xfers when the client disconnects
References: bsc#1173749
Signed-off-by: Uri Lublin <uril@redhat.com>
Acked-by: Frediano Ziglio <fziglio@redhat.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
src/vdagentd/vdagentd.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/vdagentd/vdagentd.c b/src/vdagentd/vdagentd.c
index 92885b5..8437779 100644
--- a/src/vdagentd/vdagentd.c
+++ b/src/vdagentd/vdagentd.c
@@ -168,6 +168,7 @@ static void send_capabilities(VirtioPort *vport,
static void do_client_disconnect(void)
{
+ g_hash_table_remove_all(active_xfers);
if (client_connected) {
udscs_server_write_all(server, VDAGENTD_CLIENT_DISCONNECTED, 0, 0,
NULL, 0);
--
2.28.0

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2e6b7222675ee19ea38c52165abe4d836c2ac5d5bf902d4dfca13da1ec143359
size 152510

Binary file not shown.

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:fd575fd23c54fa5a7ff5d66069638510a669c332c5f86082cfb39a7d03a31259
size 164103

Binary file not shown.

View File

@ -1,3 +1,35 @@
-------------------------------------------------------------------
Fri Jan 15 16:51:11 UTC 2021 - Bruce Rogers <brogers@suse.com>
- Update to version 0.21.0
* Changes include:
* Security fixes:
CVE-2020-25650, CVE-2020-25651, CVE-2020-25652, CVE-2020-25653
* Fix shutdown issue due to incompatible thread/fork uses with GLib
* Fix mouse pointer issues under Wayland
* Fix a crash when running without dbus (e.g: within containers)
* !9 - Introduce optional GTK4 support for monitor management
* !13 - Enable copying files from client using webdav
* Bump spice-protocol dependency to v0.14.3
* Drop all patches, since they are in base tarball now:
Add-a-test-for-session_info.patch
Avoids-unchecked-file-transfer-IDs-allocation-and-us.patch
Avoids-uncontrolled-active_xfers-allocations.patch
Avoids-unlimited-agent-connections.patch
Avoids-user-session-hijacking.patch
Better-check-for-sessions.patch
cleanup-active_xfers-when-the-client-disconnects.patch
systemd-login-Avoid-a-crash-on-container.patch
vdagent-connection-Pass-err-to-g_credentials_get_uni.patch
vdagentd-Automatically-release-agent_data.patch
vdagentd-Avoid-calling-chmod.patch
vdagentd-Better-check-for-vdagent_connection_get_pee.patch
vdagentd-Limit-number-of-agents-per-session-to-1.patch
vdagentd-Use-bool-for-agent_owns_clipboard-and-clien.patch
vdagentd-do-not-allow-to-use-an-already-used-file-xf.patch
vdagentd-init-static-uinput-before-fork.patch
vdagentd-work-around-GLib-s-fork-issues.patch
-------------------------------------------------------------------
Mon Nov 2 23:11:32 UTC 2020 - Bruce Rogers <brogers@suse.com>

View File

@ -1,386 +1,37 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: SKS 1.1.6
Comment: Hostname: pgpkeys.co.uk
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
gUzffGn8kHVtYCx64TMqLiI3TZmJB0Nh1PfTsME=
=DMP2
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
aA==
=I6a5
-----END PGP PUBLIC KEY BLOCK-----

View File

@ -1,7 +1,7 @@
#
# spec file for package spice-vdagent
#
# Copyright (c) 2020 SUSE LLC
# Copyright (c) 2021 SUSE LLC
# Copyright (c) 2014 B1 Systems GmbH, Vohburg, Germany.
#
# All modifications and additions to the file contributed by third parties
@ -21,7 +21,7 @@
%bcond_with session_info_test
Name: spice-vdagent
Version: 0.20.0
Version: 0.21.0
Release: 0
Summary: Agent for Spice guests
License: GPL-3.0-or-later
@ -30,23 +30,6 @@ URL: http://spice-space.org/
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
Patch1: vdagentd-work-around-GLib-s-fork-issues.patch
Patch2: vdagentd-init-static-uinput-before-fork.patch
Patch3: systemd-login-Avoid-a-crash-on-container.patch
Patch4: vdagentd-Use-bool-for-agent_owns_clipboard-and-clien.patch
Patch5: vdagentd-Automatically-release-agent_data.patch
Patch6: vdagent-connection-Pass-err-to-g_credentials_get_uni.patch
Patch7: vdagentd-Better-check-for-vdagent_connection_get_pee.patch
Patch8: vdagentd-Avoid-calling-chmod.patch
Patch9: Avoids-unchecked-file-transfer-IDs-allocation-and-us.patch
Patch10: Avoids-uncontrolled-active_xfers-allocations.patch
Patch11: Avoids-unlimited-agent-connections.patch
Patch12: Avoids-user-session-hijacking.patch
Patch13: Better-check-for-sessions.patch
Patch14: vdagentd-Limit-number-of-agents-per-session-to-1.patch
Patch15: cleanup-active_xfers-when-the-client-disconnects.patch
Patch16: vdagentd-do-not-allow-to-use-an-already-used-file-xf.patch
Patch17: Add-a-test-for-session_info.patch
BuildRequires: alsa-devel >= 1.0.22
BuildRequires: desktop-file-utils
@ -62,7 +45,7 @@ BuildRequires: pkgconfig(gobject-2.0) >= 2.50
BuildRequires: pkgconfig(gtk+-3.0) >= 3.22
BuildRequires: pkgconfig(libdrm)
BuildRequires: pkgconfig(libsystemd)
BuildRequires: pkgconfig(spice-protocol) >= 0.14.1
BuildRequires: pkgconfig(spice-protocol) >= 0.14.3
BuildRequires: pkgconfig(systemd)
BuildRequires: pkgconfig(udev)
Supplements: modalias(xorg-x11-server:virtio:d00000003v*)
@ -82,25 +65,6 @@ Features:
%prep
%setup -q
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%patch13 -p1
%patch14 -p1
%patch15 -p1
%patch16 -p1
%if %{with session_info_test}
%patch17 -p1
%endif
%build
autoreconf
@ -110,7 +74,9 @@ autoreconf
make %{?_smp_mflags} V=2
%check
%if %{with session_info_test}
make check V=2
%endif
%install
make install DESTDIR=%{buildroot} V=2

View File

@ -1,36 +0,0 @@
From 5654f4d2f90f95efd1f0ca70b438a3ab81022d15 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Thu, 26 Mar 2020 11:31:50 +0000
Subject: [PATCH] systemd-login: Avoid a crash on container
References: bsc#1173749
On containers dbus could be not running.
In this case dbus.system_connection is NULL and calling
dbus_connection_close on it will cause a crash.
This happens also under Gitlab CI.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Victor Toso <victortoso@redhat.com>
---
src/vdagentd/systemd-login.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/vdagentd/systemd-login.c b/src/vdagentd/systemd-login.c
index 0b8f3c1..2d2311c 100644
--- a/src/vdagentd/systemd-login.c
+++ b/src/vdagentd/systemd-login.c
@@ -250,7 +250,9 @@ void session_info_destroy(struct session_info *si)
return;
si_dbus_match_remove(si);
- dbus_connection_close(si->dbus.system_connection);
+ if (si->dbus.system_connection) {
+ dbus_connection_close(si->dbus.system_connection);
+ }
sd_login_monitor_unref(si->mon);
g_free(si->session);
g_free(si);
--
2.29.0

View File

@ -1,37 +0,0 @@
From b894975bedb2b9e01385261183db19f7d0642292 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <freddy77@gmail.com>
Date: Tue, 22 Sep 2020 11:45:56 +0100
Subject: [PATCH] vdagent-connection: Pass "err" to g_credentials_get_unix_pid
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Git-commit: b894975bedb2b9e01385261183db19f7d0642292
References: bsc#1173749
Allows to return detailed information if g_credentials_get_unix_pid
fails.
Signed-off-by: Frediano Ziglio <freddy77@gmail.com>
Acked-by: Julien Ropé <jrope@redhat.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
src/vdagent-connection.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/vdagent-connection.c b/src/vdagent-connection.c
index ede784b..ff8b88d 100644
--- a/src/vdagent-connection.c
+++ b/src/vdagent-connection.c
@@ -155,7 +155,7 @@ gint vdagent_connection_get_peer_pid(VDAgentConnection *self,
sock = g_socket_connection_get_socket(G_SOCKET_CONNECTION(priv->io_stream));
cred = g_socket_get_credentials(sock, err);
if (cred) {
- pid = g_credentials_get_unix_pid(cred, NULL);
+ pid = g_credentials_get_unix_pid(cred, err);
g_object_unref(cred);
}
--
2.29.0

View File

@ -1,75 +0,0 @@
From b4479eb9b0a30cf99806a17bcbdc468828727e89 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <freddy77@gmail.com>
Date: Mon, 21 Sep 2020 07:00:39 +0100
Subject: [PATCH] vdagentd: Automatically release "agent_data"
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Git-commit: b4479eb9b0a30cf99806a17bcbdc468828727e89
References: bsc#1173749
It's not guaranteed that agent_disconnect will release the connection
so avoid to have a dandling pointer.
Signed-off-by: Frediano Ziglio <freddy77@gmail.com>
Acked-by: Jakub Janků <jjanku@redhat.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
src/vdagentd/vdagentd.c | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/src/vdagentd/vdagentd.c b/src/vdagentd/vdagentd.c
index 54e05c3..cd6340e 100644
--- a/src/vdagentd/vdagentd.c
+++ b/src/vdagentd/vdagentd.c
@@ -86,6 +86,13 @@ static uint32_t clipboard_serial[256];
static GMainLoop *loop;
+static void agent_data_destroy(struct agent_data *agent_data)
+{
+ g_free(agent_data->session);
+ g_free(agent_data->screen_info);
+ g_free(agent_data);
+}
+
static void vdagentd_quit(gint exit_code)
{
retval = exit_code;
@@ -930,7 +937,7 @@ static void agent_connect(UdscsConnection *conn)
syslog(LOG_ERR, "Could not get peer PID, disconnecting new client: %s",
err->message);
g_error_free(err);
- g_free(agent_data);
+ agent_data_destroy(agent_data);
udscs_server_destroy_connection(server, conn);
return;
}
@@ -938,7 +945,8 @@ static void agent_connect(UdscsConnection *conn)
agent_data->session = session_info_session_for_pid(session_info, pid);
}
- g_object_set_data(G_OBJECT(conn), "agent_data", agent_data);
+ g_object_set_data_full(G_OBJECT(conn), "agent_data", agent_data,
+ (GDestroyNotify) agent_data_destroy);
udscs_write(conn, VDAGENTD_VERSION, 0, 0,
(uint8_t *)VERSION, strlen(VERSION) + 1);
update_active_session_connection(conn);
@@ -951,13 +959,8 @@ static void agent_connect(UdscsConnection *conn)
static void agent_disconnect(VDAgentConnection *conn, GError *err)
{
- struct agent_data *agent_data = g_object_get_data(G_OBJECT(conn), "agent_data");
-
g_hash_table_foreach_remove(active_xfers, remove_active_xfers, conn);
- g_clear_pointer(&agent_data->session, g_free);
- g_free(agent_data->screen_info);
- g_free(agent_data);
if (err) {
syslog(LOG_ERR, "%s", err->message);
g_error_free(err);
--
2.29.0

View File

@ -1,52 +0,0 @@
From f5f4506f6cb25bfd556f815565090a57296771ee Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <freddy77@gmail.com>
Date: Thu, 24 Sep 2020 12:13:24 +0100
Subject: [PATCH 01/10] vdagentd: Avoid calling chmod
References: bsc#1173749
Create the socket with the right permissions using umask.
This also prevents possible symlink exploitation in case socket
path is not secure.
Signed-off-by: Frediano Ziglio <freddy77@gmail.com>
Acked-by: Uri Lublin <uril@redhat.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
src/vdagentd/vdagentd.c | 12 ++----------
1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/src/vdagentd/vdagentd.c b/src/vdagentd/vdagentd.c
index dca6980..a2b74bb 100644
--- a/src/vdagentd/vdagentd.c
+++ b/src/vdagentd/vdagentd.c
@@ -1208,7 +1208,9 @@ int main(int argc, char *argv[])
/* systemd socket activation not enabled, create our own */
#endif /* WITH_SYSTEMD_SOCKET_ACTIVATION */
{
+ mode_t mode = umask(0111);
udscs_server_listen_to_address(server, vdagentd_socket, &err);
+ umask(mode);
}
if (err) {
@@ -1219,16 +1221,6 @@ int main(int argc, char *argv[])
return 1;
}
- /* no need to set permissions on a socket that was provided by systemd */
- if (own_socket) {
- if (chmod(vdagentd_socket, 0666)) {
- syslog(LOG_CRIT, "Fatal could not change permissions on %s: %m",
- vdagentd_socket);
- udscs_destroy_server(server);
- return 1;
- }
- }
-
#ifdef WITH_STATIC_UINPUT
uinput = vdagentd_uinput_create(uinput_device, 1024, 768, NULL, 0,
debug > 1, uinput_fake);
--
2.28.0

View File

@ -1,48 +0,0 @@
From 7e924bcbf0bb6b300c6518499c05e87cea13ac51 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <freddy77@gmail.com>
Date: Mon, 21 Sep 2020 16:42:26 +0100
Subject: [PATCH] vdagentd: Better check for vdagent_connection_get_peer_pid
results
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Git-commit: 7e924bcbf0bb6b300c6518499c05e87cea13ac51
References: bsc#1173749
The function can return -1 and leave "err" to NULL in some cases,
do not check only for "err".
Signed-off-by: Frediano Ziglio <freddy77@gmail.com>
Acked-by: Julien Ropé <jrope@redhat.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
src/vdagentd/vdagentd.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/src/vdagentd/vdagentd.c b/src/vdagentd/vdagentd.c
index cd6340e..560f2ce 100644
--- a/src/vdagentd/vdagentd.c
+++ b/src/vdagentd/vdagentd.c
@@ -933,10 +933,14 @@ static void agent_connect(UdscsConnection *conn)
if (session_info) {
pid = vdagent_connection_get_peer_pid(VDAGENT_CONNECTION(conn), &err);
- if (err) {
- syslog(LOG_ERR, "Could not get peer PID, disconnecting new client: %s",
- err->message);
- g_error_free(err);
+ if (err || pid <= 0) {
+ static const char msg[] = "Could not get peer PID, disconnecting new client";
+ if (err) {
+ syslog(LOG_ERR, "%s: %s", msg, err->message);
+ g_error_free(err);
+ } else {
+ syslog(LOG_ERR, "%s", msg);
+ }
agent_data_destroy(agent_data);
udscs_server_destroy_connection(server, conn);
return;
--
2.29.0

View File

@ -1,59 +0,0 @@
From cb15e7c8052cae75272bbd0d6a5cac37efa360f8 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <freddy77@gmail.com>
Date: Thu, 24 Sep 2020 12:13:44 +0100
Subject: [PATCH 07/10] vdagentd: Limit number of agents per session to 1
References: bsc#1173749
Signed-off-by: Frediano Ziglio <freddy77@gmail.com>
Acked-by: Uri Lublin <uril@redhat.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
src/vdagentd/vdagentd.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/src/vdagentd/vdagentd.c b/src/vdagentd/vdagentd.c
index 59aa523..92885b5 100644
--- a/src/vdagentd/vdagentd.c
+++ b/src/vdagentd/vdagentd.c
@@ -952,6 +952,20 @@ static gboolean remove_active_xfers(gpointer key, gpointer value, gpointer conn)
return 0;
}
+/* Check if this connection matches the passed session */
+static int connection_matches_session(UdscsConnection *conn, void *priv)
+{
+ const char *session = priv;
+ const struct agent_data *agent_data = g_object_get_data(G_OBJECT(conn), "agent_data");
+
+ if (!agent_data || !agent_data->session ||
+ strcmp(agent_data->session, session) != 0) {
+ return 0;
+ }
+
+ return 1;
+}
+
/* Check a given process has a given UID */
static bool check_uid_of_pid(pid_t pid, uid_t uid)
{
@@ -1006,6 +1020,16 @@ static void agent_connect(UdscsConnection *conn)
udscs_server_destroy_connection(server, conn);
return;
}
+
+ // Check there are no other connection for this session
+ // Note that "conn" is not counted as "agent_data" is still not attached to it
+ if (udscs_server_for_all_clients(server, connection_matches_session,
+ agent_data->session) > 0) {
+ syslog(LOG_ERR, "An agent is already connected for this session");
+ agent_data_destroy(agent_data);
+ udscs_server_destroy_connection(server, conn);
+ return;
+ }
}
g_object_set_data_full(G_OBJECT(conn), "agent_data", agent_data,
--
2.28.0

View File

@ -1,111 +0,0 @@
From 7e37b05774fb5aed1978e28e3201fc8d28498df6 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <freddy77@gmail.com>
Date: Mon, 21 Sep 2020 06:53:45 +0100
Subject: [PATCH] vdagentd: Use bool for agent_owns_clipboard and
client_connected
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Git-commit: 7e37b05774fb5aed1978e28e3201fc8d28498df6
References: bsc#1173749
More clear (instaed of 0/1) and save some bytes.
Signed-off-by: Frediano Ziglio <freddy77@gmail.com>
Acked-by: Jakub Janků <jjanku@redhat.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
src/vdagentd/vdagentd.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/src/vdagentd/vdagentd.c b/src/vdagentd/vdagentd.c
index 753c9bf..051de74 100644
--- a/src/vdagentd/vdagentd.c
+++ b/src/vdagentd/vdagentd.c
@@ -23,6 +23,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
@@ -77,9 +78,9 @@ static int capabilities_size = 0;
static const char *active_session = NULL;
static unsigned int session_count = 0;
static UdscsConnection *active_session_conn = NULL;
-static int agent_owns_clipboard[256] = { 0, };
+static bool agent_owns_clipboard[256] = { false, };
static int retval = 0;
-static int client_connected = 0;
+static bool client_connected = false;
static int max_clipboard = -1;
static uint32_t clipboard_serial[256];
@@ -155,7 +156,7 @@ static void do_client_disconnect(void)
if (client_connected) {
udscs_server_write_all(server, VDAGENTD_CLIENT_DISCONNECTED, 0, 0,
NULL, 0);
- client_connected = 0;
+ client_connected = false;
}
}
@@ -239,7 +240,7 @@ static void do_client_capabilities(VirtioPort *vport,
do_client_disconnect();
if (debug)
syslog(LOG_DEBUG, "New client connected");
- client_connected = 1;
+ client_connected = true;
memset(clipboard_serial, 0, sizeof(clipboard_serial));
send_capabilities(vport, 0);
}
@@ -286,7 +287,7 @@ static void do_client_clipboard(VirtioPort *vport,
}
msg_type = VDAGENTD_CLIPBOARD_GRAB;
- agent_owns_clipboard[selection] = 0;
+ agent_owns_clipboard[selection] = false;
break;
case VD_AGENT_CLIPBOARD_REQUEST: {
VDAgentClipboardRequest *req = (VDAgentClipboardRequest *)data;
@@ -624,7 +625,7 @@ static void virtio_port_read_complete(
static void virtio_port_error_cb(VDAgentConnection *conn, GError *err)
{
- gboolean old_client_connected = client_connected;
+ bool old_client_connected = client_connected;
syslog(LOG_CRIT, "AIIEEE lost spice client connection, reconnecting (err: %s)",
err ? err->message : "");
g_clear_error(&err);
@@ -717,7 +718,7 @@ static void do_agent_clipboard(UdscsConnection *conn,
switch (header->type) {
case VDAGENTD_CLIPBOARD_GRAB:
msg_type = VD_AGENT_CLIPBOARD_GRAB;
- agent_owns_clipboard[selection] = 1;
+ agent_owns_clipboard[selection] = true;
break;
case VDAGENTD_CLIPBOARD_REQUEST:
msg_type = VD_AGENT_CLIPBOARD_REQUEST;
@@ -737,7 +738,7 @@ static void do_agent_clipboard(UdscsConnection *conn,
case VDAGENTD_CLIPBOARD_RELEASE:
msg_type = VD_AGENT_CLIPBOARD_RELEASE;
size = 0;
- agent_owns_clipboard[selection] = 0;
+ agent_owns_clipboard[selection] = false;
break;
default:
syslog(LOG_WARNING, "unexpected clipboard message type");
@@ -851,7 +852,7 @@ static void release_clipboards(void)
vdagent_virtio_port_write(virtio_port, VDP_CLIENT_PORT,
VD_AGENT_CLIPBOARD_RELEASE, 0, &sel, 1);
}
- agent_owns_clipboard[sel] = 0;
+ agent_owns_clipboard[sel] = false;
}
}
--
2.29.0

View File

@ -1,36 +0,0 @@
From c120b431b7ccda0a0a1076e31f2f1367dbee656f Mon Sep 17 00:00:00 2001
From: Uri Lublin <uril@redhat.com>
Date: Sun, 11 Oct 2020 20:59:17 +0300
Subject: [PATCH 09/10] vdagentd: do not allow to use an already used file-xfer
id
References: bsc#1173749
Signed-off-by: Uri Lublin <uril@redhat.com>
Acked-by: Frediano Ziglio <fziglio@redhat.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
src/vdagentd/vdagentd.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/vdagentd/vdagentd.c b/src/vdagentd/vdagentd.c
index 8437779..78378aa 100644
--- a/src/vdagentd/vdagentd.c
+++ b/src/vdagentd/vdagentd.c
@@ -404,6 +404,13 @@ static void do_client_file_xfer(VirtioPort *vport,
"Cancelling client file-xfer request %u",
s->id, VD_AGENT_FILE_XFER_STATUS_ERROR, (void*) &error, detail_size);
return;
+ } else if (g_hash_table_lookup(active_xfers, GUINT_TO_POINTER(s->id)) != NULL) {
+ // id is already used -- client is confused
+ send_file_xfer_status(vport,
+ "File transfer ID is already used. "
+ "Cancelling client file-xfer request %u",
+ s->id, VD_AGENT_FILE_XFER_STATUS_ERROR, NULL, 0);
+ return;
}
msg_type = VDAGENTD_FILE_XFER_START;
id = s->id;
--
2.28.0

View File

@ -1,48 +0,0 @@
From 7b0435ef66af088c1a1be20b6bc6b0fcb76e4e1a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Jank=C5=AF?= <jjanku@redhat.com>
Date: Fri, 20 Mar 2020 17:18:32 +0100
Subject: [PATCH] vdagentd: init static uinput before fork
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Git-commit: 7b0435ef66af088c1a1be20b6bc6b0fcb76e4e1a
Otherwise the caller doesn't know that the init failed
because we're returning 0 in the parent and 1 in child.
Signed-off-by: Jakub Janků <jjanku@redhat.com>
Acked-by: Frediano Ziglio <fziglio@redhat.com>
[BR: BSC#1166895]
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
src/vdagentd/vdagentd.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/vdagentd/vdagentd.c b/src/vdagentd/vdagentd.c
index 1b63ec8..753c9bf 100644
--- a/src/vdagentd/vdagentd.c
+++ b/src/vdagentd/vdagentd.c
@@ -1224,9 +1224,6 @@ int main(int argc, char *argv[])
}
}
- if (do_daemonize)
- daemonize();
-
#ifdef WITH_STATIC_UINPUT
uinput = vdagentd_uinput_create(uinput_device, 1024, 768, NULL, 0,
debug > 1, uinput_fake);
@@ -1236,6 +1233,9 @@ int main(int argc, char *argv[])
}
#endif
+ if (do_daemonize)
+ daemonize();
+
g_unix_signal_add(SIGINT, signal_handler, NULL);
g_unix_signal_add(SIGHUP, signal_handler, NULL);
g_unix_signal_add(SIGTERM, signal_handler, NULL);
--
2.25.1

View File

@ -1,107 +0,0 @@
From 9b8c0ebb9fb573e6ce3c5416371509f416503d0c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Jank=C5=AF?= <jjanku@redhat.com>
Date: Fri, 20 Mar 2020 10:36:03 +0100
Subject: [PATCH] vdagentd: work around GLib's fork issues
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Git-commit: 9b8c0ebb9fb573e6ce3c5416371509f416503d0c
Creating threads is not compatible with forking as only the thread
that calls fork() is inherited.
Handlers registered with g_unix_signal_add() create a thread so
move these calls after fork.
Also call g_socket_service_start() after fork to avoid creation of
new threads before it is necessary.
Fixes: https://gitlab.freedesktop.org/spice/linux/vd_agent/issues/18
Also see: https://gitlab.gnome.org/GNOME/glib/issues/2073
Signed-off-by: Jakub Janků <jjanku@redhat.com>
Acked-by: Frediano Ziglio <fziglio@redhat.com>
[BR: BSC#1166895]
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
src/udscs.c | 6 ++++++
src/udscs.h | 2 ++
src/vdagentd/vdagentd.c | 9 +++++----
3 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/src/udscs.c b/src/udscs.c
index 4de75f8..7c99eed 100644
--- a/src/udscs.c
+++ b/src/udscs.c
@@ -186,6 +186,7 @@ struct udscs_server *udscs_server_new(
server->read_callback = read_callback;
server->error_cb = error_cb;
server->service = g_socket_service_new();
+ g_socket_service_stop(server->service);
g_signal_connect(server->service, "incoming",
G_CALLBACK(udscs_server_accept_cb), server);
@@ -223,6 +224,11 @@ void udscs_server_listen_to_address(struct udscs_server *server,
g_object_unref(sock_addr);
}
+void udscs_server_start(struct udscs_server *server)
+{
+ g_socket_service_start(server->service);
+}
+
void udscs_server_destroy_connection(struct udscs_server *server,
UdscsConnection *conn)
{
diff --git a/src/udscs.h b/src/udscs.h
index 45ebd3f..4f7ea36 100644
--- a/src/udscs.h
+++ b/src/udscs.h
@@ -98,6 +98,8 @@ void udscs_server_listen_to_address(struct udscs_server *server,
const gchar *addr,
GError **err);
+void udscs_server_start(struct udscs_server *server);
+
void udscs_server_destroy_connection(struct udscs_server *server,
UdscsConnection *conn);
diff --git a/src/vdagentd/vdagentd.c b/src/vdagentd/vdagentd.c
index cfd0a51..1b63ec8 100644
--- a/src/vdagentd/vdagentd.c
+++ b/src/vdagentd/vdagentd.c
@@ -1184,10 +1184,6 @@ int main(int argc, char *argv[])
uinput_device = g_strdup(DEFAULT_UINPUT_DEVICE);
}
- g_unix_signal_add(SIGINT, signal_handler, NULL);
- g_unix_signal_add(SIGHUP, signal_handler, NULL);
- g_unix_signal_add(SIGTERM, signal_handler, NULL);
-
openlog("spice-vdagentd", do_daemonize ? 0 : LOG_PERROR, LOG_USER);
/* Setup communication with vdagent process(es) */
@@ -1240,6 +1236,10 @@ int main(int argc, char *argv[])
}
#endif
+ g_unix_signal_add(SIGINT, signal_handler, NULL);
+ g_unix_signal_add(SIGHUP, signal_handler, NULL);
+ g_unix_signal_add(SIGTERM, signal_handler, NULL);
+
if (want_session_info)
session_info = session_info_create(debug);
if (session_info) {
@@ -1252,6 +1252,7 @@ int main(int argc, char *argv[])
active_xfers = g_hash_table_new(g_direct_hash, g_direct_equal);
+ udscs_server_start(server);
loop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(loop);
--
2.25.1