Sophie

Sophie

distrib > Mageia > 4 > i586 > media > core-release-src > by-pkgid > 186886424cebc51bfe54b428c3d5f5c7 > files > 5

gypsy-0.8-7.mga4.src.rpm

From aa071099802f3bf866cffbfb25196dcdf1fbba1e Mon Sep 17 00:00:00 2001
From: Michael Leibowitz <michael.leibowitz@intel.com>
Date: Wed, 16 Mar 2011 22:29:06 -0700
Subject: [PATCH] Add a config file that specifies a whitelist of allowed
 devices

This is in response to Bug 33431 "CVE-2011-0523: arbitrary file access
and buffer overflows" A new config file, /etc/gypsy.conf, is added
that specifies a whitelist of globs.  By default, they are
"/dev/tty*", "/dev/pgps", and "bluetooth" (which matches Bluetooth
addresses).

Signed-off-by: Michael Leibowitz <michael.leibowitz@intel.com>

Further changes by Bastien Nocera <hadess@hadess.net>
---
 Makefile.am        |    2 +-
 configure.ac       |    3 ++
 etc/Makefile.am    |    2 +
 etc/gypsy.conf     |    2 +
 src/gypsy-server.c |   69 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/gypsy-server.h |    1 +
 6 files changed, 78 insertions(+), 1 deletions(-)
 create mode 100644 etc/Makefile.am
 create mode 100644 etc/gypsy.conf

diff --git a/Makefile.am b/Makefile.am
index 8b4090e..174a2af 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = interfaces src gypsy examples docs
+SUBDIRS = interfaces src gypsy examples docs etc
 
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = gypsy.pc
diff --git a/configure.ac b/configure.ac
index 3484051..a441ceb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -43,6 +43,8 @@ DBUS_SYS_DIR="${sysconfdir}/dbus-1/system.d"
 AC_SUBST(DBUS_SYS_DIR)
 AC_DEFINE_UNQUOTED(DBUS_SYS_DIR, "$DBUS_SYS_DIR", [Where the system dir for D-Bus is])
 
+AC_DEFINE_UNQUOTED(CONFIG_FILE_PATH, "${sysconfdir}/gypsy.conf", [The absolute path of the config file])
+
 DBUS_SERVICES_DIR="${datadir}/dbus-1/system-services"
 AC_SUBST(DBUS_SERVICES_DIR)
 AC_DEFINE_UNQUOTED(DBUS_SERVICES_DIR, "$DBUS_SERVICES_DIR", [Where services dir for D-Bus is])
@@ -72,6 +74,7 @@ docs/Makefile
 docs/reference/Makefile
 docs/reference/version.xml
 docs/tools/Makefile
+etc/Makefile
 gypsy.pc
 ])
 
diff --git a/etc/Makefile.am b/etc/Makefile.am
new file mode 100644
index 0000000..77d58f4
--- /dev/null
+++ b/etc/Makefile.am
@@ -0,0 +1,2 @@
+configdir = $(sysconfdir)
+dist_config_DATA = gypsy.conf
diff --git a/etc/gypsy.conf b/etc/gypsy.conf
new file mode 100644
index 0000000..be76a35
--- /dev/null
+++ b/etc/gypsy.conf
@@ -0,0 +1,2 @@
+[gypsy]
+AllowedDeviceGlobs=/dev/tty*;/dev/pgps;bluetooth
diff --git a/src/gypsy-server.c b/src/gypsy-server.c
index e2e3c1c..3ff13f4 100644
--- a/src/gypsy-server.c
+++ b/src/gypsy-server.c
@@ -28,12 +28,17 @@
 /*
  * GypsyServer - The main control object that creates GPS connection objects.
  */
+#include "config.h"
 #include <glib.h>
 
 #include <dbus/dbus-glib.h>
 #include <dbus/dbus-glib-bindings.h>
 #include <dbus/dbus-glib-lowlevel.h>
 
+#ifdef HAVE_BLUEZ
+#include <bluetooth/bluetooth.h>
+#endif
+
 #include "gypsy-server.h"
 #include "gypsy-client.h"
 
@@ -49,6 +54,9 @@ typedef struct _GypsyServerPrivate {
 	int client_count; /* When client_count returns to 0, 
 			     we quit the daemon after TERMINATE_TIMEOUT */
 	guint32 terminate_id;
+
+	gchar **allowed_device_globs;
+	gsize allowed_device_glob_count;
 } GypsyServerPrivate;
 
 static guint32 signals[LAST_SIGNAL] = {0, };
