--- Begin Message ---
Package: caja
Version: 1.8.2-3
Severity: normal
Tags: patch, security
User: [email protected]
Usertags: origin-ubuntu natty ubuntu-patch
To avoid auto-run drive-by attacks by a physically proximate attacker on
the system from USB auto-mounting screen is locked, the desktop should
delay automounting until the screen is unlocked (to not interfere with
the case of sitting back down at your system, plugging in a device,
and then unlocking your screen).
This is similar to how gnome-keyring flushes all keys the when locking
the screen.
http://www.net-security.org/secworld.php?id=10544
This was fixed in Gnome upstream and in Ubuntu:
https://bugs.launchpad.net/ubuntu/+source/nautilus/+bug/714958
https://bugs.launchpad.net/ubuntu/+source/nautilus/+bug/724285
The attached patch likely needs the dbus names changed to, e.g.,
"org.mate.ScreenSaver".
Thanks!
-Kees
--
Kees Cook @debian.org
>From 98ebb6be0882ba2dbb0c621a2906e5190108bca1 Mon Sep 17 00:00:00 2001
From: Martin Pitt <[email protected]>
Date: Tue, 22 Feb 2011 14:06:14 +0100
Subject: [PATCH] disable automounting while screen is locked
On the recent Shmoocon 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 o
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 GNOME screen saver is currently locked.
Backported from gnome-settings-daemon trunk commits 71deedf7 and 90c0f8676.
https://bugzilla.gnome.org/show_bug.cgi?id=642020
---
src/nautilus-application.c | 219 +++++++++++++++++++++++++++++++++++++++++++-
src/nautilus-application.h | 5 +
2 files changed, 223 insertions(+), 1 deletions(-)
Index: nautilus-2.32.2.1/src/nautilus-application.c
===================================================================
--- nautilus-2.32.2.1.orig/src/nautilus-application.c 2010-12-28 16:54:38.000000000 +0100
+++ nautilus-2.32.2.1/src/nautilus-application.c 2011-03-15 15:04:00.659603038 +0100
@@ -116,6 +116,9 @@
static void volume_added_callback (GVolumeMonitor *monitor,
GVolume *volume,
NautilusApplication *application);
+static void volume_removed_callback (GVolumeMonitor *monitor,
+ GVolume *volume,
+ NautilusApplication *application);
static void drive_connected_callback (GVolumeMonitor *monitor,
GDrive *drive,
NautilusApplication *application);
@@ -347,6 +350,15 @@
g_object_unref (application->unique_app);
+ 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;
@@ -357,6 +369,11 @@
application->proxy = NULL;
}
+ if (application->ss_proxy != NULL) {
+ g_object_unref (application->ss_proxy);
+ application->ss_proxy = NULL;
+ }
+
G_OBJECT_CLASS (nautilus_application_parent_class)->finalize (object);
}
@@ -663,6 +680,175 @@
}
static void
+check_volume_queue (NautilusApplication *application)
+{
+ GList *l, *next;
+ GVolume *volume;
+
+ l = application->volume_queue;
+
+ if (application->screensaver_active) {
+ return;
+ }
+
+ while (l != NULL) {
+ volume = l->data;
+ next = l->next;
+
+ nautilus_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.gnome.ScreenSaver"
+#define SCREENSAVER_PATH "/org/gnome/ScreenSaver"
+#define SCREENSAVER_INTERFACE "org.gnome.ScreenSaver"
+
+static void
+screensaver_signal_callback (GDBusProxy *proxy,
+ const gchar *sender_name,
+ const gchar *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
+{
+ NautilusApplication *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)
+{
+ NautilusApplication *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)
+{
+ NautilusApplication *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)
+{
+ NautilusApplication *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)
+{
+ NautilusApplication *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 (NautilusApplication *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 (NautilusApplication *application,
gboolean no_desktop)
{
@@ -709,6 +895,10 @@
/* Initialize the ConsoleKit listener for active session */
do_initialize_consolekit (application);
+ /* Initialize GNOME 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 */
@@ -724,6 +914,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);
@@ -1520,6 +1712,33 @@
}
static void
+check_screen_lock_and_mount (NautilusApplication *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 */
+ nautilus_file_operations_mount_volume (NULL, volume, TRUE);
+ }
+}
+
+static void
+volume_removed_callback (GVolumeMonitor *monitor,
+ GVolume *volume,
+ NautilusApplication *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,
NautilusApplication *application)
@@ -1527,7 +1746,7 @@
if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_MEDIA_AUTOMOUNT) &&
g_volume_should_automount (volume) &&
g_volume_can_mount (volume)) {
- nautilus_file_operations_mount_volume (NULL, volume, TRUE);
+ check_screen_lock_and_mount (application, volume);
} else {
/* Allow nautilus_autorun() to run. When the mount is later
* added programmatically (i.e. for a blank CD),
Index: nautilus-2.32.2.1/src/nautilus-application.h
===================================================================
--- nautilus-2.32.2.1.orig/src/nautilus-application.h 2010-12-28 16:54:38.000000000 +0100
+++ nautilus-2.32.2.1/src/nautilus-application.h 2011-03-15 15:03:21.099603020 +0100
@@ -68,6 +68,11 @@
unsigned int automount_idle_id;
GDBusProxy *proxy;
gboolean session_is_active;
+
+ gboolean screensaver_active;
+ guint ss_watch_id;
+ GDBusProxy *ss_proxy;
+ GList *volume_queue;
} NautilusApplication;
typedef struct {
--- End Message ---