Commit 948e97de authored by Leo's avatar Leo Committed by Natanael Copa

main/gvfs: backport fixes for a few CVEs

- CVE-2019-12795
- CVE-2019-12449
- CVE-2019-12447
- CVE-2019-12448
parent b6c78e19
......@@ -2,7 +2,7 @@
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
pkgname=gvfs
pkgver=1.34.1
pkgrel=0
pkgrel=1
pkgdesc="Backends for the gio framework in GLib"
url="http://ftp.gnome.org/pub/gnome/sources/gvfs/${pkgver%.*}/"
arch="all"
......@@ -25,7 +25,19 @@ subpackages="$pkgname-dev $pkgname-doc $pkgname-lang
$pkgname-smb
$pkgname-mtp
"
source="https://download.gnome.org/sources/gvfs/${pkgver%.*}/gvfs-$pkgver.tar.xz"
source="https://download.gnome.org/sources/gvfs/${pkgver%.*}/gvfs-$pkgver.tar.xz
CVE-2019-12448.patch
CVE-2019-12795.patch
CVE-2019-12449.patch
CVE-2019-12447.patch
"
# secfixes:
# 1.34.1-r1:
# - CVE-2019-12447
# - CVE-2019-12448
# - CVE-2019-12795
# - CVE-2019-12449
builddir="$srcdir/$pkgname-$pkgver"
build() {
......@@ -145,4 +157,8 @@ dav() {
# pkgdesc="AFC support for gvfs"
#}
sha512sums="383f20c3dad1ff833f1d14466f215c7183459c0ed18d842fd09a68061e09814f2a4e33d574a0bf62bc9b6f5023721d03461eaaed86e840513f7e115662af91b6 gvfs-1.34.1.tar.xz"
sha512sums="383f20c3dad1ff833f1d14466f215c7183459c0ed18d842fd09a68061e09814f2a4e33d574a0bf62bc9b6f5023721d03461eaaed86e840513f7e115662af91b6 gvfs-1.34.1.tar.xz
a4daaf8e7f6ece24fd0fdbe0ca4cfa5a5d36189249c36779a09f6ab9033b0fcd1db47d1aaa0b5dd4b14c444cc3763d9e25e0580fb2e2021aa42bc5e6d1eef1ec CVE-2019-12448.patch
4d381da1e164c1205a4fea19b235163e22c8d1d65ea7ffb130df9c8c76395f20c4b5879111e4ba6d4f54cadbfb084b8c82434ab698e39e6ab2d1e5e0b5ab93ac CVE-2019-12795.patch
15c7c46f74049b539ae5d76d03f22b7efda39f0424b13582afca1e82ca90a03bb372ef8c42afdd21f257a46aae8c6c709715bdd76cb5aa4fdf13e4c1f58fa012 CVE-2019-12449.patch
02c4e94d8eef1f69b6d45ddbbbfa22ff9452238251c8bd3b8ae5cbbdc3a7c1fcde4612f96851dfff55f276bcf84f5b82561b06a18c1d9e20033457e72987013d CVE-2019-12447.patch"
diff --git a/daemon/gvfsbackendadmin.c b/daemon/gvfsbackendadmin.c
index d67353d..daa6df9 100644
--- a/daemon/gvfsbackendadmin.c
+++ b/daemon/gvfsbackendadmin.c
@@ -907,7 +907,8 @@ g_vfs_backend_admin_init (GVfsBackendAdmin *self)
#define REQUIRED_CAPS (CAP_TO_MASK(CAP_FOWNER) | \
CAP_TO_MASK(CAP_DAC_OVERRIDE) | \
- CAP_TO_MASK(CAP_DAC_READ_SEARCH))
+ CAP_TO_MASK(CAP_DAC_READ_SEARCH) | \
+ CAP_TO_MASK(CAP_CHOWN))
static void
acquire_caps (uid_t uid)
@@ -919,10 +920,15 @@ acquire_caps (uid_t uid)
if (prctl (PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0)
g_error ("prctl(PR_SET_KEEPCAPS) failed");
- /* Drop root uid, but retain the required permitted caps */
- if (setuid (uid) < 0)
+ /* Set euid to user to make dbus work */
+ if (seteuid (uid) < 0)
g_error ("unable to drop privs");
+ /* Set fsuid to still behave like root when working with files */
+ setfsuid (0);
+ if (setfsuid (-1) != 0)
+ g_error ("setfsuid failed");
+
memset (&hdr, 0, sizeof(hdr));
hdr.version = _LINUX_CAPABILITY_VERSION;
From 5cd76d627f4d1982b6e77a0e271ef9301732d09e Mon Sep 17 00:00:00 2001
From: Ondrej Holy <oholy@redhat.com>
Date: Thu, 23 May 2019 10:24:36 +0200
Subject: [PATCH] admin: Add query_info_on_read/write functionality
Admin backend doesn't implement query_info_on_read/write which might
potentially lead to some race conditions which aren't really wanted
especially in case of admin backend. Let's add this missing functionality.
---
daemon/gvfsbackendadmin.c | 79 +++++++++++++++++++++++++++++++++------
1 file changed, 67 insertions(+), 12 deletions(-)
diff --git a/daemon/gvfsbackendadmin.c b/daemon/gvfsbackendadmin.c
index 65a979e7..23d16f16 100644
--- a/daemon/gvfsbackendadmin.c
+++ b/daemon/gvfsbackendadmin.c
@@ -42,6 +42,8 @@
#include "gvfsjobopenforwrite.h"
#include "gvfsjobqueryattributes.h"
#include "gvfsjobqueryinfo.h"
+#include "gvfsjobqueryinforead.h"
+#include "gvfsjobqueryinfowrite.h"
#include "gvfsjobread.h"
#include "gvfsjobseekread.h"
#include "gvfsjobseekwrite.h"
@@ -155,6 +157,19 @@ complete_job (GVfsJob *job,
g_vfs_job_succeeded (job);
}
+static void
+fix_file_info (GFileInfo *info)
+{
+ /* Override read/write flags, since the above call will use access()
+ * to determine permissions, which does not honor our privileged
+ * capabilities.
+ */
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ, TRUE);
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, TRUE);
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE, TRUE);
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME, TRUE);
+}
+
static void
do_query_info (GVfsBackend *backend,
GVfsJobQueryInfo *query_info_job,
@@ -180,19 +195,57 @@ do_query_info (GVfsBackend *backend,
if (error != NULL)
goto out;
- /* Override read/write flags, since the above call will use access()
- * to determine permissions, which does not honor our privileged
- * capabilities.
- */
- g_file_info_set_attribute_boolean (real_info,
- G_FILE_ATTRIBUTE_ACCESS_CAN_READ, TRUE);
- g_file_info_set_attribute_boolean (real_info,
- G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, TRUE);
- g_file_info_set_attribute_boolean (real_info,
- G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE, TRUE);
- g_file_info_set_attribute_boolean (real_info,
- G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME, TRUE);
+ fix_file_info (real_info);
+ g_file_info_copy_into (real_info, info);
+ g_object_unref (real_info);
+
+ out:
+ complete_job (job, error);
+}
+
+static void
+do_query_info_on_read (GVfsBackend *backend,
+ GVfsJobQueryInfoRead *query_info_job,
+ GVfsBackendHandle handle,
+ GFileInfo *info,
+ GFileAttributeMatcher *matcher)
+{
+ GVfsJob *job = G_VFS_JOB (query_info_job);
+ GFileInputStream *stream = handle;
+ GError *error = NULL;
+ GFileInfo *real_info;
+
+ real_info = g_file_input_stream_query_info (stream, query_info_job->attributes,
+ job->cancellable, &error);
+ if (error != NULL)
+ goto out;
+
+ fix_file_info (real_info);
+ g_file_info_copy_into (real_info, info);
+ g_object_unref (real_info);
+
+ out:
+ complete_job (job, error);
+}
+
+static void
+do_query_info_on_write (GVfsBackend *backend,
+ GVfsJobQueryInfoWrite *query_info_job,
+ GVfsBackendHandle handle,
+ GFileInfo *info,
+ GFileAttributeMatcher *matcher)
+{
+ GVfsJob *job = G_VFS_JOB (query_info_job);
+ GFileOutputStream *stream = handle;
+ GError *error = NULL;
+ GFileInfo *real_info;
+
+ real_info = g_file_output_stream_query_info (stream, query_info_job->attributes,
+ job->cancellable, &error);
+ if (error != NULL)
+ goto out;
+ fix_file_info (real_info);
g_file_info_copy_into (real_info, info);
g_object_unref (real_info);
@@ -868,6 +921,8 @@ g_vfs_backend_admin_class_init (GVfsBackendAdminClass * klass)
backend_class->mount = do_mount;
backend_class->open_for_read = do_open_for_read;
backend_class->query_info = do_query_info;
+ backend_class->query_info_on_read = do_query_info_on_read;
+ backend_class->query_info_on_write = do_query_info_on_write;
backend_class->read = do_read;
backend_class->create = do_create;
backend_class->append_to = do_append_to;
--
2.21.0
From d5dfd823c94045488aef8727c553f1e0f7666b90 Mon Sep 17 00:00:00 2001
From: Ondrej Holy <oholy@redhat.com>
Date: Fri, 24 May 2019 09:43:43 +0200
Subject: [PATCH] admin: Ensure correct ownership when moving to file:// uri
User and group is not restored properly when moving (or copying with
G_FILE_COPY_ALL_METADATA) from admin:// to file://, because it is handled
by GIO fallback code, which doesn't run with root permissions. Let's
handle this case with pull method to ensure correct ownership.
---
daemon/gvfsbackendadmin.c | 46 +++++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/daemon/gvfsbackendadmin.c b/daemon/gvfsbackendadmin.c
index 32b51b1a..9a7e8295 100644
--- a/daemon/gvfsbackendadmin.c
+++ b/daemon/gvfsbackendadmin.c
@@ -807,6 +807,51 @@ do_move (GVfsBackend *backend,
complete_job (job, error);
}
+static void
+do_pull (GVfsBackend *backend,
+ GVfsJobPull *pull_job,
+ const char *source,
+ const char *local_path,
+ GFileCopyFlags flags,
+ gboolean remove_source,
+ GFileProgressCallback progress_callback,
+ gpointer progress_callback_data)
+{
+ GVfsBackendAdmin *self = G_VFS_BACKEND_ADMIN (backend);
+ GVfsJob *job = G_VFS_JOB (pull_job);
+ GError *error = NULL;
+ GFile *src_file, *dst_file;
+
+ /* Pull method is necessary when user/group needs to be restored, return
+ * G_IO_ERROR_NOT_SUPPORTED in other cases to proceed with the fallback code.
+ */
+ if (!(flags & G_FILE_COPY_ALL_METADATA))
+ {
+ g_vfs_job_failed_literal (G_VFS_JOB (job), G_IO_ERROR,
+ G_IO_ERROR_NOT_SUPPORTED,
+ _("Operation not supported"));
+ return;
+ }
+
+ if (!check_permission (self, job))
+ return;
+
+ src_file = g_file_new_for_path (source);
+ dst_file = g_file_new_for_path (local_path);
+
+ if (remove_source)
+ g_file_move (src_file, dst_file, flags, job->cancellable,
+ progress_callback, progress_callback_data, &error);
+ else
+ g_file_copy (src_file, dst_file, flags, job->cancellable,
+ progress_callback, progress_callback_data, &error);
+
+ g_object_unref (src_file);
+ g_object_unref (dst_file);
+
+ complete_job (job, error);
+}
+
static void
do_query_settable_attributes (GVfsBackend *backend,
GVfsJobQueryAttributes *query_job,
@@ -927,6 +972,7 @@ g_vfs_backend_admin_class_init (GVfsBackendAdminClass * klass)
backend_class->set_attribute = do_set_attribute;
backend_class->delete = do_delete;
backend_class->move = do_move;
+ backend_class->pull = do_pull;
backend_class->query_settable_attributes = do_query_settable_attributes;
backend_class->query_writable_namespaces = do_query_writable_namespaces;
}
--
2.21.0
From e3808a1b4042761055b1d975333a8243d67b8bfe Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@collabora.com>
Date: Wed, 5 Jun 2019 13:33:38 +0100
Subject: [PATCH] gvfsdaemon: Check that the connecting client is the same user
Otherwise, an attacker who learns the abstract socket address from
netstat(8) or similar could connect to it and issue D-Bus method
calls.
Signed-off-by: Simon McVittie <smcv@collabora.com>
---
daemon/gvfsdaemon.c | 36 +++++++++++++++++++++++++++++++++++-
1 file changed, 35 insertions(+), 1 deletion(-)
diff --git a/daemon/gvfsdaemon.c b/daemon/gvfsdaemon.c
index 406d4f8e..be148a7b 100644
--- a/daemon/gvfsdaemon.c
+++ b/daemon/gvfsdaemon.c
@@ -79,6 +79,7 @@ struct _GVfsDaemon
gint mount_counter;
+ GDBusAuthObserver *auth_observer;
GDBusConnection *conn;
GVfsDBusDaemon *daemon_skeleton;
GVfsDBusMountable *mountable_skeleton;
@@ -171,6 +172,8 @@ g_vfs_daemon_finalize (GObject *object)
}
if (daemon->conn != NULL)
g_object_unref (daemon->conn);
+ if (daemon->auth_observer != NULL)
+ g_object_unref (daemon->auth_observer);
g_hash_table_destroy (daemon->registered_paths);
g_hash_table_destroy (daemon->client_connections);
@@ -236,6 +239,35 @@ name_vanished_handler (GDBusConnection *connection,
daemon->lost_main_daemon = TRUE;
}
+/*
+ * Authentication observer signal handler that authorizes connections
+ * from the same uid as this process. This matches the behaviour of a
+ * libdbus DBusServer/DBusConnection when no DBusAllowUnixUserFunction
+ * has been set, but is not the default in GDBus.
+ */
+static gboolean
+authorize_authenticated_peer_cb (GDBusAuthObserver *observer,
+ G_GNUC_UNUSED GIOStream *stream,
+ GCredentials *credentials,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ gboolean authorized = FALSE;
+
+ if (credentials != NULL)
+ {
+ GCredentials *own_credentials;
+
+ own_credentials = g_credentials_new ();
+
+ if (g_credentials_is_same_user (credentials, own_credentials, NULL))
+ authorized = TRUE;
+
+ g_object_unref (own_credentials);
+ }
+
+ return authorized;
+}
+
static void
g_vfs_daemon_init (GVfsDaemon *daemon)
{
@@ -265,6 +297,8 @@ g_vfs_daemon_init (GVfsDaemon *daemon)
daemon->conn = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
g_assert (daemon->conn != NULL);
+ daemon->auth_observer = g_dbus_auth_observer_new ();
+ g_signal_connect (daemon->auth_observer, "authorize-authenticated-peer", G_CALLBACK (authorize_authenticated_peer_cb), NULL);
daemon->daemon_skeleton = gvfs_dbus_daemon_skeleton_new ();
g_signal_connect (daemon->daemon_skeleton, "handle-get-connection", G_CALLBACK (handle_get_connection), daemon);
@@ -876,7 +910,7 @@ handle_get_connection (GVfsDBusDaemon *object,
server = g_dbus_server_new_sync (address1,
G_DBUS_SERVER_FLAGS_NONE,
guid,
- NULL, /* GDBusAuthObserver */
+ daemon->auth_observer,
NULL, /* GCancellable */
&error);
g_free (guid);
--
2.21.0
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment