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)->profile) {
  81                struct aa_profile *profile = aad(sa)->profile;
  82                if (profile->ns != root_ns) {
  83                        audit_log_format(ab, " namespace=");
  84                        audit_log_untrustedstring(ab, profile->ns->base.hname);
  85                }
  86                audit_log_format(ab, " profile=");
  87                audit_log_untrustedstring(ab, profile->base.hname);
  88        }
  89
  90        if (aad(sa)->name) {
  91                audit_log_format(ab, " name=");
  92                audit_log_untrustedstring(ab, aad(sa)->name);
  93        }
  94}
  95
  96/**
  97 * aa_audit_msg - Log a message to the audit subsystem
  98 * @sa: audit event structure (NOT NULL)
  99 * @cb: optional callback fn for type specific fields (MAYBE NULL)
 100 */
 101void aa_audit_msg(int type, struct common_audit_data *sa,
 102                  void (*cb) (struct audit_buffer *, void *))
 103{
 104        aad(sa)->type = type;
 105        common_lsm_audit(sa, audit_pre, cb);
 106}
 107
 108/**
 109 * aa_audit - Log a profile based audit event to the audit subsystem
 110 * @type: audit type for the message
 111 * @profile: profile to check against (NOT NULL)
 112 * @sa: audit event (NOT NULL)
 113 * @cb: optional callback fn for type specific fields (MAYBE NULL)
 114 *
 115 * Handle default message switching based off of audit mode flags
 116 *
 117 * Returns: error on failure
 118 */
 119int aa_audit(int type, struct aa_profile *profile, struct common_audit_data *sa,
 120             void (*cb) (struct audit_buffer *, void *))
 121{
 122        AA_BUG(!profile);
 123
 124        if (type == AUDIT_APPARMOR_AUTO) {
 125                if (likely(!aad(sa)->error)) {
 126                        if (AUDIT_MODE(profile) != AUDIT_ALL)
 127                                return 0;
 128                        type = AUDIT_APPARMOR_AUDIT;
 129                } else if (COMPLAIN_MODE(profile))
 130                        type = AUDIT_APPARMOR_ALLOWED;
 131                else
 132                        type = AUDIT_APPARMOR_DENIED;
 133        }
 134        if (AUDIT_MODE(profile) == AUDIT_QUIET ||
 135            (type == AUDIT_APPARMOR_DENIED &&
 136             AUDIT_MODE(profile) == AUDIT_QUIET))
 137                return aad(sa)->error;
 138
 139        if (KILL_MODE(profile) && type == AUDIT_APPARMOR_DENIED)
 140                type = AUDIT_APPARMOR_KILL;
 141
 142        if (!unconfined(profile))
 143                aad(sa)->profile = profile;
 144
 145        aa_audit_msg(type, sa, cb);
 146
 147        if (aad(sa)->type == AUDIT_APPARMOR_KILL)
 148                (void)send_sig_info(SIGKILL, NULL,
 149                        sa->type == LSM_AUDIT_DATA_TASK && sa->u.tsk ?
 150                                    sa->u.tsk : current);
 151
 152        if (aad(sa)->type == AUDIT_APPARMOR_ALLOWED)
 153                return complain_error(aad(sa)->error);
 154
 155        return aad(sa)->error;
 156}
 157