From 0c012f09fb2eecc434fec5eab8c7ca78095c950a Mon Sep 17 00:00:00 2001 From: Leo Date: Mon, 22 Jul 2019 00:29:15 -0300 Subject: main/gvfs: backport fixes for a few CVEs - CVE-2019-12795 - CVE-2019-12449 - CVE-2019-12447 - CVE-2019-12448 --- main/gvfs/APKBUILD | 22 ++++++- main/gvfs/CVE-2019-12447.patch | 33 +++++++++++ main/gvfs/CVE-2019-12448.patch | 128 +++++++++++++++++++++++++++++++++++++++++ main/gvfs/CVE-2019-12449.patch | 81 ++++++++++++++++++++++++++ main/gvfs/CVE-2019-12795.patch | 93 ++++++++++++++++++++++++++++++ 5 files changed, 354 insertions(+), 3 deletions(-) create mode 100644 main/gvfs/CVE-2019-12447.patch create mode 100644 main/gvfs/CVE-2019-12448.patch create mode 100644 main/gvfs/CVE-2019-12449.patch create mode 100644 main/gvfs/CVE-2019-12795.patch (limited to 'main/gvfs') diff --git a/main/gvfs/APKBUILD b/main/gvfs/APKBUILD index c98d2eae5d..b39283b1c5 100644 --- a/main/gvfs/APKBUILD +++ b/main/gvfs/APKBUILD @@ -2,7 +2,7 @@ # Maintainer: Natanael Copa pkgname=gvfs pkgver=1.36.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" @@ -26,7 +26,19 @@ subpackages="$pkgname-dev $pkgname-lang $pkgname-nfs $pkgname-smb " -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.36.1-r1: +# - CVE-2019-12447 +# - CVE-2019-12448 +# - CVE-2019-12795 +# - CVE-2019-12449 builddir="$srcdir/$pkgname-$pkgver" build() { @@ -160,4 +172,8 @@ nfs() { usr/lib/gvfs/gvfsd-nfs } -sha512sums="44e76722b1445835a9494ab12f6888ace05791efa48df216a47c3910d652862edf1d176cf4ef2297b8b53fc079a95f2a7b0603fc127a22134dba3a1e699e74ba gvfs-1.36.1.tar.xz" +sha512sums="44e76722b1445835a9494ab12f6888ace05791efa48df216a47c3910d652862edf1d176cf4ef2297b8b53fc079a95f2a7b0603fc127a22134dba3a1e699e74ba gvfs-1.36.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/main/gvfs/CVE-2019-12447.patch b/main/gvfs/CVE-2019-12447.patch new file mode 100644 index 0000000000..4b37fc5070 --- /dev/null +++ b/main/gvfs/CVE-2019-12447.patch @@ -0,0 +1,33 @@ +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; + + diff --git a/main/gvfs/CVE-2019-12448.patch b/main/gvfs/CVE-2019-12448.patch new file mode 100644 index 0000000000..53542a3a1b --- /dev/null +++ b/main/gvfs/CVE-2019-12448.patch @@ -0,0 +1,128 @@ +From 5cd76d627f4d1982b6e77a0e271ef9301732d09e Mon Sep 17 00:00:00 2001 +From: Ondrej Holy +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 + + diff --git a/main/gvfs/CVE-2019-12449.patch b/main/gvfs/CVE-2019-12449.patch new file mode 100644 index 0000000000..7d58c5d3d8 --- /dev/null +++ b/main/gvfs/CVE-2019-12449.patch @@ -0,0 +1,81 @@ +From d5dfd823c94045488aef8727c553f1e0f7666b90 Mon Sep 17 00:00:00 2001 +From: Ondrej Holy +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 + + diff --git a/main/gvfs/CVE-2019-12795.patch b/main/gvfs/CVE-2019-12795.patch new file mode 100644 index 0000000000..8d22342424 --- /dev/null +++ b/main/gvfs/CVE-2019-12795.patch @@ -0,0 +1,93 @@ +From e3808a1b4042761055b1d975333a8243d67b8bfe Mon Sep 17 00:00:00 2001 +From: Simon McVittie +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 +--- + 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 + + -- cgit v1.2.3