From cb18435c5d42436dfedfcf9e389e023f2669c87b Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Mon, 5 Feb 2018 17:11:33 +0100 Subject: [PATCH] bus/log: log the type of policy failure on transmission We support either internal (the dbus XML policy) or SELinux, log which policy caused the failure, and log the respective security labels. Signed-off-by: Tom Gundersen --- src/bus/bus.c | 34 ++++++++++++++++++++++++++++++---- src/bus/bus.h | 7 ++++++- src/bus/driver.c | 6 ++++-- src/bus/peer.c | 9 ++++++--- src/bus/policy.c | 4 ++-- src/bus/policy.h | 1 + 6 files changed, 49 insertions(+), 12 deletions(-) diff --git a/src/bus/bus.c b/src/bus/bus.c index 5382f930..2b07d64a 100644 --- a/src/bus/bus.c +++ b/src/bus/bus.c @@ -81,7 +81,9 @@ Peer *bus_find_peer_by_name(Bus *bus, Name **namep, const char *name_str) { return peer; } -static int bus_log_commit_policy(Bus *bus, const char *action, uint64_t sender_id, uint64_t receiver_id, NameSet *sender_names, NameSet *receiver_names, Message *message) { +static int bus_log_commit_policy(Bus *bus, const char *action, const char *policy_type, uint64_t sender_id, uint64_t receiver_id, + NameSet *sender_names, NameSet *receiver_names, const char *sender_label, const char *receiver_label, + Message *message) { Log *log = bus->log; int r; @@ -89,6 +91,17 @@ static int bus_log_commit_policy(Bus *bus, const char *action, uint64_t sender_i log_appendf(log, "DBUS_BROKER_TRANSMIT_ACTION=%s\n", action); + if (policy_type) + log_appendf(log, "DBUS_BROKER_POLICY_TYPE=%s\n", policy_type); + + if (sender_label) + log_appendf(log, "DBUS_BROKER_SENDER_SECURITY_LABEL=%s\n", + sender_label); + + if (receiver_label) + log_appendf(log, "DBUS_BROKER_RECEIVER_SECURITY_LABEL=%s\n", + receiver_label); + if (sender_id == ADDRESS_ID_INVALID) { log_appendf(log, "DBUS_BROKER_SENDER_UNIQUE_NAME=org.freedesktop.DBus\n"); @@ -152,10 +165,23 @@ static int bus_log_commit_policy(Bus *bus, const char *action, uint64_t sender_i return 0; } -int bus_log_commit_policy_send(Bus *bus, uint64_t sender_id, uint64_t receiver_id, NameSet *sender_names, NameSet *receiver_names, Message *message) { - return bus_log_commit_policy(bus, "send", sender_id, receiver_id, sender_names, receiver_names, message); +int bus_log_commit_policy_send(Bus *bus, int policy_type, uint64_t sender_id, uint64_t receiver_id, NameSet *sender_names, NameSet *receiver_names, const char *sender_label, const char *receiver_label, Message *message) { + const char *policy_type_str; + + switch (policy_type) { + case BUS_LOG_POLICY_TYPE_INTERNAL: + policy_type_str = "internal"; + break; + case BUS_LOG_POLICY_TYPE_SELINUX: + policy_type_str = "selinux"; + break; + default: + assert(0); + } + + return bus_log_commit_policy(bus, "send", policy_type_str, sender_id, receiver_id, sender_names, receiver_names, sender_label, receiver_label, message); } int bus_log_commit_policy_receive(Bus *bus, uint64_t receiver_id, uint64_t sender_id, NameSet *sender_names, NameSet *receiver_names, Message *message) { - return bus_log_commit_policy(bus, "receive", sender_id, receiver_id, sender_names, receiver_names, message); + return bus_log_commit_policy(bus, "receive", "internal", sender_id, receiver_id, sender_names, receiver_names, NULL, NULL, message); } diff --git a/src/bus/bus.h b/src/bus/bus.h index 3f590f2f..a30ef0bf 100644 --- a/src/bus/bus.h +++ b/src/bus/bus.h @@ -20,6 +20,11 @@ enum { BUS_E_FAILURE, }; +enum { + BUS_LOG_POLICY_TYPE_INTERNAL, + BUS_LOG_POLICY_TYPE_SELINUX, +}; + typedef struct Bus Bus; typedef struct Log Log; typedef struct Message Message; @@ -65,5 +70,5 @@ void bus_deinit(Bus *bus); Peer *bus_find_peer_by_name(Bus *bus, Name **namep, const char *name); -int bus_log_commit_policy_send(Bus *bus, uint64_t sender_id, uint64_t receiver_id, NameSet *sender_names, NameSet *receiver_names, Message *message); +int bus_log_commit_policy_send(Bus *bus, int policy_type, uint64_t sender_id, uint64_t receiver_id, NameSet *sender_names, NameSet *receiver_names, const char *sender_label, const char *receiver_label, Message *message); int bus_log_commit_policy_receive(Bus *bus, uint64_t sender_id, uint64_t receiver_id, NameSet *sender_names, NameSet *receievr_names, Message *message); diff --git a/src/bus/driver.c b/src/bus/driver.c index 0cd84768..0c796152 100644 --- a/src/bus/driver.c +++ b/src/bus/driver.c @@ -1729,11 +1729,13 @@ static int driver_dispatch_interface(Peer *peer, uint32_t serial, const char *in r = policy_snapshot_check_send(peer->policy, NULL, NULL, interface, member, path, message->header->type); if (r) { - if (r == POLICY_E_ACCESS_DENIED) { + if (r == POLICY_E_ACCESS_DENIED || r == POLICY_E_SELINUX_ACCESS_DENIED) { NameSet names = NAME_SET_INIT_FROM_OWNER(&peer->owned_names); log_append_here(peer->bus->log, LOG_WARNING, 0); - r = bus_log_commit_policy_send(peer->bus, peer->id, ADDRESS_ID_INVALID, &names, NULL, message); + r = bus_log_commit_policy_send(peer->bus, + (r == POLICY_E_ACCESS_DENIED ? BUS_LOG_POLICY_TYPE_INTERNAL : BUS_LOG_POLICY_TYPE_SELINUX), + peer->id, ADDRESS_ID_INVALID, &names, NULL, peer->policy->seclabel, NULL, message); if (r) return error_fold(r); diff --git a/src/bus/peer.c b/src/bus/peer.c index 6ded104c..8535be93 100644 --- a/src/bus/peer.c +++ b/src/bus/peer.c @@ -651,9 +651,12 @@ int peer_queue_call(PolicySnapshot *sender_policy, NameSet *sender_names, MatchR message->metadata.fields.path, message->header->type); if (r) { - if (r == POLICY_E_ACCESS_DENIED) { + if (r == POLICY_E_ACCESS_DENIED || r == POLICY_E_SELINUX_ACCESS_DENIED) { log_append_here(receiver->bus->log, LOG_WARNING, 0); - r = bus_log_commit_policy_send(receiver->bus, sender_id, receiver->id, sender_names, &receiver_names, message); + r = bus_log_commit_policy_send(receiver->bus, + (r == POLICY_E_ACCESS_DENIED ? BUS_LOG_POLICY_TYPE_INTERNAL : BUS_LOG_POLICY_TYPE_SELINUX), + sender_id, receiver->id, sender_names, &receiver_names, + sender_policy->seclabel, receiver->policy->seclabel, message); if (r) return error_fold(r); @@ -727,7 +730,7 @@ static int peer_broadcast_to_matches(PolicySnapshot *sender_policy, NameSet *sen message->metadata.fields.path, message->header->type); if (r) { - if (r == POLICY_E_ACCESS_DENIED) + if (r == POLICY_E_ACCESS_DENIED || r == POLICY_E_SELINUX_ACCESS_DENIED) continue; return error_fold(r); diff --git a/src/bus/policy.c b/src/bus/policy.c index b175a4c3..b0043378 100644 --- a/src/bus/policy.c +++ b/src/bus/policy.c @@ -708,7 +708,7 @@ int policy_snapshot_check_own(PolicySnapshot *snapshot, const char *name_str) { r = bus_selinux_check_own(snapshot->selinux, snapshot->seclabel, name_str); if (r) { if (r == SELINUX_E_DENIED) - return POLICY_E_ACCESS_DENIED; + return POLICY_E_SELINUX_ACCESS_DENIED; return error_fold(r); } @@ -888,7 +888,7 @@ int policy_snapshot_check_send(PolicySnapshot *snapshot, r = bus_selinux_check_send(snapshot->selinux, snapshot->seclabel, subject_seclabel); if (r) { if (r == SELINUX_E_DENIED) - return POLICY_E_ACCESS_DENIED; + return POLICY_E_SELINUX_ACCESS_DENIED; return error_fold(r); } diff --git a/src/bus/policy.h b/src/bus/policy.h index e93c8fec..b60201a4 100644 --- a/src/bus/policy.h +++ b/src/bus/policy.h @@ -28,6 +28,7 @@ enum { POLICY_E_INVALID, POLICY_E_ACCESS_DENIED, + POLICY_E_SELINUX_ACCESS_DENIED, }; struct PolicyVerdict {