summaryrefslogtreecommitdiff
path: root/bus
diff options
context:
space:
mode:
authorTyler Hicks <tyhicks@canonical.com>2014-02-13 09:59:53 -0600
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2015-02-18 17:04:05 +0000
commitcd23a5df10b0465c99f91b5f9c4e160480078c1a (patch)
tree0ba4cd5181b2f6a36ab43457a28871b48b1a2087 /bus
parente8b0248eef31e2960a895613f3a9102675a7baf8 (diff)
downloaddbus-cd23a5df10b0465c99f91b5f9c4e160480078c1a.tar.gz
Store AppArmor label of connecting processes
When processes connect the bus, the AppArmor confinement context should be stored for later use when checks are to be done during message sending/receiving, acquire a name, and eavesdropping. Code outside of apparmor.c will need to initialize and unreference the confinement context, so bus_apparmor_confinement_unref() can no longer be a static function. [Move bus_apparmor_confinement_unref back to its old location for a more reasonable diff -smcv] Bug: https://bugs.freedesktop.org/show_bug.cgi?id=75113 Reviewed-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
Diffstat (limited to 'bus')
-rw-r--r--bus/apparmor.c54
-rw-r--r--bus/apparmor.h5
-rw-r--r--bus/bus.h1
-rw-r--r--bus/connection.c22
4 files changed, 79 insertions, 3 deletions
diff --git a/bus/apparmor.c b/bus/apparmor.c
index 3b2be352..d22ac672 100644
--- a/bus/apparmor.c
+++ b/bus/apparmor.c
@@ -48,6 +48,8 @@
#include <syslog.h>
#endif /* HAVE_LIBAUDIT */
+#include "utils.h"
+
/* Store the value telling us if AppArmor D-Bus mediation is enabled. */
static dbus_bool_t apparmor_enabled = FALSE;
@@ -72,8 +74,6 @@ struct BusAppArmorConfinement
const char *mode; /* AppArmor confinement mode (freed by freeing *context) */
};
-typedef struct BusAppArmorConfinement BusAppArmorConfinement;
-
static BusAppArmorConfinement *bus_con = NULL;
/**
@@ -103,9 +103,10 @@ bus_apparmor_confinement_new (char *context, const char *mode)
return confinement;
}
-static void
+void
bus_apparmor_confinement_unref (BusAppArmorConfinement *confinement)
{
+#ifdef HAVE_APPARMOR
if (!apparmor_enabled)
return;
@@ -123,6 +124,7 @@ bus_apparmor_confinement_unref (BusAppArmorConfinement *confinement)
free (confinement->context);
dbus_free (confinement);
}
+#endif
}
void
@@ -339,3 +341,49 @@ bus_apparmor_enabled (void)
return FALSE;
#endif
}
+
+BusAppArmorConfinement*
+bus_apparmor_init_connection_confinement (DBusConnection *connection,
+ DBusError *error)
+{
+#ifdef HAVE_APPARMOR
+ BusAppArmorConfinement *confinement;
+ char *context, *mode;
+ int fd;
+
+ if (!apparmor_enabled)
+ return NULL;
+
+ _dbus_assert (connection != NULL);
+
+ if (!dbus_connection_get_socket (connection, &fd))
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "Failed to get socket file descriptor of connection");
+ return NULL;
+ }
+
+ if (aa_getpeercon (fd, &context, &mode) == -1)
+ {
+ if (errno == ENOMEM)
+ BUS_SET_OOM (error);
+ else
+ dbus_set_error (error, _dbus_error_from_errno (errno),
+ "Failed to get AppArmor confinement information of socket peer: %s",
+ _dbus_strerror (errno));
+ return NULL;
+ }
+
+ confinement = bus_apparmor_confinement_new (context, mode);
+ if (confinement == NULL)
+ {
+ BUS_SET_OOM (error);
+ free (context);
+ return NULL;
+ }
+
+ return confinement;
+#else
+ return NULL;
+#endif /* HAVE_APPARMOR */
+}
diff --git a/bus/apparmor.h b/bus/apparmor.h
index 66a77c0e..861094e7 100644
--- a/bus/apparmor.h
+++ b/bus/apparmor.h
@@ -27,6 +27,7 @@
#define BUS_APPARMOR_H
#include <dbus/dbus.h>
+#include "bus.h"
void bus_apparmor_audit_init (void);
dbus_bool_t bus_apparmor_pre_init (void);
@@ -36,4 +37,8 @@ dbus_bool_t bus_apparmor_full_init (DBusError *error);
void bus_apparmor_shutdown (void);
dbus_bool_t bus_apparmor_enabled (void);
+void bus_apparmor_confinement_unref (BusAppArmorConfinement *confinement);
+BusAppArmorConfinement* bus_apparmor_init_connection_confinement (DBusConnection *connection,
+ DBusError *error);
+
#endif /* BUS_APPARMOR_H */
diff --git a/bus/bus.h b/bus/bus.h
index 57ad5c78..3fab59ff 100644
--- a/bus/bus.h
+++ b/bus/bus.h
@@ -38,6 +38,7 @@ typedef struct BusClientPolicy BusClientPolicy;
typedef struct BusPolicyRule BusPolicyRule;
typedef struct BusRegistry BusRegistry;
typedef struct BusSELinuxID BusSELinuxID;
+typedef struct BusAppArmorConfinement BusAppArmorConfinement;
typedef struct BusService BusService;
typedef struct BusOwner BusOwner;
typedef struct BusTransaction BusTransaction;
diff --git a/bus/connection.c b/bus/connection.c
index 64da1292..93f99674 100644
--- a/bus/connection.c
+++ b/bus/connection.c
@@ -30,6 +30,7 @@
#include "signals.h"
#include "expirelist.h"
#include "selinux.h"
+#include "apparmor.h"
#include <dbus/dbus-list.h>
#include <dbus/dbus-hash.h>
#include <dbus/dbus-timeout.h>
@@ -99,6 +100,7 @@ typedef struct
char *cached_loginfo_string;
BusSELinuxID *selinux_id;
+ BusAppArmorConfinement *apparmor_confinement;
long connection_tv_sec; /**< Time when we connected (seconds component) */
long connection_tv_usec; /**< Time when we connected (microsec component) */
@@ -439,6 +441,9 @@ free_connection_data (void *data)
if (d->selinux_id)
bus_selinux_id_unref (d->selinux_id);
+
+ if (d->apparmor_confinement)
+ bus_apparmor_confinement_unref (d->apparmor_confinement);
dbus_free (d->cached_loginfo_string);
@@ -714,6 +719,19 @@ bus_connections_setup_connection (BusConnections *connections,
goto out;
}
+ d->apparmor_confinement = bus_apparmor_init_connection_confinement (connection,
+ &error);
+ if (dbus_error_is_set (&error))
+ {
+ /* This is a bit bogus because we pretend all errors
+ * are OOM; this is done because we know that in bus.c
+ * an OOM error disconnects the connection, which is
+ * the same thing we want on any other error.
+ */
+ dbus_error_free (&error);
+ goto out;
+ }
+
if (!dbus_connection_set_watch_functions (connection,
add_connection_watch,
remove_connection_watch,
@@ -801,6 +819,10 @@ bus_connections_setup_connection (BusConnections *connections,
if (d->selinux_id)
bus_selinux_id_unref (d->selinux_id);
d->selinux_id = NULL;
+
+ if (d->apparmor_confinement)
+ bus_apparmor_confinement_unref (d->apparmor_confinement);
+ d->apparmor_confinement = NULL;
if (!dbus_connection_set_watch_functions (connection,
NULL, NULL, NULL,