Branch data Line data Source code
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 : :
22 : : const 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 : :
76 : : const char *const audit_mode_names[] = {
77 : : "normal",
78 : : "quiet_denied",
79 : : "quiet",
80 : : "noquiet",
81 : : "all"
82 : : };
83 : :
84 : : static 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 : : */
111 : 0 : static void audit_pre(struct audit_buffer *ab, void *ca)
112 : : {
113 : : struct common_audit_data *sa = ca;
114 : :
115 [ # # ]: 0 : if (aa_g_audit_header) {
116 : 0 : audit_log_format(ab, "apparmor=");
117 : 0 : audit_log_string(ab, aa_audit_type[sa->aad->type]);
118 : : }
119 : :
120 [ # # ]: 0 : if (sa->aad->op) {
121 : 0 : audit_log_format(ab, " operation=");
122 : 0 : audit_log_string(ab, op_table[sa->aad->op]);
123 : : }
124 : :
125 [ # # ]: 0 : if (sa->aad->info) {
126 : 0 : audit_log_format(ab, " info=");
127 : 0 : audit_log_string(ab, sa->aad->info);
128 [ # # ]: 0 : if (sa->aad->error)
129 : 0 : audit_log_format(ab, " error=%d", sa->aad->error);
130 : : }
131 : :
132 [ # # ]: 0 : if (sa->aad->profile) {
133 : : struct aa_profile *profile = sa->aad->profile;
134 [ # # ]: 0 : if (profile->ns != root_ns) {
135 : 0 : audit_log_format(ab, " namespace=");
136 : 0 : audit_log_untrustedstring(ab, profile->ns->base.hname);
137 : : }
138 : 0 : audit_log_format(ab, " profile=");
139 : 0 : audit_log_untrustedstring(ab, profile->base.hname);
140 : : }
141 : :
142 [ # # ]: 0 : if (sa->aad->name) {
143 : 0 : audit_log_format(ab, " name=");
144 : 0 : audit_log_untrustedstring(ab, sa->aad->name);
145 : : }
146 : 0 : }
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 : : */
153 : 0 : void aa_audit_msg(int type, struct common_audit_data *sa,
154 : : void (*cb) (struct audit_buffer *, void *))
155 : : {
156 : 0 : sa->aad->type = type;
157 : 0 : common_lsm_audit(sa, audit_pre, cb);
158 : 0 : }
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 : : */
172 : 0 : int 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 [ # # ]: 0 : BUG_ON(!profile);
177 : :
178 [ # # ]: 0 : if (type == AUDIT_APPARMOR_AUTO) {
179 [ # # ]: 0 : if (likely(!sa->aad->error)) {
180 [ # # ]: 0 : if (AUDIT_MODE(profile) != AUDIT_ALL)
181 : : return 0;
182 : : type = AUDIT_APPARMOR_AUDIT;
183 [ # # ][ # # ]: 0 : } else if (COMPLAIN_MODE(profile))
184 : : type = AUDIT_APPARMOR_ALLOWED;
185 : : else
186 : : type = AUDIT_APPARMOR_DENIED;
187 : : }
188 [ # # ][ # # ]: 0 : if (AUDIT_MODE(profile) == AUDIT_QUIET ||
189 [ # # ]: 0 : (type == AUDIT_APPARMOR_DENIED &&
190 : : AUDIT_MODE(profile) == AUDIT_QUIET))
191 : 0 : return sa->aad->error;
192 : :
193 [ # # ][ # # ]: 0 : if (KILL_MODE(profile) && type == AUDIT_APPARMOR_DENIED)
[ # # ]
194 : : type = AUDIT_APPARMOR_KILL;
195 : :
196 [ # # ]: 0 : if (!unconfined(profile))
197 : 0 : sa->aad->profile = profile;
198 : :
199 : : aa_audit_msg(type, sa, cb);
200 : :
201 [ # # ]: 0 : if (sa->aad->type == AUDIT_APPARMOR_KILL)
202 [ # # ]: 0 : (void)send_sig_info(SIGKILL, NULL,
203 : 0 : sa->u.tsk ? sa->u.tsk : current);
204 : :
205 [ # # ]: 0 : if (sa->aad->type == AUDIT_APPARMOR_ALLOWED)
206 : 0 : return complain_error(sa->aad->error);
207 : :
208 : 0 : return sa->aad->error;
209 : : }
|