summaryrefslogtreecommitdiffstats
path: root/bus
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2004-11-09 06:11:33 +0000
committerColin Walters <walters@verbum.org>2004-11-09 06:11:33 +0000
commit935a41a04c3f638134fa905503fc41ddbd18902f (patch)
tree0f6dee53c28bba5a8ce6658b634c66ba1cc5abda /bus
parent2f5e949851f7704b296f55ce1d1fcc4480176107 (diff)
2004-11-09 Colin Walters <walters@verbum.org>
* 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.
Diffstat (limited to 'bus')
-rw-r--r--bus/bus.c24
-rw-r--r--bus/selinux.c98
-rw-r--r--bus/selinux.h12
-rw-r--r--bus/services.c3
4 files changed, 118 insertions, 19 deletions
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 =
{
@@ -123,6 +124,18 @@ policy_reload_callback (u_int32_t event, security_id_t ssid,
}
/**
+ * 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 "