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        struct task_struct *tsk = sa->tsk ? sa->tsk : current;
 115
 116        if (aa_g_audit_header) {
 117                audit_log_format(ab, "apparmor=");
 118                audit_log_string(ab, aa_audit_type[sa->aad->type]);
 119        }
 120
 121        if (sa->aad->op) {
 122                audit_log_format(ab, " operation=");
 123                audit_log_string(ab, op_table[sa->aad->op]);
 124        }
 125
 126        if (sa->aad->info) {
 127                audit_log_format(ab, " info=");
 128                audit_log_string(ab, sa->aad->info);
 129                if (sa->aad->error)
 130                        audit_log_format(ab, " error=%d", sa->aad->error);
 131        }
 132
 133        if (sa->aad->profile) {
 134                struct aa_profile *profile = sa->aad->profile;
 135                pid_t pid;
 136                rcu_read_lock();
 137                pid = rcu_dereference(tsk->real_parent)->pid;
 138                rcu_read_unlock();
 139                audit_log_format(ab, " parent=%d", pid);
 140                if (profile->ns != root_ns) {
 141                        audit_log_format(ab, " namespace=");
 142                        audit_log_untrustedstring(ab, profile->ns->base.hname);
 143                }
 144                audit_log_format(ab, " profile=");
 145                audit_log_untrustedstring(ab, profile->base.hname);
 146        }
 147
 148        if (sa->aad->name) {
 149                audit_log_format(ab, " name=");
 150                audit_log_untrustedstring(ab, sa->aad->name);
 151        }
 152}
 153
 154/**
 155 * aa_audit_msg - Log a message to the audit subsystem
 156 * @sa: audit event structure (NOT NULL)
 157 * @cb: optional callback fn for type specific fields (MAYBE NULL)
 158 */
 159void aa_audit_msg(int type, struct common_audit_data *sa,
 160                  void (*cb) (struct audit_buffer *, void *))
 161{
 162        sa->aad->type = type;
 163        common_lsm_audit(sa, audit_pre, cb);
 164}
 165
 166/**
 167 * aa_audit - Log a profile based audit event to the audit subsystem
 168 * @type: audit type for the message
 169 * @profile: profile to check against (NOT NULL)
 170 * @gfp: allocation flags to use
 171 * @sa: audit event (NOT NULL)
 172 * @cb: optional callback fn for type specific fields (MAYBE NULL)
 173 *
 174 * Handle default message switching based off of audit mode flags
 175 *
 176 * Returns: error on failure
 177 */
 178int aa_audit(int type, struct aa_profile *profile, gfp_t gfp,
 179             struct common_audit_data *sa,
 180             void (*cb) (struct audit_buffer *, void *))
 181{
 182        BUG_ON(!profile);
 183
 184        if (type == AUDIT_APPARMOR_AUTO) {
 185                if (likely(!sa->aad->error)) {
 186                        if (AUDIT_MODE(profile) != AUDIT_ALL)
 187                                return 0;
 188                        type = AUDIT_APPARMOR_AUDIT;
 189                } else if (COMPLAIN_MODE(profile))
 190                        type = AUDIT_APPARMOR_ALLOWED;
 191                else
 192                        type = AUDIT_APPARMOR_DENIED;
 193        }
 194        if (AUDIT_MODE(profile) == AUDIT_QUIET ||
 195            (type == AUDIT_APPARMOR_DENIED &&
 196             AUDIT_MODE(profile) == AUDIT_QUIET))
 197                return sa->aad->error;
 198
 199        if (KILL_MODE(profile) && type == AUDIT_APPARMOR_DENIED)
 200                type = AUDIT_APPARMOR_KILL;
 201
 202        if (!unconfined(profile))
 203                sa->aad->profile = profile;
 204
 205        aa_audit_msg(type, sa, cb);
 206
 207        if (sa->aad->type == AUDIT_APPARMOR_KILL)
 208                (void)send_sig_info(SIGKILL, NULL, sa->tsk ? sa->tsk : current);
 209
 210        if (sa->aad->type == AUDIT_APPARMOR_ALLOWED)
 211                return complain_error(sa->aad->error);
 212
 213        return sa->aad->error;
 214}
 215