@@ -60,6 +68,9 @@ G_DEFINE_TYPE (GypsyServer, gypsy_server, G_TYPE_OBJECT);
 #define GYPSY_GPS_PATH "/org/freedesktop/Gypsy/"
 #define TERMINATE_TIMEOUT 10000 /* 10 second timeout */
 
+#define GYPSY_CONF_GROUP "gypsy"
+#define GYPSY_CONF_GLOB_KEY "AllowedDeviceGlobs"
+
 static void gypsy_server_create (GypsyServer            *gps,
 				 const char             *IN_device_path,
 				 DBusGMethodInvocation *context);
@@ -102,6 +113,8 @@ gypsy_server_create (GypsyServer           *gps,
 	GypsyClient *client;
 	char *path, *device_name, *sender;
 	GList *list;
+	int i;
+	gboolean allowed;
 
 	priv = GET_PRIVATE (gps);
 
@@ -113,6 +126,40 @@ gypsy_server_create (GypsyServer           *gps,
 	}
 
 	g_debug ("Creating client for %s", IN_device_path);
+
+	/* compare priv->device_path to allowed globs
+	 * if not allowed, error out */
+	allowed = FALSE;
+	for (i = 0; i < priv->allowed_device_glob_count; i++) {
+		if (g_str_equal (priv->allowed_device_globs[i], "bluetooth")) {
+#ifdef HAVE_BLUEZ
+			if (bachk (IN_device_path) == 0) {
+				allowed = TRUE;
+				break;
+			}
+#else
+			continue;
+#endif /* HAVE_BLUEZ */
+		}
+		if (g_pattern_match_simple (priv->allowed_device_globs[i],
+					    IN_device_path)) {
+			allowed = TRUE;
+			break;
+		}
+	}
+	if (allowed == FALSE) {
+		g_warning ("The device path %s is not allowed by config file",
+			   IN_device_path);
+		GError *error = NULL;
+		error = g_error_new (GYPSY_SERVER_ERROR,
+				     GYPSY_SERVER_ERROR_BAD_PATH,
+				     "Bad path: %s",
+				     IN_device_path);
+		dbus_g_method_return_error (context, error);
+		g_error_free (error);
+		return;
+	}
+
 	device_name = g_path_get_basename (IN_device_path);
 	g_debug ("Device name: %s", device_name);
 	path = g_strdup_printf ("%s%s", GYPSY_GPS_PATH, 
@@ -250,6 +297,7 @@ gypsy_server_init (GypsyServer *gps)
 {
 	GypsyServerPrivate *priv = GET_PRIVATE (gps);
 	GError *error = NULL;
+	GKeyFile *key_file = NULL;
 
 	priv->connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
 	if (priv->connection == NULL) {
@@ -265,6 +313,27 @@ gypsy_server_init (GypsyServer *gps)
 
 	priv->client_count = 0;
 	priv->terminate_id = 0;
+
+	key_file = g_key_file_new();
+	if (!g_key_file_load_from_file (key_file, CONFIG_FILE_PATH,
+				       G_KEY_FILE_NONE, &error))
+		goto error;
+
+	priv->allowed_device_globs = g_key_file_get_string_list (key_file,
+								 GYPSY_CONF_GROUP,
+								 GYPSY_CONF_GLOB_KEY,
+								 &(priv->allowed_device_glob_count),
+								 &error);
+	if (!priv->allowed_device_globs)
+		goto error;
+
+	return;
+
+error:
+	g_warning ("Error parsing config file:\n%s",
+		   error->message);
+	g_error_free (error);
+	g_key_file_free (key_file);
 }
 
 void
diff --git a/src/gypsy-server.h b/src/gypsy-server.h
index 465f18e..3470ba7 100644
--- a/src/gypsy-server.h
+++ b/src/gypsy-server.h
@@ -37,6 +37,7 @@ G_BEGIN_DECLS
 
 typedef enum {
 	GYPSY_SERVER_ERROR_NO_CLIENT,
+	GYPSY_SERVER_ERROR_BAD_PATH
 } GypsyServerError;
 
 typedef struct _GypsyServer {
-- 
1.7.6.2