linux/security/apparmor/audit.c
<<
>>
Prefs
   1/*
   2 * AppArmor security module
   3 *
   4 * This file contains AppArmor auditing functions
   5 *
   6 * Copyright (C) 1998-2008 Novell/SUSE
   7 * Copyright 2009-2010 Canonical Ltd.
   8 *
   9 * This program is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU General Public License as
  11 * published by the Free Software Foundation, version 2 of the
  12 * License.
  13 */
  14
  15#include <linux/audit.h>
  16#include <linux/socket.h>
  17
  18#include "include/apparmor.h"
  19#include "include/audit.h"
  20#include "include/policy.h"
  21#include "include/policy_ns.h"
  22
  23
  24const char *const audit_mode_names[] = {
  25        "normal",
  26        "quiet_denied",
  27        "quiet",
  28        "noquiet",
  29        "all"
  30};
  31
  32static const char *const aa_audit_type[] = {
  33        "AUDIT",
  34        "ALLOWED",
  35        "DENIED",
  36        "HINT",
  37        "STATUS",
  38        "ERROR",
  39        "KILLED",
  40        "AUTO"
  41};
  42
  43/*
  44 * Currently AppArmor auditing is fed straight into the audit framework.
  45 *
  46 * TODO:
  47 * netlink interface for complain mode
  48 * user auditing, - send user auditing to netlink interface
  49 * system control of whether user audit messages go to system log
  50 */
  51
  52/**
  53 * audit_base - core AppArmor function.
  54 * @ab: audit buffer to fill (NOT NULL)
  55 * @ca: audit structure containing data to audit (NOT NULL)
  56 *
  57 * Record common AppArmor audit data from @sa
  58 */
  59static void audit_pre(struct audit_buffer *ab, void *ca)
  60{
  61        struct common_audit_data *sa = ca;
  62
  63        if (aa_g_audit_header) {
  64                audit_log_format(ab, "apparmor=");
  65                audit_log_string(ab, aa_audit_type[aad(sa)->type]);
  66        }
  67
  68        if (aad(sa)->op) {
  69                audit_log_format(ab, " operation=");
  70                audit_log_string(ab, aad(sa)->op);
  71        }
  72
  73        if (aad(sa)->info) {
  74                audit_log_format(ab, " info=");
  75                audit_log_string(ab, aad(sa)->info);
  76                if (aad(sa)->error)
  77                        audit_log_format(ab, " error=%d", aad(sa)->error);
  78        }
  79
  80        if (aad(sa)->label) {
  81                struct aa_label *label = aad(sa)->label;
  82
  83                if (label_isprofile(label)) {
  84                        struct aa_profile *profile = labels_profile(label);
  85
  86                        if (profile->ns != root_ns) {
  87                                audit_log_format(ab, " namespace=");
  88                                audit_log_untrustedstring(ab,
  89                                                       profile->ns->base.hname);
  90                        }
  91                        audit_log_format(ab, " profile=");
  92                        audit_log_untrustedstring(ab, profile->base.hname);
  93                } else {
  94                        audit_log_format(ab, " label=");
  95                        aa_label_xaudit(ab, root_ns, label, FLAG_VIEW_SUBNS,
  96                                        GFP_ATOMIC);
  97                }
  98        }
  99
 100        if (aad(sa)->name) {
 101                audit_log_format(ab, " name=");
 102                audit_log_untrustedstring(ab, aad(sa)->name);
 103        }
 104}
 105
 106/**
 107 * aa_audit_msg - Log a message to the audit subsystem
 108 * @sa: audit event structure (NOT NULL)
 109 * @cb: optional callback fn for type specific fields (MAYBE NULL)
 110 */
 111void aa_audit_msg(int type, struct common_audit_data *sa,
 112                  void (*cb) (struct audit_buffer *, void *))
 113{
 114        aad(sa)->type = type;
 115        common_lsm_audit(sa, audit_pre, cb);
 116}
 117
 118/**
 119 * aa_audit - Log a profile based audit event to the audit subsystem
 120 * @type: audit type for the message
 121 * @profile: profile to check against (NOT NULL)
 122 * @sa: audit event (NOT NULL)
 123 * @cb: optional callback fn for type specific fields (MAYBE NULL)
 124 *
 125 * Handle default message switching based off of audit mode flags
 126 *
 127 * Returns: error on failure
 128 */
 129int aa_audit(int type, struct aa_profile *profile, struct common_audit_data *sa,
 130             void (*cb) (struct audit_buffer *, void *))
 131{
 132        AA_BUG(!profile);
 133
 134        if (type == AUDIT_APPARMOR_AUTO) {
 135                if (likely(!aad(sa)->error)) {
 136                        if (AUDIT_MODE(profile) != AUDIT_ALL)
 137                                return 0;
 138                        type = AUDIT_APPARMOR_AUDIT;
 139                } else if (COMPLAIN_MODE(profile))
 140                        type = AUDIT_APPARMOR_ALLOWED;
 141                else
 142                        type = AUDIT_APPARMOR_DENIED;
 143        }
 144        if (AUDIT_MODE(profile) == AUDIT_QUIET ||
 145            (type == AUDIT_APPARMOR_DENIED &&
 146             AUDIT_MODE(profile) == AUDIT_QUIET))
 147                return aad(sa)->error;
 148
 149        if (KILL_MODE(profile) && type == AUDIT_APPARMOR_DENIED)
 150                type = AUDIT_APPARMOR_KILL;
 151
 152        aad(sa)->label = &profile->label;
 153
 154        aa_audit_msg(type, sa, cb);
 155
 156        if (aad(sa)->type == AUDIT_APPARMOR_KILL)
 157                (void)send_sig_info(SIGKILL, NULL,
 158                        sa->type == LSM_AUDIT_DATA_TASK && sa->u.tsk ?
 159                                    sa->u.tsk : current);
 160
 161        if (aad(sa)->type == AUDIT_APPARMOR_ALLOWED)
 162                return complain_error(aad(sa)->error);
 163
 164        return aad(sa)->error;
 165}
 166