]> git.karo-electronics.de Git - karo-tx-linux.git/blob - security/apparmor/audit.c
Merge branch 'for-4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu
[karo-tx-linux.git] / security / apparmor / audit.c
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
24 const char *const audit_mode_names[] = {
25         "normal",
26         "quiet_denied",
27         "quiet",
28         "noquiet",
29         "all"
30 };
31
32 static 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  */
59 static 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  */
101 void 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  */
119 int 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 }