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->aad->tsk ? sa->aad->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        if (sa->aad->tsk) {
 154                audit_log_format(ab, " pid=%d comm=", tsk->pid);
 155                audit_log_untrustedstring(ab, tsk->comm);
 156        }
 157
 158}
 159
 160/**
 161 * aa_audit_msg - Log a message to the audit subsystem
 162 * @sa: audit event structure (NOT NULL)
 163 * @cb: optional callback fn for type specific fields (MAYBE NULL)
 164 */
 165void aa_audit_msg(int type, struct common_audit_data *sa,
 166                  void (*cb) (struct audit_buffer *, void *))
 167{
 168        sa->aad->type = type;
 169        common_lsm_audit(sa, audit_pre, cb);
 170}
 171
 172/**
 173 * aa_audit - Log a profile based audit event to the audit subsystem
 174 * @type: audit type for the message
 175 * @profile: profile to check against (NOT NULL)
 176 * @gfp: allocation flags to use
 177 * @sa: audit event (NOT NULL)
 178 * @cb: optional callback fn for type specific fields (MAYBE NULL)
 179 *
 180 * Handle default message switching based off of audit mode flags
 181 *
 182 * Returns: error on failure
 183 */
 184int aa_audit(int type, struct aa_profile *profile, gfp_t gfp,
 185             struct common_audit_data *sa,
 186             void (*cb) (struct audit_buffer *, void *))
 187{
 188        BUG_ON(!profile);
 189
 190        if (type == AUDIT_APPARMOR_AUTO) {
 191                if (likely(!sa->aad->error)) {
 192                        if (AUDIT_MODE(profile) != AUDIT_ALL)
 193                                return 0;
 194                        type = AUDIT_APPARMOR_AUDIT;
 195                } else if (COMPLAIN_MODE(profile))
 196                        type = AUDIT_APPARMOR_ALLOWED;
 197                else
 198                        type = AUDIT_APPARMOR_DENIED;
 199        }
 200        if (AUDIT_MODE(profile) == AUDIT_QUIET ||
 201            (type == AUDIT_APPARMOR_DENIED &&
 202             AUDIT_MODE(profile) == AUDIT_QUIET))
 203                return sa->aad->error;
 204
 205        if (KILL_MODE(profile) && type == AUDIT_APPARMOR_DENIED)
 206                type = AUDIT_APPARMOR_KILL;
 207
 208        if (!unconfined(profile))
 209                sa->aad->profile = profile;
 210
 211        aa_audit_msg(type, sa, cb);
 212
 213        if (sa->aad->type == AUDIT_APPARMOR_KILL)
 214                (void)send_sig_info(SIGKILL, NULL,
 215                                    sa->aad->tsk ?  sa->aad->tsk : current);
 216
 217        if (sa->aad->type == AUDIT_APPARMOR_ALLOWED)
 218                return complain_error(sa->aad->error);
 219
 220        return sa->aad->error;
 221}
 222