linux/security/apparmor/audit.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * AppArmor security module
   4 *
   5 * This file contains AppArmor auditing functions
   6 *
   7 * Copyright (C) 1998-2008 Novell/SUSE
   8 * Copyright 2009-2010 Canonical Ltd.
   9 */
  10
  11#include <linux/audit.h>
  12#include <linux/socket.h>
  13
  14#include "include/apparmor.h"
  15#include "include/audit.h"
  16#include "include/policy.h"
  17#include "include/policy_ns.h"
  18#include "include/secid.h"
  19
  20const char *const audit_mode_names[] = {
  21        "normal",
  22        "quiet_denied",
  23        "quiet",
  24        "noquiet",
  25        "all"
  26};
  27
  28static const char *const aa_audit_type[] = {
  29        "AUDIT",
  30        "ALLOWED",
  31        "DENIED",
  32        "HINT",
  33        "STATUS",
  34        "ERROR",
  35        "KILLED",
  36        "AUTO"
  37};
  38
  39/*
  40 * Currently AppArmor auditing is fed straight into the audit framework.
  41 *
  42 * TODO:
  43 * netlink interface for complain mode
  44 * user auditing, - send user auditing to netlink interface
  45 * system control of whether user audit messages go to system log
  46 */
  47
  48/**
  49 * audit_base - core AppArmor function.
  50 * @ab: audit buffer to fill (NOT NULL)
  51 * @ca: audit structure containing data to audit (NOT NULL)
  52 *
  53 * Record common AppArmor audit data from @sa
  54 */
  55static void audit_pre(struct audit_buffer *ab, void *ca)
  56{
  57        struct common_audit_data *sa = ca;
  58
  59        if (aa_g_audit_header) {
  60                audit_log_format(ab, "apparmor=");
  61                audit_log_string(ab, aa_audit_type[aad(sa)->type]);
  62        }
  63
  64        if (aad(sa)->op) {
  65                audit_log_format(ab, " operation=");
  66                audit_log_string(ab, aad(sa)->op);
  67        }
  68
  69        if (aad(sa)->info) {
  70                audit_log_format(ab, " info=");
  71                audit_log_string(ab, aad(sa)->info);
  72                if (aad(sa)->error)
  73                        audit_log_format(ab, " error=%d", aad(sa)->error);
  74        }
  75
  76        if (aad(sa)->label) {
  77                struct aa_label *label = aad(sa)->label;
  78
  79                if (label_isprofile(label)) {
  80                        struct aa_profile *profile = labels_profile(label);
  81
  82                        if (profile->ns != root_ns) {
  83                                audit_log_format(ab, " namespace=");
  84                                audit_log_untrustedstring(ab,
  85                                                       profile->ns->base.hname);
  86                        }
  87                        audit_log_format(ab, " profile=");
  88                        audit_log_untrustedstring(ab, profile->base.hname);
  89                } else {
  90                        audit_log_format(ab, " label=");
  91                        aa_label_xaudit(ab, root_ns, label, FLAG_VIEW_SUBNS,
  92                                        GFP_ATOMIC);
  93                }
  94        }
  95
  96        if (aad(sa)->name) {
  97                audit_log_format(ab, " name=");
  98                audit_log_untrustedstring(ab, aad(sa)->name);
  99        }
 100}
 101
 102/**
 103 * aa_audit_msg - Log a message to the audit subsystem
 104 * @sa: audit event structure (NOT NULL)
 105 * @cb: optional callback fn for type specific fields (MAYBE NULL)
 106 */
 107void aa_audit_msg(int type, struct common_audit_data *sa,
 108                  void (*cb) (struct audit_buffer *, void *))
 109{
 110        aad(sa)->type = type;
 111        common_lsm_audit(sa, audit_pre, cb);
 112}
 113
 114/**
 115 * aa_audit - Log a profile based audit event to the audit subsystem
 116 * @type: audit type for the message
 117 * @profile: profile to check against (NOT NULL)
 118 * @sa: audit event (NOT NULL)
 119 * @cb: optional callback fn for type specific fields (MAYBE NULL)
 120 *
 121 * Handle default message switching based off of audit mode flags
 122 *
 123 * Returns: error on failure
 124 */
 125int aa_audit(int type, struct aa_profile *profile, struct common_audit_data *sa,
 126             void (*cb) (struct audit_buffer *, void *))
 127{
 128        AA_BUG(!profile);
 129
 130        if (type == AUDIT_APPARMOR_AUTO) {
 131                if (likely(!aad(sa)->error)) {
 132                        if (AUDIT_MODE(profile) != AUDIT_ALL)
 133                                return 0;
 134                        type = AUDIT_APPARMOR_AUDIT;
 135                } else if (COMPLAIN_MODE(profile))
 136                        type = AUDIT_APPARMOR_ALLOWED;
 137                else
 138                        type = AUDIT_APPARMOR_DENIED;
 139        }
 140        if (AUDIT_MODE(profile) == AUDIT_QUIET ||
 141            (type == AUDIT_APPARMOR_DENIED &&
 142             AUDIT_MODE(profile) == AUDIT_QUIET))
 143                return aad(sa)->error;
 144
 145        if (KILL_MODE(profile) && type == AUDIT_APPARMOR_DENIED)
 146                type = AUDIT_APPARMOR_KILL;
 147
 148        aad(sa)->label = &profile->label;
 149
 150        aa_audit_msg(type, sa, cb);
 151
 152        if (aad(sa)->type == AUDIT_APPARMOR_KILL)
 153                (void)send_sig_info(SIGKILL, NULL,
 154                        sa->type == LSM_AUDIT_DATA_TASK && sa->u.tsk ?
 155                                    sa->u.tsk : current);
 156
 157        if (aad(sa)->type == AUDIT_APPARMOR_ALLOWED)
 158                return complain_error(aad(sa)->error);
 159
 160        return aad(sa)->error;
 161}
 162
 163struct aa_audit_rule {
 164        struct aa_label *label;
 165};
 166
 167void aa_audit_rule_free(void *vrule)
 168{
 169        struct aa_audit_rule *rule = vrule;
 170
 171        if (rule) {
 172                if (!IS_ERR(rule->label))
 173                        aa_put_label(rule->label);
 174                kfree(rule);
 175        }
 176}
 177
 178int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
 179{
 180        struct aa_audit_rule *rule;
 181
 182        switch (field) {
 183        case AUDIT_SUBJ_ROLE:
 184                if (op != Audit_equal && op != Audit_not_equal)
 185                        return -EINVAL;
 186                break;
 187        default:
 188                return -EINVAL;
 189        }
 190
 191        rule = kzalloc(sizeof(struct aa_audit_rule), GFP_KERNEL);
 192
 193        if (!rule)
 194                return -ENOMEM;
 195
 196        /* Currently rules are treated as coming from the root ns */
 197        rule->label = aa_label_parse(&root_ns->unconfined->label, rulestr,
 198                                     GFP_KERNEL, true, false);
 199        if (IS_ERR(rule->label)) {
 200                aa_audit_rule_free(rule);
 201                return PTR_ERR(rule->label);
 202        }
 203
 204        *vrule = rule;
 205        return 0;
 206}
 207
 208int aa_audit_rule_known(struct audit_krule *rule)
 209{
 210        int i;
 211
 212        for (i = 0; i < rule->field_count; i++) {
 213                struct audit_field *f = &rule->fields[i];
 214
 215                switch (f->type) {
 216                case AUDIT_SUBJ_ROLE:
 217                        return 1;
 218                }
 219        }
 220
 221        return 0;
 222}
 223
 224int aa_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule)
 225{
 226        struct aa_audit_rule *rule = vrule;
 227        struct aa_label *label;
 228        int found = 0;
 229
 230        label = aa_secid_to_label(sid);
 231
 232        if (!label)
 233                return -ENOENT;
 234
 235        if (aa_label_is_subset(label, rule->label))
 236                found = 1;
 237
 238        switch (field) {
 239        case AUDIT_SUBJ_ROLE:
 240                switch (op) {
 241                case Audit_equal:
 242                        return found;
 243                case Audit_not_equal:
 244                        return !found;
 245                }
 246        }
 247        return 0;
 248}
 249