From f3cecb119d687f6539a30d92c2c23eb47cdd46dd Mon Sep 17 00:00:00 2001 From: Laurent Bigonville 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 developping 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 https://bugs.freedesktop.org/show_bug.cgi?id=105330 --- bus/selinux.c | 86 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 35 deletions(-) diff --git a/bus/selinux.c b/bus/selinux.c index ef737c29..4db9b8ac 100644 --- a/bus/selinux.c +++ b/bus/selinux.c @@ -231,24 +231,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 @@ -270,13 +252,6 @@ bus_selinux_full_init (BusContext *context, DBusError *error) _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_open (NULL, 0) < 0) { @@ -390,19 +365,58 @@ 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, + DBusError *error) { + 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_set_error (error, DBUS_ERROR_ACCESS_DENIED, + "Error getting security class \"%s\": %s", + target_class, _dbus_strerror (errno)); + 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_set_error (error, DBUS_ERROR_ACCESS_DENIED, + "Error getting access vector \"%s\" for class \"%s\": %s", + requested, target_class, _dbus_strerror (errno)); + 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) { @@ -469,9 +483,10 @@ bus_selinux_allows_acquire_service (DBusConnection *connection, ret = bus_selinux_check (connection_sid, service_sid, - SECCLASS_DBUS, - DBUS__ACQUIRE_SVC, - &auxdata); + "dbus", + "acquire_svc", + &auxdata, + error); _dbus_string_free (&auxdata); return ret; @@ -598,9 +613,10 @@ bus_selinux_allows_send (DBusConnection *sender, ret = bus_selinux_check (sender_sid, recipient_sid, - SECCLASS_DBUS, - DBUS__SEND_MSG, - &auxdata); + "dbus", + "send_msg", + &auxdata, + error); _dbus_string_free (&auxdata); -- 2.19.0.rc1