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