mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-05-05 06:28:00 +02:00
Mediation of processes eavesdropping
When an AppArmor confined process wants to eavesdrop on a bus, a check is performed to see if the action should be allowed. The check is based on the connection's label and the bus type. This patch adds a new hook, which was not previously included in the SELinux mediation, to mediate eavesdropping from bus_driver_handle_add_match(). A new function is added to bus/signals.c to see if a match rule is an eavesdropping rule since the rule flags field is private to signals.c. An example AppArmor rule that would allow a process to eavesdrop on the session bus would be: dbus eavesdrop bus=session, Bug: https://bugs.freedesktop.org/show_bug.cgi?id=75113 Signed-off-by: Tyler Hicks <tyhicks@canonical.com> Reviewed-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
This commit is contained in:
parent
d9a2fdb96a
commit
66979aae61
5 changed files with 141 additions and 1 deletions
117
bus/apparmor.c
117
bus/apparmor.c
|
|
@ -357,6 +357,12 @@ build_message_query (DBusString *query,
|
|||
query_append (query, member);
|
||||
}
|
||||
|
||||
static dbus_bool_t
|
||||
build_eavesdrop_query (DBusString *query, const char *con, const char *bustype)
|
||||
{
|
||||
return build_common_query (query, con, bustype);
|
||||
}
|
||||
|
||||
static void
|
||||
set_error_from_query_errno (DBusError *error, int error_number)
|
||||
{
|
||||
|
|
@ -1007,3 +1013,114 @@ bus_apparmor_allows_send (DBusConnection *sender,
|
|||
return TRUE;
|
||||
#endif /* HAVE_APPARMOR */
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Apparmor security controls allow the connection to eavesdrop on
|
||||
* other connections.
|
||||
*
|
||||
* @param connection the connection attempting to eavesdrop.
|
||||
* @param bustype name of the bus
|
||||
* @param error the reason for failure when FALSE is returned
|
||||
* @returns TRUE if eavesdropping is permitted
|
||||
*/
|
||||
dbus_bool_t
|
||||
bus_apparmor_allows_eavesdropping (DBusConnection *connection,
|
||||
const char *bustype,
|
||||
DBusError *error)
|
||||
{
|
||||
#ifdef HAVE_APPARMOR
|
||||
BusAppArmorConfinement *con = NULL;
|
||||
DBusString qstr, auxdata;
|
||||
dbus_bool_t allow = FALSE, audit = TRUE;
|
||||
dbus_bool_t free_auxdata = FALSE;
|
||||
unsigned long pid;
|
||||
int res, serrno = 0;
|
||||
|
||||
if (!apparmor_enabled)
|
||||
return TRUE;
|
||||
|
||||
con = bus_connection_dup_apparmor_confinement (connection);
|
||||
|
||||
if (is_unconfined (con->context, con->mode))
|
||||
{
|
||||
allow = TRUE;
|
||||
audit = FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!_dbus_string_init (&qstr))
|
||||
goto oom;
|
||||
|
||||
if (!build_eavesdrop_query (&qstr, con->context, bustype))
|
||||
{
|
||||
_dbus_string_free (&qstr);
|
||||
goto oom;
|
||||
}
|
||||
|
||||
res = aa_query_label (AA_DBUS_EAVESDROP,
|
||||
_dbus_string_get_data (&qstr),
|
||||
_dbus_string_get_length (&qstr),
|
||||
&allow, &audit);
|
||||
_dbus_string_free (&qstr);
|
||||
if (res == -1)
|
||||
{
|
||||
serrno = errno;
|
||||
set_error_from_query_errno (error, serrno);
|
||||
goto audit;
|
||||
}
|
||||
|
||||
/* Don't fail operations on profiles in complain mode */
|
||||
if (modestr_is_complain (con->mode))
|
||||
allow = TRUE;
|
||||
|
||||
if (!allow)
|
||||
dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
|
||||
"Connection \"%s\" is not allowed to eavesdrop due to "
|
||||
"AppArmor policy",
|
||||
bus_connection_is_active (connection) ?
|
||||
bus_connection_get_name (connection) : "(inactive)");
|
||||
|
||||
if (!audit)
|
||||
goto out;
|
||||
|
||||
audit:
|
||||
if (!_dbus_string_init (&auxdata))
|
||||
goto oom;
|
||||
free_auxdata = TRUE;
|
||||
|
||||
if (!_dbus_append_pair_str (&auxdata, "bus", bustype ? bustype : "unknown"))
|
||||
goto oom;
|
||||
|
||||
if (serrno && !_dbus_append_pair_str (&auxdata, "info", strerror (serrno)))
|
||||
goto oom;
|
||||
|
||||
if (!_dbus_append_pair_str (&auxdata, "mask", "eavesdrop"))
|
||||
goto oom;
|
||||
|
||||
if (connection && dbus_connection_get_unix_process_id (connection, &pid) &&
|
||||
!_dbus_append_pair_uint (&auxdata, "pid", pid))
|
||||
goto oom;
|
||||
|
||||
if (con->context && !_dbus_append_pair_str (&auxdata, "profile", con->context))
|
||||
goto oom;
|
||||
|
||||
log_message (allow, "eavesdrop", &auxdata);
|
||||
|
||||
out:
|
||||
if (con != NULL)
|
||||
bus_apparmor_confinement_unref (con);
|
||||
if (free_auxdata)
|
||||
_dbus_string_free (&auxdata);
|
||||
|
||||
return allow;
|
||||
|
||||
oom:
|
||||
if (error != NULL && !dbus_error_is_set (error))
|
||||
BUS_SET_OOM (error);
|
||||
allow = FALSE;
|
||||
goto out;
|
||||
|
||||
#else
|
||||
return TRUE;
|
||||
#endif /* HAVE_APPARMOR */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,4 +59,8 @@ dbus_bool_t bus_apparmor_allows_send (DBusConnection *sender,
|
|||
const char *source,
|
||||
DBusError *error);
|
||||
|
||||
dbus_bool_t bus_apparmor_allows_eavesdropping (DBusConnection *connection,
|
||||
const char *bustype,
|
||||
DBusError *error);
|
||||
|
||||
#endif /* BUS_APPARMOR_H */
|
||||
|
|
|
|||
10
bus/driver.c
10
bus/driver.c
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include <config.h>
|
||||
#include "activation.h"
|
||||
#include "apparmor.h"
|
||||
#include "connection.h"
|
||||
#include "driver.h"
|
||||
#include "dispatch.h"
|
||||
|
|
@ -1110,9 +1111,10 @@ bus_driver_handle_add_match (DBusConnection *connection,
|
|||
DBusError *error)
|
||||
{
|
||||
BusMatchRule *rule;
|
||||
const char *text;
|
||||
const char *text, *bustype;
|
||||
DBusString str;
|
||||
BusMatchmaker *matchmaker;
|
||||
BusContext *context;
|
||||
|
||||
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
|
||||
|
||||
|
|
@ -1145,6 +1147,12 @@ bus_driver_handle_add_match (DBusConnection *connection,
|
|||
if (rule == NULL)
|
||||
goto failed;
|
||||
|
||||
context = bus_transaction_get_context (transaction);
|
||||
bustype = context ? bus_context_get_type (context) : NULL;
|
||||
if (bus_match_rule_get_client_is_eavesdropping (rule) &&
|
||||
!bus_apparmor_allows_eavesdropping (connection, bustype, error))
|
||||
goto failed;
|
||||
|
||||
matchmaker = bus_connection_get_matchmaker (connection);
|
||||
|
||||
if (!bus_matchmaker_add_rule (matchmaker, rule))
|
||||
|
|
|
|||
|
|
@ -410,6 +410,15 @@ bus_match_rule_set_client_is_eavesdropping (BusMatchRule *rule,
|
|||
rule->flags &= ~(BUS_MATCH_CLIENT_IS_EAVESDROPPING);
|
||||
}
|
||||
|
||||
dbus_bool_t
|
||||
bus_match_rule_get_client_is_eavesdropping (BusMatchRule *rule)
|
||||
{
|
||||
if (rule->flags & BUS_MATCH_CLIENT_IS_EAVESDROPPING)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
dbus_bool_t
|
||||
bus_match_rule_set_path (BusMatchRule *rule,
|
||||
const char *path,
|
||||
|
|
|
|||
|
|
@ -73,6 +73,8 @@ dbus_bool_t bus_match_rule_set_arg (BusMatchRule *rule,
|
|||
void bus_match_rule_set_client_is_eavesdropping (BusMatchRule *rule,
|
||||
dbus_bool_t is_eavesdropping);
|
||||
|
||||
dbus_bool_t bus_match_rule_get_client_is_eavesdropping (BusMatchRule *rule);
|
||||
|
||||
BusMatchRule* bus_match_rule_parse (DBusConnection *matches_go_to,
|
||||
const DBusString *rule_text,
|
||||
DBusError *error);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue