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 *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 *audit_mode_names[] = {
  77        "normal",
  78        "quiet_denied",
  79        "quiet",
  80        "noquiet",
  81        "all"
  82};
  83
  84static char *aa_audit_type[] = {
  85        "AUDIT",
  86        "ALLOWED",
  87        "DENIED",
  88        "HINT",
  89        "STATUS",
  90        "ERROR",
  91        "KILLED"
  92};
  93
  94/*
  95 * Currently AppArmor auditing is fed straight into the audit framework.
  96 *
  97 * TODO:
  98 * netlink interface for complain mode
  99 * user auditing, - send user auditing to netlink interface
 100 * system control of whether user audit messages go to system log
 101 */
 102
 103/**
 104 * audit_base - core AppArmor function.
 105 * @ab: audit buffer to fill (NOT NULL)
 106 * @ca: audit structure containing data to audit (NOT NULL)
 107 *
 108 * Record common AppArmor audit data from @sa
 109 */
 110static void audit_pre(struct audit_buffer *ab, void *ca)
 111{
 112        struct common_audit_data *sa = ca;
 113        struct task_struct *tsk = sa->tsk ? sa->tsk : current;
 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                pid_t pid;
 135                rcu_read_lock();
 136                pid = tsk->real_parent->pid;
 137                rcu_read_unlock();
 138                audit_log_format(ab, " parent=%d", pid);
 139                if (profile->ns != root_ns) {
 140                        audit_log_format(ab, " namespace=");
 141                        audit_log_untrustedstring(ab, profile->ns->base.hname);
 142                }
 143                audit_log_format(ab, " profile=");
 144                audit_log_untrustedstring(ab, profile->base.hname);
 145        }
 146
 147        if (sa->aad.name) {
 148                audit_log_format(ab, " name=");
 149                audit_log_untrustedstring(ab, sa->aad.name);
 150        }
 151}
 152
 153/**
 154 * aa_audit_msg - Log a message to the audit subsystem
 155 * @sa: audit event structure (NOT NULL)
 156 * @cb: optional callback fn for type specific fields (MAYBE NULL)
 157 */
 158void aa_audit_msg(int type, struct common_audit_data *sa,
 159                  void (*cb) (struct audit_buffer *, void *))
 160{
 161        sa->aad.type = type;
 162        sa->lsm_pre_audit = audit_pre;
 163        sa->lsm_post_audit = cb;
 164        common_lsm_audit(sa);
 165}
 166
 167/**
 168 * aa_audit - Log a profile based audit event to the audit subsystem
 169 * @type: audit type for the message
 170 * @profile: profile to check against (NOT NULL)
 171 * @gfp: allocation flags to use
 172 * @sa: audit event (NOT NULL)
 173 * @cb: optional callback fn for type specific fields (MAYBE NULL)
 174 *
 175 * Handle default message switching based off of audit mode flags
 176 *
 177 * Returns: error on failure
 178 */
 179int aa_audit(int type, struct aa_profile *profile, gfp_t gfp,
 180             struct common_audit_data *sa,
 181             void (*cb) (struct audit_buffer *, void *))
 182{
 183        BUG_ON(!profile);
 184
 185        if (type == AUDIT_APPARMOR_AUTO) {
 186                if (likely(!sa->aad.error)) {
 187                        if (AUDIT_MODE(profile) != AUDIT_ALL)
 188                                return 0;
 189                        type = AUDIT_APPARMOR_AUDIT;
 190                } else if (COMPLAIN_MODE(profile))
 191                        type = AUDIT_APPARMOR_ALLOWED;
 192                else
 193                        type = AUDIT_APPARMOR_DENIED;
 194        }
 195        if (AUDIT_MODE(profile) == AUDIT_QUIET ||
 196            (type == AUDIT_APPARMOR_DENIED &&
 197             AUDIT_MODE(profile) == AUDIT_QUIET))
 198                return sa->aad.error;
 199
 200        if (KILL_MODE(profile) && type == AUDIT_APPARMOR_DENIED)
 201                type = AUDIT_APPARMOR_KILL;
 202
 203        if (!unconfined(profile))
 204                sa->aad.profile = profile;
 205
 206        aa_audit_msg(type, sa, cb);
 207
 208        if (sa->aad.type == AUDIT_APPARMOR_KILL)
 209                (void)send_sig_info(SIGKILL, NULL, sa->tsk ? sa->tsk : current);
 210
 211        if (sa->aad.type == AUDIT_APPARMOR_ALLOWED)
 212                return complain_error(sa->aad.error);
 213
 214        return sa->aad.error;
 215}
 216
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.