From 935a41a04c3f638134fa905503fc41ddbd18902f Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 9 Nov 2004 06:11:33 +0000 Subject: 2004-11-09 Colin Walters * dbus/dbus-string.c (_dbus_string_get_length): New function, writes DBusString to C buffer. * dbus/dbus-string.h: Prototype it. * dbus/dbus-message.c (dbus_message_type_to_string): New function, converts message type into C string. * dbus/dbus-message.h: Prototype it. * bus/selinux.c (bus_selinux_check): Take source pid, target pid, and audit data. Pass audit data to avc_has_perm. (log_audit_callback): New function, appends extra audit information. (bus_selinux_allows_acquire_service): Also take service name, add it to audit data. (bus_selinux_allows_send): Also take message type, interface, method member, error name, and destination, and add them to audit data. (log_cb): Initialize func_audit. * bus/selinux.h (bus_selinux_allows_acquire_service) (bus_selinux_allows_send): Update prototypes * bus/services.c (bus_registry_acquire_service): Pass service name to bus_selinux_allows_acquire_service. * bus/bus.c (bus_context_check_security_policy): Pass additional audit data. Move assignment of dest to its own line. --- bus/bus.c | 24 +++++++++++--- bus/selinux.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++------ bus/selinux.h | 12 ++++--- bus/services.c | 3 +- 4 files changed, 118 insertions(+), 19 deletions(-) (limited to 'bus') diff --git a/bus/bus.c b/bus/bus.c index 65e396c3..a80636b1 100644 --- a/bus/bus.c +++ b/bus/bus.c @@ -1127,12 +1127,20 @@ bus_context_check_security_policy (BusContext *context, if (sender != NULL) { + const char *dest; + + dest = dbus_message_get_destination (message); + /* First verify the SELinux access controls. If allowed then * go on with the standard checks. */ - if (!bus_selinux_allows_send (sender, proposed_recipient)) + if (!bus_selinux_allows_send (sender, proposed_recipient, + dbus_message_type_to_string (dbus_message_get_type (message)), + dbus_message_get_interface (message), + dbus_message_get_member (message), + dbus_message_get_error_name (message), + dest ? dest : DBUS_SERVICE_ORG_FREEDESKTOP_DBUS)) { - const char *dest = dbus_message_get_destination (message); dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, "An SELinux policy prevents this sender " "from sending this message to this recipient " @@ -1255,7 +1263,9 @@ bus_context_check_security_policy (BusContext *context, proposed_recipient, message)) { - const char *dest = dbus_message_get_destination (message); + const char *dest; + + dest = dbus_message_get_destination (message); dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, "A security policy in place prevents this sender " "from sending this message to this recipient, " @@ -1280,7 +1290,9 @@ bus_context_check_security_policy (BusContext *context, addressed_recipient, proposed_recipient, message)) { - const char *dest = dbus_message_get_destination (message); + const char *dest; + + dest = dbus_message_get_destination (message); dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, "A security policy in place prevents this recipient " "from receiving this message from this sender, " @@ -1304,7 +1316,9 @@ bus_context_check_security_policy (BusContext *context, dbus_connection_get_outgoing_size (proposed_recipient) > context->limits.max_outgoing_bytes) { - const char *dest = dbus_message_get_destination (message); + const char *dest; + + dest = dbus_message_get_destination (message); dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED, "The destination service \"%s\" has a full message queue", dest ? dest : (proposed_recipient ? diff --git a/bus/selinux.c b/bus/selinux.c index 0a3dec70..9527489f 100644 --- a/bus/selinux.c +++ b/bus/selinux.c @@ -57,6 +57,7 @@ static pthread_t avc_notify_thread; /* Prototypes for AVC callback functions. */ static void log_callback (const char *fmt, ...); +static void log_audit_callback (void *data, security_class_t class, char *buf, size_t bufleft); static void *avc_create_thread (void (*run) (void)); static void avc_stop_thread (void *thread); static void *avc_alloc_lock (void); @@ -73,7 +74,7 @@ static const struct avc_memory_callback mem_cb = static const struct avc_log_callback log_cb = { .func_log = log_callback, - .func_audit = NULL + .func_audit = log_audit_callback }; static const struct avc_thread_callback thread_cb = { @@ -122,6 +123,18 @@ policy_reload_callback (u_int32_t event, security_id_t ssid, return 0; } +/** + * Log any auxiliary data + */ +static void +log_audit_callback (void *data, security_class_t class, char *buf, size_t bufleft) +{ + DBusString *audmsg = data; + _dbus_string_copy_to_buffer (audmsg, buf, bufleft); + _dbus_string_free (audmsg); + dbus_free (audmsg); +} + /** * Create thread to notify the AVC of enforcing and policy reload * changes via netlink. @@ -349,17 +362,28 @@ static dbus_bool_t bus_selinux_check (BusSELinuxID *sender_sid, BusSELinuxID *override_sid, security_class_t target_class, - access_vector_t requested) + access_vector_t requested, + unsigned long spid, + unsigned long tpid, + DBusString *auxdata) { if (!selinux_enabled) return TRUE; + if (auxdata) + { + if (spid && _dbus_string_append (auxdata, " spid=")) + _dbus_string_append_uint (auxdata, spid); + if (tpid && _dbus_string_append (auxdata, " tpid=")) + _dbus_string_append_uint (auxdata, tpid); + } + /* 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) : SELINUX_SID_FROM_BUS (bus_sid), - target_class, requested, &aeref, NULL) < 0) + target_class, requested, &aeref, auxdata) < 0) { _dbus_verbose ("SELinux denying due to security policy.\n"); return FALSE; @@ -379,20 +403,40 @@ bus_selinux_check (BusSELinuxID *sender_sid, */ dbus_bool_t bus_selinux_allows_acquire_service (DBusConnection *connection, - BusSELinuxID *service_sid) + BusSELinuxID *service_sid, + const char *service_name) { #ifdef HAVE_SELINUX BusSELinuxID *connection_sid; + unsigned long spid; + DBusString *auxdata; if (!selinux_enabled) return TRUE; connection_sid = bus_connection_get_selinux_id (connection); + if (!dbus_connection_get_unix_process_id (connection, &spid)) + spid = 0; + + auxdata = dbus_new0 (DBusString, 1); + if (auxdata) + { + if (!_dbus_string_init (auxdata)) + { + dbus_free (auxdata); + auxdata = NULL; + } + else if (_dbus_string_append (auxdata, "service=")) + _dbus_string_append (auxdata, service_name); + } return bus_selinux_check (connection_sid, - service_sid, - SECCLASS_DBUS, - DBUS__ACQUIRE_SVC); + service_sid, + SECCLASS_DBUS, + DBUS__ACQUIRE_SVC, + spid, + 0, + auxdata); #else return TRUE; #endif /* HAVE_SELINUX */ @@ -410,15 +454,50 @@ bus_selinux_allows_acquire_service (DBusConnection *connection, */ dbus_bool_t bus_selinux_allows_send (DBusConnection *sender, - DBusConnection *proposed_recipient) + DBusConnection *proposed_recipient, + const char *msgtype, + const char *interface, + const char *member, + const char *error_name, + const char *destination) { #ifdef HAVE_SELINUX BusSELinuxID *recipient_sid; BusSELinuxID *sender_sid; + unsigned long spid, tpid; + DBusString *auxdata; if (!selinux_enabled) return TRUE; + if (!dbus_connection_get_unix_process_id (sender, &spid)) + spid = 0; + if (!dbus_connection_get_unix_process_id (proposed_recipient, &tpid)) + tpid = 0; + + auxdata = dbus_new0 (DBusString, 1); + if (auxdata) + { + if (!_dbus_string_init (auxdata)) + { + dbus_free (auxdata); + auxdata = NULL; + } + else + { + if (_dbus_string_append (auxdata, "msgtype=")) + _dbus_string_append (auxdata, msgtype); + if (interface && _dbus_string_append (auxdata, " interface=")) + _dbus_string_append (auxdata, interface); + if (member && _dbus_string_append (auxdata, " member=")) + _dbus_string_append (auxdata, member); + if (error_name && _dbus_string_append (auxdata, " error_name=")) + _dbus_string_append (auxdata, error_name); + if (destination && _dbus_string_append (auxdata, " dest=")) + _dbus_string_append (auxdata, destination); + } + } + sender_sid = bus_connection_get_selinux_id (sender); /* A NULL proposed_recipient means the bus itself. */ if (proposed_recipient) @@ -427,7 +506,8 @@ bus_selinux_allows_send (DBusConnection *sender, recipient_sid = BUS_SID_FROM_SELINUX (bus_sid); return bus_selinux_check (sender_sid, recipient_sid, - SECCLASS_DBUS, DBUS__SEND_MSG); + SECCLASS_DBUS, DBUS__SEND_MSG, + spid, tpid, auxdata); #else return TRUE; #endif /* HAVE_SELINUX */ diff --git a/bus/selinux.h b/bus/selinux.h index 71271fab..3627126c 100644 --- a/bus/selinux.h +++ b/bus/selinux.h @@ -47,11 +47,15 @@ const char* bus_selinux_get_policy_root (void); dbus_bool_t bus_selinux_allows_acquire_service (DBusConnection *connection, - BusSELinuxID *service_sid); + BusSELinuxID *service_sid, + const char *service_name); dbus_bool_t bus_selinux_allows_send (DBusConnection *sender, - DBusConnection *proposed_recipient); - - + DBusConnection *proposed_recipient, + const char *msgtype, /* Supplementary audit data */ + const char *interface, + const char *member, + const char *error_name, + const char *destination); BusSELinuxID* bus_selinux_init_connection_id (DBusConnection *connection, DBusError *error); diff --git a/bus/services.c b/bus/services.c index 31041c37..1036947a 100644 --- a/bus/services.c +++ b/bus/services.c @@ -310,7 +310,8 @@ bus_registry_acquire_service (BusRegistry *registry, sid = bus_selinux_id_table_lookup (registry->service_sid_table, service_name); - if (!bus_selinux_allows_acquire_service (connection, sid)) + if (!bus_selinux_allows_acquire_service (connection, sid, + _dbus_string_get_const_data (service_name))) { dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, "Connection \"%s\" is not allowed to own the service \"%s\" due " -- cgit