orion / rpms / dbus

Forked from rpms/dbus a year ago
Clone
275029
diff -urN dbus-1.10.24.old/bus/driver.c dbus-1.10.24/bus/driver.c
275029
--- dbus-1.10.24.old/bus/driver.c	2017-09-25 16:20:08.000000000 +0100
275029
+++ dbus-1.10.24/bus/driver.c	2018-02-13 10:15:09.570439595 +0000
275029
@@ -555,6 +555,9 @@
275029
   char **services;
275029
   BusRegistry *registry;
275029
   int i;
275029
+#ifdef HAVE_SELINUX
275029
+  dbus_bool_t mls_enabled;
275029
+#endif
275029
   DBusMessageIter iter;
275029
   DBusMessageIter sub;
275029
 
275029
@@ -601,9 +604,58 @@
275029
       }
275029
   }
275029
 
275029
+#ifdef HAVE_SELINUX
275029
+  mls_enabled = bus_selinux_mls_enabled ();
275029
+#endif
275029
   i = 0;
275029
   while (i < len)
275029
     {
275029
+#ifdef HAVE_SELINUX
275029
+      if (mls_enabled)
275029
+        {
275029
+          const char *requester;
275029
+          BusService *service;
275029
+          DBusString str;
275029
+          DBusConnection *service_conn;
275029
+          DBusConnection *requester_conn;
275029
+
275029
+          requester = dbus_message_get_destination (reply);
275029
+          _dbus_string_init_const (&str, requester);
275029
+          service = bus_registry_lookup (registry, &str);
275029
+
275029
+          if (service == NULL)
275029
+            {
275029
+              _dbus_warn_check_failed ("service lookup failed: %s", requester);
275029
+              ++i;
275029
+              continue;
275029
+            }
275029
+          requester_conn = bus_service_get_primary_owners_connection (service);
275029
+          _dbus_string_init_const (&str, services[i]);
275029
+          service = bus_registry_lookup (registry, &str);
275029
+          if (service == NULL)
275029
+            {
275029
+              _dbus_warn_check_failed ("service lookup failed: %s", services[i]);
275029
+              ++i;
275029
+              continue;
275029
+            }
275029
+          service_conn = bus_service_get_primary_owners_connection (service);
275029
+
275029
+          if (!bus_selinux_allows_name (requester_conn, service_conn, error))
275029
+            {
275029
+              if (dbus_error_is_set (error) &&
275029
+                  dbus_error_has_name (error, DBUS_ERROR_NO_MEMORY))
275029
+                {
275029
+                  dbus_free_string_array (services);
275029
+                  dbus_message_unref (reply);
275029
+                  return FALSE;
275029
+                }
275029
+
275029
+              /* Skip any services which are disallowed by SELinux policy. */
275029
+              ++i;
275029
+              continue;
275029
+            }
275029
+        }
275029
+#endif
275029
       if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING,
275029
                                            &services[i]))
275029
         {
275029
diff -urN dbus-1.10.24.old/bus/selinux.c dbus-1.10.24/bus/selinux.c
275029
--- dbus-1.10.24.old/bus/selinux.c	2017-07-28 07:24:16.000000000 +0100
275029
+++ dbus-1.10.24/bus/selinux.c	2018-02-13 10:35:14.311477447 +0000
275029
@@ -61,6 +61,9 @@
275029
 /* Store the value telling us if SELinux is enabled in the kernel. */
275029
 static dbus_bool_t selinux_enabled = FALSE;
275029
 
275029
+/* Store the value telling us if SELinux with MLS is enabled in the kernel. */
275029
+static dbus_bool_t selinux_mls_enabled = FALSE;
275029
+
275029
 /* Store an avc_entry_ref to speed AVC decisions. */
275029
 static struct avc_entry_ref aeref;
275029
 
275029
@@ -273,6 +276,20 @@
275029
 }
275029
 
275029
 /**
275029
+ * Return whether or not SELinux with MLS support is enabled; must be
275029
+ * called after bus_selinux_init.
275029
+ */
275029
+dbus_bool_t
275029
+bus_selinux_mls_enabled (void)
275029
+{
275029
+#ifdef HAVE_SELINUX
275029
+  return selinux_mls_enabled;
275029
+#else
275029
+  return FALSE;
275029
+#endif /* HAVE_SELINUX */
275029
+}
275029
+
275029
+/**
275029
  * Do early initialization; determine whether SELinux is enabled.
275029
  */
275029
 dbus_bool_t
275029
@@ -292,6 +309,16 @@
275029
     }
275029
 
275029
   selinux_enabled = r != 0;
275029
+
275029
+  r = is_selinux_mls_enabled ();
275029
+  if (r < 0)
275029
+    {
275029
+      _dbus_warn ("Could not tell if SELinux MLS is enabled: %s\n",
275029
+                  _dbus_strerror (errno));
275029
+      return FALSE;
275029
+    }
275029
+
275029
+  selinux_mls_enabled = r != 0;
275029
   return TRUE;
275029
 #else
275029
   return TRUE;
275029
@@ -304,14 +331,18 @@
275029
  */
275029
 /* security dbus class constants */
275029
 #define SECCLASS_DBUS       1
275029
+#define SECCLASS_CONTEXT    2
275029
 
275029
 /* dbus's per access vector constants */
275029
 #define DBUS__ACQUIRE_SVC   1
275029
 #define DBUS__SEND_MSG      2
275029
 
275029
+#define CONTEXT__CONTAINS   1
275029
+
275029
 #ifdef HAVE_SELINUX
