From 2d9afc71d8ea83724944da9bce7b21ff598f0e0d Mon Sep 17 00:00:00 2001 From: Tyler Hicks Date: Wed, 12 Feb 2014 17:28:13 -0600 Subject: [PATCH v3 06/13] Store AppArmor label of bus during initialization During dbus-daemon initialization, the AppArmor confinement context should be stored for later use when checks are to be done on messages to/from the bus itself. AppArmor confinement contexts are documented in aa_getcon(2). They contain a confinement string and a mode string. The confinement string is typically the name of the AppArmor profile confining a given process. The mode string gives the current enforcement mode of the process confinement. For example, it may indicate that the confinement should be enforced or it may indicate that the confinement should allow all actions with the caveat that actions which would be denied should be audited. It is important to note that libapparmor mallocs a single buffer to store the con and mode strings and separates them with a NUL terminator. Because of this, only con should be freed. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=75113 Signed-off-by: Tyler Hicks --- * No changes in v2 * Changes in v3: - Added Bug link in commit message bus/apparmor.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/bus/apparmor.c b/bus/apparmor.c index 78986d9..35a297f 100644 --- a/bus/apparmor.c +++ b/bus/apparmor.c @@ -64,6 +64,56 @@ static AppArmorConfigMode apparmor_config_mode = APPARMOR_ENABLED; static int audit_fd = -1; #endif +struct BusAppArmorConfinement +{ + int refcount; /* Reference count */ + + char *context; /* AppArmor confinement context (label) */ + char *mode; /* AppArmor confinement mode */ +}; + +typedef struct BusAppArmorConfinement BusAppArmorConfinement; + +static BusAppArmorConfinement *bus_con = NULL; + +static BusAppArmorConfinement* +bus_apparmor_confinement_new (char *context, char *mode) +{ + BusAppArmorConfinement *confinement; + + confinement = dbus_new0 (BusAppArmorConfinement, 1); + if (confinement != NULL) + { + confinement->refcount = 1; + confinement->context = context; + confinement->mode = mode; + } + + return confinement; +} + +static void +bus_apparmor_confinement_unref (BusAppArmorConfinement *confinement) +{ + if (!apparmor_enabled) + return; + + _dbus_assert (confinement != NULL); + _dbus_assert (confinement->refcount > 0); + + confinement->refcount -= 1; + + if (confinement->refcount == 0) + { + /** + * Do not free confinement->mode, as libapparmor does a single malloc for + * both confinement->context and confinement->mode. + */ + free (confinement->context); + dbus_free (confinement); + } +} + void bus_apparmor_audit_init (void) { @@ -175,6 +225,8 @@ dbus_bool_t bus_apparmor_full_init (void) { #ifdef HAVE_APPARMOR + char *context, *mode; + if (apparmor_enabled) { if (apparmor_config_mode == APPARMOR_DISABLED) @@ -182,6 +234,24 @@ bus_apparmor_full_init (void) apparmor_enabled = FALSE; return TRUE; } + + if (bus_con == NULL) + { + if (aa_getcon (&context, &mode) == -1) + { + _dbus_warn ("Error getting AppArmor context of bus: %s\n", + _dbus_strerror (errno)); + return FALSE; + } + + bus_con = bus_apparmor_confinement_new (context, mode); + if (bus_con == NULL) + { + _dbus_warn ("Error allocating bus AppArmor confinement\n"); + free (context); + return FALSE; + } + } } else { @@ -209,6 +279,9 @@ bus_apparmor_shutdown (void) _dbus_verbose ("AppArmor shutdown\n"); + bus_apparmor_confinement_unref (bus_con); + bus_con = NULL; + #ifdef HAVE_LIBAUDIT audit_close (audit_fd); #endif /* HAVE_LIBAUDIT */ -- 1.9.1