You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
268 lines
7.5 KiB
268 lines
7.5 KiB
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 */
|
|
|