275029
 static struct security_class_mapping dbus_map[] = {
275029
   { "dbus", { "acquire_svc", "send_msg", NULL } },
275029
+  { "context", { "contains", NULL } },
275029
   { NULL }
275029
 };
275029
 #endif /* HAVE_SELINUX */
275029
@@ -734,6 +765,102 @@
275029
 #endif /* HAVE_SELINUX */
275029
 
275029
 /**
275029
+ * Check if SELinux security controls allow one connection to determine the
275029
+ * name of the other, taking into account MLS considerations.
275029
+ *
275029
+ * @param source the requester of the name.
275029
+ * @param destination the name being requested.
275029
+ * @returns whether the name should be visible by the source of the request
275029
+ */
275029
+dbus_bool_t
275029
+bus_selinux_allows_name (DBusConnection     *source,
275029
+                         DBusConnection     *destination,
275029
+                         DBusError          *error)
275029
+{
275029
+#ifdef HAVE_SELINUX
275029
+  int err;
275029
+  char *policy_type;
275029
+  unsigned long spid, tpid;
275029
+  BusSELinuxID *source_sid;
275029
+  BusSELinuxID *dest_sid;
275029
+  dbus_bool_t ret;
275029
+  dbus_bool_t string_alloced;
275029
+  DBusString auxdata;
275029
+
275029
+  if (!selinux_mls_enabled)
275029
+    return TRUE;
275029
+
275029
+  err = selinux_getpolicytype (&policy_type);
275029
+  if (err < 0)
275029
+    {
275029
+      dbus_set_error_const (error, DBUS_ERROR_IO_ERROR,
275029
+                            "Failed to get SELinux policy type");
275029
+      return FALSE;
275029
+    }
275029
+
275029
+  /* Only check against MLS policy if running under that policy. */
275029
+  if (strcmp (policy_type, "mls") != 0)
275029
+    {
275029
+      free (policy_type);
275029
+      return TRUE;
275029
+    }
275029
+
275029
+  free (policy_type);
275029
+
275029
+  _dbus_assert (source != NULL);
275029
+  _dbus_assert (destination != NULL);
275029
+
275029
+  if (!source || !dbus_connection_get_unix_process_id (source, &spid))
275029
+    spid = 0;
275029
+  if (!destination || !dbus_connection_get_unix_process_id (destination, &tpid))
275029
+    tpid = 0;
275029
+
275029
+  string_alloced = FALSE;
275029
+  if (!_dbus_string_init (&auxdata))
275029
+    goto oom;
275029
+  string_alloced = TRUE;
275029
+
275029
+  if (spid)
275029
+    {
275029
+      if (!_dbus_string_append (&auxdata, " spid="))
275029
+	goto oom;
275029
+
275029
+      if (!_dbus_string_append_uint (&auxdata, spid))
275029
+	goto oom;
275029
+    }
275029
+
275029
+  if (tpid)
275029
+    {
275029
+      if (!_dbus_string_append (&auxdata, " tpid="))
275029
+	goto oom;
275029
+
275029
+      if (!_dbus_string_append_uint (&auxdata, tpid))
275029
+	goto oom;
275029
+    }
275029
+
275029
+  source_sid = bus_connection_get_selinux_id (source);
275029
+  dest_sid = bus_connection_get_selinux_id (destination);
275029
+
275029
+  ret = bus_selinux_check (source_sid,
275029
+                           dest_sid,
275029
+                           SECCLASS_CONTEXT,
275029
+                           CONTEXT__CONTAINS,
275029
+                           &auxdata);
275029
+
275029
+  _dbus_string_free (&auxdata);
275029
+  return ret;
275029
+
275029
+ oom:
275029
+  if (string_alloced)
275029
+    _dbus_string_free (&auxdata);
275029
+  BUS_SET_OOM (error);
275029
+  return FALSE;
275029
+#else
275029
+  return TRUE;
275029
+#endif /* HAVE_SELINUX */
275029
+}
275029
+
275029
+/**
275029
  * Read the SELinux ID from the connection.
275029
  *
275029
  * @param connection the connection to read from
275029
Binary files dbus-1.10.24.old/bus/.selinux.c.swp and dbus-1.10.24/bus/.selinux.c.swp differ
275029
diff -urN dbus-1.10.24.old/bus/selinux.h dbus-1.10.24/bus/selinux.h
275029
--- dbus-1.10.24.old/bus/selinux.h	2017-07-28 07:24:16.000000000 +0100
275029
+++ dbus-1.10.24/bus/selinux.h	2018-02-13 10:15:09.573439444 +0000
275029
@@ -32,6 +32,7 @@
275029
 void        bus_selinux_shutdown (void);
275029
 
275029
 dbus_bool_t bus_selinux_enabled  (void);
275029
+dbus_bool_t bus_selinux_mls_enabled (void);
275029
 
275029
 void bus_selinux_id_ref    (BusSELinuxID *sid);
275029
 void bus_selinux_id_unref  (BusSELinuxID *sid);
275029
@@ -54,6 +55,10 @@
275029
 						const char     *service_name,
275029
 						DBusError      *error);
275029
 
275029
+dbus_bool_t bus_selinux_allows_name            (DBusConnection *source,
275029
+                                                DBusConnection *destination,
275029
+                                                DBusError      *error);
275029
+
275029
 dbus_bool_t bus_selinux_allows_send            (DBusConnection *sender,
275029
                                                 DBusConnection *proposed_recipient,
275029
 						const char     *msgtype, /* Supplementary audit data */