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
  22const char *const op_table[] = {
  23        "null",
  24
  25        "sysctl",
  26        "capable",
  27
  28        "unlink",
  29        "mkdir",
  30        "rmdir",
  31        "mknod",
  32        "truncate",
  33        "link",
  34        "symlink",
  35        "rename_src",
  36        "rename_dest",
  37        "chmod",
  38        "chown",
  39        "getattr",
  40        "open",
  41
  42        "file_perm",
  43        "file_lock",
  44        "file_mmap",
  45        "file_mprotect",
  46
  47        "create",
  48        "post_create",
  49        "bind",
  50        "connect",
  51        "listen",
  52        "accept",
  53        "sendmsg",
  54        "recvmsg",
  55        "getsockname",
  56        "getpeername",
  57        "getsockopt",
  58        "setsockopt",
  59        "socket_shutdown",
  60
  61        "ptrace",
  62
  63        "exec",
  64        "change_hat",
  65        "change_profile",
  66        "change_onexec",
  67
  68        "setprocattr",
  69        "setrlimit",
  70
  71        "profile_replace",
  72        "profile_load",
  73        "profile_remove"
  74};
  75
  76const char *const audit_mode_names[] = {
  77        "normal",
  78        "quiet_denied",
  79        "quiet",
  80        "noquiet",
  81        "all"
  82};
  83
  84static const char *const aa_audit_type[] = {
  85        "AUDIT",
  86        "ALLOWED",
  87        "DENIED",
  88        "HINT",
  89        "STATUS",
  90        "ERROR",
  91        "KILLED",
  92        "AUTO"
  93};
  94
  95/*
  96 * Currently AppArmor auditing is fed straight into the audit framework.
  97 *
  98 * TODO:
  99 * netlink interface for complain mode
 100 * user auditing, - send user auditing to netlink interface
 101 * system control of whether user audit messages go to system log
 102 */
 103
 104/**
 105 * audit_base - core AppArmor function.
 106 * @ab: audit buffer to fill (NOT NULL)
 107 * @ca: audit structure containing data to audit (NOT NULL)
 108 *
 109 * Record common AppArmor audit data from @sa
 110 */
 111static void audit_pre(struct audit_buffer *ab, void *ca)
 112{
 113        struct common_audit_data *sa = ca;
 114
 115        if (aa_g_audit_header) {
 116                audit_log_format(ab, "apparmor=");
 117                audit_log_string(ab, aa_audit_type[sa->aad->type]);
 118        }
 119
 120        if (sa->aad->op) {
 121                audit_log_format(ab, " operation=");
 122                audit_log_string(ab, op_table[sa->aad->op]);
 123        }
 124
 125        if (sa->aad->info) {
 126                audit_log_format(ab, " info=");
 127                audit_log_string(ab, sa->aad->info);
 128                if (sa->aad->error)
 129                        audit_log_format(ab, " error=%d", sa->aad->error);
 130        }
 131
 132        if (sa->aad->profile) {
 133                struct aa_profile *profile = sa->aad->profile;
 134                if (profile->ns != root_ns) {
 135                        audit_log_format(ab, " namespace=");
 136                        audit_log_untrustedstring(ab, profile->ns->base.hname);
 137                }
 138                audit_log_format(ab, " profile=");
 139                audit_log_untrustedstring(ab, profile->base.hname);
 140        }
 141
 142        if (sa->aad->name) {
 143                audit_log_format(ab, " name=");
 144                audit_log_untrustedstring(ab, sa->aad->name);
 145        }
 146}
 147
 148/**
 149 * aa_audit_msg - Log a message to the audit subsystem
 150 * @sa: audit event structure (NOT NULL)
 151 * @cb: optional callback fn for type specific fields (MAYBE NULL)
 152 */
 153void aa_audit_msg(int type, struct common_audit_data *sa,
 154                  void (*cb) (struct audit_buffer *, void *))
 155{
 156        sa->aad->type = type;
 157        common_lsm_audit(sa, audit_pre, cb);
 158}
 159
 160/**
 161 * aa_audit - Log a profile based audit event to the audit subsystem
 162 * @type: audit type for the message
 163 * @profile: profile to check against (NOT NULL)
 164 * @gfp: allocation flags to use
 165 * @sa: audit event (NOT NULL)
 166 * @cb: optional callback fn for type specific fields (MAYBE NULL)
 167 *
 168 * Handle default message switching based off of audit mode flags
 169 *
 170 * Returns: error on failure
 171 */
 172int aa_audit(int type, struct aa_profile *profile, gfp_t gfp,
 173             struct common_audit_data *sa,
 174             void (*cb) (struct audit_buffer *, void *))
 175{
 176        BUG_ON(!profile);
 177
 178        if (type == AUDIT_APPARMOR_AUTO) {
 179                if (likely(!sa->aad->error)) {
 180                        if (AUDIT_MODE(profile) != AUDIT_ALL)
 181                                return 0;
 182                        type = AUDIT_APPARMOR_AUDIT;
 183                } else if (COMPLAIN_MODE(profile))
 184                        type = AUDIT_APPARMOR_ALLOWED;
 185                else
 186                        type = AUDIT_APPARMOR_DENIED;
 187        }
 188        if (AUDIT_MODE(profile) == AUDIT_QUIET ||
 189            (type == AUDIT_APPARMOR_DENIED &&
 190             AUDIT_MODE(profile) == AUDIT_QUIET))
 191                return sa->aad->error;
 192
 193        if (KILL_MODE(profile) && type == AUDIT_APPARMOR_DENIED)
 194                type = AUDIT_APPARMOR_KILL;
 195
 196        if (!unconfined(profile))
 197                sa->aad->profile = profile;
 198
 199        aa_audit_msg(type, sa, cb);
 200
 201        if (sa->aad->type == AUDIT_APPARMOR_KILL)
 202                (void)send_sig_info(SIGKILL, NULL,
 203                        sa->type == LSM_AUDIT_DATA_TASK && sa->u.tsk ?
 204                                    sa->u.tsk : current);
 205
 206        if (sa->aad->type == AUDIT_APPARMOR_ALLOWED)
 207                return complain_error(sa->aad->error);
 208
 209        return sa->aad->error;
 210}
 211