diff --git a/SOURCES/daemon-Handle-lockdown-option-to-disable-writing.patch b/SOURCES/daemon-Handle-lockdown-option-to-disable-writing.patch new file mode 100644 index 0000000..211c3ba --- /dev/null +++ b/SOURCES/daemon-Handle-lockdown-option-to-disable-writing.patch @@ -0,0 +1,385 @@ +From af4d0d88604af7c196e461a743f2d1e81239d76a Mon Sep 17 00:00:00 2001 +From: Ondrej Holy +Date: Tue, 14 May 2019 09:31:37 +0200 +Subject: [PATCH 2/3] daemon: Handle lockdown option to disable writing + +Handle the new mount-removable-storage-devices-as-read-only option of +org.gnome.desktop.lockdown schema and present AFC, MTP, GPhoto2 devices +as read-only if enabled. +--- + daemon/gvfsbackend.c | 62 ++++++++++++++++++++++++++++++++-- + daemon/gvfsbackend.h | 6 ++++ + daemon/gvfsbackendafc.c | 2 ++ + daemon/gvfsbackendgphoto2.c | 1 + + daemon/gvfsbackendmtp.c | 1 + + daemon/gvfsjobcopy.c | 7 ++++ + daemon/gvfsjobdelete.c | 7 ++++ + daemon/gvfsjobmakedirectory.c | 7 ++++ + daemon/gvfsjobmakesymlink.c | 7 ++++ + daemon/gvfsjobmove.c | 7 ++++ + daemon/gvfsjobopenforwrite.c | 7 ++++ + daemon/gvfsjobpush.c | 7 ++++ + daemon/gvfsjobqueryfsinfo.c | 11 ++---- + daemon/gvfsjobsetattribute.c | 7 ++++ + daemon/gvfsjobsetdisplayname.c | 7 ++++ + daemon/gvfsjobtrash.c | 7 ++++ + 16 files changed, 143 insertions(+), 10 deletions(-) + +diff --git a/daemon/gvfsbackend.c b/daemon/gvfsbackend.c +index 4fd3455c..599733ef 100644 +--- a/daemon/gvfsbackend.c ++++ b/daemon/gvfsbackend.c +@@ -80,6 +80,9 @@ struct _GVfsBackendPrivate + char *default_location; + GMountSpec *mount_spec; + gboolean block_requests; ++ ++ GSettings *lockdown_settings; ++ gboolean readonly_lockdown; + }; + + +@@ -155,7 +158,9 @@ g_vfs_backend_finalize (GObject *object) + g_free (backend->priv->default_location); + if (backend->priv->mount_spec) + g_mount_spec_unref (backend->priv->mount_spec); +- ++ ++ g_clear_object (&backend->priv->lockdown_settings); ++ + if (G_OBJECT_CLASS (g_vfs_backend_parent_class)->finalize) + (*G_OBJECT_CLASS (g_vfs_backend_parent_class)->finalize) (object); + } +@@ -587,7 +592,29 @@ g_vfs_backend_add_auto_info (GVfsBackend *backend, + g_file_attribute_matcher_matches (matcher, + G_FILE_ATTRIBUTE_THUMBNAILING_FAILED))) + get_thumbnail_attributes (uri, info); +- ++ ++ if (backend->priv->readonly_lockdown) ++ { ++ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE, FALSE); ++ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME, FALSE); ++ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH, FALSE); ++ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, FALSE); ++ } ++} ++ ++void ++g_vfs_backend_add_auto_fs_info (GVfsBackend *backend, ++ GFileAttributeMatcher *matcher, ++ GFileInfo *info) ++{ ++ const char *type; ++ ++ type = g_vfs_backend_get_backend_type (backend); ++ if (type) ++ g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_GVFS_BACKEND, type); ++ ++ if (backend->priv->readonly_lockdown) ++ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_FILESYSTEM_READONLY, TRUE); + } + + void +@@ -1047,3 +1074,34 @@ g_vfs_backend_force_unmount (GVfsBackend *backend) + (GAsyncReadyCallback) forced_unregister_mount_callback, + NULL); + } ++ ++static void ++lockdown_settings_changed (GSettings *settings, ++ gchar *key, ++ gpointer user_data) ++{ ++ GVfsBackend *backend = G_VFS_BACKEND (user_data); ++ ++ backend->priv->readonly_lockdown = g_settings_get_boolean (settings, ++ "mount-removable-storage-devices-as-read-only"); ++} ++ ++ ++void ++g_vfs_backend_handle_readonly_lockdown (GVfsBackend *backend) ++{ ++ backend->priv->lockdown_settings = g_settings_new ("org.gnome.desktop.lockdown"); ++ backend->priv->readonly_lockdown = g_settings_get_boolean (backend->priv->lockdown_settings, ++ "mount-removable-storage-devices-as-read-only"); ++ g_signal_connect_object (backend->priv->lockdown_settings, ++ "changed", ++ G_CALLBACK (lockdown_settings_changed), ++ backend, ++ 0); ++} ++ ++gboolean ++g_vfs_backend_get_readonly_lockdown (GVfsBackend *backend) ++{ ++ return backend->priv->readonly_lockdown; ++} +diff --git a/daemon/gvfsbackend.h b/daemon/gvfsbackend.h +index 9c7476cf..431dd290 100644 +--- a/daemon/gvfsbackend.h ++++ b/daemon/gvfsbackend.h +@@ -516,6 +516,9 @@ void g_vfs_backend_add_auto_info (GVfsBackend + GFileAttributeMatcher *matcher, + GFileInfo *info, + const char *uri); ++void g_vfs_backend_add_auto_fs_info (GVfsBackend *backend, ++ GFileAttributeMatcher *matcher, ++ GFileInfo *info); + + void g_vfs_backend_set_block_requests (GVfsBackend *backend, + gboolean value); +@@ -534,6 +537,9 @@ gboolean g_vfs_backend_invocation_first_handler (GVfsDBusMount *object, + GDBusMethodInvocation *invocation, + GVfsBackend *backend); + ++void g_vfs_backend_handle_readonly_lockdown (GVfsBackend *backend); ++gboolean g_vfs_backend_get_readonly_lockdown (GVfsBackend *backend); ++ + G_END_DECLS + + #endif /* __G_VFS_BACKEND_H__ */ +diff --git a/daemon/gvfsbackendafc.c b/daemon/gvfsbackendafc.c +index b6e6a106..ce68aa45 100644 +--- a/daemon/gvfsbackendafc.c ++++ b/daemon/gvfsbackendafc.c +@@ -2760,6 +2760,8 @@ g_vfs_backend_afc_init (GVfsBackendAfc *self) + } + + g_mutex_init (&self->apps_lock); ++ ++ g_vfs_backend_handle_readonly_lockdown (G_VFS_BACKEND (self)); + } + + static void +diff --git a/daemon/gvfsbackendgphoto2.c b/daemon/gvfsbackendgphoto2.c +index 51e9a3bd..7e50194a 100644 +--- a/daemon/gvfsbackendgphoto2.c ++++ b/daemon/gvfsbackendgphoto2.c +@@ -614,6 +614,7 @@ g_vfs_backend_gphoto2_init (GVfsBackendGphoto2 *gphoto2_backend) + g_mutex_init (&gphoto2_backend->lock); + + g_vfs_backend_set_display_name (backend, "gphoto2"); ++ g_vfs_backend_handle_readonly_lockdown (G_VFS_BACKEND (backend)); + + mount_spec = g_mount_spec_new ("gphoto2"); + g_vfs_backend_set_mount_spec (backend, mount_spec); +diff --git a/daemon/gvfsbackendmtp.c b/daemon/gvfsbackendmtp.c +index e3a25ef2..c4f1e855 100644 +--- a/daemon/gvfsbackendmtp.c ++++ b/daemon/gvfsbackendmtp.c +@@ -379,6 +379,7 @@ g_vfs_backend_mtp_init (GVfsBackendMtp *backend) + g_mutex_init (&backend->mutex); + g_vfs_backend_set_display_name (G_VFS_BACKEND (backend), "mtp"); + g_vfs_backend_set_icon_name (G_VFS_BACKEND (backend), "multimedia-player"); ++ g_vfs_backend_handle_readonly_lockdown (G_VFS_BACKEND (backend)); + + mount_spec = g_mount_spec_new ("mtp"); + g_vfs_backend_set_mount_spec (G_VFS_BACKEND (backend), mount_spec); +diff --git a/daemon/gvfsjobcopy.c b/daemon/gvfsjobcopy.c +index 785d7480..cf33da56 100644 +--- a/daemon/gvfsjobcopy.c ++++ b/daemon/gvfsjobcopy.c +@@ -141,6 +141,13 @@ try (GVfsJob *job) + GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); + gboolean res; + ++ if (g_vfs_backend_get_readonly_lockdown (op_job->backend)) ++ { ++ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, ++ _("Filesystem is read-only")); ++ return TRUE; ++ } ++ + if (class->try_copy == NULL) + return FALSE; + +diff --git a/daemon/gvfsjobdelete.c b/daemon/gvfsjobdelete.c +index 92892f15..8d5e5b8e 100644 +--- a/daemon/gvfsjobdelete.c ++++ b/daemon/gvfsjobdelete.c +@@ -120,6 +120,13 @@ try (GVfsJob *job) + GVfsJobDelete *op_job = G_VFS_JOB_DELETE (job); + GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); + ++ if (g_vfs_backend_get_readonly_lockdown (op_job->backend)) ++ { ++ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, ++ _("Filesystem is read-only")); ++ return TRUE; ++ } ++ + if (class->try_delete == NULL) + return FALSE; + +diff --git a/daemon/gvfsjobmakedirectory.c b/daemon/gvfsjobmakedirectory.c +index 98bb28d5..56a9c42a 100644 +--- a/daemon/gvfsjobmakedirectory.c ++++ b/daemon/gvfsjobmakedirectory.c +@@ -120,6 +120,13 @@ try (GVfsJob *job) + GVfsJobMakeDirectory *op_job = G_VFS_JOB_MAKE_DIRECTORY (job); + GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); + ++ if (g_vfs_backend_get_readonly_lockdown (op_job->backend)) ++ { ++ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, ++ _("Filesystem is read-only")); ++ return TRUE; ++ } ++ + if (class->try_make_directory == NULL) + return FALSE; + +diff --git a/daemon/gvfsjobmakesymlink.c b/daemon/gvfsjobmakesymlink.c +index 2c55e26b..2684b6fd 100644 +--- a/daemon/gvfsjobmakesymlink.c ++++ b/daemon/gvfsjobmakesymlink.c +@@ -124,6 +124,13 @@ try (GVfsJob *job) + GVfsJobMakeSymlink *op_job = G_VFS_JOB_MAKE_SYMLINK (job); + GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); + ++ if (g_vfs_backend_get_readonly_lockdown (op_job->backend)) ++ { ++ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, ++ _("Filesystem is read-only")); ++ return TRUE; ++ } ++ + if (class->try_make_symlink == NULL) + return FALSE; + +diff --git a/daemon/gvfsjobmove.c b/daemon/gvfsjobmove.c +index cc4ad220..5903d17a 100644 +--- a/daemon/gvfsjobmove.c ++++ b/daemon/gvfsjobmove.c +@@ -141,6 +141,13 @@ try (GVfsJob *job) + GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); + gboolean res; + ++ if (g_vfs_backend_get_readonly_lockdown (op_job->backend)) ++ { ++ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, ++ _("Filesystem is read-only")); ++ return TRUE; ++ } ++ + if (class->try_move == NULL) + return FALSE; + +diff --git a/daemon/gvfsjobopenforwrite.c b/daemon/gvfsjobopenforwrite.c +index 68eae532..60ce64f9 100644 +--- a/daemon/gvfsjobopenforwrite.c ++++ b/daemon/gvfsjobopenforwrite.c +@@ -230,6 +230,13 @@ try (GVfsJob *job) + GVfsJobOpenForWrite *op_job = G_VFS_JOB_OPEN_FOR_WRITE (job); + GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); + ++ if (g_vfs_backend_get_readonly_lockdown (op_job->backend)) ++ { ++ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, ++ _("Filesystem is read-only")); ++ return TRUE; ++ } ++ + if (op_job->mode == OPEN_FOR_WRITE_CREATE) + { + if (class->try_create == NULL) +diff --git a/daemon/gvfsjobpush.c b/daemon/gvfsjobpush.c +index d7e48d86..a8df73a8 100644 +--- a/daemon/gvfsjobpush.c ++++ b/daemon/gvfsjobpush.c +@@ -146,6 +146,13 @@ try (GVfsJob *job) + GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); + gboolean res; + ++ if (g_vfs_backend_get_readonly_lockdown (op_job->backend)) ++ { ++ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, ++ _("Filesystem is read-only")); ++ return TRUE; ++ } ++ + if (class->try_push == NULL) + return FALSE; + +diff --git a/daemon/gvfsjobqueryfsinfo.c b/daemon/gvfsjobqueryfsinfo.c +index 898052ea..3363311a 100644 +--- a/daemon/gvfsjobqueryfsinfo.c ++++ b/daemon/gvfsjobqueryfsinfo.c +@@ -147,15 +147,10 @@ create_reply (GVfsJob *job, + GDBusMethodInvocation *invocation) + { + GVfsJobQueryFsInfo *op_job = G_VFS_JOB_QUERY_FS_INFO (job); +- const char *type; +- +- type = g_vfs_backend_get_backend_type (op_job->backend); +- +- if (type) +- g_file_info_set_attribute_string (op_job->file_info, +- G_FILE_ATTRIBUTE_GVFS_BACKEND, +- type); + ++ g_vfs_backend_add_auto_fs_info (op_job->backend, ++ op_job->attribute_matcher, ++ op_job->file_info); + g_file_info_set_attribute_mask (op_job->file_info, + op_job->attribute_matcher); + +diff --git a/daemon/gvfsjobsetattribute.c b/daemon/gvfsjobsetattribute.c +index 1efe7c94..ac7618a4 100644 +--- a/daemon/gvfsjobsetattribute.c ++++ b/daemon/gvfsjobsetattribute.c +@@ -146,6 +146,13 @@ try (GVfsJob *job) + GVfsJobSetAttribute *op_job = G_VFS_JOB_SET_ATTRIBUTE (job); + GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); + ++ if (g_vfs_backend_get_readonly_lockdown (op_job->backend)) ++ { ++ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, ++ _("Filesystem is read-only")); ++ return TRUE; ++ } ++ + if (class->try_set_attribute == NULL) + return FALSE; + +diff --git a/daemon/gvfsjobsetdisplayname.c b/daemon/gvfsjobsetdisplayname.c +index badb10dd..e12ae879 100644 +--- a/daemon/gvfsjobsetdisplayname.c ++++ b/daemon/gvfsjobsetdisplayname.c +@@ -124,6 +124,13 @@ try (GVfsJob *job) + GVfsJobSetDisplayName *op_job = G_VFS_JOB_SET_DISPLAY_NAME (job); + GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); + ++ if (g_vfs_backend_get_readonly_lockdown (op_job->backend)) ++ { ++ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, ++ _("Filesystem is read-only")); ++ return TRUE; ++ } ++ + if (class->try_set_display_name == NULL) + return FALSE; + +diff --git a/daemon/gvfsjobtrash.c b/daemon/gvfsjobtrash.c +index 1738f8a2..5234ebf8 100644 +--- a/daemon/gvfsjobtrash.c ++++ b/daemon/gvfsjobtrash.c +@@ -119,6 +119,13 @@ try (GVfsJob *job) + GVfsJobTrash *op_job = G_VFS_JOB_TRASH (job); + GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); + ++ if (g_vfs_backend_get_readonly_lockdown (op_job->backend)) ++ { ++ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, ++ _("Filesystem is read-only")); ++ return TRUE; ++ } ++ + if (class->try_trash == NULL) + return FALSE; + +-- +2.21.0 + diff --git a/SOURCES/daemon-Prevent-spawning-new-daemons-if-outgoing-oper.patch b/SOURCES/daemon-Prevent-spawning-new-daemons-if-outgoing-oper.patch new file mode 100644 index 0000000..305c7e5 --- /dev/null +++ b/SOURCES/daemon-Prevent-spawning-new-daemons-if-outgoing-oper.patch @@ -0,0 +1,99 @@ +From 396216f71abf6907efd1383ca0d1a597918cd83d Mon Sep 17 00:00:00 2001 +From: Ondrej Holy +Date: Thu, 11 Oct 2018 17:47:59 +0200 +Subject: [PATCH] daemon: Prevent spawning new daemons if outgoing operation + exists + +A new daemon is always spawned if MountLocation method (or LookupMount for +automounted) is called and the respective mount isn't registered yet. This +is not usually an issue, because the redundant daemons are consequently +terminated. However, this is a problem if mount operations hang for some reason. +This may happen e.g. with trash backend due to stale NFS mounts. Consequently, +new and new daemons are spawned which may lead to system failures due to lack +of system resources. See the following downstream bug report: +https://bugzilla.redhat.com/show_bug.cgi?id=1632960 + +Let's fix that behavior simply by preventing spawning of new daemons if +respective outgoing mount operations exist. + +https://gitlab.gnome.org/GNOME/gvfs/merge_requests/19 +--- + daemon/mount.c | 26 ++++++++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +diff --git a/daemon/mount.c b/daemon/mount.c +index e242666d..33cae597 100644 +--- a/daemon/mount.c ++++ b/daemon/mount.c +@@ -73,6 +73,7 @@ typedef void (*MountCallback) (VfsMountable *mountable, + + static GList *mountables = NULL; + static GList *mounts = NULL; ++static GList *ongoing = NULL; + + static gboolean fuse_available; + +@@ -253,6 +254,7 @@ typedef struct { + char *obj_path; + gboolean spawned; + GVfsDBusSpawner *spawner; ++ GList *pending; /* MountData */ + } MountData; + + static void spawn_mount (MountData *data); +@@ -264,6 +266,7 @@ mount_data_free (MountData *data) + g_mount_spec_unref (data->mount_spec); + g_free (data->obj_path); + g_clear_object (&data->spawner); ++ g_list_free_full (data->pending, (GDestroyNotify) mount_data_free); + + g_free (data); + } +@@ -271,7 +274,17 @@ mount_data_free (MountData *data) + static void + mount_finish (MountData *data, GError *error) + { ++ GList *l; ++ ++ ongoing = g_list_remove (ongoing, data); ++ + data->callback (data->mountable, error, data->user_data); ++ for (l = data->pending; l != NULL; l = l->next) ++ { ++ MountData *pending_data = l->data; ++ pending_data->callback (pending_data->mountable, error, pending_data->user_data); ++ } ++ + mount_data_free (data); + } + +@@ -493,6 +506,7 @@ mountable_mount (VfsMountable *mountable, + gpointer user_data) + { + MountData *data; ++ GList *l; + + data = g_new0 (MountData, 1); + data->automount = automount; +@@ -502,6 +516,18 @@ mountable_mount (VfsMountable *mountable, + data->callback = callback; + data->user_data = user_data; + ++ for (l = ongoing; l != NULL; l = l->next) ++ { ++ MountData *ongoing_data = l->data; ++ if (g_mount_spec_equal (ongoing_data->mount_spec, mount_spec)) ++ { ++ ongoing_data->pending = g_list_append (ongoing_data->pending, data); ++ return; ++ } ++ } ++ ++ ongoing = g_list_append (ongoing, data); ++ + if (mountable->dbus_name == NULL) + spawn_mount (data); + else +-- +2.20.1 + diff --git a/SOURCES/gvfsdaemon-Check-that-the-connecting-client-is-the-s.patch b/SOURCES/gvfsdaemon-Check-that-the-connecting-client-is-the-s.patch new file mode 100644 index 0000000..cebad56 --- /dev/null +++ b/SOURCES/gvfsdaemon-Check-that-the-connecting-client-is-the-s.patch @@ -0,0 +1,92 @@ +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 + diff --git a/SOURCES/smbbrowse-Force-NT1-protocol-version-for-workgroup-s.patch b/SOURCES/smbbrowse-Force-NT1-protocol-version-for-workgroup-s.patch new file mode 100644 index 0000000..4bf9934 --- /dev/null +++ b/SOURCES/smbbrowse-Force-NT1-protocol-version-for-workgroup-s.patch @@ -0,0 +1,89 @@ +diff --git a/configure.ac b/configure.ac +index 3b5836ff..daeee728 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -546,6 +546,11 @@ if test "x$enable_samba" != "xno"; then + if test "x$msg_samba" = "xyes"; then + PKG_CHECK_MODULES([SAMBA], [smbclient]) + AC_DEFINE([HAVE_SAMBA], 1, [Define to 1 if you have the samba libraries]) ++ ++ AC_CHECK_LIB(smbclient, smbc_setOptionProtocols, ++ AC_DEFINE(HAVE_SMBC_SETOPTIONPROTOCOLS, 1, [Define to 1 if smbc_setOptionProtocols() is available]), ++ [] ++ ) + fi + fi + +diff --git a/daemon/gvfsbackendsmbbrowse.c b/daemon/gvfsbackendsmbbrowse.c +index f08d2988..3b11883e 100644 +--- a/daemon/gvfsbackendsmbbrowse.c ++++ b/daemon/gvfsbackendsmbbrowse.c +@@ -45,6 +45,7 @@ + #include "gvfskeyring.h" + #include "gmounttracker.h" + #include "gvfsbackendsmbprivate.h" ++#include "gvfsutils.h" + + #include + +@@ -847,6 +848,47 @@ do_mount (GVfsBackend *backend, + else + op_backend->server = g_strdup (op_backend->mounted_server); + ++#ifdef HAVE_SMBC_SETOPTIONPROTOCOLS ++ /* Force NT1 protocol version if server can't be resolved (i.e. is not ++ * hostname, nor IP address). This is needed for workgroup support, because ++ * "client max protocol" has been changed from NT1 to SMB3 in recent samba ++ * versions. ++ */ ++ ++ if (op_backend->server != NULL) ++ { ++ GResolver *resolver; ++ GList *addresses; ++ GError *error = NULL; ++ gchar *server; ++ ++ resolver = g_resolver_get_default (); ++ ++ /* IPv6 server includes brackets in GMountSpec, GResolver doesn't */ ++ if (gvfs_is_ipv6 (op_backend->server)) ++ server = g_strndup (op_backend->server + 1, strlen (op_backend->server) - 2); ++ else ++ server = g_strdup (op_backend->server); ++ ++ addresses = g_resolver_lookup_by_name (resolver, server, NULL, &error); ++ if (addresses == NULL) ++ { ++ if (error != NULL) ++ { ++ g_debug ("%s\n", error->message); ++ g_error_free (error); ++ } ++ ++ g_debug ("Forcing NT1 protocol version\n"); ++ smbc_setOptionProtocols (smb_context, "NT1", "NT1"); ++ } ++ ++ g_resolver_free_addresses (addresses); ++ g_object_unref (resolver); ++ g_free (server); ++ } ++#endif ++ + icon = NULL; + symbolic_icon = NULL; + if (op_backend->server == NULL) +diff --git a/meson.build b/meson.build +index 34600188..3a876172 100644 +--- a/meson.build ++++ b/meson.build +@@ -416,6 +416,8 @@ config_h.set10('HAVE_LIBUSB', enable_libusb) + enable_samba = get_option('smb') + if enable_samba + smbclient_dep = dependency('smbclient') ++ ++ config_h.set('HAVE_SMBC_SETOPTIONPROTOCOLS', cc.has_function('smbc_setOptionProtocols', dependencies: smbclient_dep)) + endif + + # *** Check for libarchive *** diff --git a/SOURCES/udisks2-Handle-lockdown-option-to-disable-writing.patch b/SOURCES/udisks2-Handle-lockdown-option-to-disable-writing.patch new file mode 100644 index 0000000..deb4da3 --- /dev/null +++ b/SOURCES/udisks2-Handle-lockdown-option-to-disable-writing.patch @@ -0,0 +1,128 @@ +From 9fdd59cfda93b508e76770146a8295d0a26b175d Mon Sep 17 00:00:00 2001 +From: Ondrej Holy +Date: Tue, 14 May 2019 08:46:48 +0200 +Subject: [PATCH 1/3] udisks2: Handle lockdown option to disable writing + +Handle the new mount-removable-storage-devices-as-read-only option of +org.gnome.desktop.lockdown schema and mount removable devices as read-only +if enabled. +--- + monitor/udisks2/gvfsudisks2volume.c | 8 +++++ + monitor/udisks2/gvfsudisks2volumemonitor.c | 34 ++++++++++++++++++++++ + monitor/udisks2/gvfsudisks2volumemonitor.h | 1 + + 3 files changed, 43 insertions(+) + +diff --git a/monitor/udisks2/gvfsudisks2volume.c b/monitor/udisks2/gvfsudisks2volume.c +index a509b5dd..b2545058 100644 +--- a/monitor/udisks2/gvfsudisks2volume.c ++++ b/monitor/udisks2/gvfsudisks2volume.c +@@ -1093,6 +1093,7 @@ do_mount (GTask *task) + { + MountData *data = g_task_get_task_data (task); + GVariantBuilder builder; ++ GVfsUDisks2Volume *volume = g_task_get_source_object (task); + + g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); + if (data->mount_operation == NULL) +@@ -1101,6 +1102,13 @@ do_mount (GTask *task) + "{sv}", + "auth.no_user_interaction", g_variant_new_boolean (TRUE)); + } ++ if (gvfs_udisks2_volume_monitor_get_readonly_lockdown (volume->monitor)) ++ { ++ g_variant_builder_add (&builder, ++ "{sv}", ++ "options", g_variant_new_string ("ro")); ++ ++ } + udisks_filesystem_call_mount (data->filesystem_to_mount, + g_variant_builder_end (&builder), + g_task_get_cancellable (task), +diff --git a/monitor/udisks2/gvfsudisks2volumemonitor.c b/monitor/udisks2/gvfsudisks2volumemonitor.c +index 0a5ce96e..37c81fcf 100644 +--- a/monitor/udisks2/gvfsudisks2volumemonitor.c ++++ b/monitor/udisks2/gvfsudisks2volumemonitor.c +@@ -65,6 +65,9 @@ struct _GVfsUDisks2VolumeMonitor + /* we keep volumes/mounts for blank and audio discs separate to handle e.g. mixed discs properly */ + GList *disc_volumes; + GList *disc_mounts; ++ ++ GSettings *lockdown_settings; ++ gboolean readonly_lockdown; + }; + + static UDisksClient *get_udisks_client_sync (GError **error); +@@ -140,6 +143,8 @@ gvfs_udisks2_volume_monitor_finalize (GObject *object) + g_list_free_full (monitor->disc_volumes, g_object_unref); + g_list_free_full (monitor->disc_mounts, g_object_unref); + ++ g_clear_object (&monitor->lockdown_settings); ++ + G_OBJECT_CLASS (gvfs_udisks2_volume_monitor_parent_class)->finalize (object); + } + +@@ -304,6 +309,17 @@ gvfs_udisks2_volume_monitor_constructor (GType type, + return ret; + } + ++static void ++lockdown_settings_changed (GSettings *settings, ++ gchar *key, ++ gpointer user_data) ++{ ++ GVfsUDisks2VolumeMonitor *monitor = GVFS_UDISKS2_VOLUME_MONITOR (user_data); ++ ++ monitor->readonly_lockdown = g_settings_get_boolean (settings, ++ "mount-removable-storage-devices-as-read-only"); ++} ++ + static void + gvfs_udisks2_volume_monitor_init (GVfsUDisks2VolumeMonitor *monitor) + { +@@ -325,6 +341,15 @@ gvfs_udisks2_volume_monitor_init (GVfsUDisks2VolumeMonitor *monitor) + G_CALLBACK (mountpoints_changed), + monitor); + ++ monitor->lockdown_settings = g_settings_new ("org.gnome.desktop.lockdown"); ++ monitor->readonly_lockdown = g_settings_get_boolean (monitor->lockdown_settings, ++ "mount-removable-storage-devices-as-read-only"); ++ g_signal_connect_object (monitor->lockdown_settings, ++ "changed", ++ G_CALLBACK (lockdown_settings_changed), ++ monitor, ++ 0); ++ + update_all (monitor, FALSE, TRUE); + } + +@@ -388,6 +413,15 @@ gvfs_udisks2_volume_monitor_get_gudev_client (GVfsUDisks2VolumeMonitor *monitor) + + /* ---------------------------------------------------------------------------------------------------- */ + ++gboolean ++gvfs_udisks2_volume_monitor_get_readonly_lockdown (GVfsUDisks2VolumeMonitor *monitor) ++{ ++ g_return_val_if_fail (GVFS_IS_UDISKS2_VOLUME_MONITOR (monitor), FALSE); ++ return monitor->readonly_lockdown; ++} ++ ++/* ---------------------------------------------------------------------------------------------------- */ ++ + void + gvfs_udisks2_volume_monitor_update (GVfsUDisks2VolumeMonitor *monitor) + { +diff --git a/monitor/udisks2/gvfsudisks2volumemonitor.h b/monitor/udisks2/gvfsudisks2volumemonitor.h +index 7f0215dc..751a0236 100644 +--- a/monitor/udisks2/gvfsudisks2volumemonitor.h ++++ b/monitor/udisks2/gvfsudisks2volumemonitor.h +@@ -49,6 +49,7 @@ GVolumeMonitor *gvfs_udisks2_volume_monitor_new (void); + UDisksClient *gvfs_udisks2_volume_monitor_get_udisks_client (GVfsUDisks2VolumeMonitor *monitor); + void gvfs_udisks2_volume_monitor_update (GVfsUDisks2VolumeMonitor *monitor); + GUdevClient *gvfs_udisks2_volume_monitor_get_gudev_client (GVfsUDisks2VolumeMonitor *monitor); ++gboolean gvfs_udisks2_volume_monitor_get_readonly_lockdown (GVfsUDisks2VolumeMonitor *monitor); + + G_END_DECLS + +-- +2.21.0 + diff --git a/SPECS/gvfs.spec b/SPECS/gvfs.spec index 29590ed..0f72956 100644 --- a/SPECS/gvfs.spec +++ b/SPECS/gvfs.spec @@ -5,6 +5,7 @@ %global gettext_version 0.19.4 %global glib2_version 2.51.0 %global goa_version 3.17.1 +%global gsettings_desktop_schemas_version 3.28.1-2 %global gudev_version 147 %global libarchive_version 3.0.22 %global libcdio_paranoia_version 0.78.2 @@ -24,16 +25,29 @@ Name: gvfs Version: 1.36.2 -Release: 2%{?dist}.1 +Release: 6%{?dist} Summary: Backends for the gio framework in GLib License: GPLv3 and LGPLv2+ and BSD and MPLv2.0 URL: https://wiki.gnome.org/Projects/gvfs Source0: https://download.gnome.org/sources/gvfs/1.36/gvfs-%{version}.tar.xz -# https://bugzilla.redhat.com/show_bug.cgi?id=1690470 +# https://bugzilla.redhat.com/show_bug.cgi?id=1673888 Patch0: admin-Prevent-access-if-any-authentication-agent-isn.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=1662193 +Patch1: udisks2-Handle-lockdown-option-to-disable-writing.patch +Patch2: daemon-Handle-lockdown-option-to-disable-writing.patch + +# https://bugzilla.redhat.com/show_bug.cgi?id=1729885 +Patch3: gvfsdaemon-Check-that-the-connecting-client-is-the-s.patch + +# https://bugzilla.redhat.com/show_bug.cgi?id=1739117 +Patch4: daemon-Prevent-spawning-new-daemons-if-outgoing-oper.patch + +# https://bugzilla.redhat.com/show_bug.cgi?id=1739116 +Patch5: smbbrowse-Force-NT1-protocol-version-for-workgroup-s.patch + BuildRequires: pkgconfig BuildRequires: pkgconfig(glib-2.0) >= %{glib2_version} BuildRequires: pkgconfig(dbus-glib-1) @@ -60,6 +74,7 @@ BuildRequires: libtool Requires: %{name}-client%{?_isa} = %{version}-%{release} Requires: glib2%{?_isa} >= %{glib2_version} Requires: udisks2 >= %{udisks2_version} +Requires: gsettings-desktop-schemas >= %{gsettings_desktop_schemas_version} # for file triggers Requires(post): desktop-file-utils >= 0.22-6 @@ -215,8 +230,7 @@ The gvfs-tests package contains tests that can be used to verify the functionality of the installed gvfs package. %prep -%setup -q -%patch0 -p1 -b .admin-Prevent-access-if-any-authentication-agent-isn +%autosetup -p1 autoreconf -fi @@ -409,8 +423,18 @@ killall -USR1 gvfsd >&/dev/null || : %{_datadir}/installed-tests %changelog -* Mon Apr 01 2019 Ondrej Holy - 1.36.2-2.1 -- CVE-2019-3827: Prevent access if any authentication agent isn't available (#1690470) +* Fri Aug 09 2019 Ondrej Holy - 1.36.2-6 +- Prevent spawning new daemons if outgoing operation exists (#1739117) +- Force NT1 protocol version for workgroup support (#1739116) + +* Thu Aug 08 2019 Ondrej Holy - 1.36.2-5 +- CVE-2019-12795 Check that the connecting client is the same user (#1729885) + +* Thu May 16 2019 Ondrej Holy - 1.36.2-4 +- Handle lockdown option to disable writing (#1662193) + +* Mon Apr 01 2019 Ondrej Holy - 1.36.2-3 +- CVE-2019-3827: Prevent access if any authentication agent isn't available (#1673888) * Fri Dec 14 2018 Ray Strode - 1.36.2-2 - rebuild