From 6072f8b24153d844a3033108a17bcd0c1a967816 Mon Sep 17 00:00:00 2001
From: Laurent Bigonville <bigon@bigon.be>
Date: Sat, 3 Mar 2018 11:15:23 +0100
Subject: [PATCH] Stop using selinux_set_mapping() function

Currently, if the "dbus" security class or the associated AV doesn't
exist, dbus-daemon fails to initialize and exits immediately. Also the
security classes or access vector cannot be reordered in the policy.
This can be a problem for people developing their own policy or trying
to access a machine where, for some reasons, there is not policy defined
at all.

The code here copy the behaviour of the selinux_check_access() function.
We cannot use this function here as it doesn't allow us to define the
AVC entry reference.

See the discussion at https://marc.info/?l=selinux&m=152163374332372&w=2

Resolves: https://gitlab.freedesktop.org/dbus/dbus/issues/198

Conflict:function bus_selinux_full_init (void) is modified to adapt to the context.
Reference:https://github.com/freedesktop/dbus/commit/6072f8b24153d844a3033108a17bcd0c1a967816
---
 bus/selinux.c | 75 ++++++++++++++++++++++++++++-----------------------
 1 file changed, 42 insertions(+), 33 deletions(-)

diff --git a/bus/selinux.c b/bus/selinux.c
index a005b84f..7e63348c 100644
--- a/bus/selinux.c
+++ b/bus/selinux.c
@@ -232,24 +232,6 @@ bus_selinux_pre_init (void)
 #endif
 }
 
-/*
- * Private Flask definitions; the order of these constants must
- * exactly match that of the structure array below!
- */
-/* security dbus class constants */
-#define SECCLASS_DBUS       1
-
-/* dbus's per access vector constants */
-#define DBUS__ACQUIRE_SVC   1
-#define DBUS__SEND_MSG      2
-
-#ifdef HAVE_SELINUX
-static struct security_class_mapping dbus_map[] = {
-  { "dbus", { "acquire_svc", "send_msg", NULL } },
-  { NULL }
-};
-#endif /* HAVE_SELINUX */
-
 /**
  * Establish dynamic object class and permission mapping and
  * initialize the user space access vector cache (AVC) for D-Bus and set up
@@ -350,13 +350,6 @@ bus_selinux_full_init (void)
 
   _dbus_verbose ("SELinux is enabled in this kernel.\n");
 
-  if (selinux_set_mapping (dbus_map) < 0)
-    {
-      _dbus_warn ("Failed to set up security class mapping (selinux_set_mapping():%s).",
-                   strerror (errno));
-      return FALSE; 
-    }
-
   avc_entry_ref_init (&aeref);
   if (avc_init ("avc", &mem_cb, &log_cb, &thread_cb, &lock_cb) < 0)
     {
@@ -392,19 +367,53 @@ error:
 static dbus_bool_t
 bus_selinux_check (BusSELinuxID        *sender_sid,
                    BusSELinuxID        *override_sid,
-                   security_class_t     target_class,
-                   access_vector_t      requested,
-		   DBusString          *auxdata)
+                   const char          *target_class,
+                   const char          *requested,
+                   DBusString          *auxdata)
 {
+  int saved_errno;
+  security_class_t security_class;
+  access_vector_t requested_access;
+
   if (!selinux_enabled)
     return TRUE;
 
+  security_class = string_to_security_class (target_class);
+  if (security_class == 0)
+    {
+      saved_errno = errno;
+      log_callback (SELINUX_ERROR, "Unknown class %s", target_class);
+      if (security_deny_unknown () == 0)
+        {
+          return TRUE;
+	}
+
+      _dbus_verbose ("Unknown class %s\n", target_class);
+      errno = saved_errno;
+      return FALSE;
+    }
+
+  requested_access = string_to_av_perm (security_class, requested);
+  if (requested_access == 0)
+    {
+      saved_errno = errno;
+      log_callback (SELINUX_ERROR, "Unknown permission %s for class %s", requested, target_class);
+      if (security_deny_unknown () == 0)
+        {
+          return TRUE;
+	}
+
+      _dbus_verbose ("Unknown permission %s for class %s\n", requested, target_class);
+      errno = saved_errno;
+      return FALSE;
+    }
+
   /* Make the security check.  AVC checks enforcing mode here as well. */
   if (avc_has_perm (SELINUX_SID_FROM_BUS (sender_sid),
                     override_sid ?
                     SELINUX_SID_FROM_BUS (override_sid) :
                     bus_sid,
-                    target_class, requested, &aeref, auxdata) < 0)
+                    security_class, requested_access, &aeref, auxdata) < 0)
     {
     switch (errno)
       {
@@ -471,8 +480,8 @@ bus_selinux_allows_acquire_service (DBusConnection     *connection,
   
   ret = bus_selinux_check (connection_sid,
 			   service_sid,
-			   SECCLASS_DBUS,
-			   DBUS__ACQUIRE_SVC,
+			   "dbus",
+			   "acquire_svc",
 			   &auxdata);
 
   _dbus_string_free (&auxdata);
@@ -600,8 +609,8 @@ bus_selinux_allows_send (DBusConnection     *sender,
 
   ret = bus_selinux_check (sender_sid, 
 			   recipient_sid,
-			   SECCLASS_DBUS, 
-			   DBUS__SEND_MSG,
+			   "dbus",
+			   "send_msg",
 			   &auxdata);
 
   _dbus_string_free (&auxdata);
-- 
2.23.0

