From 6e4660477ded38019ddecacba5cc1f5a17494179 Mon Sep 17 00:00:00 2001 From: "osmond.sun" Date: Sun, 3 Nov 2013 06:43:10 +0800 Subject: [PATCH] Dbus selinux: get the class value and perm access vector bit from policy Get the class value and perm access vector bit according to the selinux policy, instead of the hard coded value from flask.h and av_permissions.h. If use the hard coded value, the index value of "dbus" class must be 52 in the selinux's policy ,elsewise there will be "SELinux: Invalid class 52". SELinux can dynamically discover class and permission values upon policy load, I think we should let dbus can be used for more selinux policy not just for refpolicy or something else. --- bus/selinux.c | 96 ++++- 1 files changed, 2445 insertions(+), 11 deletions(-) diff --git a/bus/selinux.c b/bus/selinux.c index 36287e9..c58a21b 100644 --- a/bus/selinux.c +++ b/bus/selinux.c @@ -480,7 +480,9 @@ bus_selinux_allows_acquire_service (DBusConnection *connection, unsigned long spid; DBusString auxdata; dbus_bool_t ret; - + int get_class_ret; + security_class_t class_dbus; + access_vector_t dbus_av_perm; if (!selinux_enabled) return TRUE; @@ -505,13 +507,23 @@ bus_selinux_allows_acquire_service (DBusConnection *connection, if (!_dbus_string_append_uint (&auxdata, spid)) goto oom; } - - ret = bus_selinux_check (connection_sid, - service_sid, - SECCLASS_DBUS, - DBUS__ACQUIRE_SVC, - &auxdata); + get_class_ret = bus_selinux_get_class_perm_value ("dbus", + "acquire_svc", + &class_dbus, + &dbus_av_perm); + if (get_class_ret == 0) + { + ret = bus_selinux_check (connection_sid, + service_sid, + class_dbus, + dbus_av_perm, + &auxdata); + } + else + { + ret = (get_class_ret == 1) ? TRUE : FALSE; + } _dbus_string_free (&auxdata); return ret; @@ -525,6 +537,54 @@ bus_selinux_allows_acquire_service (DBusConnection *connection, #endif /* HAVE_SELINUX */ } +#ifdef HAVE_SELINUX +/** + * Get dbus's class value and it's access vecotr bit from policy instead of + * hard coded. + * If can't get find the class from the policy ,use deny_unknown bit to + * determine the queries + * + * @param class_str the class to get,here will always be "dbus" + * @param perm_str the access vector name + * @param class_dbus the class value corresponding to the string name class_str + * @param dbus_perm the access vector bit corresponding the string perm_str + * @returns 0 get the class value and access vector success + * -1 deny all the request + * 1 allow all the request + */ +int +bus_selinux_get_class_perm_value(char * class_str, + char * perm_str, + security_class_t * class_dbus, + access_vector_t * dbus_perm) +{ + int deny_unknown; + if ((deny_unknown = security_deny_unknown()) == -1) + { + _dbus_warn("Error getting deny_unknown status."); + //if security_deny_unknown error ,we treat the queries as being denied; + deny_unknown = 1; + } + if ((*class_dbus = string_to_security_class(class_str)) == 0) + { + _dbus_warn("Error getting security class \"%s\" value.",class_str); + goto error; + } + if ((*dbus_perm = string_to_av_perm(*class_dbus,perm_str)) == 0) + { + _dbus_warn("Error getting the access vector bit corresponding to the security class \"%s\" and perm \"%s\".",class_str, perm_str); + goto error; + } + return 0; +error: + if (deny_unknown) + return -1; + else + return 1; +} +#endif /* HAVE_SELINUX */ + + /** * Check if SELinux security controls allow the message to be sent to a * particular connection based on the security context of the sender and @@ -552,6 +612,9 @@ bus_selinux_allows_send (DBusConnection *sender, DBusString auxdata; dbus_bool_t ret; dbus_bool_t string_alloced; + int get_class_ret; + security_class_t class_dbus; + access_vector_t dbus_av_perm; if (!selinux_enabled) return TRUE; @@ -629,11 +692,22 @@ bus_selinux_allows_send (DBusConnection *sender, else recipient_sid = BUS_SID_FROM_SELINUX (bus_sid); - ret = bus_selinux_check (sender_sid, - recipient_sid, - SECCLASS_DBUS, - DBUS__SEND_MSG, + get_class_ret = bus_selinux_get_class_perm_value ("dbus", + "send_msg", + &class_dbus, + &dbus_av_perm); + if(get_class_ret == 0) + { + ret = bus_selinux_check (sender_sid, + recipient_sid, + class_dbus, + dbus_av_perm, &auxdata); + } + else + { + ret = (get_class_ret == 1) ? TRUE : FALSE; + } _dbus_string_free (&auxdata);