Commit cd23a5df authored by Tyler Hicks's avatar Tyler Hicks Committed by Simon McVittie

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=75113Reviewed-by: default avatarSimon McVittie <simon.mcvittie@collabora.co.uk>
parent e8b0248e
......@@ -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 */
}
......@@ -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 */
......@@ -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;
......
......@@ -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,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment