Skip to content

Commit

Permalink
util/apparmor: add apparmor support
Browse files Browse the repository at this point in the history
Add full AppArmor support using libapparmor. This requires af_unix
mediation support in the kernel (which has not yet landed upstream).

Signed-off-by: Sebastian Reichel <[email protected]>
  • Loading branch information
sre committed May 18, 2022
1 parent 6e8fbf4 commit d5ff60c
Show file tree
Hide file tree
Showing 6 changed files with 564 additions and 3 deletions.
7 changes: 7 additions & 0 deletions src/bus/driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "dbus/message.h"
#include "dbus/protocol.h"
#include "dbus/socket.h"
#include "util/apparmor.h"
#include "util/error.h"
#include "util/selinux.h"
#include "util/string.h"
Expand Down Expand Up @@ -1834,6 +1835,12 @@ static int driver_method_become_monitor(Peer *peer, const char *path, CDVar *in_
if (!peer_is_privileged(peer))
return DRIVER_E_PEER_NOT_PRIVILEGED;

r = bus_apparmor_check_eavesdrop(peer->policy->apparmor, peer->policy->seclabel);
if (r == BUS_APPARMOR_E_DENIED)
return DRIVER_E_PEER_NOT_PRIVILEGED;
if (r)
return r;

/* first create all the match objects before modifying the peer */
match_owner_init(&owned_matches);

Expand Down
44 changes: 41 additions & 3 deletions src/bus/policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "bus/name.h"
#include "bus/policy.h"
#include "dbus/protocol.h"
#include "util/apparmor.h"
#include "util/common.h"
#include "util/error.h"
#include "util/selinux.h"
Expand Down Expand Up @@ -413,6 +414,10 @@ int policy_registry_new(PolicyRegistry **registryp, const char *fallback_seclabe

*registry = (PolicyRegistry)POLICY_REGISTRY_NULL;

r = bus_apparmor_registry_new(&registry->apparmor, fallback_seclabel);
if (r)
return error_fold(r);

r = bus_selinux_registry_new(&registry->selinux, fallback_seclabel);
if (r)
return error_fold(r);
Expand Down Expand Up @@ -444,6 +449,7 @@ PolicyRegistry *policy_registry_free(PolicyRegistry *registry) {

policy_batch_unref(registry->default_batch);
bus_selinux_registry_unref(registry->selinux);
bus_apparmor_registry_unref(registry->apparmor);
free(registry);

return NULL;
Expand Down Expand Up @@ -691,9 +697,11 @@ int policy_registry_import(PolicyRegistry *registry, CDVar *v) {

c_dvar_read(v, "]bs)>", &apparmor, &bustype);

if (apparmor)
/* XXX: AppArmor is currently not supported. */
return POLICY_E_INVALID;
if (apparmor) {
r = bus_apparmor_set_bus_type(registry->apparmor, bustype ? bustype : "");
if (r)
return error_trace(r);
}

r = c_dvar_get_poison(v);
if (r)
Expand Down Expand Up @@ -730,6 +738,7 @@ int policy_snapshot_new(PolicySnapshot **snapshotp,

*snapshot = (PolicySnapshot)POLICY_SNAPSHOT_NULL;

snapshot->apparmor = bus_apparmor_registry_ref(registry->apparmor);
snapshot->selinux = bus_selinux_registry_ref(registry->selinux);

snapshot->seclabel = strdup(seclabel);
Expand Down Expand Up @@ -778,6 +787,7 @@ PolicySnapshot *policy_snapshot_free(PolicySnapshot *snapshot) {
policy_batch_unref(snapshot->batches[snapshot->n_batches]);
free(snapshot->seclabel);
bus_selinux_registry_unref(snapshot->selinux);
bus_apparmor_registry_unref(snapshot->apparmor);
free(snapshot);

return NULL;
Expand All @@ -796,6 +806,7 @@ int policy_snapshot_dup(PolicySnapshot *snapshot, PolicySnapshot **newp) {

*new = (PolicySnapshot)POLICY_SNAPSHOT_NULL;

new->apparmor = bus_apparmor_registry_ref(snapshot->apparmor);
new->selinux = bus_selinux_registry_ref(snapshot->selinux);

new->seclabel = strdup(snapshot->seclabel);
Expand Down Expand Up @@ -835,6 +846,14 @@ int policy_snapshot_check_own(PolicySnapshot *snapshot, const char *name_str) {
size_t i;
int v, r;

r = bus_apparmor_check_own(snapshot->apparmor, snapshot->seclabel, name_str);
if (r) {
if (r == BUS_APPARMOR_E_DENIED)
return POLICY_E_APPARMOR_ACCESS_DENIED;

return error_fold(r);
}

r = bus_selinux_check_own(snapshot->selinux, snapshot->seclabel, name_str);
if (r) {
if (r == SELINUX_E_DENIED)
Expand Down Expand Up @@ -1047,6 +1066,15 @@ int policy_snapshot_check_send(PolicySnapshot *snapshot,
size_t i;
int r;

r = bus_apparmor_check_xmit(snapshot->apparmor, true, snapshot->seclabel, subject_seclabel,
subject, subject_id, path, interface, method);
if (r) {
if (r == BUS_APPARMOR_E_DENIED)
return POLICY_E_APPARMOR_ACCESS_DENIED;

return error_fold(r);
}

r = bus_selinux_check_send(snapshot->selinux, snapshot->seclabel, subject_seclabel);
if (r) {
if (r == SELINUX_E_DENIED)
Expand Down Expand Up @@ -1085,6 +1113,16 @@ int policy_snapshot_check_receive(PolicySnapshot *snapshot,
size_t n_fds) {
PolicyVerdict verdict = POLICY_VERDICT_INIT;
size_t i;
int r;

r = bus_apparmor_check_xmit(snapshot->apparmor, false, subject_seclabel, snapshot->seclabel,
subject, subject_id, path, interface, method);
if (r) {
if (r == BUS_APPARMOR_E_DENIED)
return POLICY_E_APPARMOR_ACCESS_DENIED;

return error_fold(r);
}

for (i = 0; i < snapshot->n_batches; ++i)
policy_snapshot_check_xmit(snapshot->batches[i],
Expand Down
3 changes: 3 additions & 0 deletions src/bus/policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "dbus/protocol.h"
#include "util/ref.h"

typedef struct BusAppArmorRegistry BusAppArmorRegistry;
typedef struct BusSELinuxRegistry BusSELinuxRegistry;
typedef struct NameSet NameSet;
typedef struct PolicyBatch PolicyBatch;
Expand Down Expand Up @@ -112,6 +113,7 @@ struct PolicyRegistryNode {
}

struct PolicyRegistry {
BusAppArmorRegistry *apparmor;
BusSELinuxRegistry *selinux;
PolicyBatch *default_batch;
CRBTree uid_range_tree;
Expand All @@ -126,6 +128,7 @@ struct PolicyRegistry {
}

struct PolicySnapshot {
BusAppArmorRegistry *apparmor;
BusSELinuxRegistry *selinux;
char *seclabel;
size_t n_batches;
Expand Down
34 changes: 34 additions & 0 deletions src/util/apparmor-fallback.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <stdio.h>
#include <stdlib.h>
#include "util/apparmor.h"
#include "util/error.h"

/**
* bus_apparmor_is_enabled() - checks if AppArmor is currently enabled
Expand Down Expand Up @@ -39,3 +40,36 @@ int bus_apparmor_dbus_supported(bool *supportedp) {
*supportedp = false;
return 0;
}

int bus_apparmor_registry_new(struct BusAppArmorRegistry **registryp, const char *fallback_context) {
*registryp = NULL;
return 0;
}

BusAppArmorRegistry *bus_apparmor_registry_ref(BusAppArmorRegistry *registry) {
return NULL;
}

BusAppArmorRegistry *bus_apparmor_registry_unref(BusAppArmorRegistry *registry) {
return NULL;
}

int bus_apparmor_set_bus_type(BusAppArmorRegistry *registry, const char *bustype) {
return 0;
}

int bus_apparmor_check_own(struct BusAppArmorRegistry *registry, const char *owner_context,
const char *name) {
return 0;
}

int bus_apparmor_check_xmit(BusAppArmorRegistry *registry, bool check_send,
const char *sender_context, const char *receiver_context,
NameSet *subject, uint64_t subject_id,
const char *path, const char *interface, const char *method) {
return 0;
}

int bus_apparmor_check_eavesdrop(BusAppArmorRegistry *registry, const char *context) {
return 0;
}
Loading

0 comments on commit d5ff60c

Please sign in to comment.