[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#784962: jessie-pu: package caja/1.8.2-3+deb8u1



Package: release.debian.org
Severity: normal
Tags: jessie
User: release.debian.org@packages.debian.org
Usertags: pu

Please pre-approve the following changes for caja in Debian jessie:

+  * debian/patches:
+    + Add 0004_avoid-automounts-while-screen-is-locked.patch. Don't mount
+      newly added USB flash drives / optical disks / etc. while a session
+      is locked by the screensaver. Delay the automounting action until the
+      session has been unlocked again. (Closes: #781608).

-> This patch fixes a nasty issue in caja when using the "Change User"
feature in KDM or GDM3.

Flashdrives and optical disks will now only get automounted after the
session of a user has been unlocked. In previous versions of caja in
Debian, the flash drive / disc would have been mounted by the locked
session (and by the running session on another VT).

Except from this being a security issue (but a no-dsa as stated by the
security team), the observed behaviour lead into a race condition between
the in parallel running MATE desktop sessions. All of them would have
tried to mount freshly inserted devices simultaneously which often made
flash drives and discs unaccessible for the currently active MATE desktop
session (because caja inside a locked session would have been faster and
thus locked the device).

light+love,
Mike

-- System Information:
Debian Release: 8.0
  APT prefers stable-updates
  APT policy: (500, 'stable-updates'), (500, 'proposed-updates'), (500, 'stable')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 3.16.0-4-amd64 (SMP w/4 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
diff -Nru caja-1.8.2/debian/changelog caja-1.8.2/debian/changelog
--- caja-1.8.2/debian/changelog	2015-03-23 18:19:22.000000000 +0100
+++ caja-1.8.2/debian/changelog	2015-05-11 09:28:52.000000000 +0200
@@ -1,3 +1,13 @@
+caja (1.8.2-3+deb8u1) jessie-proposed-updates; urgency=medium
+
+  * debian/patches:
+    + Add 0004_avoid-automounts-while-screen-is-locked.patch. Don't mount
+      newly added USB flash drives / optical disks / etc. while a session
+      is locked by the screensaver. Delay the automounting action until the
+      session has been unlocked again. (Closes: #781608).
+
+ -- Mike Gabriel <sunweaver@debian.org>  Mon, 11 May 2015 09:28:03 +0200
+
 caja (1.8.2-3) unstable; urgency=medium
 
   * debian/control:
diff -Nru caja-1.8.2/debian/patches/0004_avoid-automounts-while-screen-is-locked.patch caja-1.8.2/debian/patches/0004_avoid-automounts-while-screen-is-locked.patch
--- caja-1.8.2/debian/patches/0004_avoid-automounts-while-screen-is-locked.patch	1970-01-01 01:00:00.000000000 +0100
+++ caja-1.8.2/debian/patches/0004_avoid-automounts-while-screen-is-locked.patch	2015-05-11 09:26:06.000000000 +0200
@@ -0,0 +1,334 @@
+From adc45ec84298f6246d9ed219607bb5c169f50e08 Mon Sep 17 00:00:00 2001
+From: tarakbumba <tarakbumba@gmail.com>
+Date: Tue, 7 Apr 2015 00:07:27 +0300
+Subject: [PATCH 1/2] Fix for https://github.com/mate-desktop/caja/issues/398
+
+On the Shmoocon at 2011 there was a presentation by Jon Larimer demonstrating
+how to abuse vulnerabilities and bugs, or even just creating socially or
+security compromising thumbnails in mounting and thumbnailing, which happens
+on automounting USB drives. This is a particular issue when this happens on a
+locked box where the attacker doesn't otherwise have access to the user
+account:
+
+http://www.net-security.org/secworld.php?id=10544
+
+Disable automounting if the MATE screen saver is currently locked.
+
+See also https://bugzilla.gnome.org/show_bug.cgi?id=642020
+
+This commit is merely based on :
+https://git.gnome.org/browse/nautilus/commit/?h=gnome-2-32&id=b7262fa945ef1ea936c15f0d248ad7a024d97dca
+
+v2: Patch rebased against caja 1.8.x (Mike Gabriel)
+---
+ src/caja-application.c | 232 ++++++++++++++++++++++++++++++++++++++++++++++++-
+ src/caja-application.h |   4 +
+ 2 files changed, 232 insertions(+), 4 deletions(-)
+
+--- a/src/caja-application.c
++++ b/src/caja-application.c
+@@ -122,7 +122,10 @@
+ static void     volume_added_callback              (GVolumeMonitor           *monitor,
+         GVolume                  *volume,
+         CajaApplication      *application);
+-static void     drive_connected_callback           (GVolumeMonitor           *monitor,
++static void     volume_removed_callback            (GVolumeMonitor           *monitor,
++	    GVolume                  *volume,
++	    CajaApplication      *application);
++ static void     drive_connected_callback           (GVolumeMonitor           *monitor,
+         GDrive                   *drive,
+         CajaApplication      *application);
+ static void     drive_listen_for_eject_button      (GDrive *drive,
+@@ -362,7 +365,18 @@
+ 
+     g_object_unref (application->unique_app);
+ 
+-    if (application->automount_idle_id != 0)
++	if (application->ss_watch_id > 0)
++	{
++		g_bus_unwatch_name (application->ss_watch_id);
++	}
++	
++	if (application->volume_queue != NULL)
++	{
++		g_list_free_full (application->volume_queue, g_object_unref);
++		application->volume_queue = NULL;
++	}
++
++ 	if (application->automount_idle_id != 0)
+     {
+         g_source_remove (application->automount_idle_id);
+         application->automount_idle_id = 0;
+@@ -374,6 +388,12 @@
+         fdb_manager = NULL;
+     }
+ 
++    if (application->ss_proxy != NULL)
++    {
++		g_object_unref (application->ss_proxy);
++		application->ss_proxy = NULL;
++	}
++
+     G_OBJECT_CLASS (caja_application_parent_class)->finalize (object);
+ }
+ 
+@@ -554,6 +574,180 @@
+ }
+ 
+ static void
++check_volume_queue (CajaApplication *application)
++{
++        GList *l, *next;
++        GVolume *volume;
++
++        l = application->volume_queue;
++
++        if (application->screensaver_active)
++        {
++                return;
++        }
++
++        while (l != NULL) {
++		volume = l->data;
++		next = l->next;
++
++		caja_file_operations_mount_volume (NULL, volume, TRUE);
++		application->volume_queue =
++			g_list_remove (application->volume_queue, volume);
++
++		g_object_unref (volume);
++		l = next;
++        }
++
++        application->volume_queue = NULL;
++}
++
++#define SCREENSAVER_NAME "org.mate.ScreenSaver"
++#define SCREENSAVER_PATH "/org/mate/ScreenSaver"
++#define SCREENSAVER_INTERFACE "org.mate.ScreenSaver"
++
++static void
++screensaver_signal_callback (GDBusProxy *proxy,
++                             const gchar *sender_name,
++                             const gchar *signal_name,
++                             GVariant *parameters,
++                             gpointer user_data)
++{
++	CajaApplication *application = user_data;
++
++	if (g_strcmp0 (signal_name, "ActiveChanged") == 0)
++	{
++		g_variant_get (parameters, "(b)", &application->screensaver_active);
++		g_debug ("Screensaver active changed to %d", application->screensaver_active);
++
++		check_volume_queue (application);
++	}
++}
++
++static void
++screensaver_get_active_ready_cb (GObject *source,
++				 GAsyncResult *res,
++				 gpointer user_data)
++{
++	CajaApplication *application = user_data;
++	GDBusProxy *proxy = application->ss_proxy;
++	GVariant *result;
++	GError *error = NULL;
++
++	result = g_dbus_proxy_call_finish (proxy,
++					   res,
++					   &error);
++
++	if (error != NULL) {
++		g_warning ("Can't call GetActive() on the ScreenSaver object: %s",
++			   error->message);
++		g_error_free (error);
++
++		return;
++	}
++
++	g_variant_get (result, "(b)", &application->screensaver_active);
++	g_variant_unref (result);
++
++	g_debug ("Screensaver GetActive() returned %d", application->screensaver_active);
++}
++
++static void
++screensaver_proxy_ready_cb (GObject *source,
++			    GAsyncResult *res,
++			    gpointer user_data)
++{
++	CajaApplication *application = user_data;
++	GError *error = NULL;
++	GDBusProxy *ss_proxy;
++	
++	ss_proxy = g_dbus_proxy_new_finish (res, &error);
++
++	if (error != NULL)
++	{
++		g_warning ("Can't get proxy for the ScreenSaver object: %s",
++			   error->message);
++		g_error_free (error);
++
++		return;
++	}
++
++	g_debug ("ScreenSaver proxy ready");
++
++	application->ss_proxy = ss_proxy;
++
++	g_signal_connect (ss_proxy, "g-signal",
++			  G_CALLBACK (screensaver_signal_callback), application);
++
++	g_dbus_proxy_call (ss_proxy,
++			   "GetActive",
++			   NULL,
++			   G_DBUS_CALL_FLAGS_NO_AUTO_START,
++			   -1,
++			   NULL,
++			   screensaver_get_active_ready_cb,
++			   application);
++}
++
++static void
++screensaver_appeared_callback (GDBusConnection *connection,
++			       const gchar *name,
++			       const gchar *name_owner,
++			       gpointer user_data)
++{
++	CajaApplication *application = user_data;
++
++	g_debug ("ScreenSaver name appeared");
++
++	application->screensaver_active = FALSE;
++
++	g_dbus_proxy_new (connection,
++			  G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
++			  NULL,
++			  name,
++			  SCREENSAVER_PATH,
++			  SCREENSAVER_INTERFACE,
++			  NULL,
++			  screensaver_proxy_ready_cb,
++			  application);
++}
++
++static void
++screensaver_vanished_callback (GDBusConnection *connection,
++			       const gchar *name,
++			       gpointer user_data)
++{
++	CajaApplication *application = user_data;
++
++	g_debug ("ScreenSaver name vanished");
++
++	application->screensaver_active = FALSE;
++	g_object_unref (&application->ss_proxy);
++
++	/* in this case force a clear of the volume queue, without
++	 * mounting them.
++	 */
++	if (application->volume_queue != NULL)
++	{
++		g_list_free_full (application->volume_queue, g_object_unref);
++		application->volume_queue = NULL;
++	}
++}
++
++static void
++do_initialize_screensaver (CajaApplication *application)
++{
++	application->ss_watch_id =
++		g_bus_watch_name (G_BUS_TYPE_SESSION,
++				  SCREENSAVER_NAME,
++				  G_BUS_NAME_WATCHER_FLAGS_NONE,
++				  screensaver_appeared_callback,
++				  screensaver_vanished_callback,
++				  application,
++				  NULL);
++}
++
++
++static void
+ do_upgrades_once (CajaApplication *application,
+                   gboolean no_desktop)
+ {
+@@ -601,7 +795,11 @@
+     /* Initialize the desktop link monitor singleton */
+     caja_desktop_link_monitor_get ();
+ 
+-    /* Watch for mounts so we can restore open windows This used
++    /* Initialize MATE screen saver listener to control automount
++	 * permission */
++	do_initialize_screensaver (application);
++
++ 	/* Watch for mounts so we can restore open windows This used
+      * to be for showing new window on mount, but is not used
+      * anymore */
+ 
+@@ -616,6 +814,8 @@
+                              G_CALLBACK (mount_added_callback), application, 0);
+     g_signal_connect_object (application->volume_monitor, "volume_added",
+                              G_CALLBACK (volume_added_callback), application, 0);
++    g_signal_connect_object (application->volume_monitor, "volume_removed",
++                             G_CALLBACK (volume_removed_callback), application, 0);
+     g_signal_connect_object (application->volume_monitor, "drive_connected",
+                              G_CALLBACK (drive_connected_callback), application, 0);
+ 
+@@ -1477,6 +1677,34 @@
+ }
+ 
+ static void
++check_screen_lock_and_mount (CajaApplication *application,
++                             GVolume *volume)
++{
++        if (application->screensaver_active)
++        {
++                /* queue the volume, to mount it after the screensaver state changed */
++                g_debug ("Queuing volume %p", volume);
++                application->volume_queue = g_list_prepend (application->volume_queue,
++                                                              g_object_ref (volume));
++        } else {
++                /* mount it immediately */
++		caja_file_operations_mount_volume (NULL, volume, TRUE);
++        }       
++}
++
++static void
++volume_removed_callback (GVolumeMonitor *monitor,
++                         GVolume *volume,
++                         CajaApplication *application)
++{
++        g_debug ("Volume %p removed, removing from the queue", volume);
++
++        /* clear it from the queue, if present */
++        application->volume_queue =
++                g_list_remove (application->volume_queue, volume);
++}
++
++static void
+ volume_added_callback (GVolumeMonitor *monitor,
+                        GVolume *volume,
+                        CajaApplication *application)
+@@ -1485,7 +1713,7 @@
+             g_volume_should_automount (volume) &&
+             g_volume_can_mount (volume))
+     {
+-        caja_file_operations_mount_volume (NULL, volume, TRUE);
++        check_screen_lock_and_mount (application, volume);
+     }
+     else
+     {
+--- a/src/caja-application.h
++++ b/src/caja-application.h
+@@ -66,6 +66,10 @@
+     EggSMClient* smclient;
+     GVolumeMonitor* volume_monitor;
+     unsigned int automount_idle_id;
++    gboolean screensaver_active;
++    guint ss_watch_id;
++    GDBusProxy *ss_proxy;
++    GList *volume_queue;
+ } CajaApplication;
+ 
+ typedef struct
diff -Nru caja-1.8.2/debian/patches/series caja-1.8.2/debian/patches/series
--- caja-1.8.2/debian/patches/series	2015-03-23 18:17:16.000000000 +0100
+++ caja-1.8.2/debian/patches/series	2015-05-11 09:26:06.000000000 +0200
@@ -1,3 +1,4 @@
 0001_fix-desktop-icon-size.patch
 0002_dont-start-desktop-outside-of-MATE-sessions.patch
 0003_fix-crash-in-places-sidebar.patch
+0004_avoid-automounts-while-screen-is-locked.patch

Reply to: