Commit d7a96f3a1ae279a2129653d6cb18d722f2f00f91
Committed by
James Morris
1 parent
03d37d25e0
Exists in
master
and in
39 other branches
Audit: internally use the new LSM audit hooks
Convert Audit to use the new LSM Audit hooks instead of the exported SELinux interface. Basically, use: security_audit_rule_init secuirty_audit_rule_free security_audit_rule_known security_audit_rule_match instad of (respectively) : selinux_audit_rule_init selinux_audit_rule_free audit_rule_has_selinux selinux_audit_rule_match Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com> Acked-by: James Morris <jmorris@namei.org>
Showing 3 changed files with 22 additions and 55 deletions Inline Diff
kernel/audit.c
1 | /* audit.c -- Auditing support | 1 | /* audit.c -- Auditing support |
2 | * Gateway between the kernel (e.g., selinux) and the user-space audit daemon. | 2 | * Gateway between the kernel (e.g., selinux) and the user-space audit daemon. |
3 | * System-call specific features have moved to auditsc.c | 3 | * System-call specific features have moved to auditsc.c |
4 | * | 4 | * |
5 | * Copyright 2003-2007 Red Hat Inc., Durham, North Carolina. | 5 | * Copyright 2003-2007 Red Hat Inc., Durham, North Carolina. |
6 | * All Rights Reserved. | 6 | * All Rights Reserved. |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
10 | * the Free Software Foundation; either version 2 of the License, or | 10 | * the Free Software Foundation; either version 2 of the License, or |
11 | * (at your option) any later version. | 11 | * (at your option) any later version. |
12 | * | 12 | * |
13 | * This program is distributed in the hope that it will be useful, | 13 | * This program is distributed in the hope that it will be useful, |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | * GNU General Public License for more details. | 16 | * GNU General Public License for more details. |
17 | * | 17 | * |
18 | * You should have received a copy of the GNU General Public License | 18 | * You should have received a copy of the GNU General Public License |
19 | * along with this program; if not, write to the Free Software | 19 | * along with this program; if not, write to the Free Software |
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
21 | * | 21 | * |
22 | * Written by Rickard E. (Rik) Faith <faith@redhat.com> | 22 | * Written by Rickard E. (Rik) Faith <faith@redhat.com> |
23 | * | 23 | * |
24 | * Goals: 1) Integrate fully with SELinux. | 24 | * Goals: 1) Integrate fully with Security Modules. |
25 | * 2) Minimal run-time overhead: | 25 | * 2) Minimal run-time overhead: |
26 | * a) Minimal when syscall auditing is disabled (audit_enable=0). | 26 | * a) Minimal when syscall auditing is disabled (audit_enable=0). |
27 | * b) Small when syscall auditing is enabled and no audit record | 27 | * b) Small when syscall auditing is enabled and no audit record |
28 | * is generated (defer as much work as possible to record | 28 | * is generated (defer as much work as possible to record |
29 | * generation time): | 29 | * generation time): |
30 | * i) context is allocated, | 30 | * i) context is allocated, |
31 | * ii) names from getname are stored without a copy, and | 31 | * ii) names from getname are stored without a copy, and |
32 | * iii) inode information stored from path_lookup. | 32 | * iii) inode information stored from path_lookup. |
33 | * 3) Ability to disable syscall auditing at boot time (audit=0). | 33 | * 3) Ability to disable syscall auditing at boot time (audit=0). |
34 | * 4) Usable by other parts of the kernel (if audit_log* is called, | 34 | * 4) Usable by other parts of the kernel (if audit_log* is called, |
35 | * then a syscall record will be generated automatically for the | 35 | * then a syscall record will be generated automatically for the |
36 | * current syscall). | 36 | * current syscall). |
37 | * 5) Netlink interface to user-space. | 37 | * 5) Netlink interface to user-space. |
38 | * 6) Support low-overhead kernel-based filtering to minimize the | 38 | * 6) Support low-overhead kernel-based filtering to minimize the |
39 | * information that must be passed to user-space. | 39 | * information that must be passed to user-space. |
40 | * | 40 | * |
41 | * Example user-space utilities: http://people.redhat.com/sgrubb/audit/ | 41 | * Example user-space utilities: http://people.redhat.com/sgrubb/audit/ |
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include <linux/init.h> | 44 | #include <linux/init.h> |
45 | #include <asm/types.h> | 45 | #include <asm/types.h> |
46 | #include <asm/atomic.h> | 46 | #include <asm/atomic.h> |
47 | #include <linux/mm.h> | 47 | #include <linux/mm.h> |
48 | #include <linux/module.h> | 48 | #include <linux/module.h> |
49 | #include <linux/err.h> | 49 | #include <linux/err.h> |
50 | #include <linux/kthread.h> | 50 | #include <linux/kthread.h> |
51 | 51 | ||
52 | #include <linux/audit.h> | 52 | #include <linux/audit.h> |
53 | 53 | ||
54 | #include <net/sock.h> | 54 | #include <net/sock.h> |
55 | #include <net/netlink.h> | 55 | #include <net/netlink.h> |
56 | #include <linux/skbuff.h> | 56 | #include <linux/skbuff.h> |
57 | #include <linux/netlink.h> | 57 | #include <linux/netlink.h> |
58 | #include <linux/selinux.h> | ||
59 | #include <linux/inotify.h> | 58 | #include <linux/inotify.h> |
60 | #include <linux/freezer.h> | 59 | #include <linux/freezer.h> |
61 | #include <linux/tty.h> | 60 | #include <linux/tty.h> |
62 | 61 | ||
63 | #include "audit.h" | 62 | #include "audit.h" |
64 | 63 | ||
65 | /* No auditing will take place until audit_initialized != 0. | 64 | /* No auditing will take place until audit_initialized != 0. |
66 | * (Initialization happens after skb_init is called.) */ | 65 | * (Initialization happens after skb_init is called.) */ |
67 | static int audit_initialized; | 66 | static int audit_initialized; |
68 | 67 | ||
69 | #define AUDIT_OFF 0 | 68 | #define AUDIT_OFF 0 |
70 | #define AUDIT_ON 1 | 69 | #define AUDIT_ON 1 |
71 | #define AUDIT_LOCKED 2 | 70 | #define AUDIT_LOCKED 2 |
72 | int audit_enabled; | 71 | int audit_enabled; |
73 | int audit_ever_enabled; | 72 | int audit_ever_enabled; |
74 | 73 | ||
75 | /* Default state when kernel boots without any parameters. */ | 74 | /* Default state when kernel boots without any parameters. */ |
76 | static int audit_default; | 75 | static int audit_default; |
77 | 76 | ||
78 | /* If auditing cannot proceed, audit_failure selects what happens. */ | 77 | /* If auditing cannot proceed, audit_failure selects what happens. */ |
79 | static int audit_failure = AUDIT_FAIL_PRINTK; | 78 | static int audit_failure = AUDIT_FAIL_PRINTK; |
80 | 79 | ||
81 | /* | 80 | /* |
82 | * If audit records are to be written to the netlink socket, audit_pid | 81 | * If audit records are to be written to the netlink socket, audit_pid |
83 | * contains the pid of the auditd process and audit_nlk_pid contains | 82 | * contains the pid of the auditd process and audit_nlk_pid contains |
84 | * the pid to use to send netlink messages to that process. | 83 | * the pid to use to send netlink messages to that process. |
85 | */ | 84 | */ |
86 | int audit_pid; | 85 | int audit_pid; |
87 | static int audit_nlk_pid; | 86 | static int audit_nlk_pid; |
88 | 87 | ||
89 | /* If audit_rate_limit is non-zero, limit the rate of sending audit records | 88 | /* If audit_rate_limit is non-zero, limit the rate of sending audit records |
90 | * to that number per second. This prevents DoS attacks, but results in | 89 | * to that number per second. This prevents DoS attacks, but results in |
91 | * audit records being dropped. */ | 90 | * audit records being dropped. */ |
92 | static int audit_rate_limit; | 91 | static int audit_rate_limit; |
93 | 92 | ||
94 | /* Number of outstanding audit_buffers allowed. */ | 93 | /* Number of outstanding audit_buffers allowed. */ |
95 | static int audit_backlog_limit = 64; | 94 | static int audit_backlog_limit = 64; |
96 | static int audit_backlog_wait_time = 60 * HZ; | 95 | static int audit_backlog_wait_time = 60 * HZ; |
97 | static int audit_backlog_wait_overflow = 0; | 96 | static int audit_backlog_wait_overflow = 0; |
98 | 97 | ||
99 | /* The identity of the user shutting down the audit system. */ | 98 | /* The identity of the user shutting down the audit system. */ |
100 | uid_t audit_sig_uid = -1; | 99 | uid_t audit_sig_uid = -1; |
101 | pid_t audit_sig_pid = -1; | 100 | pid_t audit_sig_pid = -1; |
102 | u32 audit_sig_sid = 0; | 101 | u32 audit_sig_sid = 0; |
103 | 102 | ||
104 | /* Records can be lost in several ways: | 103 | /* Records can be lost in several ways: |
105 | 0) [suppressed in audit_alloc] | 104 | 0) [suppressed in audit_alloc] |
106 | 1) out of memory in audit_log_start [kmalloc of struct audit_buffer] | 105 | 1) out of memory in audit_log_start [kmalloc of struct audit_buffer] |
107 | 2) out of memory in audit_log_move [alloc_skb] | 106 | 2) out of memory in audit_log_move [alloc_skb] |
108 | 3) suppressed due to audit_rate_limit | 107 | 3) suppressed due to audit_rate_limit |
109 | 4) suppressed due to audit_backlog_limit | 108 | 4) suppressed due to audit_backlog_limit |
110 | */ | 109 | */ |
111 | static atomic_t audit_lost = ATOMIC_INIT(0); | 110 | static atomic_t audit_lost = ATOMIC_INIT(0); |
112 | 111 | ||
113 | /* The netlink socket. */ | 112 | /* The netlink socket. */ |
114 | static struct sock *audit_sock; | 113 | static struct sock *audit_sock; |
115 | 114 | ||
116 | /* Inotify handle. */ | 115 | /* Inotify handle. */ |
117 | struct inotify_handle *audit_ih; | 116 | struct inotify_handle *audit_ih; |
118 | 117 | ||
119 | /* Hash for inode-based rules */ | 118 | /* Hash for inode-based rules */ |
120 | struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS]; | 119 | struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS]; |
121 | 120 | ||
122 | /* The audit_freelist is a list of pre-allocated audit buffers (if more | 121 | /* The audit_freelist is a list of pre-allocated audit buffers (if more |
123 | * than AUDIT_MAXFREE are in use, the audit buffer is freed instead of | 122 | * than AUDIT_MAXFREE are in use, the audit buffer is freed instead of |
124 | * being placed on the freelist). */ | 123 | * being placed on the freelist). */ |
125 | static DEFINE_SPINLOCK(audit_freelist_lock); | 124 | static DEFINE_SPINLOCK(audit_freelist_lock); |
126 | static int audit_freelist_count; | 125 | static int audit_freelist_count; |
127 | static LIST_HEAD(audit_freelist); | 126 | static LIST_HEAD(audit_freelist); |
128 | 127 | ||
129 | static struct sk_buff_head audit_skb_queue; | 128 | static struct sk_buff_head audit_skb_queue; |
130 | static struct task_struct *kauditd_task; | 129 | static struct task_struct *kauditd_task; |
131 | static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait); | 130 | static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait); |
132 | static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait); | 131 | static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait); |
133 | 132 | ||
134 | /* Serialize requests from userspace. */ | 133 | /* Serialize requests from userspace. */ |
135 | static DEFINE_MUTEX(audit_cmd_mutex); | 134 | static DEFINE_MUTEX(audit_cmd_mutex); |
136 | 135 | ||
137 | /* AUDIT_BUFSIZ is the size of the temporary buffer used for formatting | 136 | /* AUDIT_BUFSIZ is the size of the temporary buffer used for formatting |
138 | * audit records. Since printk uses a 1024 byte buffer, this buffer | 137 | * audit records. Since printk uses a 1024 byte buffer, this buffer |
139 | * should be at least that large. */ | 138 | * should be at least that large. */ |
140 | #define AUDIT_BUFSIZ 1024 | 139 | #define AUDIT_BUFSIZ 1024 |
141 | 140 | ||
142 | /* AUDIT_MAXFREE is the number of empty audit_buffers we keep on the | 141 | /* AUDIT_MAXFREE is the number of empty audit_buffers we keep on the |
143 | * audit_freelist. Doing so eliminates many kmalloc/kfree calls. */ | 142 | * audit_freelist. Doing so eliminates many kmalloc/kfree calls. */ |
144 | #define AUDIT_MAXFREE (2*NR_CPUS) | 143 | #define AUDIT_MAXFREE (2*NR_CPUS) |
145 | 144 | ||
146 | /* The audit_buffer is used when formatting an audit record. The caller | 145 | /* The audit_buffer is used when formatting an audit record. The caller |
147 | * locks briefly to get the record off the freelist or to allocate the | 146 | * locks briefly to get the record off the freelist or to allocate the |
148 | * buffer, and locks briefly to send the buffer to the netlink layer or | 147 | * buffer, and locks briefly to send the buffer to the netlink layer or |
149 | * to place it on a transmit queue. Multiple audit_buffers can be in | 148 | * to place it on a transmit queue. Multiple audit_buffers can be in |
150 | * use simultaneously. */ | 149 | * use simultaneously. */ |
151 | struct audit_buffer { | 150 | struct audit_buffer { |
152 | struct list_head list; | 151 | struct list_head list; |
153 | struct sk_buff *skb; /* formatted skb ready to send */ | 152 | struct sk_buff *skb; /* formatted skb ready to send */ |
154 | struct audit_context *ctx; /* NULL or associated context */ | 153 | struct audit_context *ctx; /* NULL or associated context */ |
155 | gfp_t gfp_mask; | 154 | gfp_t gfp_mask; |
156 | }; | 155 | }; |
157 | 156 | ||
158 | static void audit_set_pid(struct audit_buffer *ab, pid_t pid) | 157 | static void audit_set_pid(struct audit_buffer *ab, pid_t pid) |
159 | { | 158 | { |
160 | if (ab) { | 159 | if (ab) { |
161 | struct nlmsghdr *nlh = nlmsg_hdr(ab->skb); | 160 | struct nlmsghdr *nlh = nlmsg_hdr(ab->skb); |
162 | nlh->nlmsg_pid = pid; | 161 | nlh->nlmsg_pid = pid; |
163 | } | 162 | } |
164 | } | 163 | } |
165 | 164 | ||
166 | void audit_panic(const char *message) | 165 | void audit_panic(const char *message) |
167 | { | 166 | { |
168 | switch (audit_failure) | 167 | switch (audit_failure) |
169 | { | 168 | { |
170 | case AUDIT_FAIL_SILENT: | 169 | case AUDIT_FAIL_SILENT: |
171 | break; | 170 | break; |
172 | case AUDIT_FAIL_PRINTK: | 171 | case AUDIT_FAIL_PRINTK: |
173 | if (printk_ratelimit()) | 172 | if (printk_ratelimit()) |
174 | printk(KERN_ERR "audit: %s\n", message); | 173 | printk(KERN_ERR "audit: %s\n", message); |
175 | break; | 174 | break; |
176 | case AUDIT_FAIL_PANIC: | 175 | case AUDIT_FAIL_PANIC: |
177 | /* test audit_pid since printk is always losey, why bother? */ | 176 | /* test audit_pid since printk is always losey, why bother? */ |
178 | if (audit_pid) | 177 | if (audit_pid) |
179 | panic("audit: %s\n", message); | 178 | panic("audit: %s\n", message); |
180 | break; | 179 | break; |
181 | } | 180 | } |
182 | } | 181 | } |
183 | 182 | ||
184 | static inline int audit_rate_check(void) | 183 | static inline int audit_rate_check(void) |
185 | { | 184 | { |
186 | static unsigned long last_check = 0; | 185 | static unsigned long last_check = 0; |
187 | static int messages = 0; | 186 | static int messages = 0; |
188 | static DEFINE_SPINLOCK(lock); | 187 | static DEFINE_SPINLOCK(lock); |
189 | unsigned long flags; | 188 | unsigned long flags; |
190 | unsigned long now; | 189 | unsigned long now; |
191 | unsigned long elapsed; | 190 | unsigned long elapsed; |
192 | int retval = 0; | 191 | int retval = 0; |
193 | 192 | ||
194 | if (!audit_rate_limit) return 1; | 193 | if (!audit_rate_limit) return 1; |
195 | 194 | ||
196 | spin_lock_irqsave(&lock, flags); | 195 | spin_lock_irqsave(&lock, flags); |
197 | if (++messages < audit_rate_limit) { | 196 | if (++messages < audit_rate_limit) { |
198 | retval = 1; | 197 | retval = 1; |
199 | } else { | 198 | } else { |
200 | now = jiffies; | 199 | now = jiffies; |
201 | elapsed = now - last_check; | 200 | elapsed = now - last_check; |
202 | if (elapsed > HZ) { | 201 | if (elapsed > HZ) { |
203 | last_check = now; | 202 | last_check = now; |
204 | messages = 0; | 203 | messages = 0; |
205 | retval = 1; | 204 | retval = 1; |
206 | } | 205 | } |
207 | } | 206 | } |
208 | spin_unlock_irqrestore(&lock, flags); | 207 | spin_unlock_irqrestore(&lock, flags); |
209 | 208 | ||
210 | return retval; | 209 | return retval; |
211 | } | 210 | } |
212 | 211 | ||
213 | /** | 212 | /** |
214 | * audit_log_lost - conditionally log lost audit message event | 213 | * audit_log_lost - conditionally log lost audit message event |
215 | * @message: the message stating reason for lost audit message | 214 | * @message: the message stating reason for lost audit message |
216 | * | 215 | * |
217 | * Emit at least 1 message per second, even if audit_rate_check is | 216 | * Emit at least 1 message per second, even if audit_rate_check is |
218 | * throttling. | 217 | * throttling. |
219 | * Always increment the lost messages counter. | 218 | * Always increment the lost messages counter. |
220 | */ | 219 | */ |
221 | void audit_log_lost(const char *message) | 220 | void audit_log_lost(const char *message) |
222 | { | 221 | { |
223 | static unsigned long last_msg = 0; | 222 | static unsigned long last_msg = 0; |
224 | static DEFINE_SPINLOCK(lock); | 223 | static DEFINE_SPINLOCK(lock); |
225 | unsigned long flags; | 224 | unsigned long flags; |
226 | unsigned long now; | 225 | unsigned long now; |
227 | int print; | 226 | int print; |
228 | 227 | ||
229 | atomic_inc(&audit_lost); | 228 | atomic_inc(&audit_lost); |
230 | 229 | ||
231 | print = (audit_failure == AUDIT_FAIL_PANIC || !audit_rate_limit); | 230 | print = (audit_failure == AUDIT_FAIL_PANIC || !audit_rate_limit); |
232 | 231 | ||
233 | if (!print) { | 232 | if (!print) { |
234 | spin_lock_irqsave(&lock, flags); | 233 | spin_lock_irqsave(&lock, flags); |
235 | now = jiffies; | 234 | now = jiffies; |
236 | if (now - last_msg > HZ) { | 235 | if (now - last_msg > HZ) { |
237 | print = 1; | 236 | print = 1; |
238 | last_msg = now; | 237 | last_msg = now; |
239 | } | 238 | } |
240 | spin_unlock_irqrestore(&lock, flags); | 239 | spin_unlock_irqrestore(&lock, flags); |
241 | } | 240 | } |
242 | 241 | ||
243 | if (print) { | 242 | if (print) { |
244 | if (printk_ratelimit()) | 243 | if (printk_ratelimit()) |
245 | printk(KERN_WARNING | 244 | printk(KERN_WARNING |
246 | "audit: audit_lost=%d audit_rate_limit=%d " | 245 | "audit: audit_lost=%d audit_rate_limit=%d " |
247 | "audit_backlog_limit=%d\n", | 246 | "audit_backlog_limit=%d\n", |
248 | atomic_read(&audit_lost), | 247 | atomic_read(&audit_lost), |
249 | audit_rate_limit, | 248 | audit_rate_limit, |
250 | audit_backlog_limit); | 249 | audit_backlog_limit); |
251 | audit_panic(message); | 250 | audit_panic(message); |
252 | } | 251 | } |
253 | } | 252 | } |
254 | 253 | ||
255 | static int audit_log_config_change(char *function_name, int new, int old, | 254 | static int audit_log_config_change(char *function_name, int new, int old, |
256 | uid_t loginuid, u32 sid, int allow_changes) | 255 | uid_t loginuid, u32 sid, int allow_changes) |
257 | { | 256 | { |
258 | struct audit_buffer *ab; | 257 | struct audit_buffer *ab; |
259 | int rc = 0; | 258 | int rc = 0; |
260 | 259 | ||
261 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); | 260 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); |
262 | audit_log_format(ab, "%s=%d old=%d by auid=%u", function_name, new, | 261 | audit_log_format(ab, "%s=%d old=%d by auid=%u", function_name, new, |
263 | old, loginuid); | 262 | old, loginuid); |
264 | if (sid) { | 263 | if (sid) { |
265 | char *ctx = NULL; | 264 | char *ctx = NULL; |
266 | u32 len; | 265 | u32 len; |
267 | 266 | ||
268 | rc = security_secid_to_secctx(sid, &ctx, &len); | 267 | rc = security_secid_to_secctx(sid, &ctx, &len); |
269 | if (rc) { | 268 | if (rc) { |
270 | audit_log_format(ab, " sid=%u", sid); | 269 | audit_log_format(ab, " sid=%u", sid); |
271 | allow_changes = 0; /* Something weird, deny request */ | 270 | allow_changes = 0; /* Something weird, deny request */ |
272 | } else { | 271 | } else { |
273 | audit_log_format(ab, " subj=%s", ctx); | 272 | audit_log_format(ab, " subj=%s", ctx); |
274 | security_release_secctx(ctx, len); | 273 | security_release_secctx(ctx, len); |
275 | } | 274 | } |
276 | } | 275 | } |
277 | audit_log_format(ab, " res=%d", allow_changes); | 276 | audit_log_format(ab, " res=%d", allow_changes); |
278 | audit_log_end(ab); | 277 | audit_log_end(ab); |
279 | return rc; | 278 | return rc; |
280 | } | 279 | } |
281 | 280 | ||
282 | static int audit_do_config_change(char *function_name, int *to_change, | 281 | static int audit_do_config_change(char *function_name, int *to_change, |
283 | int new, uid_t loginuid, u32 sid) | 282 | int new, uid_t loginuid, u32 sid) |
284 | { | 283 | { |
285 | int allow_changes, rc = 0, old = *to_change; | 284 | int allow_changes, rc = 0, old = *to_change; |
286 | 285 | ||
287 | /* check if we are locked */ | 286 | /* check if we are locked */ |
288 | if (audit_enabled == AUDIT_LOCKED) | 287 | if (audit_enabled == AUDIT_LOCKED) |
289 | allow_changes = 0; | 288 | allow_changes = 0; |
290 | else | 289 | else |
291 | allow_changes = 1; | 290 | allow_changes = 1; |
292 | 291 | ||
293 | if (audit_enabled != AUDIT_OFF) { | 292 | if (audit_enabled != AUDIT_OFF) { |
294 | rc = audit_log_config_change(function_name, new, old, | 293 | rc = audit_log_config_change(function_name, new, old, |
295 | loginuid, sid, allow_changes); | 294 | loginuid, sid, allow_changes); |
296 | if (rc) | 295 | if (rc) |
297 | allow_changes = 0; | 296 | allow_changes = 0; |
298 | } | 297 | } |
299 | 298 | ||
300 | /* If we are allowed, make the change */ | 299 | /* If we are allowed, make the change */ |
301 | if (allow_changes == 1) | 300 | if (allow_changes == 1) |
302 | *to_change = new; | 301 | *to_change = new; |
303 | /* Not allowed, update reason */ | 302 | /* Not allowed, update reason */ |
304 | else if (rc == 0) | 303 | else if (rc == 0) |
305 | rc = -EPERM; | 304 | rc = -EPERM; |
306 | return rc; | 305 | return rc; |
307 | } | 306 | } |
308 | 307 | ||
309 | static int audit_set_rate_limit(int limit, uid_t loginuid, u32 sid) | 308 | static int audit_set_rate_limit(int limit, uid_t loginuid, u32 sid) |
310 | { | 309 | { |
311 | return audit_do_config_change("audit_rate_limit", &audit_rate_limit, | 310 | return audit_do_config_change("audit_rate_limit", &audit_rate_limit, |
312 | limit, loginuid, sid); | 311 | limit, loginuid, sid); |
313 | } | 312 | } |
314 | 313 | ||
315 | static int audit_set_backlog_limit(int limit, uid_t loginuid, u32 sid) | 314 | static int audit_set_backlog_limit(int limit, uid_t loginuid, u32 sid) |
316 | { | 315 | { |
317 | return audit_do_config_change("audit_backlog_limit", &audit_backlog_limit, | 316 | return audit_do_config_change("audit_backlog_limit", &audit_backlog_limit, |
318 | limit, loginuid, sid); | 317 | limit, loginuid, sid); |
319 | } | 318 | } |
320 | 319 | ||
321 | static int audit_set_enabled(int state, uid_t loginuid, u32 sid) | 320 | static int audit_set_enabled(int state, uid_t loginuid, u32 sid) |
322 | { | 321 | { |
323 | int rc; | 322 | int rc; |
324 | if (state < AUDIT_OFF || state > AUDIT_LOCKED) | 323 | if (state < AUDIT_OFF || state > AUDIT_LOCKED) |
325 | return -EINVAL; | 324 | return -EINVAL; |
326 | 325 | ||
327 | rc = audit_do_config_change("audit_enabled", &audit_enabled, state, | 326 | rc = audit_do_config_change("audit_enabled", &audit_enabled, state, |
328 | loginuid, sid); | 327 | loginuid, sid); |
329 | 328 | ||
330 | if (!rc) | 329 | if (!rc) |
331 | audit_ever_enabled |= !!state; | 330 | audit_ever_enabled |= !!state; |
332 | 331 | ||
333 | return rc; | 332 | return rc; |
334 | } | 333 | } |
335 | 334 | ||
336 | static int audit_set_failure(int state, uid_t loginuid, u32 sid) | 335 | static int audit_set_failure(int state, uid_t loginuid, u32 sid) |
337 | { | 336 | { |
338 | if (state != AUDIT_FAIL_SILENT | 337 | if (state != AUDIT_FAIL_SILENT |
339 | && state != AUDIT_FAIL_PRINTK | 338 | && state != AUDIT_FAIL_PRINTK |
340 | && state != AUDIT_FAIL_PANIC) | 339 | && state != AUDIT_FAIL_PANIC) |
341 | return -EINVAL; | 340 | return -EINVAL; |
342 | 341 | ||
343 | return audit_do_config_change("audit_failure", &audit_failure, state, | 342 | return audit_do_config_change("audit_failure", &audit_failure, state, |
344 | loginuid, sid); | 343 | loginuid, sid); |
345 | } | 344 | } |
346 | 345 | ||
347 | static int kauditd_thread(void *dummy) | 346 | static int kauditd_thread(void *dummy) |
348 | { | 347 | { |
349 | struct sk_buff *skb; | 348 | struct sk_buff *skb; |
350 | 349 | ||
351 | set_freezable(); | 350 | set_freezable(); |
352 | while (!kthread_should_stop()) { | 351 | while (!kthread_should_stop()) { |
353 | skb = skb_dequeue(&audit_skb_queue); | 352 | skb = skb_dequeue(&audit_skb_queue); |
354 | wake_up(&audit_backlog_wait); | 353 | wake_up(&audit_backlog_wait); |
355 | if (skb) { | 354 | if (skb) { |
356 | if (audit_pid) { | 355 | if (audit_pid) { |
357 | int err = netlink_unicast(audit_sock, skb, audit_nlk_pid, 0); | 356 | int err = netlink_unicast(audit_sock, skb, audit_nlk_pid, 0); |
358 | if (err < 0) { | 357 | if (err < 0) { |
359 | BUG_ON(err != -ECONNREFUSED); /* Shoudn't happen */ | 358 | BUG_ON(err != -ECONNREFUSED); /* Shoudn't happen */ |
360 | printk(KERN_ERR "audit: *NO* daemon at audit_pid=%d\n", audit_pid); | 359 | printk(KERN_ERR "audit: *NO* daemon at audit_pid=%d\n", audit_pid); |
361 | audit_log_lost("auditd dissapeared\n"); | 360 | audit_log_lost("auditd dissapeared\n"); |
362 | audit_pid = 0; | 361 | audit_pid = 0; |
363 | } | 362 | } |
364 | } else { | 363 | } else { |
365 | if (printk_ratelimit()) | 364 | if (printk_ratelimit()) |
366 | printk(KERN_NOTICE "%s\n", skb->data + | 365 | printk(KERN_NOTICE "%s\n", skb->data + |
367 | NLMSG_SPACE(0)); | 366 | NLMSG_SPACE(0)); |
368 | else | 367 | else |
369 | audit_log_lost("printk limit exceeded\n"); | 368 | audit_log_lost("printk limit exceeded\n"); |
370 | kfree_skb(skb); | 369 | kfree_skb(skb); |
371 | } | 370 | } |
372 | } else { | 371 | } else { |
373 | DECLARE_WAITQUEUE(wait, current); | 372 | DECLARE_WAITQUEUE(wait, current); |
374 | set_current_state(TASK_INTERRUPTIBLE); | 373 | set_current_state(TASK_INTERRUPTIBLE); |
375 | add_wait_queue(&kauditd_wait, &wait); | 374 | add_wait_queue(&kauditd_wait, &wait); |
376 | 375 | ||
377 | if (!skb_queue_len(&audit_skb_queue)) { | 376 | if (!skb_queue_len(&audit_skb_queue)) { |
378 | try_to_freeze(); | 377 | try_to_freeze(); |
379 | schedule(); | 378 | schedule(); |
380 | } | 379 | } |
381 | 380 | ||
382 | __set_current_state(TASK_RUNNING); | 381 | __set_current_state(TASK_RUNNING); |
383 | remove_wait_queue(&kauditd_wait, &wait); | 382 | remove_wait_queue(&kauditd_wait, &wait); |
384 | } | 383 | } |
385 | } | 384 | } |
386 | return 0; | 385 | return 0; |
387 | } | 386 | } |
388 | 387 | ||
389 | static int audit_prepare_user_tty(pid_t pid, uid_t loginuid) | 388 | static int audit_prepare_user_tty(pid_t pid, uid_t loginuid) |
390 | { | 389 | { |
391 | struct task_struct *tsk; | 390 | struct task_struct *tsk; |
392 | int err; | 391 | int err; |
393 | 392 | ||
394 | read_lock(&tasklist_lock); | 393 | read_lock(&tasklist_lock); |
395 | tsk = find_task_by_pid(pid); | 394 | tsk = find_task_by_pid(pid); |
396 | err = -ESRCH; | 395 | err = -ESRCH; |
397 | if (!tsk) | 396 | if (!tsk) |
398 | goto out; | 397 | goto out; |
399 | err = 0; | 398 | err = 0; |
400 | 399 | ||
401 | spin_lock_irq(&tsk->sighand->siglock); | 400 | spin_lock_irq(&tsk->sighand->siglock); |
402 | if (!tsk->signal->audit_tty) | 401 | if (!tsk->signal->audit_tty) |
403 | err = -EPERM; | 402 | err = -EPERM; |
404 | spin_unlock_irq(&tsk->sighand->siglock); | 403 | spin_unlock_irq(&tsk->sighand->siglock); |
405 | if (err) | 404 | if (err) |
406 | goto out; | 405 | goto out; |
407 | 406 | ||
408 | tty_audit_push_task(tsk, loginuid); | 407 | tty_audit_push_task(tsk, loginuid); |
409 | out: | 408 | out: |
410 | read_unlock(&tasklist_lock); | 409 | read_unlock(&tasklist_lock); |
411 | return err; | 410 | return err; |
412 | } | 411 | } |
413 | 412 | ||
414 | int audit_send_list(void *_dest) | 413 | int audit_send_list(void *_dest) |
415 | { | 414 | { |
416 | struct audit_netlink_list *dest = _dest; | 415 | struct audit_netlink_list *dest = _dest; |
417 | int pid = dest->pid; | 416 | int pid = dest->pid; |
418 | struct sk_buff *skb; | 417 | struct sk_buff *skb; |
419 | 418 | ||
420 | /* wait for parent to finish and send an ACK */ | 419 | /* wait for parent to finish and send an ACK */ |
421 | mutex_lock(&audit_cmd_mutex); | 420 | mutex_lock(&audit_cmd_mutex); |
422 | mutex_unlock(&audit_cmd_mutex); | 421 | mutex_unlock(&audit_cmd_mutex); |
423 | 422 | ||
424 | while ((skb = __skb_dequeue(&dest->q)) != NULL) | 423 | while ((skb = __skb_dequeue(&dest->q)) != NULL) |
425 | netlink_unicast(audit_sock, skb, pid, 0); | 424 | netlink_unicast(audit_sock, skb, pid, 0); |
426 | 425 | ||
427 | kfree(dest); | 426 | kfree(dest); |
428 | 427 | ||
429 | return 0; | 428 | return 0; |
430 | } | 429 | } |
431 | 430 | ||
432 | #ifdef CONFIG_AUDIT_TREE | 431 | #ifdef CONFIG_AUDIT_TREE |
433 | static int prune_tree_thread(void *unused) | 432 | static int prune_tree_thread(void *unused) |
434 | { | 433 | { |
435 | mutex_lock(&audit_cmd_mutex); | 434 | mutex_lock(&audit_cmd_mutex); |
436 | audit_prune_trees(); | 435 | audit_prune_trees(); |
437 | mutex_unlock(&audit_cmd_mutex); | 436 | mutex_unlock(&audit_cmd_mutex); |
438 | return 0; | 437 | return 0; |
439 | } | 438 | } |
440 | 439 | ||
441 | void audit_schedule_prune(void) | 440 | void audit_schedule_prune(void) |
442 | { | 441 | { |
443 | kthread_run(prune_tree_thread, NULL, "audit_prune_tree"); | 442 | kthread_run(prune_tree_thread, NULL, "audit_prune_tree"); |
444 | } | 443 | } |
445 | #endif | 444 | #endif |
446 | 445 | ||
447 | struct sk_buff *audit_make_reply(int pid, int seq, int type, int done, | 446 | struct sk_buff *audit_make_reply(int pid, int seq, int type, int done, |
448 | int multi, void *payload, int size) | 447 | int multi, void *payload, int size) |
449 | { | 448 | { |
450 | struct sk_buff *skb; | 449 | struct sk_buff *skb; |
451 | struct nlmsghdr *nlh; | 450 | struct nlmsghdr *nlh; |
452 | int len = NLMSG_SPACE(size); | 451 | int len = NLMSG_SPACE(size); |
453 | void *data; | 452 | void *data; |
454 | int flags = multi ? NLM_F_MULTI : 0; | 453 | int flags = multi ? NLM_F_MULTI : 0; |
455 | int t = done ? NLMSG_DONE : type; | 454 | int t = done ? NLMSG_DONE : type; |
456 | 455 | ||
457 | skb = alloc_skb(len, GFP_KERNEL); | 456 | skb = alloc_skb(len, GFP_KERNEL); |
458 | if (!skb) | 457 | if (!skb) |
459 | return NULL; | 458 | return NULL; |
460 | 459 | ||
461 | nlh = NLMSG_PUT(skb, pid, seq, t, size); | 460 | nlh = NLMSG_PUT(skb, pid, seq, t, size); |
462 | nlh->nlmsg_flags = flags; | 461 | nlh->nlmsg_flags = flags; |
463 | data = NLMSG_DATA(nlh); | 462 | data = NLMSG_DATA(nlh); |
464 | memcpy(data, payload, size); | 463 | memcpy(data, payload, size); |
465 | return skb; | 464 | return skb; |
466 | 465 | ||
467 | nlmsg_failure: /* Used by NLMSG_PUT */ | 466 | nlmsg_failure: /* Used by NLMSG_PUT */ |
468 | if (skb) | 467 | if (skb) |
469 | kfree_skb(skb); | 468 | kfree_skb(skb); |
470 | return NULL; | 469 | return NULL; |
471 | } | 470 | } |
472 | 471 | ||
473 | /** | 472 | /** |
474 | * audit_send_reply - send an audit reply message via netlink | 473 | * audit_send_reply - send an audit reply message via netlink |
475 | * @pid: process id to send reply to | 474 | * @pid: process id to send reply to |
476 | * @seq: sequence number | 475 | * @seq: sequence number |
477 | * @type: audit message type | 476 | * @type: audit message type |
478 | * @done: done (last) flag | 477 | * @done: done (last) flag |
479 | * @multi: multi-part message flag | 478 | * @multi: multi-part message flag |
480 | * @payload: payload data | 479 | * @payload: payload data |
481 | * @size: payload size | 480 | * @size: payload size |
482 | * | 481 | * |
483 | * Allocates an skb, builds the netlink message, and sends it to the pid. | 482 | * Allocates an skb, builds the netlink message, and sends it to the pid. |
484 | * No failure notifications. | 483 | * No failure notifications. |
485 | */ | 484 | */ |
486 | void audit_send_reply(int pid, int seq, int type, int done, int multi, | 485 | void audit_send_reply(int pid, int seq, int type, int done, int multi, |
487 | void *payload, int size) | 486 | void *payload, int size) |
488 | { | 487 | { |
489 | struct sk_buff *skb; | 488 | struct sk_buff *skb; |
490 | skb = audit_make_reply(pid, seq, type, done, multi, payload, size); | 489 | skb = audit_make_reply(pid, seq, type, done, multi, payload, size); |
491 | if (!skb) | 490 | if (!skb) |
492 | return; | 491 | return; |
493 | /* Ignore failure. It'll only happen if the sender goes away, | 492 | /* Ignore failure. It'll only happen if the sender goes away, |
494 | because our timeout is set to infinite. */ | 493 | because our timeout is set to infinite. */ |
495 | netlink_unicast(audit_sock, skb, pid, 0); | 494 | netlink_unicast(audit_sock, skb, pid, 0); |
496 | return; | 495 | return; |
497 | } | 496 | } |
498 | 497 | ||
499 | /* | 498 | /* |
500 | * Check for appropriate CAP_AUDIT_ capabilities on incoming audit | 499 | * Check for appropriate CAP_AUDIT_ capabilities on incoming audit |
501 | * control messages. | 500 | * control messages. |
502 | */ | 501 | */ |
503 | static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type) | 502 | static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type) |
504 | { | 503 | { |
505 | int err = 0; | 504 | int err = 0; |
506 | 505 | ||
507 | switch (msg_type) { | 506 | switch (msg_type) { |
508 | case AUDIT_GET: | 507 | case AUDIT_GET: |
509 | case AUDIT_LIST: | 508 | case AUDIT_LIST: |
510 | case AUDIT_LIST_RULES: | 509 | case AUDIT_LIST_RULES: |
511 | case AUDIT_SET: | 510 | case AUDIT_SET: |
512 | case AUDIT_ADD: | 511 | case AUDIT_ADD: |
513 | case AUDIT_ADD_RULE: | 512 | case AUDIT_ADD_RULE: |
514 | case AUDIT_DEL: | 513 | case AUDIT_DEL: |
515 | case AUDIT_DEL_RULE: | 514 | case AUDIT_DEL_RULE: |
516 | case AUDIT_SIGNAL_INFO: | 515 | case AUDIT_SIGNAL_INFO: |
517 | case AUDIT_TTY_GET: | 516 | case AUDIT_TTY_GET: |
518 | case AUDIT_TTY_SET: | 517 | case AUDIT_TTY_SET: |
519 | case AUDIT_TRIM: | 518 | case AUDIT_TRIM: |
520 | case AUDIT_MAKE_EQUIV: | 519 | case AUDIT_MAKE_EQUIV: |
521 | if (security_netlink_recv(skb, CAP_AUDIT_CONTROL)) | 520 | if (security_netlink_recv(skb, CAP_AUDIT_CONTROL)) |
522 | err = -EPERM; | 521 | err = -EPERM; |
523 | break; | 522 | break; |
524 | case AUDIT_USER: | 523 | case AUDIT_USER: |
525 | case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG: | 524 | case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG: |
526 | case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2: | 525 | case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2: |
527 | if (security_netlink_recv(skb, CAP_AUDIT_WRITE)) | 526 | if (security_netlink_recv(skb, CAP_AUDIT_WRITE)) |
528 | err = -EPERM; | 527 | err = -EPERM; |
529 | break; | 528 | break; |
530 | default: /* bad msg */ | 529 | default: /* bad msg */ |
531 | err = -EINVAL; | 530 | err = -EINVAL; |
532 | } | 531 | } |
533 | 532 | ||
534 | return err; | 533 | return err; |
535 | } | 534 | } |
536 | 535 | ||
537 | static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type, | 536 | static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type, |
538 | u32 pid, u32 uid, uid_t auid, u32 sid) | 537 | u32 pid, u32 uid, uid_t auid, u32 sid) |
539 | { | 538 | { |
540 | int rc = 0; | 539 | int rc = 0; |
541 | char *ctx = NULL; | 540 | char *ctx = NULL; |
542 | u32 len; | 541 | u32 len; |
543 | 542 | ||
544 | if (!audit_enabled) { | 543 | if (!audit_enabled) { |
545 | *ab = NULL; | 544 | *ab = NULL; |
546 | return rc; | 545 | return rc; |
547 | } | 546 | } |
548 | 547 | ||
549 | *ab = audit_log_start(NULL, GFP_KERNEL, msg_type); | 548 | *ab = audit_log_start(NULL, GFP_KERNEL, msg_type); |
550 | audit_log_format(*ab, "user pid=%d uid=%u auid=%u", | 549 | audit_log_format(*ab, "user pid=%d uid=%u auid=%u", |
551 | pid, uid, auid); | 550 | pid, uid, auid); |
552 | if (sid) { | 551 | if (sid) { |
553 | rc = security_secid_to_secctx(sid, &ctx, &len); | 552 | rc = security_secid_to_secctx(sid, &ctx, &len); |
554 | if (rc) | 553 | if (rc) |
555 | audit_log_format(*ab, " ssid=%u", sid); | 554 | audit_log_format(*ab, " ssid=%u", sid); |
556 | else { | 555 | else { |
557 | audit_log_format(*ab, " subj=%s", ctx); | 556 | audit_log_format(*ab, " subj=%s", ctx); |
558 | security_release_secctx(ctx, len); | 557 | security_release_secctx(ctx, len); |
559 | } | 558 | } |
560 | } | 559 | } |
561 | 560 | ||
562 | return rc; | 561 | return rc; |
563 | } | 562 | } |
564 | 563 | ||
565 | static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | 564 | static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) |
566 | { | 565 | { |
567 | u32 uid, pid, seq, sid; | 566 | u32 uid, pid, seq, sid; |
568 | void *data; | 567 | void *data; |
569 | struct audit_status *status_get, status_set; | 568 | struct audit_status *status_get, status_set; |
570 | int err; | 569 | int err; |
571 | struct audit_buffer *ab; | 570 | struct audit_buffer *ab; |
572 | u16 msg_type = nlh->nlmsg_type; | 571 | u16 msg_type = nlh->nlmsg_type; |
573 | uid_t loginuid; /* loginuid of sender */ | 572 | uid_t loginuid; /* loginuid of sender */ |
574 | struct audit_sig_info *sig_data; | 573 | struct audit_sig_info *sig_data; |
575 | char *ctx = NULL; | 574 | char *ctx = NULL; |
576 | u32 len; | 575 | u32 len; |
577 | 576 | ||
578 | err = audit_netlink_ok(skb, msg_type); | 577 | err = audit_netlink_ok(skb, msg_type); |
579 | if (err) | 578 | if (err) |
580 | return err; | 579 | return err; |
581 | 580 | ||
582 | /* As soon as there's any sign of userspace auditd, | 581 | /* As soon as there's any sign of userspace auditd, |
583 | * start kauditd to talk to it */ | 582 | * start kauditd to talk to it */ |
584 | if (!kauditd_task) | 583 | if (!kauditd_task) |
585 | kauditd_task = kthread_run(kauditd_thread, NULL, "kauditd"); | 584 | kauditd_task = kthread_run(kauditd_thread, NULL, "kauditd"); |
586 | if (IS_ERR(kauditd_task)) { | 585 | if (IS_ERR(kauditd_task)) { |
587 | err = PTR_ERR(kauditd_task); | 586 | err = PTR_ERR(kauditd_task); |
588 | kauditd_task = NULL; | 587 | kauditd_task = NULL; |
589 | return err; | 588 | return err; |
590 | } | 589 | } |
591 | 590 | ||
592 | pid = NETLINK_CREDS(skb)->pid; | 591 | pid = NETLINK_CREDS(skb)->pid; |
593 | uid = NETLINK_CREDS(skb)->uid; | 592 | uid = NETLINK_CREDS(skb)->uid; |
594 | loginuid = NETLINK_CB(skb).loginuid; | 593 | loginuid = NETLINK_CB(skb).loginuid; |
595 | sid = NETLINK_CB(skb).sid; | 594 | sid = NETLINK_CB(skb).sid; |
596 | seq = nlh->nlmsg_seq; | 595 | seq = nlh->nlmsg_seq; |
597 | data = NLMSG_DATA(nlh); | 596 | data = NLMSG_DATA(nlh); |
598 | 597 | ||
599 | switch (msg_type) { | 598 | switch (msg_type) { |
600 | case AUDIT_GET: | 599 | case AUDIT_GET: |
601 | status_set.enabled = audit_enabled; | 600 | status_set.enabled = audit_enabled; |
602 | status_set.failure = audit_failure; | 601 | status_set.failure = audit_failure; |
603 | status_set.pid = audit_pid; | 602 | status_set.pid = audit_pid; |
604 | status_set.rate_limit = audit_rate_limit; | 603 | status_set.rate_limit = audit_rate_limit; |
605 | status_set.backlog_limit = audit_backlog_limit; | 604 | status_set.backlog_limit = audit_backlog_limit; |
606 | status_set.lost = atomic_read(&audit_lost); | 605 | status_set.lost = atomic_read(&audit_lost); |
607 | status_set.backlog = skb_queue_len(&audit_skb_queue); | 606 | status_set.backlog = skb_queue_len(&audit_skb_queue); |
608 | audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_GET, 0, 0, | 607 | audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_GET, 0, 0, |
609 | &status_set, sizeof(status_set)); | 608 | &status_set, sizeof(status_set)); |
610 | break; | 609 | break; |
611 | case AUDIT_SET: | 610 | case AUDIT_SET: |
612 | if (nlh->nlmsg_len < sizeof(struct audit_status)) | 611 | if (nlh->nlmsg_len < sizeof(struct audit_status)) |
613 | return -EINVAL; | 612 | return -EINVAL; |
614 | status_get = (struct audit_status *)data; | 613 | status_get = (struct audit_status *)data; |
615 | if (status_get->mask & AUDIT_STATUS_ENABLED) { | 614 | if (status_get->mask & AUDIT_STATUS_ENABLED) { |
616 | err = audit_set_enabled(status_get->enabled, | 615 | err = audit_set_enabled(status_get->enabled, |
617 | loginuid, sid); | 616 | loginuid, sid); |
618 | if (err < 0) return err; | 617 | if (err < 0) return err; |
619 | } | 618 | } |
620 | if (status_get->mask & AUDIT_STATUS_FAILURE) { | 619 | if (status_get->mask & AUDIT_STATUS_FAILURE) { |
621 | err = audit_set_failure(status_get->failure, | 620 | err = audit_set_failure(status_get->failure, |
622 | loginuid, sid); | 621 | loginuid, sid); |
623 | if (err < 0) return err; | 622 | if (err < 0) return err; |
624 | } | 623 | } |
625 | if (status_get->mask & AUDIT_STATUS_PID) { | 624 | if (status_get->mask & AUDIT_STATUS_PID) { |
626 | int new_pid = status_get->pid; | 625 | int new_pid = status_get->pid; |
627 | 626 | ||
628 | if (audit_enabled != AUDIT_OFF) | 627 | if (audit_enabled != AUDIT_OFF) |
629 | audit_log_config_change("audit_pid", new_pid, | 628 | audit_log_config_change("audit_pid", new_pid, |
630 | audit_pid, loginuid, | 629 | audit_pid, loginuid, |
631 | sid, 1); | 630 | sid, 1); |
632 | 631 | ||
633 | audit_pid = new_pid; | 632 | audit_pid = new_pid; |
634 | audit_nlk_pid = NETLINK_CB(skb).pid; | 633 | audit_nlk_pid = NETLINK_CB(skb).pid; |
635 | } | 634 | } |
636 | if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) | 635 | if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) |
637 | err = audit_set_rate_limit(status_get->rate_limit, | 636 | err = audit_set_rate_limit(status_get->rate_limit, |
638 | loginuid, sid); | 637 | loginuid, sid); |
639 | if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT) | 638 | if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT) |
640 | err = audit_set_backlog_limit(status_get->backlog_limit, | 639 | err = audit_set_backlog_limit(status_get->backlog_limit, |
641 | loginuid, sid); | 640 | loginuid, sid); |
642 | break; | 641 | break; |
643 | case AUDIT_USER: | 642 | case AUDIT_USER: |
644 | case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG: | 643 | case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG: |
645 | case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2: | 644 | case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2: |
646 | if (!audit_enabled && msg_type != AUDIT_USER_AVC) | 645 | if (!audit_enabled && msg_type != AUDIT_USER_AVC) |
647 | return 0; | 646 | return 0; |
648 | 647 | ||
649 | err = audit_filter_user(&NETLINK_CB(skb), msg_type); | 648 | err = audit_filter_user(&NETLINK_CB(skb), msg_type); |
650 | if (err == 1) { | 649 | if (err == 1) { |
651 | err = 0; | 650 | err = 0; |
652 | if (msg_type == AUDIT_USER_TTY) { | 651 | if (msg_type == AUDIT_USER_TTY) { |
653 | err = audit_prepare_user_tty(pid, loginuid); | 652 | err = audit_prepare_user_tty(pid, loginuid); |
654 | if (err) | 653 | if (err) |
655 | break; | 654 | break; |
656 | } | 655 | } |
657 | audit_log_common_recv_msg(&ab, msg_type, pid, uid, | 656 | audit_log_common_recv_msg(&ab, msg_type, pid, uid, |
658 | loginuid, sid); | 657 | loginuid, sid); |
659 | 658 | ||
660 | if (msg_type != AUDIT_USER_TTY) | 659 | if (msg_type != AUDIT_USER_TTY) |
661 | audit_log_format(ab, " msg='%.1024s'", | 660 | audit_log_format(ab, " msg='%.1024s'", |
662 | (char *)data); | 661 | (char *)data); |
663 | else { | 662 | else { |
664 | int size; | 663 | int size; |
665 | 664 | ||
666 | audit_log_format(ab, " msg="); | 665 | audit_log_format(ab, " msg="); |
667 | size = nlmsg_len(nlh); | 666 | size = nlmsg_len(nlh); |
668 | audit_log_n_untrustedstring(ab, size, | 667 | audit_log_n_untrustedstring(ab, size, |
669 | data); | 668 | data); |
670 | } | 669 | } |
671 | audit_set_pid(ab, pid); | 670 | audit_set_pid(ab, pid); |
672 | audit_log_end(ab); | 671 | audit_log_end(ab); |
673 | } | 672 | } |
674 | break; | 673 | break; |
675 | case AUDIT_ADD: | 674 | case AUDIT_ADD: |
676 | case AUDIT_DEL: | 675 | case AUDIT_DEL: |
677 | if (nlmsg_len(nlh) < sizeof(struct audit_rule)) | 676 | if (nlmsg_len(nlh) < sizeof(struct audit_rule)) |
678 | return -EINVAL; | 677 | return -EINVAL; |
679 | if (audit_enabled == AUDIT_LOCKED) { | 678 | if (audit_enabled == AUDIT_LOCKED) { |
680 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, | 679 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, |
681 | uid, loginuid, sid); | 680 | uid, loginuid, sid); |
682 | 681 | ||
683 | audit_log_format(ab, " audit_enabled=%d res=0", | 682 | audit_log_format(ab, " audit_enabled=%d res=0", |
684 | audit_enabled); | 683 | audit_enabled); |
685 | audit_log_end(ab); | 684 | audit_log_end(ab); |
686 | return -EPERM; | 685 | return -EPERM; |
687 | } | 686 | } |
688 | /* fallthrough */ | 687 | /* fallthrough */ |
689 | case AUDIT_LIST: | 688 | case AUDIT_LIST: |
690 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, | 689 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, |
691 | uid, seq, data, nlmsg_len(nlh), | 690 | uid, seq, data, nlmsg_len(nlh), |
692 | loginuid, sid); | 691 | loginuid, sid); |
693 | break; | 692 | break; |
694 | case AUDIT_ADD_RULE: | 693 | case AUDIT_ADD_RULE: |
695 | case AUDIT_DEL_RULE: | 694 | case AUDIT_DEL_RULE: |
696 | if (nlmsg_len(nlh) < sizeof(struct audit_rule_data)) | 695 | if (nlmsg_len(nlh) < sizeof(struct audit_rule_data)) |
697 | return -EINVAL; | 696 | return -EINVAL; |
698 | if (audit_enabled == AUDIT_LOCKED) { | 697 | if (audit_enabled == AUDIT_LOCKED) { |
699 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, | 698 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, |
700 | uid, loginuid, sid); | 699 | uid, loginuid, sid); |
701 | 700 | ||
702 | audit_log_format(ab, " audit_enabled=%d res=0", | 701 | audit_log_format(ab, " audit_enabled=%d res=0", |
703 | audit_enabled); | 702 | audit_enabled); |
704 | audit_log_end(ab); | 703 | audit_log_end(ab); |
705 | return -EPERM; | 704 | return -EPERM; |
706 | } | 705 | } |
707 | /* fallthrough */ | 706 | /* fallthrough */ |
708 | case AUDIT_LIST_RULES: | 707 | case AUDIT_LIST_RULES: |
709 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, | 708 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, |
710 | uid, seq, data, nlmsg_len(nlh), | 709 | uid, seq, data, nlmsg_len(nlh), |
711 | loginuid, sid); | 710 | loginuid, sid); |
712 | break; | 711 | break; |
713 | case AUDIT_TRIM: | 712 | case AUDIT_TRIM: |
714 | audit_trim_trees(); | 713 | audit_trim_trees(); |
715 | 714 | ||
716 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, | 715 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, |
717 | uid, loginuid, sid); | 716 | uid, loginuid, sid); |
718 | 717 | ||
719 | audit_log_format(ab, " op=trim res=1"); | 718 | audit_log_format(ab, " op=trim res=1"); |
720 | audit_log_end(ab); | 719 | audit_log_end(ab); |
721 | break; | 720 | break; |
722 | case AUDIT_MAKE_EQUIV: { | 721 | case AUDIT_MAKE_EQUIV: { |
723 | void *bufp = data; | 722 | void *bufp = data; |
724 | u32 sizes[2]; | 723 | u32 sizes[2]; |
725 | size_t len = nlmsg_len(nlh); | 724 | size_t len = nlmsg_len(nlh); |
726 | char *old, *new; | 725 | char *old, *new; |
727 | 726 | ||
728 | err = -EINVAL; | 727 | err = -EINVAL; |
729 | if (len < 2 * sizeof(u32)) | 728 | if (len < 2 * sizeof(u32)) |
730 | break; | 729 | break; |
731 | memcpy(sizes, bufp, 2 * sizeof(u32)); | 730 | memcpy(sizes, bufp, 2 * sizeof(u32)); |
732 | bufp += 2 * sizeof(u32); | 731 | bufp += 2 * sizeof(u32); |
733 | len -= 2 * sizeof(u32); | 732 | len -= 2 * sizeof(u32); |
734 | old = audit_unpack_string(&bufp, &len, sizes[0]); | 733 | old = audit_unpack_string(&bufp, &len, sizes[0]); |
735 | if (IS_ERR(old)) { | 734 | if (IS_ERR(old)) { |
736 | err = PTR_ERR(old); | 735 | err = PTR_ERR(old); |
737 | break; | 736 | break; |
738 | } | 737 | } |
739 | new = audit_unpack_string(&bufp, &len, sizes[1]); | 738 | new = audit_unpack_string(&bufp, &len, sizes[1]); |
740 | if (IS_ERR(new)) { | 739 | if (IS_ERR(new)) { |
741 | err = PTR_ERR(new); | 740 | err = PTR_ERR(new); |
742 | kfree(old); | 741 | kfree(old); |
743 | break; | 742 | break; |
744 | } | 743 | } |
745 | /* OK, here comes... */ | 744 | /* OK, here comes... */ |
746 | err = audit_tag_tree(old, new); | 745 | err = audit_tag_tree(old, new); |
747 | 746 | ||
748 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, | 747 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, |
749 | uid, loginuid, sid); | 748 | uid, loginuid, sid); |
750 | 749 | ||
751 | audit_log_format(ab, " op=make_equiv old="); | 750 | audit_log_format(ab, " op=make_equiv old="); |
752 | audit_log_untrustedstring(ab, old); | 751 | audit_log_untrustedstring(ab, old); |
753 | audit_log_format(ab, " new="); | 752 | audit_log_format(ab, " new="); |
754 | audit_log_untrustedstring(ab, new); | 753 | audit_log_untrustedstring(ab, new); |
755 | audit_log_format(ab, " res=%d", !err); | 754 | audit_log_format(ab, " res=%d", !err); |
756 | audit_log_end(ab); | 755 | audit_log_end(ab); |
757 | kfree(old); | 756 | kfree(old); |
758 | kfree(new); | 757 | kfree(new); |
759 | break; | 758 | break; |
760 | } | 759 | } |
761 | case AUDIT_SIGNAL_INFO: | 760 | case AUDIT_SIGNAL_INFO: |
762 | err = security_secid_to_secctx(audit_sig_sid, &ctx, &len); | 761 | err = security_secid_to_secctx(audit_sig_sid, &ctx, &len); |
763 | if (err) | 762 | if (err) |
764 | return err; | 763 | return err; |
765 | sig_data = kmalloc(sizeof(*sig_data) + len, GFP_KERNEL); | 764 | sig_data = kmalloc(sizeof(*sig_data) + len, GFP_KERNEL); |
766 | if (!sig_data) { | 765 | if (!sig_data) { |
767 | security_release_secctx(ctx, len); | 766 | security_release_secctx(ctx, len); |
768 | return -ENOMEM; | 767 | return -ENOMEM; |
769 | } | 768 | } |
770 | sig_data->uid = audit_sig_uid; | 769 | sig_data->uid = audit_sig_uid; |
771 | sig_data->pid = audit_sig_pid; | 770 | sig_data->pid = audit_sig_pid; |
772 | memcpy(sig_data->ctx, ctx, len); | 771 | memcpy(sig_data->ctx, ctx, len); |
773 | security_release_secctx(ctx, len); | 772 | security_release_secctx(ctx, len); |
774 | audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO, | 773 | audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO, |
775 | 0, 0, sig_data, sizeof(*sig_data) + len); | 774 | 0, 0, sig_data, sizeof(*sig_data) + len); |
776 | kfree(sig_data); | 775 | kfree(sig_data); |
777 | break; | 776 | break; |
778 | case AUDIT_TTY_GET: { | 777 | case AUDIT_TTY_GET: { |
779 | struct audit_tty_status s; | 778 | struct audit_tty_status s; |
780 | struct task_struct *tsk; | 779 | struct task_struct *tsk; |
781 | 780 | ||
782 | read_lock(&tasklist_lock); | 781 | read_lock(&tasklist_lock); |
783 | tsk = find_task_by_pid(pid); | 782 | tsk = find_task_by_pid(pid); |
784 | if (!tsk) | 783 | if (!tsk) |
785 | err = -ESRCH; | 784 | err = -ESRCH; |
786 | else { | 785 | else { |
787 | spin_lock_irq(&tsk->sighand->siglock); | 786 | spin_lock_irq(&tsk->sighand->siglock); |
788 | s.enabled = tsk->signal->audit_tty != 0; | 787 | s.enabled = tsk->signal->audit_tty != 0; |
789 | spin_unlock_irq(&tsk->sighand->siglock); | 788 | spin_unlock_irq(&tsk->sighand->siglock); |
790 | } | 789 | } |
791 | read_unlock(&tasklist_lock); | 790 | read_unlock(&tasklist_lock); |
792 | audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_TTY_GET, 0, 0, | 791 | audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_TTY_GET, 0, 0, |
793 | &s, sizeof(s)); | 792 | &s, sizeof(s)); |
794 | break; | 793 | break; |
795 | } | 794 | } |
796 | case AUDIT_TTY_SET: { | 795 | case AUDIT_TTY_SET: { |
797 | struct audit_tty_status *s; | 796 | struct audit_tty_status *s; |
798 | struct task_struct *tsk; | 797 | struct task_struct *tsk; |
799 | 798 | ||
800 | if (nlh->nlmsg_len < sizeof(struct audit_tty_status)) | 799 | if (nlh->nlmsg_len < sizeof(struct audit_tty_status)) |
801 | return -EINVAL; | 800 | return -EINVAL; |
802 | s = data; | 801 | s = data; |
803 | if (s->enabled != 0 && s->enabled != 1) | 802 | if (s->enabled != 0 && s->enabled != 1) |
804 | return -EINVAL; | 803 | return -EINVAL; |
805 | read_lock(&tasklist_lock); | 804 | read_lock(&tasklist_lock); |
806 | tsk = find_task_by_pid(pid); | 805 | tsk = find_task_by_pid(pid); |
807 | if (!tsk) | 806 | if (!tsk) |
808 | err = -ESRCH; | 807 | err = -ESRCH; |
809 | else { | 808 | else { |
810 | spin_lock_irq(&tsk->sighand->siglock); | 809 | spin_lock_irq(&tsk->sighand->siglock); |
811 | tsk->signal->audit_tty = s->enabled != 0; | 810 | tsk->signal->audit_tty = s->enabled != 0; |
812 | spin_unlock_irq(&tsk->sighand->siglock); | 811 | spin_unlock_irq(&tsk->sighand->siglock); |
813 | } | 812 | } |
814 | read_unlock(&tasklist_lock); | 813 | read_unlock(&tasklist_lock); |
815 | break; | 814 | break; |
816 | } | 815 | } |
817 | default: | 816 | default: |
818 | err = -EINVAL; | 817 | err = -EINVAL; |
819 | break; | 818 | break; |
820 | } | 819 | } |
821 | 820 | ||
822 | return err < 0 ? err : 0; | 821 | return err < 0 ? err : 0; |
823 | } | 822 | } |
824 | 823 | ||
825 | /* | 824 | /* |
826 | * Get message from skb (based on rtnetlink_rcv_skb). Each message is | 825 | * Get message from skb (based on rtnetlink_rcv_skb). Each message is |
827 | * processed by audit_receive_msg. Malformed skbs with wrong length are | 826 | * processed by audit_receive_msg. Malformed skbs with wrong length are |
828 | * discarded silently. | 827 | * discarded silently. |
829 | */ | 828 | */ |
830 | static void audit_receive_skb(struct sk_buff *skb) | 829 | static void audit_receive_skb(struct sk_buff *skb) |
831 | { | 830 | { |
832 | int err; | 831 | int err; |
833 | struct nlmsghdr *nlh; | 832 | struct nlmsghdr *nlh; |
834 | u32 rlen; | 833 | u32 rlen; |
835 | 834 | ||
836 | while (skb->len >= NLMSG_SPACE(0)) { | 835 | while (skb->len >= NLMSG_SPACE(0)) { |
837 | nlh = nlmsg_hdr(skb); | 836 | nlh = nlmsg_hdr(skb); |
838 | if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len) | 837 | if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len) |
839 | return; | 838 | return; |
840 | rlen = NLMSG_ALIGN(nlh->nlmsg_len); | 839 | rlen = NLMSG_ALIGN(nlh->nlmsg_len); |
841 | if (rlen > skb->len) | 840 | if (rlen > skb->len) |
842 | rlen = skb->len; | 841 | rlen = skb->len; |
843 | if ((err = audit_receive_msg(skb, nlh))) { | 842 | if ((err = audit_receive_msg(skb, nlh))) { |
844 | netlink_ack(skb, nlh, err); | 843 | netlink_ack(skb, nlh, err); |
845 | } else if (nlh->nlmsg_flags & NLM_F_ACK) | 844 | } else if (nlh->nlmsg_flags & NLM_F_ACK) |
846 | netlink_ack(skb, nlh, 0); | 845 | netlink_ack(skb, nlh, 0); |
847 | skb_pull(skb, rlen); | 846 | skb_pull(skb, rlen); |
848 | } | 847 | } |
849 | } | 848 | } |
850 | 849 | ||
851 | /* Receive messages from netlink socket. */ | 850 | /* Receive messages from netlink socket. */ |
852 | static void audit_receive(struct sk_buff *skb) | 851 | static void audit_receive(struct sk_buff *skb) |
853 | { | 852 | { |
854 | mutex_lock(&audit_cmd_mutex); | 853 | mutex_lock(&audit_cmd_mutex); |
855 | audit_receive_skb(skb); | 854 | audit_receive_skb(skb); |
856 | mutex_unlock(&audit_cmd_mutex); | 855 | mutex_unlock(&audit_cmd_mutex); |
857 | } | 856 | } |
858 | 857 | ||
859 | #ifdef CONFIG_AUDITSYSCALL | 858 | #ifdef CONFIG_AUDITSYSCALL |
860 | static const struct inotify_operations audit_inotify_ops = { | 859 | static const struct inotify_operations audit_inotify_ops = { |
861 | .handle_event = audit_handle_ievent, | 860 | .handle_event = audit_handle_ievent, |
862 | .destroy_watch = audit_free_parent, | 861 | .destroy_watch = audit_free_parent, |
863 | }; | 862 | }; |
864 | #endif | 863 | #endif |
865 | 864 | ||
866 | /* Initialize audit support at boot time. */ | 865 | /* Initialize audit support at boot time. */ |
867 | static int __init audit_init(void) | 866 | static int __init audit_init(void) |
868 | { | 867 | { |
869 | int i; | 868 | int i; |
870 | 869 | ||
871 | printk(KERN_INFO "audit: initializing netlink socket (%s)\n", | 870 | printk(KERN_INFO "audit: initializing netlink socket (%s)\n", |
872 | audit_default ? "enabled" : "disabled"); | 871 | audit_default ? "enabled" : "disabled"); |
873 | audit_sock = netlink_kernel_create(&init_net, NETLINK_AUDIT, 0, | 872 | audit_sock = netlink_kernel_create(&init_net, NETLINK_AUDIT, 0, |
874 | audit_receive, NULL, THIS_MODULE); | 873 | audit_receive, NULL, THIS_MODULE); |
875 | if (!audit_sock) | 874 | if (!audit_sock) |
876 | audit_panic("cannot initialize netlink socket"); | 875 | audit_panic("cannot initialize netlink socket"); |
877 | else | 876 | else |
878 | audit_sock->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT; | 877 | audit_sock->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT; |
879 | 878 | ||
880 | skb_queue_head_init(&audit_skb_queue); | 879 | skb_queue_head_init(&audit_skb_queue); |
881 | audit_initialized = 1; | 880 | audit_initialized = 1; |
882 | audit_enabled = audit_default; | 881 | audit_enabled = audit_default; |
883 | audit_ever_enabled |= !!audit_default; | 882 | audit_ever_enabled |= !!audit_default; |
884 | |||
885 | /* Register the callback with selinux. This callback will be invoked | ||
886 | * when a new policy is loaded. */ | ||
887 | selinux_audit_set_callback(&selinux_audit_rule_update); | ||
888 | 883 | ||
889 | audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized"); | 884 | audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized"); |
890 | 885 | ||
891 | #ifdef CONFIG_AUDITSYSCALL | 886 | #ifdef CONFIG_AUDITSYSCALL |
892 | audit_ih = inotify_init(&audit_inotify_ops); | 887 | audit_ih = inotify_init(&audit_inotify_ops); |
893 | if (IS_ERR(audit_ih)) | 888 | if (IS_ERR(audit_ih)) |
894 | audit_panic("cannot initialize inotify handle"); | 889 | audit_panic("cannot initialize inotify handle"); |
895 | #endif | 890 | #endif |
896 | 891 | ||
897 | for (i = 0; i < AUDIT_INODE_BUCKETS; i++) | 892 | for (i = 0; i < AUDIT_INODE_BUCKETS; i++) |
898 | INIT_LIST_HEAD(&audit_inode_hash[i]); | 893 | INIT_LIST_HEAD(&audit_inode_hash[i]); |
899 | 894 | ||
900 | return 0; | 895 | return 0; |
901 | } | 896 | } |
902 | __initcall(audit_init); | 897 | __initcall(audit_init); |
903 | 898 | ||
904 | /* Process kernel command-line parameter at boot time. audit=0 or audit=1. */ | 899 | /* Process kernel command-line parameter at boot time. audit=0 or audit=1. */ |
905 | static int __init audit_enable(char *str) | 900 | static int __init audit_enable(char *str) |
906 | { | 901 | { |
907 | audit_default = !!simple_strtol(str, NULL, 0); | 902 | audit_default = !!simple_strtol(str, NULL, 0); |
908 | printk(KERN_INFO "audit: %s%s\n", | 903 | printk(KERN_INFO "audit: %s%s\n", |
909 | audit_default ? "enabled" : "disabled", | 904 | audit_default ? "enabled" : "disabled", |
910 | audit_initialized ? "" : " (after initialization)"); | 905 | audit_initialized ? "" : " (after initialization)"); |
911 | if (audit_initialized) { | 906 | if (audit_initialized) { |
912 | audit_enabled = audit_default; | 907 | audit_enabled = audit_default; |
913 | audit_ever_enabled |= !!audit_default; | 908 | audit_ever_enabled |= !!audit_default; |
914 | } | 909 | } |
915 | return 1; | 910 | return 1; |
916 | } | 911 | } |
917 | 912 | ||
918 | __setup("audit=", audit_enable); | 913 | __setup("audit=", audit_enable); |
919 | 914 | ||
920 | static void audit_buffer_free(struct audit_buffer *ab) | 915 | static void audit_buffer_free(struct audit_buffer *ab) |
921 | { | 916 | { |
922 | unsigned long flags; | 917 | unsigned long flags; |
923 | 918 | ||
924 | if (!ab) | 919 | if (!ab) |
925 | return; | 920 | return; |
926 | 921 | ||
927 | if (ab->skb) | 922 | if (ab->skb) |
928 | kfree_skb(ab->skb); | 923 | kfree_skb(ab->skb); |
929 | 924 | ||
930 | spin_lock_irqsave(&audit_freelist_lock, flags); | 925 | spin_lock_irqsave(&audit_freelist_lock, flags); |
931 | if (audit_freelist_count > AUDIT_MAXFREE) | 926 | if (audit_freelist_count > AUDIT_MAXFREE) |
932 | kfree(ab); | 927 | kfree(ab); |
933 | else { | 928 | else { |
934 | audit_freelist_count++; | 929 | audit_freelist_count++; |
935 | list_add(&ab->list, &audit_freelist); | 930 | list_add(&ab->list, &audit_freelist); |
936 | } | 931 | } |
937 | spin_unlock_irqrestore(&audit_freelist_lock, flags); | 932 | spin_unlock_irqrestore(&audit_freelist_lock, flags); |
938 | } | 933 | } |
939 | 934 | ||
940 | static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx, | 935 | static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx, |
941 | gfp_t gfp_mask, int type) | 936 | gfp_t gfp_mask, int type) |
942 | { | 937 | { |
943 | unsigned long flags; | 938 | unsigned long flags; |
944 | struct audit_buffer *ab = NULL; | 939 | struct audit_buffer *ab = NULL; |
945 | struct nlmsghdr *nlh; | 940 | struct nlmsghdr *nlh; |
946 | 941 | ||
947 | spin_lock_irqsave(&audit_freelist_lock, flags); | 942 | spin_lock_irqsave(&audit_freelist_lock, flags); |
948 | if (!list_empty(&audit_freelist)) { | 943 | if (!list_empty(&audit_freelist)) { |
949 | ab = list_entry(audit_freelist.next, | 944 | ab = list_entry(audit_freelist.next, |
950 | struct audit_buffer, list); | 945 | struct audit_buffer, list); |
951 | list_del(&ab->list); | 946 | list_del(&ab->list); |
952 | --audit_freelist_count; | 947 | --audit_freelist_count; |
953 | } | 948 | } |
954 | spin_unlock_irqrestore(&audit_freelist_lock, flags); | 949 | spin_unlock_irqrestore(&audit_freelist_lock, flags); |
955 | 950 | ||
956 | if (!ab) { | 951 | if (!ab) { |
957 | ab = kmalloc(sizeof(*ab), gfp_mask); | 952 | ab = kmalloc(sizeof(*ab), gfp_mask); |
958 | if (!ab) | 953 | if (!ab) |
959 | goto err; | 954 | goto err; |
960 | } | 955 | } |
961 | 956 | ||
962 | ab->skb = alloc_skb(AUDIT_BUFSIZ, gfp_mask); | 957 | ab->skb = alloc_skb(AUDIT_BUFSIZ, gfp_mask); |
963 | if (!ab->skb) | 958 | if (!ab->skb) |
964 | goto err; | 959 | goto err; |
965 | 960 | ||
966 | ab->ctx = ctx; | 961 | ab->ctx = ctx; |
967 | ab->gfp_mask = gfp_mask; | 962 | ab->gfp_mask = gfp_mask; |
968 | nlh = (struct nlmsghdr *)skb_put(ab->skb, NLMSG_SPACE(0)); | 963 | nlh = (struct nlmsghdr *)skb_put(ab->skb, NLMSG_SPACE(0)); |
969 | nlh->nlmsg_type = type; | 964 | nlh->nlmsg_type = type; |
970 | nlh->nlmsg_flags = 0; | 965 | nlh->nlmsg_flags = 0; |
971 | nlh->nlmsg_pid = 0; | 966 | nlh->nlmsg_pid = 0; |
972 | nlh->nlmsg_seq = 0; | 967 | nlh->nlmsg_seq = 0; |
973 | return ab; | 968 | return ab; |
974 | err: | 969 | err: |
975 | audit_buffer_free(ab); | 970 | audit_buffer_free(ab); |
976 | return NULL; | 971 | return NULL; |
977 | } | 972 | } |
978 | 973 | ||
979 | /** | 974 | /** |
980 | * audit_serial - compute a serial number for the audit record | 975 | * audit_serial - compute a serial number for the audit record |
981 | * | 976 | * |
982 | * Compute a serial number for the audit record. Audit records are | 977 | * Compute a serial number for the audit record. Audit records are |
983 | * written to user-space as soon as they are generated, so a complete | 978 | * written to user-space as soon as they are generated, so a complete |
984 | * audit record may be written in several pieces. The timestamp of the | 979 | * audit record may be written in several pieces. The timestamp of the |
985 | * record and this serial number are used by the user-space tools to | 980 | * record and this serial number are used by the user-space tools to |
986 | * determine which pieces belong to the same audit record. The | 981 | * determine which pieces belong to the same audit record. The |
987 | * (timestamp,serial) tuple is unique for each syscall and is live from | 982 | * (timestamp,serial) tuple is unique for each syscall and is live from |
988 | * syscall entry to syscall exit. | 983 | * syscall entry to syscall exit. |
989 | * | 984 | * |
990 | * NOTE: Another possibility is to store the formatted records off the | 985 | * NOTE: Another possibility is to store the formatted records off the |
991 | * audit context (for those records that have a context), and emit them | 986 | * audit context (for those records that have a context), and emit them |
992 | * all at syscall exit. However, this could delay the reporting of | 987 | * all at syscall exit. However, this could delay the reporting of |
993 | * significant errors until syscall exit (or never, if the system | 988 | * significant errors until syscall exit (or never, if the system |
994 | * halts). | 989 | * halts). |
995 | */ | 990 | */ |
996 | unsigned int audit_serial(void) | 991 | unsigned int audit_serial(void) |
997 | { | 992 | { |
998 | static DEFINE_SPINLOCK(serial_lock); | 993 | static DEFINE_SPINLOCK(serial_lock); |
999 | static unsigned int serial = 0; | 994 | static unsigned int serial = 0; |
1000 | 995 | ||
1001 | unsigned long flags; | 996 | unsigned long flags; |
1002 | unsigned int ret; | 997 | unsigned int ret; |
1003 | 998 | ||
1004 | spin_lock_irqsave(&serial_lock, flags); | 999 | spin_lock_irqsave(&serial_lock, flags); |
1005 | do { | 1000 | do { |
1006 | ret = ++serial; | 1001 | ret = ++serial; |
1007 | } while (unlikely(!ret)); | 1002 | } while (unlikely(!ret)); |
1008 | spin_unlock_irqrestore(&serial_lock, flags); | 1003 | spin_unlock_irqrestore(&serial_lock, flags); |
1009 | 1004 | ||
1010 | return ret; | 1005 | return ret; |
1011 | } | 1006 | } |
1012 | 1007 | ||
1013 | static inline void audit_get_stamp(struct audit_context *ctx, | 1008 | static inline void audit_get_stamp(struct audit_context *ctx, |
1014 | struct timespec *t, unsigned int *serial) | 1009 | struct timespec *t, unsigned int *serial) |
1015 | { | 1010 | { |
1016 | if (ctx) | 1011 | if (ctx) |
1017 | auditsc_get_stamp(ctx, t, serial); | 1012 | auditsc_get_stamp(ctx, t, serial); |
1018 | else { | 1013 | else { |
1019 | *t = CURRENT_TIME; | 1014 | *t = CURRENT_TIME; |
1020 | *serial = audit_serial(); | 1015 | *serial = audit_serial(); |
1021 | } | 1016 | } |
1022 | } | 1017 | } |
1023 | 1018 | ||
1024 | /* Obtain an audit buffer. This routine does locking to obtain the | 1019 | /* Obtain an audit buffer. This routine does locking to obtain the |
1025 | * audit buffer, but then no locking is required for calls to | 1020 | * audit buffer, but then no locking is required for calls to |
1026 | * audit_log_*format. If the tsk is a task that is currently in a | 1021 | * audit_log_*format. If the tsk is a task that is currently in a |
1027 | * syscall, then the syscall is marked as auditable and an audit record | 1022 | * syscall, then the syscall is marked as auditable and an audit record |
1028 | * will be written at syscall exit. If there is no associated task, tsk | 1023 | * will be written at syscall exit. If there is no associated task, tsk |
1029 | * should be NULL. */ | 1024 | * should be NULL. */ |
1030 | 1025 | ||
1031 | /** | 1026 | /** |
1032 | * audit_log_start - obtain an audit buffer | 1027 | * audit_log_start - obtain an audit buffer |
1033 | * @ctx: audit_context (may be NULL) | 1028 | * @ctx: audit_context (may be NULL) |
1034 | * @gfp_mask: type of allocation | 1029 | * @gfp_mask: type of allocation |
1035 | * @type: audit message type | 1030 | * @type: audit message type |
1036 | * | 1031 | * |
1037 | * Returns audit_buffer pointer on success or NULL on error. | 1032 | * Returns audit_buffer pointer on success or NULL on error. |
1038 | * | 1033 | * |
1039 | * Obtain an audit buffer. This routine does locking to obtain the | 1034 | * Obtain an audit buffer. This routine does locking to obtain the |
1040 | * audit buffer, but then no locking is required for calls to | 1035 | * audit buffer, but then no locking is required for calls to |
1041 | * audit_log_*format. If the task (ctx) is a task that is currently in a | 1036 | * audit_log_*format. If the task (ctx) is a task that is currently in a |
1042 | * syscall, then the syscall is marked as auditable and an audit record | 1037 | * syscall, then the syscall is marked as auditable and an audit record |
1043 | * will be written at syscall exit. If there is no associated task, then | 1038 | * will be written at syscall exit. If there is no associated task, then |
1044 | * task context (ctx) should be NULL. | 1039 | * task context (ctx) should be NULL. |
1045 | */ | 1040 | */ |
1046 | struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, | 1041 | struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, |
1047 | int type) | 1042 | int type) |
1048 | { | 1043 | { |
1049 | struct audit_buffer *ab = NULL; | 1044 | struct audit_buffer *ab = NULL; |
1050 | struct timespec t; | 1045 | struct timespec t; |
1051 | unsigned int uninitialized_var(serial); | 1046 | unsigned int uninitialized_var(serial); |
1052 | int reserve; | 1047 | int reserve; |
1053 | unsigned long timeout_start = jiffies; | 1048 | unsigned long timeout_start = jiffies; |
1054 | 1049 | ||
1055 | if (!audit_initialized) | 1050 | if (!audit_initialized) |
1056 | return NULL; | 1051 | return NULL; |
1057 | 1052 | ||
1058 | if (unlikely(audit_filter_type(type))) | 1053 | if (unlikely(audit_filter_type(type))) |
1059 | return NULL; | 1054 | return NULL; |
1060 | 1055 | ||
1061 | if (gfp_mask & __GFP_WAIT) | 1056 | if (gfp_mask & __GFP_WAIT) |
1062 | reserve = 0; | 1057 | reserve = 0; |
1063 | else | 1058 | else |
1064 | reserve = 5; /* Allow atomic callers to go up to five | 1059 | reserve = 5; /* Allow atomic callers to go up to five |
1065 | entries over the normal backlog limit */ | 1060 | entries over the normal backlog limit */ |
1066 | 1061 | ||
1067 | while (audit_backlog_limit | 1062 | while (audit_backlog_limit |
1068 | && skb_queue_len(&audit_skb_queue) > audit_backlog_limit + reserve) { | 1063 | && skb_queue_len(&audit_skb_queue) > audit_backlog_limit + reserve) { |
1069 | if (gfp_mask & __GFP_WAIT && audit_backlog_wait_time | 1064 | if (gfp_mask & __GFP_WAIT && audit_backlog_wait_time |
1070 | && time_before(jiffies, timeout_start + audit_backlog_wait_time)) { | 1065 | && time_before(jiffies, timeout_start + audit_backlog_wait_time)) { |
1071 | 1066 | ||
1072 | /* Wait for auditd to drain the queue a little */ | 1067 | /* Wait for auditd to drain the queue a little */ |
1073 | DECLARE_WAITQUEUE(wait, current); | 1068 | DECLARE_WAITQUEUE(wait, current); |
1074 | set_current_state(TASK_INTERRUPTIBLE); | 1069 | set_current_state(TASK_INTERRUPTIBLE); |
1075 | add_wait_queue(&audit_backlog_wait, &wait); | 1070 | add_wait_queue(&audit_backlog_wait, &wait); |
1076 | 1071 | ||
1077 | if (audit_backlog_limit && | 1072 | if (audit_backlog_limit && |
1078 | skb_queue_len(&audit_skb_queue) > audit_backlog_limit) | 1073 | skb_queue_len(&audit_skb_queue) > audit_backlog_limit) |
1079 | schedule_timeout(timeout_start + audit_backlog_wait_time - jiffies); | 1074 | schedule_timeout(timeout_start + audit_backlog_wait_time - jiffies); |
1080 | 1075 | ||
1081 | __set_current_state(TASK_RUNNING); | 1076 | __set_current_state(TASK_RUNNING); |
1082 | remove_wait_queue(&audit_backlog_wait, &wait); | 1077 | remove_wait_queue(&audit_backlog_wait, &wait); |
1083 | continue; | 1078 | continue; |
1084 | } | 1079 | } |
1085 | if (audit_rate_check() && printk_ratelimit()) | 1080 | if (audit_rate_check() && printk_ratelimit()) |
1086 | printk(KERN_WARNING | 1081 | printk(KERN_WARNING |
1087 | "audit: audit_backlog=%d > " | 1082 | "audit: audit_backlog=%d > " |
1088 | "audit_backlog_limit=%d\n", | 1083 | "audit_backlog_limit=%d\n", |
1089 | skb_queue_len(&audit_skb_queue), | 1084 | skb_queue_len(&audit_skb_queue), |
1090 | audit_backlog_limit); | 1085 | audit_backlog_limit); |
1091 | audit_log_lost("backlog limit exceeded"); | 1086 | audit_log_lost("backlog limit exceeded"); |
1092 | audit_backlog_wait_time = audit_backlog_wait_overflow; | 1087 | audit_backlog_wait_time = audit_backlog_wait_overflow; |
1093 | wake_up(&audit_backlog_wait); | 1088 | wake_up(&audit_backlog_wait); |
1094 | return NULL; | 1089 | return NULL; |
1095 | } | 1090 | } |
1096 | 1091 | ||
1097 | ab = audit_buffer_alloc(ctx, gfp_mask, type); | 1092 | ab = audit_buffer_alloc(ctx, gfp_mask, type); |
1098 | if (!ab) { | 1093 | if (!ab) { |
1099 | audit_log_lost("out of memory in audit_log_start"); | 1094 | audit_log_lost("out of memory in audit_log_start"); |
1100 | return NULL; | 1095 | return NULL; |
1101 | } | 1096 | } |
1102 | 1097 | ||
1103 | audit_get_stamp(ab->ctx, &t, &serial); | 1098 | audit_get_stamp(ab->ctx, &t, &serial); |
1104 | 1099 | ||
1105 | audit_log_format(ab, "audit(%lu.%03lu:%u): ", | 1100 | audit_log_format(ab, "audit(%lu.%03lu:%u): ", |
1106 | t.tv_sec, t.tv_nsec/1000000, serial); | 1101 | t.tv_sec, t.tv_nsec/1000000, serial); |
1107 | return ab; | 1102 | return ab; |
1108 | } | 1103 | } |
1109 | 1104 | ||
1110 | /** | 1105 | /** |
1111 | * audit_expand - expand skb in the audit buffer | 1106 | * audit_expand - expand skb in the audit buffer |
1112 | * @ab: audit_buffer | 1107 | * @ab: audit_buffer |
1113 | * @extra: space to add at tail of the skb | 1108 | * @extra: space to add at tail of the skb |
1114 | * | 1109 | * |
1115 | * Returns 0 (no space) on failed expansion, or available space if | 1110 | * Returns 0 (no space) on failed expansion, or available space if |
1116 | * successful. | 1111 | * successful. |
1117 | */ | 1112 | */ |
1118 | static inline int audit_expand(struct audit_buffer *ab, int extra) | 1113 | static inline int audit_expand(struct audit_buffer *ab, int extra) |
1119 | { | 1114 | { |
1120 | struct sk_buff *skb = ab->skb; | 1115 | struct sk_buff *skb = ab->skb; |
1121 | int oldtail = skb_tailroom(skb); | 1116 | int oldtail = skb_tailroom(skb); |
1122 | int ret = pskb_expand_head(skb, 0, extra, ab->gfp_mask); | 1117 | int ret = pskb_expand_head(skb, 0, extra, ab->gfp_mask); |
1123 | int newtail = skb_tailroom(skb); | 1118 | int newtail = skb_tailroom(skb); |
1124 | 1119 | ||
1125 | if (ret < 0) { | 1120 | if (ret < 0) { |
1126 | audit_log_lost("out of memory in audit_expand"); | 1121 | audit_log_lost("out of memory in audit_expand"); |
1127 | return 0; | 1122 | return 0; |
1128 | } | 1123 | } |
1129 | 1124 | ||
1130 | skb->truesize += newtail - oldtail; | 1125 | skb->truesize += newtail - oldtail; |
1131 | return newtail; | 1126 | return newtail; |
1132 | } | 1127 | } |
1133 | 1128 | ||
1134 | /* | 1129 | /* |
1135 | * Format an audit message into the audit buffer. If there isn't enough | 1130 | * Format an audit message into the audit buffer. If there isn't enough |
1136 | * room in the audit buffer, more room will be allocated and vsnprint | 1131 | * room in the audit buffer, more room will be allocated and vsnprint |
1137 | * will be called a second time. Currently, we assume that a printk | 1132 | * will be called a second time. Currently, we assume that a printk |
1138 | * can't format message larger than 1024 bytes, so we don't either. | 1133 | * can't format message larger than 1024 bytes, so we don't either. |
1139 | */ | 1134 | */ |
1140 | static void audit_log_vformat(struct audit_buffer *ab, const char *fmt, | 1135 | static void audit_log_vformat(struct audit_buffer *ab, const char *fmt, |
1141 | va_list args) | 1136 | va_list args) |
1142 | { | 1137 | { |
1143 | int len, avail; | 1138 | int len, avail; |
1144 | struct sk_buff *skb; | 1139 | struct sk_buff *skb; |
1145 | va_list args2; | 1140 | va_list args2; |
1146 | 1141 | ||
1147 | if (!ab) | 1142 | if (!ab) |
1148 | return; | 1143 | return; |
1149 | 1144 | ||
1150 | BUG_ON(!ab->skb); | 1145 | BUG_ON(!ab->skb); |
1151 | skb = ab->skb; | 1146 | skb = ab->skb; |
1152 | avail = skb_tailroom(skb); | 1147 | avail = skb_tailroom(skb); |
1153 | if (avail == 0) { | 1148 | if (avail == 0) { |
1154 | avail = audit_expand(ab, AUDIT_BUFSIZ); | 1149 | avail = audit_expand(ab, AUDIT_BUFSIZ); |
1155 | if (!avail) | 1150 | if (!avail) |
1156 | goto out; | 1151 | goto out; |
1157 | } | 1152 | } |
1158 | va_copy(args2, args); | 1153 | va_copy(args2, args); |
1159 | len = vsnprintf(skb_tail_pointer(skb), avail, fmt, args); | 1154 | len = vsnprintf(skb_tail_pointer(skb), avail, fmt, args); |
1160 | if (len >= avail) { | 1155 | if (len >= avail) { |
1161 | /* The printk buffer is 1024 bytes long, so if we get | 1156 | /* The printk buffer is 1024 bytes long, so if we get |
1162 | * here and AUDIT_BUFSIZ is at least 1024, then we can | 1157 | * here and AUDIT_BUFSIZ is at least 1024, then we can |
1163 | * log everything that printk could have logged. */ | 1158 | * log everything that printk could have logged. */ |
1164 | avail = audit_expand(ab, | 1159 | avail = audit_expand(ab, |
1165 | max_t(unsigned, AUDIT_BUFSIZ, 1+len-avail)); | 1160 | max_t(unsigned, AUDIT_BUFSIZ, 1+len-avail)); |
1166 | if (!avail) | 1161 | if (!avail) |
1167 | goto out; | 1162 | goto out; |
1168 | len = vsnprintf(skb_tail_pointer(skb), avail, fmt, args2); | 1163 | len = vsnprintf(skb_tail_pointer(skb), avail, fmt, args2); |
1169 | } | 1164 | } |
1170 | va_end(args2); | 1165 | va_end(args2); |
1171 | if (len > 0) | 1166 | if (len > 0) |
1172 | skb_put(skb, len); | 1167 | skb_put(skb, len); |
1173 | out: | 1168 | out: |
1174 | return; | 1169 | return; |
1175 | } | 1170 | } |
1176 | 1171 | ||
1177 | /** | 1172 | /** |
1178 | * audit_log_format - format a message into the audit buffer. | 1173 | * audit_log_format - format a message into the audit buffer. |
1179 | * @ab: audit_buffer | 1174 | * @ab: audit_buffer |
1180 | * @fmt: format string | 1175 | * @fmt: format string |
1181 | * @...: optional parameters matching @fmt string | 1176 | * @...: optional parameters matching @fmt string |
1182 | * | 1177 | * |
1183 | * All the work is done in audit_log_vformat. | 1178 | * All the work is done in audit_log_vformat. |
1184 | */ | 1179 | */ |
1185 | void audit_log_format(struct audit_buffer *ab, const char *fmt, ...) | 1180 | void audit_log_format(struct audit_buffer *ab, const char *fmt, ...) |
1186 | { | 1181 | { |
1187 | va_list args; | 1182 | va_list args; |
1188 | 1183 | ||
1189 | if (!ab) | 1184 | if (!ab) |
1190 | return; | 1185 | return; |
1191 | va_start(args, fmt); | 1186 | va_start(args, fmt); |
1192 | audit_log_vformat(ab, fmt, args); | 1187 | audit_log_vformat(ab, fmt, args); |
1193 | va_end(args); | 1188 | va_end(args); |
1194 | } | 1189 | } |
1195 | 1190 | ||
1196 | /** | 1191 | /** |
1197 | * audit_log_hex - convert a buffer to hex and append it to the audit skb | 1192 | * audit_log_hex - convert a buffer to hex and append it to the audit skb |
1198 | * @ab: the audit_buffer | 1193 | * @ab: the audit_buffer |
1199 | * @buf: buffer to convert to hex | 1194 | * @buf: buffer to convert to hex |
1200 | * @len: length of @buf to be converted | 1195 | * @len: length of @buf to be converted |
1201 | * | 1196 | * |
1202 | * No return value; failure to expand is silently ignored. | 1197 | * No return value; failure to expand is silently ignored. |
1203 | * | 1198 | * |
1204 | * This function will take the passed buf and convert it into a string of | 1199 | * This function will take the passed buf and convert it into a string of |
1205 | * ascii hex digits. The new string is placed onto the skb. | 1200 | * ascii hex digits. The new string is placed onto the skb. |
1206 | */ | 1201 | */ |
1207 | void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf, | 1202 | void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf, |
1208 | size_t len) | 1203 | size_t len) |
1209 | { | 1204 | { |
1210 | int i, avail, new_len; | 1205 | int i, avail, new_len; |
1211 | unsigned char *ptr; | 1206 | unsigned char *ptr; |
1212 | struct sk_buff *skb; | 1207 | struct sk_buff *skb; |
1213 | static const unsigned char *hex = "0123456789ABCDEF"; | 1208 | static const unsigned char *hex = "0123456789ABCDEF"; |
1214 | 1209 | ||
1215 | if (!ab) | 1210 | if (!ab) |
1216 | return; | 1211 | return; |
1217 | 1212 | ||
1218 | BUG_ON(!ab->skb); | 1213 | BUG_ON(!ab->skb); |
1219 | skb = ab->skb; | 1214 | skb = ab->skb; |
1220 | avail = skb_tailroom(skb); | 1215 | avail = skb_tailroom(skb); |
1221 | new_len = len<<1; | 1216 | new_len = len<<1; |
1222 | if (new_len >= avail) { | 1217 | if (new_len >= avail) { |
1223 | /* Round the buffer request up to the next multiple */ | 1218 | /* Round the buffer request up to the next multiple */ |
1224 | new_len = AUDIT_BUFSIZ*(((new_len-avail)/AUDIT_BUFSIZ) + 1); | 1219 | new_len = AUDIT_BUFSIZ*(((new_len-avail)/AUDIT_BUFSIZ) + 1); |
1225 | avail = audit_expand(ab, new_len); | 1220 | avail = audit_expand(ab, new_len); |
1226 | if (!avail) | 1221 | if (!avail) |
1227 | return; | 1222 | return; |
1228 | } | 1223 | } |
1229 | 1224 | ||
1230 | ptr = skb_tail_pointer(skb); | 1225 | ptr = skb_tail_pointer(skb); |
1231 | for (i=0; i<len; i++) { | 1226 | for (i=0; i<len; i++) { |
1232 | *ptr++ = hex[(buf[i] & 0xF0)>>4]; /* Upper nibble */ | 1227 | *ptr++ = hex[(buf[i] & 0xF0)>>4]; /* Upper nibble */ |
1233 | *ptr++ = hex[buf[i] & 0x0F]; /* Lower nibble */ | 1228 | *ptr++ = hex[buf[i] & 0x0F]; /* Lower nibble */ |
1234 | } | 1229 | } |
1235 | *ptr = 0; | 1230 | *ptr = 0; |
1236 | skb_put(skb, len << 1); /* new string is twice the old string */ | 1231 | skb_put(skb, len << 1); /* new string is twice the old string */ |
1237 | } | 1232 | } |
1238 | 1233 | ||
1239 | /* | 1234 | /* |
1240 | * Format a string of no more than slen characters into the audit buffer, | 1235 | * Format a string of no more than slen characters into the audit buffer, |
1241 | * enclosed in quote marks. | 1236 | * enclosed in quote marks. |
1242 | */ | 1237 | */ |
1243 | static void audit_log_n_string(struct audit_buffer *ab, size_t slen, | 1238 | static void audit_log_n_string(struct audit_buffer *ab, size_t slen, |
1244 | const char *string) | 1239 | const char *string) |
1245 | { | 1240 | { |
1246 | int avail, new_len; | 1241 | int avail, new_len; |
1247 | unsigned char *ptr; | 1242 | unsigned char *ptr; |
1248 | struct sk_buff *skb; | 1243 | struct sk_buff *skb; |
1249 | 1244 | ||
1250 | if (!ab) | 1245 | if (!ab) |
1251 | return; | 1246 | return; |
1252 | 1247 | ||
1253 | BUG_ON(!ab->skb); | 1248 | BUG_ON(!ab->skb); |
1254 | skb = ab->skb; | 1249 | skb = ab->skb; |
1255 | avail = skb_tailroom(skb); | 1250 | avail = skb_tailroom(skb); |
1256 | new_len = slen + 3; /* enclosing quotes + null terminator */ | 1251 | new_len = slen + 3; /* enclosing quotes + null terminator */ |
1257 | if (new_len > avail) { | 1252 | if (new_len > avail) { |
1258 | avail = audit_expand(ab, new_len); | 1253 | avail = audit_expand(ab, new_len); |
1259 | if (!avail) | 1254 | if (!avail) |
1260 | return; | 1255 | return; |
1261 | } | 1256 | } |
1262 | ptr = skb_tail_pointer(skb); | 1257 | ptr = skb_tail_pointer(skb); |
1263 | *ptr++ = '"'; | 1258 | *ptr++ = '"'; |
1264 | memcpy(ptr, string, slen); | 1259 | memcpy(ptr, string, slen); |
1265 | ptr += slen; | 1260 | ptr += slen; |
1266 | *ptr++ = '"'; | 1261 | *ptr++ = '"'; |
1267 | *ptr = 0; | 1262 | *ptr = 0; |
1268 | skb_put(skb, slen + 2); /* don't include null terminator */ | 1263 | skb_put(skb, slen + 2); /* don't include null terminator */ |
1269 | } | 1264 | } |
1270 | 1265 | ||
1271 | /** | 1266 | /** |
1272 | * audit_string_contains_control - does a string need to be logged in hex | 1267 | * audit_string_contains_control - does a string need to be logged in hex |
1273 | * @string: string to be checked | 1268 | * @string: string to be checked |
1274 | * @len: max length of the string to check | 1269 | * @len: max length of the string to check |
1275 | */ | 1270 | */ |
1276 | int audit_string_contains_control(const char *string, size_t len) | 1271 | int audit_string_contains_control(const char *string, size_t len) |
1277 | { | 1272 | { |
1278 | const unsigned char *p; | 1273 | const unsigned char *p; |
1279 | for (p = string; p < (const unsigned char *)string + len && *p; p++) { | 1274 | for (p = string; p < (const unsigned char *)string + len && *p; p++) { |
1280 | if (*p == '"' || *p < 0x21 || *p > 0x7f) | 1275 | if (*p == '"' || *p < 0x21 || *p > 0x7f) |
1281 | return 1; | 1276 | return 1; |
1282 | } | 1277 | } |
1283 | return 0; | 1278 | return 0; |
1284 | } | 1279 | } |
1285 | 1280 | ||
1286 | /** | 1281 | /** |
1287 | * audit_log_n_untrustedstring - log a string that may contain random characters | 1282 | * audit_log_n_untrustedstring - log a string that may contain random characters |
1288 | * @ab: audit_buffer | 1283 | * @ab: audit_buffer |
1289 | * @len: length of string (not including trailing null) | 1284 | * @len: length of string (not including trailing null) |
1290 | * @string: string to be logged | 1285 | * @string: string to be logged |
1291 | * | 1286 | * |
1292 | * This code will escape a string that is passed to it if the string | 1287 | * This code will escape a string that is passed to it if the string |
1293 | * contains a control character, unprintable character, double quote mark, | 1288 | * contains a control character, unprintable character, double quote mark, |
1294 | * or a space. Unescaped strings will start and end with a double quote mark. | 1289 | * or a space. Unescaped strings will start and end with a double quote mark. |
1295 | * Strings that are escaped are printed in hex (2 digits per char). | 1290 | * Strings that are escaped are printed in hex (2 digits per char). |
1296 | * | 1291 | * |
1297 | * The caller specifies the number of characters in the string to log, which may | 1292 | * The caller specifies the number of characters in the string to log, which may |
1298 | * or may not be the entire string. | 1293 | * or may not be the entire string. |
1299 | */ | 1294 | */ |
1300 | void audit_log_n_untrustedstring(struct audit_buffer *ab, size_t len, | 1295 | void audit_log_n_untrustedstring(struct audit_buffer *ab, size_t len, |
1301 | const char *string) | 1296 | const char *string) |
1302 | { | 1297 | { |
1303 | if (audit_string_contains_control(string, len)) | 1298 | if (audit_string_contains_control(string, len)) |
1304 | audit_log_hex(ab, string, len); | 1299 | audit_log_hex(ab, string, len); |
1305 | else | 1300 | else |
1306 | audit_log_n_string(ab, len, string); | 1301 | audit_log_n_string(ab, len, string); |
1307 | } | 1302 | } |
1308 | 1303 | ||
1309 | /** | 1304 | /** |
1310 | * audit_log_untrustedstring - log a string that may contain random characters | 1305 | * audit_log_untrustedstring - log a string that may contain random characters |
1311 | * @ab: audit_buffer | 1306 | * @ab: audit_buffer |
1312 | * @string: string to be logged | 1307 | * @string: string to be logged |
1313 | * | 1308 | * |
1314 | * Same as audit_log_n_untrustedstring(), except that strlen is used to | 1309 | * Same as audit_log_n_untrustedstring(), except that strlen is used to |
1315 | * determine string length. | 1310 | * determine string length. |
1316 | */ | 1311 | */ |
1317 | void audit_log_untrustedstring(struct audit_buffer *ab, const char *string) | 1312 | void audit_log_untrustedstring(struct audit_buffer *ab, const char *string) |
1318 | { | 1313 | { |
1319 | audit_log_n_untrustedstring(ab, strlen(string), string); | 1314 | audit_log_n_untrustedstring(ab, strlen(string), string); |
1320 | } | 1315 | } |
1321 | 1316 | ||
1322 | /* This is a helper-function to print the escaped d_path */ | 1317 | /* This is a helper-function to print the escaped d_path */ |
1323 | void audit_log_d_path(struct audit_buffer *ab, const char *prefix, | 1318 | void audit_log_d_path(struct audit_buffer *ab, const char *prefix, |
1324 | struct path *path) | 1319 | struct path *path) |
1325 | { | 1320 | { |
1326 | char *p, *pathname; | 1321 | char *p, *pathname; |
1327 | 1322 | ||
1328 | if (prefix) | 1323 | if (prefix) |
1329 | audit_log_format(ab, " %s", prefix); | 1324 | audit_log_format(ab, " %s", prefix); |
1330 | 1325 | ||
1331 | /* We will allow 11 spaces for ' (deleted)' to be appended */ | 1326 | /* We will allow 11 spaces for ' (deleted)' to be appended */ |
1332 | pathname = kmalloc(PATH_MAX+11, ab->gfp_mask); | 1327 | pathname = kmalloc(PATH_MAX+11, ab->gfp_mask); |
1333 | if (!pathname) { | 1328 | if (!pathname) { |
1334 | audit_log_format(ab, "<no memory>"); | 1329 | audit_log_format(ab, "<no memory>"); |
1335 | return; | 1330 | return; |
1336 | } | 1331 | } |
1337 | p = d_path(path, pathname, PATH_MAX+11); | 1332 | p = d_path(path, pathname, PATH_MAX+11); |
1338 | if (IS_ERR(p)) { /* Should never happen since we send PATH_MAX */ | 1333 | if (IS_ERR(p)) { /* Should never happen since we send PATH_MAX */ |
1339 | /* FIXME: can we save some information here? */ | 1334 | /* FIXME: can we save some information here? */ |
1340 | audit_log_format(ab, "<too long>"); | 1335 | audit_log_format(ab, "<too long>"); |
1341 | } else | 1336 | } else |
1342 | audit_log_untrustedstring(ab, p); | 1337 | audit_log_untrustedstring(ab, p); |
1343 | kfree(pathname); | 1338 | kfree(pathname); |
1344 | } | 1339 | } |
1345 | 1340 | ||
1346 | /** | 1341 | /** |
1347 | * audit_log_end - end one audit record | 1342 | * audit_log_end - end one audit record |
1348 | * @ab: the audit_buffer | 1343 | * @ab: the audit_buffer |
1349 | * | 1344 | * |
1350 | * The netlink_* functions cannot be called inside an irq context, so | 1345 | * The netlink_* functions cannot be called inside an irq context, so |
1351 | * the audit buffer is placed on a queue and a tasklet is scheduled to | 1346 | * the audit buffer is placed on a queue and a tasklet is scheduled to |
1352 | * remove them from the queue outside the irq context. May be called in | 1347 | * remove them from the queue outside the irq context. May be called in |
1353 | * any context. | 1348 | * any context. |
1354 | */ | 1349 | */ |
1355 | void audit_log_end(struct audit_buffer *ab) | 1350 | void audit_log_end(struct audit_buffer *ab) |
1356 | { | 1351 | { |
1357 | if (!ab) | 1352 | if (!ab) |
1358 | return; | 1353 | return; |
1359 | if (!audit_rate_check()) { | 1354 | if (!audit_rate_check()) { |
1360 | audit_log_lost("rate limit exceeded"); | 1355 | audit_log_lost("rate limit exceeded"); |
1361 | } else { | 1356 | } else { |
1362 | struct nlmsghdr *nlh = nlmsg_hdr(ab->skb); | 1357 | struct nlmsghdr *nlh = nlmsg_hdr(ab->skb); |
1363 | if (audit_pid) { | 1358 | if (audit_pid) { |
1364 | nlh->nlmsg_len = ab->skb->len - NLMSG_SPACE(0); | 1359 | nlh->nlmsg_len = ab->skb->len - NLMSG_SPACE(0); |
1365 | skb_queue_tail(&audit_skb_queue, ab->skb); | 1360 | skb_queue_tail(&audit_skb_queue, ab->skb); |
1366 | ab->skb = NULL; | 1361 | ab->skb = NULL; |
1367 | wake_up_interruptible(&kauditd_wait); | 1362 | wake_up_interruptible(&kauditd_wait); |
1368 | } else if (nlh->nlmsg_type != AUDIT_EOE) { | 1363 | } else if (nlh->nlmsg_type != AUDIT_EOE) { |
1369 | if (printk_ratelimit()) { | 1364 | if (printk_ratelimit()) { |
1370 | printk(KERN_NOTICE "type=%d %s\n", | 1365 | printk(KERN_NOTICE "type=%d %s\n", |
1371 | nlh->nlmsg_type, | 1366 | nlh->nlmsg_type, |
1372 | ab->skb->data + NLMSG_SPACE(0)); | 1367 | ab->skb->data + NLMSG_SPACE(0)); |
1373 | } else | 1368 | } else |
1374 | audit_log_lost("printk limit exceeded\n"); | 1369 | audit_log_lost("printk limit exceeded\n"); |
1375 | } | 1370 | } |
1376 | } | 1371 | } |
1377 | audit_buffer_free(ab); | 1372 | audit_buffer_free(ab); |
1378 | } | 1373 | } |
1379 | 1374 | ||
1380 | /** | 1375 | /** |
1381 | * audit_log - Log an audit record | 1376 | * audit_log - Log an audit record |
1382 | * @ctx: audit context | 1377 | * @ctx: audit context |
1383 | * @gfp_mask: type of allocation | 1378 | * @gfp_mask: type of allocation |
1384 | * @type: audit message type | 1379 | * @type: audit message type |
1385 | * @fmt: format string to use | 1380 | * @fmt: format string to use |
1386 | * @...: variable parameters matching the format string | 1381 | * @...: variable parameters matching the format string |
1387 | * | 1382 | * |
1388 | * This is a convenience function that calls audit_log_start, | 1383 | * This is a convenience function that calls audit_log_start, |
1389 | * audit_log_vformat, and audit_log_end. It may be called | 1384 | * audit_log_vformat, and audit_log_end. It may be called |
1390 | * in any context. | 1385 | * in any context. |
1391 | */ | 1386 | */ |
1392 | void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type, | 1387 | void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type, |
1393 | const char *fmt, ...) | 1388 | const char *fmt, ...) |
1394 | { | 1389 | { |
1395 | struct audit_buffer *ab; | 1390 | struct audit_buffer *ab; |
1396 | va_list args; | 1391 | va_list args; |
1397 | 1392 | ||
1398 | ab = audit_log_start(ctx, gfp_mask, type); | 1393 | ab = audit_log_start(ctx, gfp_mask, type); |
1399 | if (ab) { | 1394 | if (ab) { |
1400 | va_start(args, fmt); | 1395 | va_start(args, fmt); |
1401 | audit_log_vformat(ab, fmt, args); | 1396 | audit_log_vformat(ab, fmt, args); |
1402 | va_end(args); | 1397 | va_end(args); |
1403 | audit_log_end(ab); | 1398 | audit_log_end(ab); |
1404 | } | 1399 | } |
1405 | } | 1400 | } |
1406 | 1401 | ||
1407 | EXPORT_SYMBOL(audit_log_start); | 1402 | EXPORT_SYMBOL(audit_log_start); |
1408 | EXPORT_SYMBOL(audit_log_end); | 1403 | EXPORT_SYMBOL(audit_log_end); |
1409 | EXPORT_SYMBOL(audit_log_format); | 1404 | EXPORT_SYMBOL(audit_log_format); |
1410 | EXPORT_SYMBOL(audit_log); | 1405 | EXPORT_SYMBOL(audit_log); |
1411 | 1406 |
kernel/auditfilter.c
1 | /* auditfilter.c -- filtering of audit events | 1 | /* auditfilter.c -- filtering of audit events |
2 | * | 2 | * |
3 | * Copyright 2003-2004 Red Hat, Inc. | 3 | * Copyright 2003-2004 Red Hat, Inc. |
4 | * Copyright 2005 Hewlett-Packard Development Company, L.P. | 4 | * Copyright 2005 Hewlett-Packard Development Company, L.P. |
5 | * Copyright 2005 IBM Corporation | 5 | * Copyright 2005 IBM Corporation |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
9 | * the Free Software Foundation; either version 2 of the License, or | 9 | * the Free Software Foundation; either version 2 of the License, or |
10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
11 | * | 11 | * |
12 | * This program is distributed in the hope that it will be useful, | 12 | * This program is distributed in the hope that it will be useful, |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | * GNU General Public License for more details. | 15 | * GNU General Public License for more details. |
16 | * | 16 | * |
17 | * You should have received a copy of the GNU General Public License | 17 | * You should have received a copy of the GNU General Public License |
18 | * along with this program; if not, write to the Free Software | 18 | * along with this program; if not, write to the Free Software |
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/audit.h> | 23 | #include <linux/audit.h> |
24 | #include <linux/kthread.h> | 24 | #include <linux/kthread.h> |
25 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
26 | #include <linux/fs.h> | 26 | #include <linux/fs.h> |
27 | #include <linux/namei.h> | 27 | #include <linux/namei.h> |
28 | #include <linux/netlink.h> | 28 | #include <linux/netlink.h> |
29 | #include <linux/sched.h> | 29 | #include <linux/sched.h> |
30 | #include <linux/inotify.h> | 30 | #include <linux/inotify.h> |
31 | #include <linux/security.h> | 31 | #include <linux/security.h> |
32 | #include <linux/selinux.h> | ||
33 | #include "audit.h" | 32 | #include "audit.h" |
34 | 33 | ||
35 | /* | 34 | /* |
36 | * Locking model: | 35 | * Locking model: |
37 | * | 36 | * |
38 | * audit_filter_mutex: | 37 | * audit_filter_mutex: |
39 | * Synchronizes writes and blocking reads of audit's filterlist | 38 | * Synchronizes writes and blocking reads of audit's filterlist |
40 | * data. Rcu is used to traverse the filterlist and access | 39 | * data. Rcu is used to traverse the filterlist and access |
41 | * contents of structs audit_entry, audit_watch and opaque | 40 | * contents of structs audit_entry, audit_watch and opaque |
42 | * selinux rules during filtering. If modified, these structures | 41 | * LSM rules during filtering. If modified, these structures |
43 | * must be copied and replace their counterparts in the filterlist. | 42 | * must be copied and replace their counterparts in the filterlist. |
44 | * An audit_parent struct is not accessed during filtering, so may | 43 | * An audit_parent struct is not accessed during filtering, so may |
45 | * be written directly provided audit_filter_mutex is held. | 44 | * be written directly provided audit_filter_mutex is held. |
46 | */ | 45 | */ |
47 | 46 | ||
48 | /* | 47 | /* |
49 | * Reference counting: | 48 | * Reference counting: |
50 | * | 49 | * |
51 | * audit_parent: lifetime is from audit_init_parent() to receipt of an IN_IGNORED | 50 | * audit_parent: lifetime is from audit_init_parent() to receipt of an IN_IGNORED |
52 | * event. Each audit_watch holds a reference to its associated parent. | 51 | * event. Each audit_watch holds a reference to its associated parent. |
53 | * | 52 | * |
54 | * audit_watch: if added to lists, lifetime is from audit_init_watch() to | 53 | * audit_watch: if added to lists, lifetime is from audit_init_watch() to |
55 | * audit_remove_watch(). Additionally, an audit_watch may exist | 54 | * audit_remove_watch(). Additionally, an audit_watch may exist |
56 | * temporarily to assist in searching existing filter data. Each | 55 | * temporarily to assist in searching existing filter data. Each |
57 | * audit_krule holds a reference to its associated watch. | 56 | * audit_krule holds a reference to its associated watch. |
58 | */ | 57 | */ |
59 | 58 | ||
60 | struct audit_parent { | 59 | struct audit_parent { |
61 | struct list_head ilist; /* entry in inotify registration list */ | 60 | struct list_head ilist; /* entry in inotify registration list */ |
62 | struct list_head watches; /* associated watches */ | 61 | struct list_head watches; /* associated watches */ |
63 | struct inotify_watch wdata; /* inotify watch data */ | 62 | struct inotify_watch wdata; /* inotify watch data */ |
64 | unsigned flags; /* status flags */ | 63 | unsigned flags; /* status flags */ |
65 | }; | 64 | }; |
66 | 65 | ||
67 | /* | 66 | /* |
68 | * audit_parent status flags: | 67 | * audit_parent status flags: |
69 | * | 68 | * |
70 | * AUDIT_PARENT_INVALID - set anytime rules/watches are auto-removed due to | 69 | * AUDIT_PARENT_INVALID - set anytime rules/watches are auto-removed due to |
71 | * a filesystem event to ensure we're adding audit watches to a valid parent. | 70 | * a filesystem event to ensure we're adding audit watches to a valid parent. |
72 | * Technically not needed for IN_DELETE_SELF or IN_UNMOUNT events, as we cannot | 71 | * Technically not needed for IN_DELETE_SELF or IN_UNMOUNT events, as we cannot |
73 | * receive them while we have nameidata, but must be used for IN_MOVE_SELF which | 72 | * receive them while we have nameidata, but must be used for IN_MOVE_SELF which |
74 | * we can receive while holding nameidata. | 73 | * we can receive while holding nameidata. |
75 | */ | 74 | */ |
76 | #define AUDIT_PARENT_INVALID 0x001 | 75 | #define AUDIT_PARENT_INVALID 0x001 |
77 | 76 | ||
78 | /* Audit filter lists, defined in <linux/audit.h> */ | 77 | /* Audit filter lists, defined in <linux/audit.h> */ |
79 | struct list_head audit_filter_list[AUDIT_NR_FILTERS] = { | 78 | struct list_head audit_filter_list[AUDIT_NR_FILTERS] = { |
80 | LIST_HEAD_INIT(audit_filter_list[0]), | 79 | LIST_HEAD_INIT(audit_filter_list[0]), |
81 | LIST_HEAD_INIT(audit_filter_list[1]), | 80 | LIST_HEAD_INIT(audit_filter_list[1]), |
82 | LIST_HEAD_INIT(audit_filter_list[2]), | 81 | LIST_HEAD_INIT(audit_filter_list[2]), |
83 | LIST_HEAD_INIT(audit_filter_list[3]), | 82 | LIST_HEAD_INIT(audit_filter_list[3]), |
84 | LIST_HEAD_INIT(audit_filter_list[4]), | 83 | LIST_HEAD_INIT(audit_filter_list[4]), |
85 | LIST_HEAD_INIT(audit_filter_list[5]), | 84 | LIST_HEAD_INIT(audit_filter_list[5]), |
86 | #if AUDIT_NR_FILTERS != 6 | 85 | #if AUDIT_NR_FILTERS != 6 |
87 | #error Fix audit_filter_list initialiser | 86 | #error Fix audit_filter_list initialiser |
88 | #endif | 87 | #endif |
89 | }; | 88 | }; |
90 | 89 | ||
91 | DEFINE_MUTEX(audit_filter_mutex); | 90 | DEFINE_MUTEX(audit_filter_mutex); |
92 | 91 | ||
93 | /* Inotify handle */ | 92 | /* Inotify handle */ |
94 | extern struct inotify_handle *audit_ih; | 93 | extern struct inotify_handle *audit_ih; |
95 | 94 | ||
96 | /* Inotify events we care about. */ | 95 | /* Inotify events we care about. */ |
97 | #define AUDIT_IN_WATCH IN_MOVE|IN_CREATE|IN_DELETE|IN_DELETE_SELF|IN_MOVE_SELF | 96 | #define AUDIT_IN_WATCH IN_MOVE|IN_CREATE|IN_DELETE|IN_DELETE_SELF|IN_MOVE_SELF |
98 | 97 | ||
99 | extern int audit_enabled; | 98 | extern int audit_enabled; |
100 | 99 | ||
101 | void audit_free_parent(struct inotify_watch *i_watch) | 100 | void audit_free_parent(struct inotify_watch *i_watch) |
102 | { | 101 | { |
103 | struct audit_parent *parent; | 102 | struct audit_parent *parent; |
104 | 103 | ||
105 | parent = container_of(i_watch, struct audit_parent, wdata); | 104 | parent = container_of(i_watch, struct audit_parent, wdata); |
106 | WARN_ON(!list_empty(&parent->watches)); | 105 | WARN_ON(!list_empty(&parent->watches)); |
107 | kfree(parent); | 106 | kfree(parent); |
108 | } | 107 | } |
109 | 108 | ||
110 | static inline void audit_get_watch(struct audit_watch *watch) | 109 | static inline void audit_get_watch(struct audit_watch *watch) |
111 | { | 110 | { |
112 | atomic_inc(&watch->count); | 111 | atomic_inc(&watch->count); |
113 | } | 112 | } |
114 | 113 | ||
115 | static void audit_put_watch(struct audit_watch *watch) | 114 | static void audit_put_watch(struct audit_watch *watch) |
116 | { | 115 | { |
117 | if (atomic_dec_and_test(&watch->count)) { | 116 | if (atomic_dec_and_test(&watch->count)) { |
118 | WARN_ON(watch->parent); | 117 | WARN_ON(watch->parent); |
119 | WARN_ON(!list_empty(&watch->rules)); | 118 | WARN_ON(!list_empty(&watch->rules)); |
120 | kfree(watch->path); | 119 | kfree(watch->path); |
121 | kfree(watch); | 120 | kfree(watch); |
122 | } | 121 | } |
123 | } | 122 | } |
124 | 123 | ||
125 | static void audit_remove_watch(struct audit_watch *watch) | 124 | static void audit_remove_watch(struct audit_watch *watch) |
126 | { | 125 | { |
127 | list_del(&watch->wlist); | 126 | list_del(&watch->wlist); |
128 | put_inotify_watch(&watch->parent->wdata); | 127 | put_inotify_watch(&watch->parent->wdata); |
129 | watch->parent = NULL; | 128 | watch->parent = NULL; |
130 | audit_put_watch(watch); /* match initial get */ | 129 | audit_put_watch(watch); /* match initial get */ |
131 | } | 130 | } |
132 | 131 | ||
133 | static inline void audit_free_rule(struct audit_entry *e) | 132 | static inline void audit_free_rule(struct audit_entry *e) |
134 | { | 133 | { |
135 | int i; | 134 | int i; |
136 | 135 | ||
137 | /* some rules don't have associated watches */ | 136 | /* some rules don't have associated watches */ |
138 | if (e->rule.watch) | 137 | if (e->rule.watch) |
139 | audit_put_watch(e->rule.watch); | 138 | audit_put_watch(e->rule.watch); |
140 | if (e->rule.fields) | 139 | if (e->rule.fields) |
141 | for (i = 0; i < e->rule.field_count; i++) { | 140 | for (i = 0; i < e->rule.field_count; i++) { |
142 | struct audit_field *f = &e->rule.fields[i]; | 141 | struct audit_field *f = &e->rule.fields[i]; |
143 | kfree(f->se_str); | 142 | kfree(f->se_str); |
144 | selinux_audit_rule_free(f->se_rule); | 143 | security_audit_rule_free(f->se_rule); |
145 | } | 144 | } |
146 | kfree(e->rule.fields); | 145 | kfree(e->rule.fields); |
147 | kfree(e->rule.filterkey); | 146 | kfree(e->rule.filterkey); |
148 | kfree(e); | 147 | kfree(e); |
149 | } | 148 | } |
150 | 149 | ||
151 | void audit_free_rule_rcu(struct rcu_head *head) | 150 | void audit_free_rule_rcu(struct rcu_head *head) |
152 | { | 151 | { |
153 | struct audit_entry *e = container_of(head, struct audit_entry, rcu); | 152 | struct audit_entry *e = container_of(head, struct audit_entry, rcu); |
154 | audit_free_rule(e); | 153 | audit_free_rule(e); |
155 | } | 154 | } |
156 | 155 | ||
157 | /* Initialize a parent watch entry. */ | 156 | /* Initialize a parent watch entry. */ |
158 | static struct audit_parent *audit_init_parent(struct nameidata *ndp) | 157 | static struct audit_parent *audit_init_parent(struct nameidata *ndp) |
159 | { | 158 | { |
160 | struct audit_parent *parent; | 159 | struct audit_parent *parent; |
161 | s32 wd; | 160 | s32 wd; |
162 | 161 | ||
163 | parent = kzalloc(sizeof(*parent), GFP_KERNEL); | 162 | parent = kzalloc(sizeof(*parent), GFP_KERNEL); |
164 | if (unlikely(!parent)) | 163 | if (unlikely(!parent)) |
165 | return ERR_PTR(-ENOMEM); | 164 | return ERR_PTR(-ENOMEM); |
166 | 165 | ||
167 | INIT_LIST_HEAD(&parent->watches); | 166 | INIT_LIST_HEAD(&parent->watches); |
168 | parent->flags = 0; | 167 | parent->flags = 0; |
169 | 168 | ||
170 | inotify_init_watch(&parent->wdata); | 169 | inotify_init_watch(&parent->wdata); |
171 | /* grab a ref so inotify watch hangs around until we take audit_filter_mutex */ | 170 | /* grab a ref so inotify watch hangs around until we take audit_filter_mutex */ |
172 | get_inotify_watch(&parent->wdata); | 171 | get_inotify_watch(&parent->wdata); |
173 | wd = inotify_add_watch(audit_ih, &parent->wdata, | 172 | wd = inotify_add_watch(audit_ih, &parent->wdata, |
174 | ndp->path.dentry->d_inode, AUDIT_IN_WATCH); | 173 | ndp->path.dentry->d_inode, AUDIT_IN_WATCH); |
175 | if (wd < 0) { | 174 | if (wd < 0) { |
176 | audit_free_parent(&parent->wdata); | 175 | audit_free_parent(&parent->wdata); |
177 | return ERR_PTR(wd); | 176 | return ERR_PTR(wd); |
178 | } | 177 | } |
179 | 178 | ||
180 | return parent; | 179 | return parent; |
181 | } | 180 | } |
182 | 181 | ||
183 | /* Initialize a watch entry. */ | 182 | /* Initialize a watch entry. */ |
184 | static struct audit_watch *audit_init_watch(char *path) | 183 | static struct audit_watch *audit_init_watch(char *path) |
185 | { | 184 | { |
186 | struct audit_watch *watch; | 185 | struct audit_watch *watch; |
187 | 186 | ||
188 | watch = kzalloc(sizeof(*watch), GFP_KERNEL); | 187 | watch = kzalloc(sizeof(*watch), GFP_KERNEL); |
189 | if (unlikely(!watch)) | 188 | if (unlikely(!watch)) |
190 | return ERR_PTR(-ENOMEM); | 189 | return ERR_PTR(-ENOMEM); |
191 | 190 | ||
192 | INIT_LIST_HEAD(&watch->rules); | 191 | INIT_LIST_HEAD(&watch->rules); |
193 | atomic_set(&watch->count, 1); | 192 | atomic_set(&watch->count, 1); |
194 | watch->path = path; | 193 | watch->path = path; |
195 | watch->dev = (dev_t)-1; | 194 | watch->dev = (dev_t)-1; |
196 | watch->ino = (unsigned long)-1; | 195 | watch->ino = (unsigned long)-1; |
197 | 196 | ||
198 | return watch; | 197 | return watch; |
199 | } | 198 | } |
200 | 199 | ||
201 | /* Initialize an audit filterlist entry. */ | 200 | /* Initialize an audit filterlist entry. */ |
202 | static inline struct audit_entry *audit_init_entry(u32 field_count) | 201 | static inline struct audit_entry *audit_init_entry(u32 field_count) |
203 | { | 202 | { |
204 | struct audit_entry *entry; | 203 | struct audit_entry *entry; |
205 | struct audit_field *fields; | 204 | struct audit_field *fields; |
206 | 205 | ||
207 | entry = kzalloc(sizeof(*entry), GFP_KERNEL); | 206 | entry = kzalloc(sizeof(*entry), GFP_KERNEL); |
208 | if (unlikely(!entry)) | 207 | if (unlikely(!entry)) |
209 | return NULL; | 208 | return NULL; |
210 | 209 | ||
211 | fields = kzalloc(sizeof(*fields) * field_count, GFP_KERNEL); | 210 | fields = kzalloc(sizeof(*fields) * field_count, GFP_KERNEL); |
212 | if (unlikely(!fields)) { | 211 | if (unlikely(!fields)) { |
213 | kfree(entry); | 212 | kfree(entry); |
214 | return NULL; | 213 | return NULL; |
215 | } | 214 | } |
216 | entry->rule.fields = fields; | 215 | entry->rule.fields = fields; |
217 | 216 | ||
218 | return entry; | 217 | return entry; |
219 | } | 218 | } |
220 | 219 | ||
221 | /* Unpack a filter field's string representation from user-space | 220 | /* Unpack a filter field's string representation from user-space |
222 | * buffer. */ | 221 | * buffer. */ |
223 | char *audit_unpack_string(void **bufp, size_t *remain, size_t len) | 222 | char *audit_unpack_string(void **bufp, size_t *remain, size_t len) |
224 | { | 223 | { |
225 | char *str; | 224 | char *str; |
226 | 225 | ||
227 | if (!*bufp || (len == 0) || (len > *remain)) | 226 | if (!*bufp || (len == 0) || (len > *remain)) |
228 | return ERR_PTR(-EINVAL); | 227 | return ERR_PTR(-EINVAL); |
229 | 228 | ||
230 | /* Of the currently implemented string fields, PATH_MAX | 229 | /* Of the currently implemented string fields, PATH_MAX |
231 | * defines the longest valid length. | 230 | * defines the longest valid length. |
232 | */ | 231 | */ |
233 | if (len > PATH_MAX) | 232 | if (len > PATH_MAX) |
234 | return ERR_PTR(-ENAMETOOLONG); | 233 | return ERR_PTR(-ENAMETOOLONG); |
235 | 234 | ||
236 | str = kmalloc(len + 1, GFP_KERNEL); | 235 | str = kmalloc(len + 1, GFP_KERNEL); |
237 | if (unlikely(!str)) | 236 | if (unlikely(!str)) |
238 | return ERR_PTR(-ENOMEM); | 237 | return ERR_PTR(-ENOMEM); |
239 | 238 | ||
240 | memcpy(str, *bufp, len); | 239 | memcpy(str, *bufp, len); |
241 | str[len] = 0; | 240 | str[len] = 0; |
242 | *bufp += len; | 241 | *bufp += len; |
243 | *remain -= len; | 242 | *remain -= len; |
244 | 243 | ||
245 | return str; | 244 | return str; |
246 | } | 245 | } |
247 | 246 | ||
248 | /* Translate an inode field to kernel respresentation. */ | 247 | /* Translate an inode field to kernel respresentation. */ |
249 | static inline int audit_to_inode(struct audit_krule *krule, | 248 | static inline int audit_to_inode(struct audit_krule *krule, |
250 | struct audit_field *f) | 249 | struct audit_field *f) |
251 | { | 250 | { |
252 | if (krule->listnr != AUDIT_FILTER_EXIT || | 251 | if (krule->listnr != AUDIT_FILTER_EXIT || |
253 | krule->watch || krule->inode_f || krule->tree) | 252 | krule->watch || krule->inode_f || krule->tree) |
254 | return -EINVAL; | 253 | return -EINVAL; |
255 | 254 | ||
256 | krule->inode_f = f; | 255 | krule->inode_f = f; |
257 | return 0; | 256 | return 0; |
258 | } | 257 | } |
259 | 258 | ||
260 | /* Translate a watch string to kernel respresentation. */ | 259 | /* Translate a watch string to kernel respresentation. */ |
261 | static int audit_to_watch(struct audit_krule *krule, char *path, int len, | 260 | static int audit_to_watch(struct audit_krule *krule, char *path, int len, |
262 | u32 op) | 261 | u32 op) |
263 | { | 262 | { |
264 | struct audit_watch *watch; | 263 | struct audit_watch *watch; |
265 | 264 | ||
266 | if (!audit_ih) | 265 | if (!audit_ih) |
267 | return -EOPNOTSUPP; | 266 | return -EOPNOTSUPP; |
268 | 267 | ||
269 | if (path[0] != '/' || path[len-1] == '/' || | 268 | if (path[0] != '/' || path[len-1] == '/' || |
270 | krule->listnr != AUDIT_FILTER_EXIT || | 269 | krule->listnr != AUDIT_FILTER_EXIT || |
271 | op & ~AUDIT_EQUAL || | 270 | op & ~AUDIT_EQUAL || |
272 | krule->inode_f || krule->watch || krule->tree) | 271 | krule->inode_f || krule->watch || krule->tree) |
273 | return -EINVAL; | 272 | return -EINVAL; |
274 | 273 | ||
275 | watch = audit_init_watch(path); | 274 | watch = audit_init_watch(path); |
276 | if (unlikely(IS_ERR(watch))) | 275 | if (unlikely(IS_ERR(watch))) |
277 | return PTR_ERR(watch); | 276 | return PTR_ERR(watch); |
278 | 277 | ||
279 | audit_get_watch(watch); | 278 | audit_get_watch(watch); |
280 | krule->watch = watch; | 279 | krule->watch = watch; |
281 | 280 | ||
282 | return 0; | 281 | return 0; |
283 | } | 282 | } |
284 | 283 | ||
285 | static __u32 *classes[AUDIT_SYSCALL_CLASSES]; | 284 | static __u32 *classes[AUDIT_SYSCALL_CLASSES]; |
286 | 285 | ||
287 | int __init audit_register_class(int class, unsigned *list) | 286 | int __init audit_register_class(int class, unsigned *list) |
288 | { | 287 | { |
289 | __u32 *p = kzalloc(AUDIT_BITMASK_SIZE * sizeof(__u32), GFP_KERNEL); | 288 | __u32 *p = kzalloc(AUDIT_BITMASK_SIZE * sizeof(__u32), GFP_KERNEL); |
290 | if (!p) | 289 | if (!p) |
291 | return -ENOMEM; | 290 | return -ENOMEM; |
292 | while (*list != ~0U) { | 291 | while (*list != ~0U) { |
293 | unsigned n = *list++; | 292 | unsigned n = *list++; |
294 | if (n >= AUDIT_BITMASK_SIZE * 32 - AUDIT_SYSCALL_CLASSES) { | 293 | if (n >= AUDIT_BITMASK_SIZE * 32 - AUDIT_SYSCALL_CLASSES) { |
295 | kfree(p); | 294 | kfree(p); |
296 | return -EINVAL; | 295 | return -EINVAL; |
297 | } | 296 | } |
298 | p[AUDIT_WORD(n)] |= AUDIT_BIT(n); | 297 | p[AUDIT_WORD(n)] |= AUDIT_BIT(n); |
299 | } | 298 | } |
300 | if (class >= AUDIT_SYSCALL_CLASSES || classes[class]) { | 299 | if (class >= AUDIT_SYSCALL_CLASSES || classes[class]) { |
301 | kfree(p); | 300 | kfree(p); |
302 | return -EINVAL; | 301 | return -EINVAL; |
303 | } | 302 | } |
304 | classes[class] = p; | 303 | classes[class] = p; |
305 | return 0; | 304 | return 0; |
306 | } | 305 | } |
307 | 306 | ||
308 | int audit_match_class(int class, unsigned syscall) | 307 | int audit_match_class(int class, unsigned syscall) |
309 | { | 308 | { |
310 | if (unlikely(syscall >= AUDIT_BITMASK_SIZE * 32)) | 309 | if (unlikely(syscall >= AUDIT_BITMASK_SIZE * 32)) |
311 | return 0; | 310 | return 0; |
312 | if (unlikely(class >= AUDIT_SYSCALL_CLASSES || !classes[class])) | 311 | if (unlikely(class >= AUDIT_SYSCALL_CLASSES || !classes[class])) |
313 | return 0; | 312 | return 0; |
314 | return classes[class][AUDIT_WORD(syscall)] & AUDIT_BIT(syscall); | 313 | return classes[class][AUDIT_WORD(syscall)] & AUDIT_BIT(syscall); |
315 | } | 314 | } |
316 | 315 | ||
317 | #ifdef CONFIG_AUDITSYSCALL | 316 | #ifdef CONFIG_AUDITSYSCALL |
318 | static inline int audit_match_class_bits(int class, u32 *mask) | 317 | static inline int audit_match_class_bits(int class, u32 *mask) |
319 | { | 318 | { |
320 | int i; | 319 | int i; |
321 | 320 | ||
322 | if (classes[class]) { | 321 | if (classes[class]) { |
323 | for (i = 0; i < AUDIT_BITMASK_SIZE; i++) | 322 | for (i = 0; i < AUDIT_BITMASK_SIZE; i++) |
324 | if (mask[i] & classes[class][i]) | 323 | if (mask[i] & classes[class][i]) |
325 | return 0; | 324 | return 0; |
326 | } | 325 | } |
327 | return 1; | 326 | return 1; |
328 | } | 327 | } |
329 | 328 | ||
330 | static int audit_match_signal(struct audit_entry *entry) | 329 | static int audit_match_signal(struct audit_entry *entry) |
331 | { | 330 | { |
332 | struct audit_field *arch = entry->rule.arch_f; | 331 | struct audit_field *arch = entry->rule.arch_f; |
333 | 332 | ||
334 | if (!arch) { | 333 | if (!arch) { |
335 | /* When arch is unspecified, we must check both masks on biarch | 334 | /* When arch is unspecified, we must check both masks on biarch |
336 | * as syscall number alone is ambiguous. */ | 335 | * as syscall number alone is ambiguous. */ |
337 | return (audit_match_class_bits(AUDIT_CLASS_SIGNAL, | 336 | return (audit_match_class_bits(AUDIT_CLASS_SIGNAL, |
338 | entry->rule.mask) && | 337 | entry->rule.mask) && |
339 | audit_match_class_bits(AUDIT_CLASS_SIGNAL_32, | 338 | audit_match_class_bits(AUDIT_CLASS_SIGNAL_32, |
340 | entry->rule.mask)); | 339 | entry->rule.mask)); |
341 | } | 340 | } |
342 | 341 | ||
343 | switch(audit_classify_arch(arch->val)) { | 342 | switch(audit_classify_arch(arch->val)) { |
344 | case 0: /* native */ | 343 | case 0: /* native */ |
345 | return (audit_match_class_bits(AUDIT_CLASS_SIGNAL, | 344 | return (audit_match_class_bits(AUDIT_CLASS_SIGNAL, |
346 | entry->rule.mask)); | 345 | entry->rule.mask)); |
347 | case 1: /* 32bit on biarch */ | 346 | case 1: /* 32bit on biarch */ |
348 | return (audit_match_class_bits(AUDIT_CLASS_SIGNAL_32, | 347 | return (audit_match_class_bits(AUDIT_CLASS_SIGNAL_32, |
349 | entry->rule.mask)); | 348 | entry->rule.mask)); |
350 | default: | 349 | default: |
351 | return 1; | 350 | return 1; |
352 | } | 351 | } |
353 | } | 352 | } |
354 | #endif | 353 | #endif |
355 | 354 | ||
356 | /* Common user-space to kernel rule translation. */ | 355 | /* Common user-space to kernel rule translation. */ |
357 | static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule) | 356 | static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule) |
358 | { | 357 | { |
359 | unsigned listnr; | 358 | unsigned listnr; |
360 | struct audit_entry *entry; | 359 | struct audit_entry *entry; |
361 | int i, err; | 360 | int i, err; |
362 | 361 | ||
363 | err = -EINVAL; | 362 | err = -EINVAL; |
364 | listnr = rule->flags & ~AUDIT_FILTER_PREPEND; | 363 | listnr = rule->flags & ~AUDIT_FILTER_PREPEND; |
365 | switch(listnr) { | 364 | switch(listnr) { |
366 | default: | 365 | default: |
367 | goto exit_err; | 366 | goto exit_err; |
368 | case AUDIT_FILTER_USER: | 367 | case AUDIT_FILTER_USER: |
369 | case AUDIT_FILTER_TYPE: | 368 | case AUDIT_FILTER_TYPE: |
370 | #ifdef CONFIG_AUDITSYSCALL | 369 | #ifdef CONFIG_AUDITSYSCALL |
371 | case AUDIT_FILTER_ENTRY: | 370 | case AUDIT_FILTER_ENTRY: |
372 | case AUDIT_FILTER_EXIT: | 371 | case AUDIT_FILTER_EXIT: |
373 | case AUDIT_FILTER_TASK: | 372 | case AUDIT_FILTER_TASK: |
374 | #endif | 373 | #endif |
375 | ; | 374 | ; |
376 | } | 375 | } |
377 | if (unlikely(rule->action == AUDIT_POSSIBLE)) { | 376 | if (unlikely(rule->action == AUDIT_POSSIBLE)) { |
378 | printk(KERN_ERR "AUDIT_POSSIBLE is deprecated\n"); | 377 | printk(KERN_ERR "AUDIT_POSSIBLE is deprecated\n"); |
379 | goto exit_err; | 378 | goto exit_err; |
380 | } | 379 | } |
381 | if (rule->action != AUDIT_NEVER && rule->action != AUDIT_ALWAYS) | 380 | if (rule->action != AUDIT_NEVER && rule->action != AUDIT_ALWAYS) |
382 | goto exit_err; | 381 | goto exit_err; |
383 | if (rule->field_count > AUDIT_MAX_FIELDS) | 382 | if (rule->field_count > AUDIT_MAX_FIELDS) |
384 | goto exit_err; | 383 | goto exit_err; |
385 | 384 | ||
386 | err = -ENOMEM; | 385 | err = -ENOMEM; |
387 | entry = audit_init_entry(rule->field_count); | 386 | entry = audit_init_entry(rule->field_count); |
388 | if (!entry) | 387 | if (!entry) |
389 | goto exit_err; | 388 | goto exit_err; |
390 | 389 | ||
391 | entry->rule.flags = rule->flags & AUDIT_FILTER_PREPEND; | 390 | entry->rule.flags = rule->flags & AUDIT_FILTER_PREPEND; |
392 | entry->rule.listnr = listnr; | 391 | entry->rule.listnr = listnr; |
393 | entry->rule.action = rule->action; | 392 | entry->rule.action = rule->action; |
394 | entry->rule.field_count = rule->field_count; | 393 | entry->rule.field_count = rule->field_count; |
395 | 394 | ||
396 | for (i = 0; i < AUDIT_BITMASK_SIZE; i++) | 395 | for (i = 0; i < AUDIT_BITMASK_SIZE; i++) |
397 | entry->rule.mask[i] = rule->mask[i]; | 396 | entry->rule.mask[i] = rule->mask[i]; |
398 | 397 | ||
399 | for (i = 0; i < AUDIT_SYSCALL_CLASSES; i++) { | 398 | for (i = 0; i < AUDIT_SYSCALL_CLASSES; i++) { |
400 | int bit = AUDIT_BITMASK_SIZE * 32 - i - 1; | 399 | int bit = AUDIT_BITMASK_SIZE * 32 - i - 1; |
401 | __u32 *p = &entry->rule.mask[AUDIT_WORD(bit)]; | 400 | __u32 *p = &entry->rule.mask[AUDIT_WORD(bit)]; |
402 | __u32 *class; | 401 | __u32 *class; |
403 | 402 | ||
404 | if (!(*p & AUDIT_BIT(bit))) | 403 | if (!(*p & AUDIT_BIT(bit))) |
405 | continue; | 404 | continue; |
406 | *p &= ~AUDIT_BIT(bit); | 405 | *p &= ~AUDIT_BIT(bit); |
407 | class = classes[i]; | 406 | class = classes[i]; |
408 | if (class) { | 407 | if (class) { |
409 | int j; | 408 | int j; |
410 | for (j = 0; j < AUDIT_BITMASK_SIZE; j++) | 409 | for (j = 0; j < AUDIT_BITMASK_SIZE; j++) |
411 | entry->rule.mask[j] |= class[j]; | 410 | entry->rule.mask[j] |= class[j]; |
412 | } | 411 | } |
413 | } | 412 | } |
414 | 413 | ||
415 | return entry; | 414 | return entry; |
416 | 415 | ||
417 | exit_err: | 416 | exit_err: |
418 | return ERR_PTR(err); | 417 | return ERR_PTR(err); |
419 | } | 418 | } |
420 | 419 | ||
421 | /* Translate struct audit_rule to kernel's rule respresentation. | 420 | /* Translate struct audit_rule to kernel's rule respresentation. |
422 | * Exists for backward compatibility with userspace. */ | 421 | * Exists for backward compatibility with userspace. */ |
423 | static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule) | 422 | static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule) |
424 | { | 423 | { |
425 | struct audit_entry *entry; | 424 | struct audit_entry *entry; |
426 | struct audit_field *f; | 425 | struct audit_field *f; |
427 | int err = 0; | 426 | int err = 0; |
428 | int i; | 427 | int i; |
429 | 428 | ||
430 | entry = audit_to_entry_common(rule); | 429 | entry = audit_to_entry_common(rule); |
431 | if (IS_ERR(entry)) | 430 | if (IS_ERR(entry)) |
432 | goto exit_nofree; | 431 | goto exit_nofree; |
433 | 432 | ||
434 | for (i = 0; i < rule->field_count; i++) { | 433 | for (i = 0; i < rule->field_count; i++) { |
435 | struct audit_field *f = &entry->rule.fields[i]; | 434 | struct audit_field *f = &entry->rule.fields[i]; |
436 | 435 | ||
437 | f->op = rule->fields[i] & (AUDIT_NEGATE|AUDIT_OPERATORS); | 436 | f->op = rule->fields[i] & (AUDIT_NEGATE|AUDIT_OPERATORS); |
438 | f->type = rule->fields[i] & ~(AUDIT_NEGATE|AUDIT_OPERATORS); | 437 | f->type = rule->fields[i] & ~(AUDIT_NEGATE|AUDIT_OPERATORS); |
439 | f->val = rule->values[i]; | 438 | f->val = rule->values[i]; |
440 | 439 | ||
441 | err = -EINVAL; | 440 | err = -EINVAL; |
442 | switch(f->type) { | 441 | switch(f->type) { |
443 | default: | 442 | default: |
444 | goto exit_free; | 443 | goto exit_free; |
445 | case AUDIT_PID: | 444 | case AUDIT_PID: |
446 | case AUDIT_UID: | 445 | case AUDIT_UID: |
447 | case AUDIT_EUID: | 446 | case AUDIT_EUID: |
448 | case AUDIT_SUID: | 447 | case AUDIT_SUID: |
449 | case AUDIT_FSUID: | 448 | case AUDIT_FSUID: |
450 | case AUDIT_GID: | 449 | case AUDIT_GID: |
451 | case AUDIT_EGID: | 450 | case AUDIT_EGID: |
452 | case AUDIT_SGID: | 451 | case AUDIT_SGID: |
453 | case AUDIT_FSGID: | 452 | case AUDIT_FSGID: |
454 | case AUDIT_LOGINUID: | 453 | case AUDIT_LOGINUID: |
455 | case AUDIT_PERS: | 454 | case AUDIT_PERS: |
456 | case AUDIT_MSGTYPE: | 455 | case AUDIT_MSGTYPE: |
457 | case AUDIT_PPID: | 456 | case AUDIT_PPID: |
458 | case AUDIT_DEVMAJOR: | 457 | case AUDIT_DEVMAJOR: |
459 | case AUDIT_DEVMINOR: | 458 | case AUDIT_DEVMINOR: |
460 | case AUDIT_EXIT: | 459 | case AUDIT_EXIT: |
461 | case AUDIT_SUCCESS: | 460 | case AUDIT_SUCCESS: |
462 | /* bit ops are only useful on syscall args */ | 461 | /* bit ops are only useful on syscall args */ |
463 | if (f->op == AUDIT_BIT_MASK || | 462 | if (f->op == AUDIT_BIT_MASK || |
464 | f->op == AUDIT_BIT_TEST) { | 463 | f->op == AUDIT_BIT_TEST) { |
465 | err = -EINVAL; | 464 | err = -EINVAL; |
466 | goto exit_free; | 465 | goto exit_free; |
467 | } | 466 | } |
468 | break; | 467 | break; |
469 | case AUDIT_ARG0: | 468 | case AUDIT_ARG0: |
470 | case AUDIT_ARG1: | 469 | case AUDIT_ARG1: |
471 | case AUDIT_ARG2: | 470 | case AUDIT_ARG2: |
472 | case AUDIT_ARG3: | 471 | case AUDIT_ARG3: |
473 | break; | 472 | break; |
474 | /* arch is only allowed to be = or != */ | 473 | /* arch is only allowed to be = or != */ |
475 | case AUDIT_ARCH: | 474 | case AUDIT_ARCH: |
476 | if ((f->op != AUDIT_NOT_EQUAL) && (f->op != AUDIT_EQUAL) | 475 | if ((f->op != AUDIT_NOT_EQUAL) && (f->op != AUDIT_EQUAL) |
477 | && (f->op != AUDIT_NEGATE) && (f->op)) { | 476 | && (f->op != AUDIT_NEGATE) && (f->op)) { |
478 | err = -EINVAL; | 477 | err = -EINVAL; |
479 | goto exit_free; | 478 | goto exit_free; |
480 | } | 479 | } |
481 | entry->rule.arch_f = f; | 480 | entry->rule.arch_f = f; |
482 | break; | 481 | break; |
483 | case AUDIT_PERM: | 482 | case AUDIT_PERM: |
484 | if (f->val & ~15) | 483 | if (f->val & ~15) |
485 | goto exit_free; | 484 | goto exit_free; |
486 | break; | 485 | break; |
487 | case AUDIT_INODE: | 486 | case AUDIT_INODE: |
488 | err = audit_to_inode(&entry->rule, f); | 487 | err = audit_to_inode(&entry->rule, f); |
489 | if (err) | 488 | if (err) |
490 | goto exit_free; | 489 | goto exit_free; |
491 | break; | 490 | break; |
492 | } | 491 | } |
493 | 492 | ||
494 | entry->rule.vers_ops = (f->op & AUDIT_OPERATORS) ? 2 : 1; | 493 | entry->rule.vers_ops = (f->op & AUDIT_OPERATORS) ? 2 : 1; |
495 | 494 | ||
496 | /* Support for legacy operators where | 495 | /* Support for legacy operators where |
497 | * AUDIT_NEGATE bit signifies != and otherwise assumes == */ | 496 | * AUDIT_NEGATE bit signifies != and otherwise assumes == */ |
498 | if (f->op & AUDIT_NEGATE) | 497 | if (f->op & AUDIT_NEGATE) |
499 | f->op = AUDIT_NOT_EQUAL; | 498 | f->op = AUDIT_NOT_EQUAL; |
500 | else if (!f->op) | 499 | else if (!f->op) |
501 | f->op = AUDIT_EQUAL; | 500 | f->op = AUDIT_EQUAL; |
502 | else if (f->op == AUDIT_OPERATORS) { | 501 | else if (f->op == AUDIT_OPERATORS) { |
503 | err = -EINVAL; | 502 | err = -EINVAL; |
504 | goto exit_free; | 503 | goto exit_free; |
505 | } | 504 | } |
506 | } | 505 | } |
507 | 506 | ||
508 | f = entry->rule.inode_f; | 507 | f = entry->rule.inode_f; |
509 | if (f) { | 508 | if (f) { |
510 | switch(f->op) { | 509 | switch(f->op) { |
511 | case AUDIT_NOT_EQUAL: | 510 | case AUDIT_NOT_EQUAL: |
512 | entry->rule.inode_f = NULL; | 511 | entry->rule.inode_f = NULL; |
513 | case AUDIT_EQUAL: | 512 | case AUDIT_EQUAL: |
514 | break; | 513 | break; |
515 | default: | 514 | default: |
516 | err = -EINVAL; | 515 | err = -EINVAL; |
517 | goto exit_free; | 516 | goto exit_free; |
518 | } | 517 | } |
519 | } | 518 | } |
520 | 519 | ||
521 | exit_nofree: | 520 | exit_nofree: |
522 | return entry; | 521 | return entry; |
523 | 522 | ||
524 | exit_free: | 523 | exit_free: |
525 | audit_free_rule(entry); | 524 | audit_free_rule(entry); |
526 | return ERR_PTR(err); | 525 | return ERR_PTR(err); |
527 | } | 526 | } |
528 | 527 | ||
529 | /* Translate struct audit_rule_data to kernel's rule respresentation. */ | 528 | /* Translate struct audit_rule_data to kernel's rule respresentation. */ |
530 | static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, | 529 | static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, |
531 | size_t datasz) | 530 | size_t datasz) |
532 | { | 531 | { |
533 | int err = 0; | 532 | int err = 0; |
534 | struct audit_entry *entry; | 533 | struct audit_entry *entry; |
535 | struct audit_field *f; | 534 | struct audit_field *f; |
536 | void *bufp; | 535 | void *bufp; |
537 | size_t remain = datasz - sizeof(struct audit_rule_data); | 536 | size_t remain = datasz - sizeof(struct audit_rule_data); |
538 | int i; | 537 | int i; |
539 | char *str; | 538 | char *str; |
540 | 539 | ||
541 | entry = audit_to_entry_common((struct audit_rule *)data); | 540 | entry = audit_to_entry_common((struct audit_rule *)data); |
542 | if (IS_ERR(entry)) | 541 | if (IS_ERR(entry)) |
543 | goto exit_nofree; | 542 | goto exit_nofree; |
544 | 543 | ||
545 | bufp = data->buf; | 544 | bufp = data->buf; |
546 | entry->rule.vers_ops = 2; | 545 | entry->rule.vers_ops = 2; |
547 | for (i = 0; i < data->field_count; i++) { | 546 | for (i = 0; i < data->field_count; i++) { |
548 | struct audit_field *f = &entry->rule.fields[i]; | 547 | struct audit_field *f = &entry->rule.fields[i]; |
549 | 548 | ||
550 | err = -EINVAL; | 549 | err = -EINVAL; |
551 | if (!(data->fieldflags[i] & AUDIT_OPERATORS) || | 550 | if (!(data->fieldflags[i] & AUDIT_OPERATORS) || |
552 | data->fieldflags[i] & ~AUDIT_OPERATORS) | 551 | data->fieldflags[i] & ~AUDIT_OPERATORS) |
553 | goto exit_free; | 552 | goto exit_free; |
554 | 553 | ||
555 | f->op = data->fieldflags[i] & AUDIT_OPERATORS; | 554 | f->op = data->fieldflags[i] & AUDIT_OPERATORS; |
556 | f->type = data->fields[i]; | 555 | f->type = data->fields[i]; |
557 | f->val = data->values[i]; | 556 | f->val = data->values[i]; |
558 | f->se_str = NULL; | 557 | f->se_str = NULL; |
559 | f->se_rule = NULL; | 558 | f->se_rule = NULL; |
560 | switch(f->type) { | 559 | switch(f->type) { |
561 | case AUDIT_PID: | 560 | case AUDIT_PID: |
562 | case AUDIT_UID: | 561 | case AUDIT_UID: |
563 | case AUDIT_EUID: | 562 | case AUDIT_EUID: |
564 | case AUDIT_SUID: | 563 | case AUDIT_SUID: |
565 | case AUDIT_FSUID: | 564 | case AUDIT_FSUID: |
566 | case AUDIT_GID: | 565 | case AUDIT_GID: |
567 | case AUDIT_EGID: | 566 | case AUDIT_EGID: |
568 | case AUDIT_SGID: | 567 | case AUDIT_SGID: |
569 | case AUDIT_FSGID: | 568 | case AUDIT_FSGID: |
570 | case AUDIT_LOGINUID: | 569 | case AUDIT_LOGINUID: |
571 | case AUDIT_PERS: | 570 | case AUDIT_PERS: |
572 | case AUDIT_MSGTYPE: | 571 | case AUDIT_MSGTYPE: |
573 | case AUDIT_PPID: | 572 | case AUDIT_PPID: |
574 | case AUDIT_DEVMAJOR: | 573 | case AUDIT_DEVMAJOR: |
575 | case AUDIT_DEVMINOR: | 574 | case AUDIT_DEVMINOR: |
576 | case AUDIT_EXIT: | 575 | case AUDIT_EXIT: |
577 | case AUDIT_SUCCESS: | 576 | case AUDIT_SUCCESS: |
578 | case AUDIT_ARG0: | 577 | case AUDIT_ARG0: |
579 | case AUDIT_ARG1: | 578 | case AUDIT_ARG1: |
580 | case AUDIT_ARG2: | 579 | case AUDIT_ARG2: |
581 | case AUDIT_ARG3: | 580 | case AUDIT_ARG3: |
582 | break; | 581 | break; |
583 | case AUDIT_ARCH: | 582 | case AUDIT_ARCH: |
584 | entry->rule.arch_f = f; | 583 | entry->rule.arch_f = f; |
585 | break; | 584 | break; |
586 | case AUDIT_SUBJ_USER: | 585 | case AUDIT_SUBJ_USER: |
587 | case AUDIT_SUBJ_ROLE: | 586 | case AUDIT_SUBJ_ROLE: |
588 | case AUDIT_SUBJ_TYPE: | 587 | case AUDIT_SUBJ_TYPE: |
589 | case AUDIT_SUBJ_SEN: | 588 | case AUDIT_SUBJ_SEN: |
590 | case AUDIT_SUBJ_CLR: | 589 | case AUDIT_SUBJ_CLR: |
591 | case AUDIT_OBJ_USER: | 590 | case AUDIT_OBJ_USER: |
592 | case AUDIT_OBJ_ROLE: | 591 | case AUDIT_OBJ_ROLE: |
593 | case AUDIT_OBJ_TYPE: | 592 | case AUDIT_OBJ_TYPE: |
594 | case AUDIT_OBJ_LEV_LOW: | 593 | case AUDIT_OBJ_LEV_LOW: |
595 | case AUDIT_OBJ_LEV_HIGH: | 594 | case AUDIT_OBJ_LEV_HIGH: |
596 | str = audit_unpack_string(&bufp, &remain, f->val); | 595 | str = audit_unpack_string(&bufp, &remain, f->val); |
597 | if (IS_ERR(str)) | 596 | if (IS_ERR(str)) |
598 | goto exit_free; | 597 | goto exit_free; |
599 | entry->rule.buflen += f->val; | 598 | entry->rule.buflen += f->val; |
600 | 599 | ||
601 | err = selinux_audit_rule_init(f->type, f->op, str, | 600 | err = security_audit_rule_init(f->type, f->op, str, |
602 | &f->se_rule); | 601 | (void **)&f->se_rule); |
603 | /* Keep currently invalid fields around in case they | 602 | /* Keep currently invalid fields around in case they |
604 | * become valid after a policy reload. */ | 603 | * become valid after a policy reload. */ |
605 | if (err == -EINVAL) { | 604 | if (err == -EINVAL) { |
606 | printk(KERN_WARNING "audit rule for selinux " | 605 | printk(KERN_WARNING "audit rule for LSM " |
607 | "\'%s\' is invalid\n", str); | 606 | "\'%s\' is invalid\n", str); |
608 | err = 0; | 607 | err = 0; |
609 | } | 608 | } |
610 | if (err) { | 609 | if (err) { |
611 | kfree(str); | 610 | kfree(str); |
612 | goto exit_free; | 611 | goto exit_free; |
613 | } else | 612 | } else |
614 | f->se_str = str; | 613 | f->se_str = str; |
615 | break; | 614 | break; |
616 | case AUDIT_WATCH: | 615 | case AUDIT_WATCH: |
617 | str = audit_unpack_string(&bufp, &remain, f->val); | 616 | str = audit_unpack_string(&bufp, &remain, f->val); |
618 | if (IS_ERR(str)) | 617 | if (IS_ERR(str)) |
619 | goto exit_free; | 618 | goto exit_free; |
620 | entry->rule.buflen += f->val; | 619 | entry->rule.buflen += f->val; |
621 | 620 | ||
622 | err = audit_to_watch(&entry->rule, str, f->val, f->op); | 621 | err = audit_to_watch(&entry->rule, str, f->val, f->op); |
623 | if (err) { | 622 | if (err) { |
624 | kfree(str); | 623 | kfree(str); |
625 | goto exit_free; | 624 | goto exit_free; |
626 | } | 625 | } |
627 | break; | 626 | break; |
628 | case AUDIT_DIR: | 627 | case AUDIT_DIR: |
629 | str = audit_unpack_string(&bufp, &remain, f->val); | 628 | str = audit_unpack_string(&bufp, &remain, f->val); |
630 | if (IS_ERR(str)) | 629 | if (IS_ERR(str)) |
631 | goto exit_free; | 630 | goto exit_free; |
632 | entry->rule.buflen += f->val; | 631 | entry->rule.buflen += f->val; |
633 | 632 | ||
634 | err = audit_make_tree(&entry->rule, str, f->op); | 633 | err = audit_make_tree(&entry->rule, str, f->op); |
635 | kfree(str); | 634 | kfree(str); |
636 | if (err) | 635 | if (err) |
637 | goto exit_free; | 636 | goto exit_free; |
638 | break; | 637 | break; |
639 | case AUDIT_INODE: | 638 | case AUDIT_INODE: |
640 | err = audit_to_inode(&entry->rule, f); | 639 | err = audit_to_inode(&entry->rule, f); |
641 | if (err) | 640 | if (err) |
642 | goto exit_free; | 641 | goto exit_free; |
643 | break; | 642 | break; |
644 | case AUDIT_FILTERKEY: | 643 | case AUDIT_FILTERKEY: |
645 | err = -EINVAL; | 644 | err = -EINVAL; |
646 | if (entry->rule.filterkey || f->val > AUDIT_MAX_KEY_LEN) | 645 | if (entry->rule.filterkey || f->val > AUDIT_MAX_KEY_LEN) |
647 | goto exit_free; | 646 | goto exit_free; |
648 | str = audit_unpack_string(&bufp, &remain, f->val); | 647 | str = audit_unpack_string(&bufp, &remain, f->val); |
649 | if (IS_ERR(str)) | 648 | if (IS_ERR(str)) |
650 | goto exit_free; | 649 | goto exit_free; |
651 | entry->rule.buflen += f->val; | 650 | entry->rule.buflen += f->val; |
652 | entry->rule.filterkey = str; | 651 | entry->rule.filterkey = str; |
653 | break; | 652 | break; |
654 | case AUDIT_PERM: | 653 | case AUDIT_PERM: |
655 | if (f->val & ~15) | 654 | if (f->val & ~15) |
656 | goto exit_free; | 655 | goto exit_free; |
657 | break; | 656 | break; |
658 | default: | 657 | default: |
659 | goto exit_free; | 658 | goto exit_free; |
660 | } | 659 | } |
661 | } | 660 | } |
662 | 661 | ||
663 | f = entry->rule.inode_f; | 662 | f = entry->rule.inode_f; |
664 | if (f) { | 663 | if (f) { |
665 | switch(f->op) { | 664 | switch(f->op) { |
666 | case AUDIT_NOT_EQUAL: | 665 | case AUDIT_NOT_EQUAL: |
667 | entry->rule.inode_f = NULL; | 666 | entry->rule.inode_f = NULL; |
668 | case AUDIT_EQUAL: | 667 | case AUDIT_EQUAL: |
669 | break; | 668 | break; |
670 | default: | 669 | default: |
671 | err = -EINVAL; | 670 | err = -EINVAL; |
672 | goto exit_free; | 671 | goto exit_free; |
673 | } | 672 | } |
674 | } | 673 | } |
675 | 674 | ||
676 | exit_nofree: | 675 | exit_nofree: |
677 | return entry; | 676 | return entry; |
678 | 677 | ||
679 | exit_free: | 678 | exit_free: |
680 | audit_free_rule(entry); | 679 | audit_free_rule(entry); |
681 | return ERR_PTR(err); | 680 | return ERR_PTR(err); |
682 | } | 681 | } |
683 | 682 | ||
684 | /* Pack a filter field's string representation into data block. */ | 683 | /* Pack a filter field's string representation into data block. */ |
685 | static inline size_t audit_pack_string(void **bufp, const char *str) | 684 | static inline size_t audit_pack_string(void **bufp, const char *str) |
686 | { | 685 | { |
687 | size_t len = strlen(str); | 686 | size_t len = strlen(str); |
688 | 687 | ||
689 | memcpy(*bufp, str, len); | 688 | memcpy(*bufp, str, len); |
690 | *bufp += len; | 689 | *bufp += len; |
691 | 690 | ||
692 | return len; | 691 | return len; |
693 | } | 692 | } |
694 | 693 | ||
695 | /* Translate kernel rule respresentation to struct audit_rule. | 694 | /* Translate kernel rule respresentation to struct audit_rule. |
696 | * Exists for backward compatibility with userspace. */ | 695 | * Exists for backward compatibility with userspace. */ |
697 | static struct audit_rule *audit_krule_to_rule(struct audit_krule *krule) | 696 | static struct audit_rule *audit_krule_to_rule(struct audit_krule *krule) |
698 | { | 697 | { |
699 | struct audit_rule *rule; | 698 | struct audit_rule *rule; |
700 | int i; | 699 | int i; |
701 | 700 | ||
702 | rule = kzalloc(sizeof(*rule), GFP_KERNEL); | 701 | rule = kzalloc(sizeof(*rule), GFP_KERNEL); |
703 | if (unlikely(!rule)) | 702 | if (unlikely(!rule)) |
704 | return NULL; | 703 | return NULL; |
705 | 704 | ||
706 | rule->flags = krule->flags | krule->listnr; | 705 | rule->flags = krule->flags | krule->listnr; |
707 | rule->action = krule->action; | 706 | rule->action = krule->action; |
708 | rule->field_count = krule->field_count; | 707 | rule->field_count = krule->field_count; |
709 | for (i = 0; i < rule->field_count; i++) { | 708 | for (i = 0; i < rule->field_count; i++) { |
710 | rule->values[i] = krule->fields[i].val; | 709 | rule->values[i] = krule->fields[i].val; |
711 | rule->fields[i] = krule->fields[i].type; | 710 | rule->fields[i] = krule->fields[i].type; |
712 | 711 | ||
713 | if (krule->vers_ops == 1) { | 712 | if (krule->vers_ops == 1) { |
714 | if (krule->fields[i].op & AUDIT_NOT_EQUAL) | 713 | if (krule->fields[i].op & AUDIT_NOT_EQUAL) |
715 | rule->fields[i] |= AUDIT_NEGATE; | 714 | rule->fields[i] |= AUDIT_NEGATE; |
716 | } else { | 715 | } else { |
717 | rule->fields[i] |= krule->fields[i].op; | 716 | rule->fields[i] |= krule->fields[i].op; |
718 | } | 717 | } |
719 | } | 718 | } |
720 | for (i = 0; i < AUDIT_BITMASK_SIZE; i++) rule->mask[i] = krule->mask[i]; | 719 | for (i = 0; i < AUDIT_BITMASK_SIZE; i++) rule->mask[i] = krule->mask[i]; |
721 | 720 | ||
722 | return rule; | 721 | return rule; |
723 | } | 722 | } |
724 | 723 | ||
725 | /* Translate kernel rule respresentation to struct audit_rule_data. */ | 724 | /* Translate kernel rule respresentation to struct audit_rule_data. */ |
726 | static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule) | 725 | static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule) |
727 | { | 726 | { |
728 | struct audit_rule_data *data; | 727 | struct audit_rule_data *data; |
729 | void *bufp; | 728 | void *bufp; |
730 | int i; | 729 | int i; |
731 | 730 | ||
732 | data = kmalloc(sizeof(*data) + krule->buflen, GFP_KERNEL); | 731 | data = kmalloc(sizeof(*data) + krule->buflen, GFP_KERNEL); |
733 | if (unlikely(!data)) | 732 | if (unlikely(!data)) |
734 | return NULL; | 733 | return NULL; |
735 | memset(data, 0, sizeof(*data)); | 734 | memset(data, 0, sizeof(*data)); |
736 | 735 | ||
737 | data->flags = krule->flags | krule->listnr; | 736 | data->flags = krule->flags | krule->listnr; |
738 | data->action = krule->action; | 737 | data->action = krule->action; |
739 | data->field_count = krule->field_count; | 738 | data->field_count = krule->field_count; |
740 | bufp = data->buf; | 739 | bufp = data->buf; |
741 | for (i = 0; i < data->field_count; i++) { | 740 | for (i = 0; i < data->field_count; i++) { |
742 | struct audit_field *f = &krule->fields[i]; | 741 | struct audit_field *f = &krule->fields[i]; |
743 | 742 | ||
744 | data->fields[i] = f->type; | 743 | data->fields[i] = f->type; |
745 | data->fieldflags[i] = f->op; | 744 | data->fieldflags[i] = f->op; |
746 | switch(f->type) { | 745 | switch(f->type) { |
747 | case AUDIT_SUBJ_USER: | 746 | case AUDIT_SUBJ_USER: |
748 | case AUDIT_SUBJ_ROLE: | 747 | case AUDIT_SUBJ_ROLE: |
749 | case AUDIT_SUBJ_TYPE: | 748 | case AUDIT_SUBJ_TYPE: |
750 | case AUDIT_SUBJ_SEN: | 749 | case AUDIT_SUBJ_SEN: |
751 | case AUDIT_SUBJ_CLR: | 750 | case AUDIT_SUBJ_CLR: |
752 | case AUDIT_OBJ_USER: | 751 | case AUDIT_OBJ_USER: |
753 | case AUDIT_OBJ_ROLE: | 752 | case AUDIT_OBJ_ROLE: |
754 | case AUDIT_OBJ_TYPE: | 753 | case AUDIT_OBJ_TYPE: |
755 | case AUDIT_OBJ_LEV_LOW: | 754 | case AUDIT_OBJ_LEV_LOW: |
756 | case AUDIT_OBJ_LEV_HIGH: | 755 | case AUDIT_OBJ_LEV_HIGH: |
757 | data->buflen += data->values[i] = | 756 | data->buflen += data->values[i] = |
758 | audit_pack_string(&bufp, f->se_str); | 757 | audit_pack_string(&bufp, f->se_str); |
759 | break; | 758 | break; |
760 | case AUDIT_WATCH: | 759 | case AUDIT_WATCH: |
761 | data->buflen += data->values[i] = | 760 | data->buflen += data->values[i] = |
762 | audit_pack_string(&bufp, krule->watch->path); | 761 | audit_pack_string(&bufp, krule->watch->path); |
763 | break; | 762 | break; |
764 | case AUDIT_DIR: | 763 | case AUDIT_DIR: |
765 | data->buflen += data->values[i] = | 764 | data->buflen += data->values[i] = |
766 | audit_pack_string(&bufp, | 765 | audit_pack_string(&bufp, |
767 | audit_tree_path(krule->tree)); | 766 | audit_tree_path(krule->tree)); |
768 | break; | 767 | break; |
769 | case AUDIT_FILTERKEY: | 768 | case AUDIT_FILTERKEY: |
770 | data->buflen += data->values[i] = | 769 | data->buflen += data->values[i] = |
771 | audit_pack_string(&bufp, krule->filterkey); | 770 | audit_pack_string(&bufp, krule->filterkey); |
772 | break; | 771 | break; |
773 | default: | 772 | default: |
774 | data->values[i] = f->val; | 773 | data->values[i] = f->val; |
775 | } | 774 | } |
776 | } | 775 | } |
777 | for (i = 0; i < AUDIT_BITMASK_SIZE; i++) data->mask[i] = krule->mask[i]; | 776 | for (i = 0; i < AUDIT_BITMASK_SIZE; i++) data->mask[i] = krule->mask[i]; |
778 | 777 | ||
779 | return data; | 778 | return data; |
780 | } | 779 | } |
781 | 780 | ||
782 | /* Compare two rules in kernel format. Considered success if rules | 781 | /* Compare two rules in kernel format. Considered success if rules |
783 | * don't match. */ | 782 | * don't match. */ |
784 | static int audit_compare_rule(struct audit_krule *a, struct audit_krule *b) | 783 | static int audit_compare_rule(struct audit_krule *a, struct audit_krule *b) |
785 | { | 784 | { |
786 | int i; | 785 | int i; |
787 | 786 | ||
788 | if (a->flags != b->flags || | 787 | if (a->flags != b->flags || |
789 | a->listnr != b->listnr || | 788 | a->listnr != b->listnr || |
790 | a->action != b->action || | 789 | a->action != b->action || |
791 | a->field_count != b->field_count) | 790 | a->field_count != b->field_count) |
792 | return 1; | 791 | return 1; |
793 | 792 | ||
794 | for (i = 0; i < a->field_count; i++) { | 793 | for (i = 0; i < a->field_count; i++) { |
795 | if (a->fields[i].type != b->fields[i].type || | 794 | if (a->fields[i].type != b->fields[i].type || |
796 | a->fields[i].op != b->fields[i].op) | 795 | a->fields[i].op != b->fields[i].op) |
797 | return 1; | 796 | return 1; |
798 | 797 | ||
799 | switch(a->fields[i].type) { | 798 | switch(a->fields[i].type) { |
800 | case AUDIT_SUBJ_USER: | 799 | case AUDIT_SUBJ_USER: |
801 | case AUDIT_SUBJ_ROLE: | 800 | case AUDIT_SUBJ_ROLE: |
802 | case AUDIT_SUBJ_TYPE: | 801 | case AUDIT_SUBJ_TYPE: |
803 | case AUDIT_SUBJ_SEN: | 802 | case AUDIT_SUBJ_SEN: |
804 | case AUDIT_SUBJ_CLR: | 803 | case AUDIT_SUBJ_CLR: |
805 | case AUDIT_OBJ_USER: | 804 | case AUDIT_OBJ_USER: |
806 | case AUDIT_OBJ_ROLE: | 805 | case AUDIT_OBJ_ROLE: |
807 | case AUDIT_OBJ_TYPE: | 806 | case AUDIT_OBJ_TYPE: |
808 | case AUDIT_OBJ_LEV_LOW: | 807 | case AUDIT_OBJ_LEV_LOW: |
809 | case AUDIT_OBJ_LEV_HIGH: | 808 | case AUDIT_OBJ_LEV_HIGH: |
810 | if (strcmp(a->fields[i].se_str, b->fields[i].se_str)) | 809 | if (strcmp(a->fields[i].se_str, b->fields[i].se_str)) |
811 | return 1; | 810 | return 1; |
812 | break; | 811 | break; |
813 | case AUDIT_WATCH: | 812 | case AUDIT_WATCH: |
814 | if (strcmp(a->watch->path, b->watch->path)) | 813 | if (strcmp(a->watch->path, b->watch->path)) |
815 | return 1; | 814 | return 1; |
816 | break; | 815 | break; |
817 | case AUDIT_DIR: | 816 | case AUDIT_DIR: |
818 | if (strcmp(audit_tree_path(a->tree), | 817 | if (strcmp(audit_tree_path(a->tree), |
819 | audit_tree_path(b->tree))) | 818 | audit_tree_path(b->tree))) |
820 | return 1; | 819 | return 1; |
821 | break; | 820 | break; |
822 | case AUDIT_FILTERKEY: | 821 | case AUDIT_FILTERKEY: |
823 | /* both filterkeys exist based on above type compare */ | 822 | /* both filterkeys exist based on above type compare */ |
824 | if (strcmp(a->filterkey, b->filterkey)) | 823 | if (strcmp(a->filterkey, b->filterkey)) |
825 | return 1; | 824 | return 1; |
826 | break; | 825 | break; |
827 | default: | 826 | default: |
828 | if (a->fields[i].val != b->fields[i].val) | 827 | if (a->fields[i].val != b->fields[i].val) |
829 | return 1; | 828 | return 1; |
830 | } | 829 | } |
831 | } | 830 | } |
832 | 831 | ||
833 | for (i = 0; i < AUDIT_BITMASK_SIZE; i++) | 832 | for (i = 0; i < AUDIT_BITMASK_SIZE; i++) |
834 | if (a->mask[i] != b->mask[i]) | 833 | if (a->mask[i] != b->mask[i]) |
835 | return 1; | 834 | return 1; |
836 | 835 | ||
837 | return 0; | 836 | return 0; |
838 | } | 837 | } |
839 | 838 | ||
840 | /* Duplicate the given audit watch. The new watch's rules list is initialized | 839 | /* Duplicate the given audit watch. The new watch's rules list is initialized |
841 | * to an empty list and wlist is undefined. */ | 840 | * to an empty list and wlist is undefined. */ |
842 | static struct audit_watch *audit_dupe_watch(struct audit_watch *old) | 841 | static struct audit_watch *audit_dupe_watch(struct audit_watch *old) |
843 | { | 842 | { |
844 | char *path; | 843 | char *path; |
845 | struct audit_watch *new; | 844 | struct audit_watch *new; |
846 | 845 | ||
847 | path = kstrdup(old->path, GFP_KERNEL); | 846 | path = kstrdup(old->path, GFP_KERNEL); |
848 | if (unlikely(!path)) | 847 | if (unlikely(!path)) |
849 | return ERR_PTR(-ENOMEM); | 848 | return ERR_PTR(-ENOMEM); |
850 | 849 | ||
851 | new = audit_init_watch(path); | 850 | new = audit_init_watch(path); |
852 | if (unlikely(IS_ERR(new))) { | 851 | if (unlikely(IS_ERR(new))) { |
853 | kfree(path); | 852 | kfree(path); |
854 | goto out; | 853 | goto out; |
855 | } | 854 | } |
856 | 855 | ||
857 | new->dev = old->dev; | 856 | new->dev = old->dev; |
858 | new->ino = old->ino; | 857 | new->ino = old->ino; |
859 | get_inotify_watch(&old->parent->wdata); | 858 | get_inotify_watch(&old->parent->wdata); |
860 | new->parent = old->parent; | 859 | new->parent = old->parent; |
861 | 860 | ||
862 | out: | 861 | out: |
863 | return new; | 862 | return new; |
864 | } | 863 | } |
865 | 864 | ||
866 | /* Duplicate selinux field information. The se_rule is opaque, so must be | 865 | /* Duplicate LSM field information. The se_rule is opaque, so must be |
867 | * re-initialized. */ | 866 | * re-initialized. */ |
868 | static inline int audit_dupe_selinux_field(struct audit_field *df, | 867 | static inline int audit_dupe_lsm_field(struct audit_field *df, |
869 | struct audit_field *sf) | 868 | struct audit_field *sf) |
870 | { | 869 | { |
871 | int ret = 0; | 870 | int ret = 0; |
872 | char *se_str; | 871 | char *se_str; |
873 | 872 | ||
874 | /* our own copy of se_str */ | 873 | /* our own copy of se_str */ |
875 | se_str = kstrdup(sf->se_str, GFP_KERNEL); | 874 | se_str = kstrdup(sf->se_str, GFP_KERNEL); |
876 | if (unlikely(!se_str)) | 875 | if (unlikely(!se_str)) |
877 | return -ENOMEM; | 876 | return -ENOMEM; |
878 | df->se_str = se_str; | 877 | df->se_str = se_str; |
879 | 878 | ||
880 | /* our own (refreshed) copy of se_rule */ | 879 | /* our own (refreshed) copy of se_rule */ |
881 | ret = selinux_audit_rule_init(df->type, df->op, df->se_str, | 880 | ret = security_audit_rule_init(df->type, df->op, df->se_str, |
882 | &df->se_rule); | 881 | (void **)&df->se_rule); |
883 | /* Keep currently invalid fields around in case they | 882 | /* Keep currently invalid fields around in case they |
884 | * become valid after a policy reload. */ | 883 | * become valid after a policy reload. */ |
885 | if (ret == -EINVAL) { | 884 | if (ret == -EINVAL) { |
886 | printk(KERN_WARNING "audit rule for selinux \'%s\' is " | 885 | printk(KERN_WARNING "audit rule for LSM \'%s\' is " |
887 | "invalid\n", df->se_str); | 886 | "invalid\n", df->se_str); |
888 | ret = 0; | 887 | ret = 0; |
889 | } | 888 | } |
890 | 889 | ||
891 | return ret; | 890 | return ret; |
892 | } | 891 | } |
893 | 892 | ||
894 | /* Duplicate an audit rule. This will be a deep copy with the exception | 893 | /* Duplicate an audit rule. This will be a deep copy with the exception |
895 | * of the watch - that pointer is carried over. The selinux specific fields | 894 | * of the watch - that pointer is carried over. The LSM specific fields |
896 | * will be updated in the copy. The point is to be able to replace the old | 895 | * will be updated in the copy. The point is to be able to replace the old |
897 | * rule with the new rule in the filterlist, then free the old rule. | 896 | * rule with the new rule in the filterlist, then free the old rule. |
898 | * The rlist element is undefined; list manipulations are handled apart from | 897 | * The rlist element is undefined; list manipulations are handled apart from |
899 | * the initial copy. */ | 898 | * the initial copy. */ |
900 | static struct audit_entry *audit_dupe_rule(struct audit_krule *old, | 899 | static struct audit_entry *audit_dupe_rule(struct audit_krule *old, |
901 | struct audit_watch *watch) | 900 | struct audit_watch *watch) |
902 | { | 901 | { |
903 | u32 fcount = old->field_count; | 902 | u32 fcount = old->field_count; |
904 | struct audit_entry *entry; | 903 | struct audit_entry *entry; |
905 | struct audit_krule *new; | 904 | struct audit_krule *new; |
906 | char *fk; | 905 | char *fk; |
907 | int i, err = 0; | 906 | int i, err = 0; |
908 | 907 | ||
909 | entry = audit_init_entry(fcount); | 908 | entry = audit_init_entry(fcount); |
910 | if (unlikely(!entry)) | 909 | if (unlikely(!entry)) |
911 | return ERR_PTR(-ENOMEM); | 910 | return ERR_PTR(-ENOMEM); |
912 | 911 | ||
913 | new = &entry->rule; | 912 | new = &entry->rule; |
914 | new->vers_ops = old->vers_ops; | 913 | new->vers_ops = old->vers_ops; |
915 | new->flags = old->flags; | 914 | new->flags = old->flags; |
916 | new->listnr = old->listnr; | 915 | new->listnr = old->listnr; |
917 | new->action = old->action; | 916 | new->action = old->action; |
918 | for (i = 0; i < AUDIT_BITMASK_SIZE; i++) | 917 | for (i = 0; i < AUDIT_BITMASK_SIZE; i++) |
919 | new->mask[i] = old->mask[i]; | 918 | new->mask[i] = old->mask[i]; |
920 | new->buflen = old->buflen; | 919 | new->buflen = old->buflen; |
921 | new->inode_f = old->inode_f; | 920 | new->inode_f = old->inode_f; |
922 | new->watch = NULL; | 921 | new->watch = NULL; |
923 | new->field_count = old->field_count; | 922 | new->field_count = old->field_count; |
924 | /* | 923 | /* |
925 | * note that we are OK with not refcounting here; audit_match_tree() | 924 | * note that we are OK with not refcounting here; audit_match_tree() |
926 | * never dereferences tree and we can't get false positives there | 925 | * never dereferences tree and we can't get false positives there |
927 | * since we'd have to have rule gone from the list *and* removed | 926 | * since we'd have to have rule gone from the list *and* removed |
928 | * before the chunks found by lookup had been allocated, i.e. before | 927 | * before the chunks found by lookup had been allocated, i.e. before |
929 | * the beginning of list scan. | 928 | * the beginning of list scan. |
930 | */ | 929 | */ |
931 | new->tree = old->tree; | 930 | new->tree = old->tree; |
932 | memcpy(new->fields, old->fields, sizeof(struct audit_field) * fcount); | 931 | memcpy(new->fields, old->fields, sizeof(struct audit_field) * fcount); |
933 | 932 | ||
934 | /* deep copy this information, updating the se_rule fields, because | 933 | /* deep copy this information, updating the se_rule fields, because |
935 | * the originals will all be freed when the old rule is freed. */ | 934 | * the originals will all be freed when the old rule is freed. */ |
936 | for (i = 0; i < fcount; i++) { | 935 | for (i = 0; i < fcount; i++) { |
937 | switch (new->fields[i].type) { | 936 | switch (new->fields[i].type) { |
938 | case AUDIT_SUBJ_USER: | 937 | case AUDIT_SUBJ_USER: |
939 | case AUDIT_SUBJ_ROLE: | 938 | case AUDIT_SUBJ_ROLE: |
940 | case AUDIT_SUBJ_TYPE: | 939 | case AUDIT_SUBJ_TYPE: |
941 | case AUDIT_SUBJ_SEN: | 940 | case AUDIT_SUBJ_SEN: |
942 | case AUDIT_SUBJ_CLR: | 941 | case AUDIT_SUBJ_CLR: |
943 | case AUDIT_OBJ_USER: | 942 | case AUDIT_OBJ_USER: |
944 | case AUDIT_OBJ_ROLE: | 943 | case AUDIT_OBJ_ROLE: |
945 | case AUDIT_OBJ_TYPE: | 944 | case AUDIT_OBJ_TYPE: |
946 | case AUDIT_OBJ_LEV_LOW: | 945 | case AUDIT_OBJ_LEV_LOW: |
947 | case AUDIT_OBJ_LEV_HIGH: | 946 | case AUDIT_OBJ_LEV_HIGH: |
948 | err = audit_dupe_selinux_field(&new->fields[i], | 947 | err = audit_dupe_lsm_field(&new->fields[i], |
949 | &old->fields[i]); | 948 | &old->fields[i]); |
950 | break; | 949 | break; |
951 | case AUDIT_FILTERKEY: | 950 | case AUDIT_FILTERKEY: |
952 | fk = kstrdup(old->filterkey, GFP_KERNEL); | 951 | fk = kstrdup(old->filterkey, GFP_KERNEL); |
953 | if (unlikely(!fk)) | 952 | if (unlikely(!fk)) |
954 | err = -ENOMEM; | 953 | err = -ENOMEM; |
955 | else | 954 | else |
956 | new->filterkey = fk; | 955 | new->filterkey = fk; |
957 | } | 956 | } |
958 | if (err) { | 957 | if (err) { |
959 | audit_free_rule(entry); | 958 | audit_free_rule(entry); |
960 | return ERR_PTR(err); | 959 | return ERR_PTR(err); |
961 | } | 960 | } |
962 | } | 961 | } |
963 | 962 | ||
964 | if (watch) { | 963 | if (watch) { |
965 | audit_get_watch(watch); | 964 | audit_get_watch(watch); |
966 | new->watch = watch; | 965 | new->watch = watch; |
967 | } | 966 | } |
968 | 967 | ||
969 | return entry; | 968 | return entry; |
970 | } | 969 | } |
971 | 970 | ||
972 | /* Update inode info in audit rules based on filesystem event. */ | 971 | /* Update inode info in audit rules based on filesystem event. */ |
973 | static void audit_update_watch(struct audit_parent *parent, | 972 | static void audit_update_watch(struct audit_parent *parent, |
974 | const char *dname, dev_t dev, | 973 | const char *dname, dev_t dev, |
975 | unsigned long ino, unsigned invalidating) | 974 | unsigned long ino, unsigned invalidating) |
976 | { | 975 | { |
977 | struct audit_watch *owatch, *nwatch, *nextw; | 976 | struct audit_watch *owatch, *nwatch, *nextw; |
978 | struct audit_krule *r, *nextr; | 977 | struct audit_krule *r, *nextr; |
979 | struct audit_entry *oentry, *nentry; | 978 | struct audit_entry *oentry, *nentry; |
980 | 979 | ||
981 | mutex_lock(&audit_filter_mutex); | 980 | mutex_lock(&audit_filter_mutex); |
982 | list_for_each_entry_safe(owatch, nextw, &parent->watches, wlist) { | 981 | list_for_each_entry_safe(owatch, nextw, &parent->watches, wlist) { |
983 | if (audit_compare_dname_path(dname, owatch->path, NULL)) | 982 | if (audit_compare_dname_path(dname, owatch->path, NULL)) |
984 | continue; | 983 | continue; |
985 | 984 | ||
986 | /* If the update involves invalidating rules, do the inode-based | 985 | /* If the update involves invalidating rules, do the inode-based |
987 | * filtering now, so we don't omit records. */ | 986 | * filtering now, so we don't omit records. */ |
988 | if (invalidating && current->audit_context && | 987 | if (invalidating && current->audit_context && |
989 | audit_filter_inodes(current, current->audit_context) == AUDIT_RECORD_CONTEXT) | 988 | audit_filter_inodes(current, current->audit_context) == AUDIT_RECORD_CONTEXT) |
990 | audit_set_auditable(current->audit_context); | 989 | audit_set_auditable(current->audit_context); |
991 | 990 | ||
992 | nwatch = audit_dupe_watch(owatch); | 991 | nwatch = audit_dupe_watch(owatch); |
993 | if (unlikely(IS_ERR(nwatch))) { | 992 | if (unlikely(IS_ERR(nwatch))) { |
994 | mutex_unlock(&audit_filter_mutex); | 993 | mutex_unlock(&audit_filter_mutex); |
995 | audit_panic("error updating watch, skipping"); | 994 | audit_panic("error updating watch, skipping"); |
996 | return; | 995 | return; |
997 | } | 996 | } |
998 | nwatch->dev = dev; | 997 | nwatch->dev = dev; |
999 | nwatch->ino = ino; | 998 | nwatch->ino = ino; |
1000 | 999 | ||
1001 | list_for_each_entry_safe(r, nextr, &owatch->rules, rlist) { | 1000 | list_for_each_entry_safe(r, nextr, &owatch->rules, rlist) { |
1002 | 1001 | ||
1003 | oentry = container_of(r, struct audit_entry, rule); | 1002 | oentry = container_of(r, struct audit_entry, rule); |
1004 | list_del(&oentry->rule.rlist); | 1003 | list_del(&oentry->rule.rlist); |
1005 | list_del_rcu(&oentry->list); | 1004 | list_del_rcu(&oentry->list); |
1006 | 1005 | ||
1007 | nentry = audit_dupe_rule(&oentry->rule, nwatch); | 1006 | nentry = audit_dupe_rule(&oentry->rule, nwatch); |
1008 | if (unlikely(IS_ERR(nentry))) | 1007 | if (unlikely(IS_ERR(nentry))) |
1009 | audit_panic("error updating watch, removing"); | 1008 | audit_panic("error updating watch, removing"); |
1010 | else { | 1009 | else { |
1011 | int h = audit_hash_ino((u32)ino); | 1010 | int h = audit_hash_ino((u32)ino); |
1012 | list_add(&nentry->rule.rlist, &nwatch->rules); | 1011 | list_add(&nentry->rule.rlist, &nwatch->rules); |
1013 | list_add_rcu(&nentry->list, &audit_inode_hash[h]); | 1012 | list_add_rcu(&nentry->list, &audit_inode_hash[h]); |
1014 | } | 1013 | } |
1015 | 1014 | ||
1016 | call_rcu(&oentry->rcu, audit_free_rule_rcu); | 1015 | call_rcu(&oentry->rcu, audit_free_rule_rcu); |
1017 | } | 1016 | } |
1018 | 1017 | ||
1019 | if (audit_enabled) { | 1018 | if (audit_enabled) { |
1020 | struct audit_buffer *ab; | 1019 | struct audit_buffer *ab; |
1021 | ab = audit_log_start(NULL, GFP_KERNEL, | 1020 | ab = audit_log_start(NULL, GFP_KERNEL, |
1022 | AUDIT_CONFIG_CHANGE); | 1021 | AUDIT_CONFIG_CHANGE); |
1023 | audit_log_format(ab, | 1022 | audit_log_format(ab, |
1024 | "op=updated rules specifying path="); | 1023 | "op=updated rules specifying path="); |
1025 | audit_log_untrustedstring(ab, owatch->path); | 1024 | audit_log_untrustedstring(ab, owatch->path); |
1026 | audit_log_format(ab, " with dev=%u ino=%lu\n", | 1025 | audit_log_format(ab, " with dev=%u ino=%lu\n", |
1027 | dev, ino); | 1026 | dev, ino); |
1028 | audit_log_format(ab, " list=%d res=1", r->listnr); | 1027 | audit_log_format(ab, " list=%d res=1", r->listnr); |
1029 | audit_log_end(ab); | 1028 | audit_log_end(ab); |
1030 | } | 1029 | } |
1031 | audit_remove_watch(owatch); | 1030 | audit_remove_watch(owatch); |
1032 | goto add_watch_to_parent; /* event applies to a single watch */ | 1031 | goto add_watch_to_parent; /* event applies to a single watch */ |
1033 | } | 1032 | } |
1034 | mutex_unlock(&audit_filter_mutex); | 1033 | mutex_unlock(&audit_filter_mutex); |
1035 | return; | 1034 | return; |
1036 | 1035 | ||
1037 | add_watch_to_parent: | 1036 | add_watch_to_parent: |
1038 | list_add(&nwatch->wlist, &parent->watches); | 1037 | list_add(&nwatch->wlist, &parent->watches); |
1039 | mutex_unlock(&audit_filter_mutex); | 1038 | mutex_unlock(&audit_filter_mutex); |
1040 | return; | 1039 | return; |
1041 | } | 1040 | } |
1042 | 1041 | ||
1043 | /* Remove all watches & rules associated with a parent that is going away. */ | 1042 | /* Remove all watches & rules associated with a parent that is going away. */ |
1044 | static void audit_remove_parent_watches(struct audit_parent *parent) | 1043 | static void audit_remove_parent_watches(struct audit_parent *parent) |
1045 | { | 1044 | { |
1046 | struct audit_watch *w, *nextw; | 1045 | struct audit_watch *w, *nextw; |
1047 | struct audit_krule *r, *nextr; | 1046 | struct audit_krule *r, *nextr; |
1048 | struct audit_entry *e; | 1047 | struct audit_entry *e; |
1049 | 1048 | ||
1050 | mutex_lock(&audit_filter_mutex); | 1049 | mutex_lock(&audit_filter_mutex); |
1051 | parent->flags |= AUDIT_PARENT_INVALID; | 1050 | parent->flags |= AUDIT_PARENT_INVALID; |
1052 | list_for_each_entry_safe(w, nextw, &parent->watches, wlist) { | 1051 | list_for_each_entry_safe(w, nextw, &parent->watches, wlist) { |
1053 | list_for_each_entry_safe(r, nextr, &w->rules, rlist) { | 1052 | list_for_each_entry_safe(r, nextr, &w->rules, rlist) { |
1054 | e = container_of(r, struct audit_entry, rule); | 1053 | e = container_of(r, struct audit_entry, rule); |
1055 | if (audit_enabled) { | 1054 | if (audit_enabled) { |
1056 | struct audit_buffer *ab; | 1055 | struct audit_buffer *ab; |
1057 | ab = audit_log_start(NULL, GFP_KERNEL, | 1056 | ab = audit_log_start(NULL, GFP_KERNEL, |
1058 | AUDIT_CONFIG_CHANGE); | 1057 | AUDIT_CONFIG_CHANGE); |
1059 | audit_log_format(ab, "op=remove rule path="); | 1058 | audit_log_format(ab, "op=remove rule path="); |
1060 | audit_log_untrustedstring(ab, w->path); | 1059 | audit_log_untrustedstring(ab, w->path); |
1061 | if (r->filterkey) { | 1060 | if (r->filterkey) { |
1062 | audit_log_format(ab, " key="); | 1061 | audit_log_format(ab, " key="); |
1063 | audit_log_untrustedstring(ab, | 1062 | audit_log_untrustedstring(ab, |
1064 | r->filterkey); | 1063 | r->filterkey); |
1065 | } else | 1064 | } else |
1066 | audit_log_format(ab, " key=(null)"); | 1065 | audit_log_format(ab, " key=(null)"); |
1067 | audit_log_format(ab, " list=%d res=1", | 1066 | audit_log_format(ab, " list=%d res=1", |
1068 | r->listnr); | 1067 | r->listnr); |
1069 | audit_log_end(ab); | 1068 | audit_log_end(ab); |
1070 | } | 1069 | } |
1071 | list_del(&r->rlist); | 1070 | list_del(&r->rlist); |
1072 | list_del_rcu(&e->list); | 1071 | list_del_rcu(&e->list); |
1073 | call_rcu(&e->rcu, audit_free_rule_rcu); | 1072 | call_rcu(&e->rcu, audit_free_rule_rcu); |
1074 | } | 1073 | } |
1075 | audit_remove_watch(w); | 1074 | audit_remove_watch(w); |
1076 | } | 1075 | } |
1077 | mutex_unlock(&audit_filter_mutex); | 1076 | mutex_unlock(&audit_filter_mutex); |
1078 | } | 1077 | } |
1079 | 1078 | ||
1080 | /* Unregister inotify watches for parents on in_list. | 1079 | /* Unregister inotify watches for parents on in_list. |
1081 | * Generates an IN_IGNORED event. */ | 1080 | * Generates an IN_IGNORED event. */ |
1082 | static void audit_inotify_unregister(struct list_head *in_list) | 1081 | static void audit_inotify_unregister(struct list_head *in_list) |
1083 | { | 1082 | { |
1084 | struct audit_parent *p, *n; | 1083 | struct audit_parent *p, *n; |
1085 | 1084 | ||
1086 | list_for_each_entry_safe(p, n, in_list, ilist) { | 1085 | list_for_each_entry_safe(p, n, in_list, ilist) { |
1087 | list_del(&p->ilist); | 1086 | list_del(&p->ilist); |
1088 | inotify_rm_watch(audit_ih, &p->wdata); | 1087 | inotify_rm_watch(audit_ih, &p->wdata); |
1089 | /* the put matching the get in audit_do_del_rule() */ | 1088 | /* the put matching the get in audit_do_del_rule() */ |
1090 | put_inotify_watch(&p->wdata); | 1089 | put_inotify_watch(&p->wdata); |
1091 | } | 1090 | } |
1092 | } | 1091 | } |
1093 | 1092 | ||
1094 | /* Find an existing audit rule. | 1093 | /* Find an existing audit rule. |
1095 | * Caller must hold audit_filter_mutex to prevent stale rule data. */ | 1094 | * Caller must hold audit_filter_mutex to prevent stale rule data. */ |
1096 | static struct audit_entry *audit_find_rule(struct audit_entry *entry, | 1095 | static struct audit_entry *audit_find_rule(struct audit_entry *entry, |
1097 | struct list_head *list) | 1096 | struct list_head *list) |
1098 | { | 1097 | { |
1099 | struct audit_entry *e, *found = NULL; | 1098 | struct audit_entry *e, *found = NULL; |
1100 | int h; | 1099 | int h; |
1101 | 1100 | ||
1102 | if (entry->rule.watch) { | 1101 | if (entry->rule.watch) { |
1103 | /* we don't know the inode number, so must walk entire hash */ | 1102 | /* we don't know the inode number, so must walk entire hash */ |
1104 | for (h = 0; h < AUDIT_INODE_BUCKETS; h++) { | 1103 | for (h = 0; h < AUDIT_INODE_BUCKETS; h++) { |
1105 | list = &audit_inode_hash[h]; | 1104 | list = &audit_inode_hash[h]; |
1106 | list_for_each_entry(e, list, list) | 1105 | list_for_each_entry(e, list, list) |
1107 | if (!audit_compare_rule(&entry->rule, &e->rule)) { | 1106 | if (!audit_compare_rule(&entry->rule, &e->rule)) { |
1108 | found = e; | 1107 | found = e; |
1109 | goto out; | 1108 | goto out; |
1110 | } | 1109 | } |
1111 | } | 1110 | } |
1112 | goto out; | 1111 | goto out; |
1113 | } | 1112 | } |
1114 | 1113 | ||
1115 | list_for_each_entry(e, list, list) | 1114 | list_for_each_entry(e, list, list) |
1116 | if (!audit_compare_rule(&entry->rule, &e->rule)) { | 1115 | if (!audit_compare_rule(&entry->rule, &e->rule)) { |
1117 | found = e; | 1116 | found = e; |
1118 | goto out; | 1117 | goto out; |
1119 | } | 1118 | } |
1120 | 1119 | ||
1121 | out: | 1120 | out: |
1122 | return found; | 1121 | return found; |
1123 | } | 1122 | } |
1124 | 1123 | ||
1125 | /* Get path information necessary for adding watches. */ | 1124 | /* Get path information necessary for adding watches. */ |
1126 | static int audit_get_nd(char *path, struct nameidata **ndp, | 1125 | static int audit_get_nd(char *path, struct nameidata **ndp, |
1127 | struct nameidata **ndw) | 1126 | struct nameidata **ndw) |
1128 | { | 1127 | { |
1129 | struct nameidata *ndparent, *ndwatch; | 1128 | struct nameidata *ndparent, *ndwatch; |
1130 | int err; | 1129 | int err; |
1131 | 1130 | ||
1132 | ndparent = kmalloc(sizeof(*ndparent), GFP_KERNEL); | 1131 | ndparent = kmalloc(sizeof(*ndparent), GFP_KERNEL); |
1133 | if (unlikely(!ndparent)) | 1132 | if (unlikely(!ndparent)) |
1134 | return -ENOMEM; | 1133 | return -ENOMEM; |
1135 | 1134 | ||
1136 | ndwatch = kmalloc(sizeof(*ndwatch), GFP_KERNEL); | 1135 | ndwatch = kmalloc(sizeof(*ndwatch), GFP_KERNEL); |
1137 | if (unlikely(!ndwatch)) { | 1136 | if (unlikely(!ndwatch)) { |
1138 | kfree(ndparent); | 1137 | kfree(ndparent); |
1139 | return -ENOMEM; | 1138 | return -ENOMEM; |
1140 | } | 1139 | } |
1141 | 1140 | ||
1142 | err = path_lookup(path, LOOKUP_PARENT, ndparent); | 1141 | err = path_lookup(path, LOOKUP_PARENT, ndparent); |
1143 | if (err) { | 1142 | if (err) { |
1144 | kfree(ndparent); | 1143 | kfree(ndparent); |
1145 | kfree(ndwatch); | 1144 | kfree(ndwatch); |
1146 | return err; | 1145 | return err; |
1147 | } | 1146 | } |
1148 | 1147 | ||
1149 | err = path_lookup(path, 0, ndwatch); | 1148 | err = path_lookup(path, 0, ndwatch); |
1150 | if (err) { | 1149 | if (err) { |
1151 | kfree(ndwatch); | 1150 | kfree(ndwatch); |
1152 | ndwatch = NULL; | 1151 | ndwatch = NULL; |
1153 | } | 1152 | } |
1154 | 1153 | ||
1155 | *ndp = ndparent; | 1154 | *ndp = ndparent; |
1156 | *ndw = ndwatch; | 1155 | *ndw = ndwatch; |
1157 | 1156 | ||
1158 | return 0; | 1157 | return 0; |
1159 | } | 1158 | } |
1160 | 1159 | ||
1161 | /* Release resources used for watch path information. */ | 1160 | /* Release resources used for watch path information. */ |
1162 | static void audit_put_nd(struct nameidata *ndp, struct nameidata *ndw) | 1161 | static void audit_put_nd(struct nameidata *ndp, struct nameidata *ndw) |
1163 | { | 1162 | { |
1164 | if (ndp) { | 1163 | if (ndp) { |
1165 | path_put(&ndp->path); | 1164 | path_put(&ndp->path); |
1166 | kfree(ndp); | 1165 | kfree(ndp); |
1167 | } | 1166 | } |
1168 | if (ndw) { | 1167 | if (ndw) { |
1169 | path_put(&ndw->path); | 1168 | path_put(&ndw->path); |
1170 | kfree(ndw); | 1169 | kfree(ndw); |
1171 | } | 1170 | } |
1172 | } | 1171 | } |
1173 | 1172 | ||
1174 | /* Associate the given rule with an existing parent inotify_watch. | 1173 | /* Associate the given rule with an existing parent inotify_watch. |
1175 | * Caller must hold audit_filter_mutex. */ | 1174 | * Caller must hold audit_filter_mutex. */ |
1176 | static void audit_add_to_parent(struct audit_krule *krule, | 1175 | static void audit_add_to_parent(struct audit_krule *krule, |
1177 | struct audit_parent *parent) | 1176 | struct audit_parent *parent) |
1178 | { | 1177 | { |
1179 | struct audit_watch *w, *watch = krule->watch; | 1178 | struct audit_watch *w, *watch = krule->watch; |
1180 | int watch_found = 0; | 1179 | int watch_found = 0; |
1181 | 1180 | ||
1182 | list_for_each_entry(w, &parent->watches, wlist) { | 1181 | list_for_each_entry(w, &parent->watches, wlist) { |
1183 | if (strcmp(watch->path, w->path)) | 1182 | if (strcmp(watch->path, w->path)) |
1184 | continue; | 1183 | continue; |
1185 | 1184 | ||
1186 | watch_found = 1; | 1185 | watch_found = 1; |
1187 | 1186 | ||
1188 | /* put krule's and initial refs to temporary watch */ | 1187 | /* put krule's and initial refs to temporary watch */ |
1189 | audit_put_watch(watch); | 1188 | audit_put_watch(watch); |
1190 | audit_put_watch(watch); | 1189 | audit_put_watch(watch); |
1191 | 1190 | ||
1192 | audit_get_watch(w); | 1191 | audit_get_watch(w); |
1193 | krule->watch = watch = w; | 1192 | krule->watch = watch = w; |
1194 | break; | 1193 | break; |
1195 | } | 1194 | } |
1196 | 1195 | ||
1197 | if (!watch_found) { | 1196 | if (!watch_found) { |
1198 | get_inotify_watch(&parent->wdata); | 1197 | get_inotify_watch(&parent->wdata); |
1199 | watch->parent = parent; | 1198 | watch->parent = parent; |
1200 | 1199 | ||
1201 | list_add(&watch->wlist, &parent->watches); | 1200 | list_add(&watch->wlist, &parent->watches); |
1202 | } | 1201 | } |
1203 | list_add(&krule->rlist, &watch->rules); | 1202 | list_add(&krule->rlist, &watch->rules); |
1204 | } | 1203 | } |
1205 | 1204 | ||
1206 | /* Find a matching watch entry, or add this one. | 1205 | /* Find a matching watch entry, or add this one. |
1207 | * Caller must hold audit_filter_mutex. */ | 1206 | * Caller must hold audit_filter_mutex. */ |
1208 | static int audit_add_watch(struct audit_krule *krule, struct nameidata *ndp, | 1207 | static int audit_add_watch(struct audit_krule *krule, struct nameidata *ndp, |
1209 | struct nameidata *ndw) | 1208 | struct nameidata *ndw) |
1210 | { | 1209 | { |
1211 | struct audit_watch *watch = krule->watch; | 1210 | struct audit_watch *watch = krule->watch; |
1212 | struct inotify_watch *i_watch; | 1211 | struct inotify_watch *i_watch; |
1213 | struct audit_parent *parent; | 1212 | struct audit_parent *parent; |
1214 | int ret = 0; | 1213 | int ret = 0; |
1215 | 1214 | ||
1216 | /* update watch filter fields */ | 1215 | /* update watch filter fields */ |
1217 | if (ndw) { | 1216 | if (ndw) { |
1218 | watch->dev = ndw->path.dentry->d_inode->i_sb->s_dev; | 1217 | watch->dev = ndw->path.dentry->d_inode->i_sb->s_dev; |
1219 | watch->ino = ndw->path.dentry->d_inode->i_ino; | 1218 | watch->ino = ndw->path.dentry->d_inode->i_ino; |
1220 | } | 1219 | } |
1221 | 1220 | ||
1222 | /* The audit_filter_mutex must not be held during inotify calls because | 1221 | /* The audit_filter_mutex must not be held during inotify calls because |
1223 | * we hold it during inotify event callback processing. If an existing | 1222 | * we hold it during inotify event callback processing. If an existing |
1224 | * inotify watch is found, inotify_find_watch() grabs a reference before | 1223 | * inotify watch is found, inotify_find_watch() grabs a reference before |
1225 | * returning. | 1224 | * returning. |
1226 | */ | 1225 | */ |
1227 | mutex_unlock(&audit_filter_mutex); | 1226 | mutex_unlock(&audit_filter_mutex); |
1228 | 1227 | ||
1229 | if (inotify_find_watch(audit_ih, ndp->path.dentry->d_inode, | 1228 | if (inotify_find_watch(audit_ih, ndp->path.dentry->d_inode, |
1230 | &i_watch) < 0) { | 1229 | &i_watch) < 0) { |
1231 | parent = audit_init_parent(ndp); | 1230 | parent = audit_init_parent(ndp); |
1232 | if (IS_ERR(parent)) { | 1231 | if (IS_ERR(parent)) { |
1233 | /* caller expects mutex locked */ | 1232 | /* caller expects mutex locked */ |
1234 | mutex_lock(&audit_filter_mutex); | 1233 | mutex_lock(&audit_filter_mutex); |
1235 | return PTR_ERR(parent); | 1234 | return PTR_ERR(parent); |
1236 | } | 1235 | } |
1237 | } else | 1236 | } else |
1238 | parent = container_of(i_watch, struct audit_parent, wdata); | 1237 | parent = container_of(i_watch, struct audit_parent, wdata); |
1239 | 1238 | ||
1240 | mutex_lock(&audit_filter_mutex); | 1239 | mutex_lock(&audit_filter_mutex); |
1241 | 1240 | ||
1242 | /* parent was moved before we took audit_filter_mutex */ | 1241 | /* parent was moved before we took audit_filter_mutex */ |
1243 | if (parent->flags & AUDIT_PARENT_INVALID) | 1242 | if (parent->flags & AUDIT_PARENT_INVALID) |
1244 | ret = -ENOENT; | 1243 | ret = -ENOENT; |
1245 | else | 1244 | else |
1246 | audit_add_to_parent(krule, parent); | 1245 | audit_add_to_parent(krule, parent); |
1247 | 1246 | ||
1248 | /* match get in audit_init_parent or inotify_find_watch */ | 1247 | /* match get in audit_init_parent or inotify_find_watch */ |
1249 | put_inotify_watch(&parent->wdata); | 1248 | put_inotify_watch(&parent->wdata); |
1250 | return ret; | 1249 | return ret; |
1251 | } | 1250 | } |
1252 | 1251 | ||
1253 | /* Add rule to given filterlist if not a duplicate. */ | 1252 | /* Add rule to given filterlist if not a duplicate. */ |
1254 | static inline int audit_add_rule(struct audit_entry *entry, | 1253 | static inline int audit_add_rule(struct audit_entry *entry, |
1255 | struct list_head *list) | 1254 | struct list_head *list) |
1256 | { | 1255 | { |
1257 | struct audit_entry *e; | 1256 | struct audit_entry *e; |
1258 | struct audit_field *inode_f = entry->rule.inode_f; | 1257 | struct audit_field *inode_f = entry->rule.inode_f; |
1259 | struct audit_watch *watch = entry->rule.watch; | 1258 | struct audit_watch *watch = entry->rule.watch; |
1260 | struct audit_tree *tree = entry->rule.tree; | 1259 | struct audit_tree *tree = entry->rule.tree; |
1261 | struct nameidata *ndp = NULL, *ndw = NULL; | 1260 | struct nameidata *ndp = NULL, *ndw = NULL; |
1262 | int h, err; | 1261 | int h, err; |
1263 | #ifdef CONFIG_AUDITSYSCALL | 1262 | #ifdef CONFIG_AUDITSYSCALL |
1264 | int dont_count = 0; | 1263 | int dont_count = 0; |
1265 | 1264 | ||
1266 | /* If either of these, don't count towards total */ | 1265 | /* If either of these, don't count towards total */ |
1267 | if (entry->rule.listnr == AUDIT_FILTER_USER || | 1266 | if (entry->rule.listnr == AUDIT_FILTER_USER || |
1268 | entry->rule.listnr == AUDIT_FILTER_TYPE) | 1267 | entry->rule.listnr == AUDIT_FILTER_TYPE) |
1269 | dont_count = 1; | 1268 | dont_count = 1; |
1270 | #endif | 1269 | #endif |
1271 | 1270 | ||
1272 | if (inode_f) { | 1271 | if (inode_f) { |
1273 | h = audit_hash_ino(inode_f->val); | 1272 | h = audit_hash_ino(inode_f->val); |
1274 | list = &audit_inode_hash[h]; | 1273 | list = &audit_inode_hash[h]; |
1275 | } | 1274 | } |
1276 | 1275 | ||
1277 | mutex_lock(&audit_filter_mutex); | 1276 | mutex_lock(&audit_filter_mutex); |
1278 | e = audit_find_rule(entry, list); | 1277 | e = audit_find_rule(entry, list); |
1279 | mutex_unlock(&audit_filter_mutex); | 1278 | mutex_unlock(&audit_filter_mutex); |
1280 | if (e) { | 1279 | if (e) { |
1281 | err = -EEXIST; | 1280 | err = -EEXIST; |
1282 | /* normally audit_add_tree_rule() will free it on failure */ | 1281 | /* normally audit_add_tree_rule() will free it on failure */ |
1283 | if (tree) | 1282 | if (tree) |
1284 | audit_put_tree(tree); | 1283 | audit_put_tree(tree); |
1285 | goto error; | 1284 | goto error; |
1286 | } | 1285 | } |
1287 | 1286 | ||
1288 | /* Avoid calling path_lookup under audit_filter_mutex. */ | 1287 | /* Avoid calling path_lookup under audit_filter_mutex. */ |
1289 | if (watch) { | 1288 | if (watch) { |
1290 | err = audit_get_nd(watch->path, &ndp, &ndw); | 1289 | err = audit_get_nd(watch->path, &ndp, &ndw); |
1291 | if (err) | 1290 | if (err) |
1292 | goto error; | 1291 | goto error; |
1293 | } | 1292 | } |
1294 | 1293 | ||
1295 | mutex_lock(&audit_filter_mutex); | 1294 | mutex_lock(&audit_filter_mutex); |
1296 | if (watch) { | 1295 | if (watch) { |
1297 | /* audit_filter_mutex is dropped and re-taken during this call */ | 1296 | /* audit_filter_mutex is dropped and re-taken during this call */ |
1298 | err = audit_add_watch(&entry->rule, ndp, ndw); | 1297 | err = audit_add_watch(&entry->rule, ndp, ndw); |
1299 | if (err) { | 1298 | if (err) { |
1300 | mutex_unlock(&audit_filter_mutex); | 1299 | mutex_unlock(&audit_filter_mutex); |
1301 | goto error; | 1300 | goto error; |
1302 | } | 1301 | } |
1303 | h = audit_hash_ino((u32)watch->ino); | 1302 | h = audit_hash_ino((u32)watch->ino); |
1304 | list = &audit_inode_hash[h]; | 1303 | list = &audit_inode_hash[h]; |
1305 | } | 1304 | } |
1306 | if (tree) { | 1305 | if (tree) { |
1307 | err = audit_add_tree_rule(&entry->rule); | 1306 | err = audit_add_tree_rule(&entry->rule); |
1308 | if (err) { | 1307 | if (err) { |
1309 | mutex_unlock(&audit_filter_mutex); | 1308 | mutex_unlock(&audit_filter_mutex); |
1310 | goto error; | 1309 | goto error; |
1311 | } | 1310 | } |
1312 | } | 1311 | } |
1313 | 1312 | ||
1314 | if (entry->rule.flags & AUDIT_FILTER_PREPEND) { | 1313 | if (entry->rule.flags & AUDIT_FILTER_PREPEND) { |
1315 | list_add_rcu(&entry->list, list); | 1314 | list_add_rcu(&entry->list, list); |
1316 | entry->rule.flags &= ~AUDIT_FILTER_PREPEND; | 1315 | entry->rule.flags &= ~AUDIT_FILTER_PREPEND; |
1317 | } else { | 1316 | } else { |
1318 | list_add_tail_rcu(&entry->list, list); | 1317 | list_add_tail_rcu(&entry->list, list); |
1319 | } | 1318 | } |
1320 | #ifdef CONFIG_AUDITSYSCALL | 1319 | #ifdef CONFIG_AUDITSYSCALL |
1321 | if (!dont_count) | 1320 | if (!dont_count) |
1322 | audit_n_rules++; | 1321 | audit_n_rules++; |
1323 | 1322 | ||
1324 | if (!audit_match_signal(entry)) | 1323 | if (!audit_match_signal(entry)) |
1325 | audit_signals++; | 1324 | audit_signals++; |
1326 | #endif | 1325 | #endif |
1327 | mutex_unlock(&audit_filter_mutex); | 1326 | mutex_unlock(&audit_filter_mutex); |
1328 | 1327 | ||
1329 | audit_put_nd(ndp, ndw); /* NULL args OK */ | 1328 | audit_put_nd(ndp, ndw); /* NULL args OK */ |
1330 | return 0; | 1329 | return 0; |
1331 | 1330 | ||
1332 | error: | 1331 | error: |
1333 | audit_put_nd(ndp, ndw); /* NULL args OK */ | 1332 | audit_put_nd(ndp, ndw); /* NULL args OK */ |
1334 | if (watch) | 1333 | if (watch) |
1335 | audit_put_watch(watch); /* tmp watch, matches initial get */ | 1334 | audit_put_watch(watch); /* tmp watch, matches initial get */ |
1336 | return err; | 1335 | return err; |
1337 | } | 1336 | } |
1338 | 1337 | ||
1339 | /* Remove an existing rule from filterlist. */ | 1338 | /* Remove an existing rule from filterlist. */ |
1340 | static inline int audit_del_rule(struct audit_entry *entry, | 1339 | static inline int audit_del_rule(struct audit_entry *entry, |
1341 | struct list_head *list) | 1340 | struct list_head *list) |
1342 | { | 1341 | { |
1343 | struct audit_entry *e; | 1342 | struct audit_entry *e; |
1344 | struct audit_field *inode_f = entry->rule.inode_f; | 1343 | struct audit_field *inode_f = entry->rule.inode_f; |
1345 | struct audit_watch *watch, *tmp_watch = entry->rule.watch; | 1344 | struct audit_watch *watch, *tmp_watch = entry->rule.watch; |
1346 | struct audit_tree *tree = entry->rule.tree; | 1345 | struct audit_tree *tree = entry->rule.tree; |
1347 | LIST_HEAD(inotify_list); | 1346 | LIST_HEAD(inotify_list); |
1348 | int h, ret = 0; | 1347 | int h, ret = 0; |
1349 | #ifdef CONFIG_AUDITSYSCALL | 1348 | #ifdef CONFIG_AUDITSYSCALL |
1350 | int dont_count = 0; | 1349 | int dont_count = 0; |
1351 | 1350 | ||
1352 | /* If either of these, don't count towards total */ | 1351 | /* If either of these, don't count towards total */ |
1353 | if (entry->rule.listnr == AUDIT_FILTER_USER || | 1352 | if (entry->rule.listnr == AUDIT_FILTER_USER || |
1354 | entry->rule.listnr == AUDIT_FILTER_TYPE) | 1353 | entry->rule.listnr == AUDIT_FILTER_TYPE) |
1355 | dont_count = 1; | 1354 | dont_count = 1; |
1356 | #endif | 1355 | #endif |
1357 | 1356 | ||
1358 | if (inode_f) { | 1357 | if (inode_f) { |
1359 | h = audit_hash_ino(inode_f->val); | 1358 | h = audit_hash_ino(inode_f->val); |
1360 | list = &audit_inode_hash[h]; | 1359 | list = &audit_inode_hash[h]; |
1361 | } | 1360 | } |
1362 | 1361 | ||
1363 | mutex_lock(&audit_filter_mutex); | 1362 | mutex_lock(&audit_filter_mutex); |
1364 | e = audit_find_rule(entry, list); | 1363 | e = audit_find_rule(entry, list); |
1365 | if (!e) { | 1364 | if (!e) { |
1366 | mutex_unlock(&audit_filter_mutex); | 1365 | mutex_unlock(&audit_filter_mutex); |
1367 | ret = -ENOENT; | 1366 | ret = -ENOENT; |
1368 | goto out; | 1367 | goto out; |
1369 | } | 1368 | } |
1370 | 1369 | ||
1371 | watch = e->rule.watch; | 1370 | watch = e->rule.watch; |
1372 | if (watch) { | 1371 | if (watch) { |
1373 | struct audit_parent *parent = watch->parent; | 1372 | struct audit_parent *parent = watch->parent; |
1374 | 1373 | ||
1375 | list_del(&e->rule.rlist); | 1374 | list_del(&e->rule.rlist); |
1376 | 1375 | ||
1377 | if (list_empty(&watch->rules)) { | 1376 | if (list_empty(&watch->rules)) { |
1378 | audit_remove_watch(watch); | 1377 | audit_remove_watch(watch); |
1379 | 1378 | ||
1380 | if (list_empty(&parent->watches)) { | 1379 | if (list_empty(&parent->watches)) { |
1381 | /* Put parent on the inotify un-registration | 1380 | /* Put parent on the inotify un-registration |
1382 | * list. Grab a reference before releasing | 1381 | * list. Grab a reference before releasing |
1383 | * audit_filter_mutex, to be released in | 1382 | * audit_filter_mutex, to be released in |
1384 | * audit_inotify_unregister(). */ | 1383 | * audit_inotify_unregister(). */ |
1385 | list_add(&parent->ilist, &inotify_list); | 1384 | list_add(&parent->ilist, &inotify_list); |
1386 | get_inotify_watch(&parent->wdata); | 1385 | get_inotify_watch(&parent->wdata); |
1387 | } | 1386 | } |
1388 | } | 1387 | } |
1389 | } | 1388 | } |
1390 | 1389 | ||
1391 | if (e->rule.tree) | 1390 | if (e->rule.tree) |
1392 | audit_remove_tree_rule(&e->rule); | 1391 | audit_remove_tree_rule(&e->rule); |
1393 | 1392 | ||
1394 | list_del_rcu(&e->list); | 1393 | list_del_rcu(&e->list); |
1395 | call_rcu(&e->rcu, audit_free_rule_rcu); | 1394 | call_rcu(&e->rcu, audit_free_rule_rcu); |
1396 | 1395 | ||
1397 | #ifdef CONFIG_AUDITSYSCALL | 1396 | #ifdef CONFIG_AUDITSYSCALL |
1398 | if (!dont_count) | 1397 | if (!dont_count) |
1399 | audit_n_rules--; | 1398 | audit_n_rules--; |
1400 | 1399 | ||
1401 | if (!audit_match_signal(entry)) | 1400 | if (!audit_match_signal(entry)) |
1402 | audit_signals--; | 1401 | audit_signals--; |
1403 | #endif | 1402 | #endif |
1404 | mutex_unlock(&audit_filter_mutex); | 1403 | mutex_unlock(&audit_filter_mutex); |
1405 | 1404 | ||
1406 | if (!list_empty(&inotify_list)) | 1405 | if (!list_empty(&inotify_list)) |
1407 | audit_inotify_unregister(&inotify_list); | 1406 | audit_inotify_unregister(&inotify_list); |
1408 | 1407 | ||
1409 | out: | 1408 | out: |
1410 | if (tmp_watch) | 1409 | if (tmp_watch) |
1411 | audit_put_watch(tmp_watch); /* match initial get */ | 1410 | audit_put_watch(tmp_watch); /* match initial get */ |
1412 | if (tree) | 1411 | if (tree) |
1413 | audit_put_tree(tree); /* that's the temporary one */ | 1412 | audit_put_tree(tree); /* that's the temporary one */ |
1414 | 1413 | ||
1415 | return ret; | 1414 | return ret; |
1416 | } | 1415 | } |
1417 | 1416 | ||
1418 | /* List rules using struct audit_rule. Exists for backward | 1417 | /* List rules using struct audit_rule. Exists for backward |
1419 | * compatibility with userspace. */ | 1418 | * compatibility with userspace. */ |
1420 | static void audit_list(int pid, int seq, struct sk_buff_head *q) | 1419 | static void audit_list(int pid, int seq, struct sk_buff_head *q) |
1421 | { | 1420 | { |
1422 | struct sk_buff *skb; | 1421 | struct sk_buff *skb; |
1423 | struct audit_entry *entry; | 1422 | struct audit_entry *entry; |
1424 | int i; | 1423 | int i; |
1425 | 1424 | ||
1426 | /* This is a blocking read, so use audit_filter_mutex instead of rcu | 1425 | /* This is a blocking read, so use audit_filter_mutex instead of rcu |
1427 | * iterator to sync with list writers. */ | 1426 | * iterator to sync with list writers. */ |
1428 | for (i=0; i<AUDIT_NR_FILTERS; i++) { | 1427 | for (i=0; i<AUDIT_NR_FILTERS; i++) { |
1429 | list_for_each_entry(entry, &audit_filter_list[i], list) { | 1428 | list_for_each_entry(entry, &audit_filter_list[i], list) { |
1430 | struct audit_rule *rule; | 1429 | struct audit_rule *rule; |
1431 | 1430 | ||
1432 | rule = audit_krule_to_rule(&entry->rule); | 1431 | rule = audit_krule_to_rule(&entry->rule); |
1433 | if (unlikely(!rule)) | 1432 | if (unlikely(!rule)) |
1434 | break; | 1433 | break; |
1435 | skb = audit_make_reply(pid, seq, AUDIT_LIST, 0, 1, | 1434 | skb = audit_make_reply(pid, seq, AUDIT_LIST, 0, 1, |
1436 | rule, sizeof(*rule)); | 1435 | rule, sizeof(*rule)); |
1437 | if (skb) | 1436 | if (skb) |
1438 | skb_queue_tail(q, skb); | 1437 | skb_queue_tail(q, skb); |
1439 | kfree(rule); | 1438 | kfree(rule); |
1440 | } | 1439 | } |
1441 | } | 1440 | } |
1442 | for (i = 0; i < AUDIT_INODE_BUCKETS; i++) { | 1441 | for (i = 0; i < AUDIT_INODE_BUCKETS; i++) { |
1443 | list_for_each_entry(entry, &audit_inode_hash[i], list) { | 1442 | list_for_each_entry(entry, &audit_inode_hash[i], list) { |
1444 | struct audit_rule *rule; | 1443 | struct audit_rule *rule; |
1445 | 1444 | ||
1446 | rule = audit_krule_to_rule(&entry->rule); | 1445 | rule = audit_krule_to_rule(&entry->rule); |
1447 | if (unlikely(!rule)) | 1446 | if (unlikely(!rule)) |
1448 | break; | 1447 | break; |
1449 | skb = audit_make_reply(pid, seq, AUDIT_LIST, 0, 1, | 1448 | skb = audit_make_reply(pid, seq, AUDIT_LIST, 0, 1, |
1450 | rule, sizeof(*rule)); | 1449 | rule, sizeof(*rule)); |
1451 | if (skb) | 1450 | if (skb) |
1452 | skb_queue_tail(q, skb); | 1451 | skb_queue_tail(q, skb); |
1453 | kfree(rule); | 1452 | kfree(rule); |
1454 | } | 1453 | } |
1455 | } | 1454 | } |
1456 | skb = audit_make_reply(pid, seq, AUDIT_LIST, 1, 1, NULL, 0); | 1455 | skb = audit_make_reply(pid, seq, AUDIT_LIST, 1, 1, NULL, 0); |
1457 | if (skb) | 1456 | if (skb) |
1458 | skb_queue_tail(q, skb); | 1457 | skb_queue_tail(q, skb); |
1459 | } | 1458 | } |
1460 | 1459 | ||
1461 | /* List rules using struct audit_rule_data. */ | 1460 | /* List rules using struct audit_rule_data. */ |
1462 | static void audit_list_rules(int pid, int seq, struct sk_buff_head *q) | 1461 | static void audit_list_rules(int pid, int seq, struct sk_buff_head *q) |
1463 | { | 1462 | { |
1464 | struct sk_buff *skb; | 1463 | struct sk_buff *skb; |
1465 | struct audit_entry *e; | 1464 | struct audit_entry *e; |
1466 | int i; | 1465 | int i; |
1467 | 1466 | ||
1468 | /* This is a blocking read, so use audit_filter_mutex instead of rcu | 1467 | /* This is a blocking read, so use audit_filter_mutex instead of rcu |
1469 | * iterator to sync with list writers. */ | 1468 | * iterator to sync with list writers. */ |
1470 | for (i=0; i<AUDIT_NR_FILTERS; i++) { | 1469 | for (i=0; i<AUDIT_NR_FILTERS; i++) { |
1471 | list_for_each_entry(e, &audit_filter_list[i], list) { | 1470 | list_for_each_entry(e, &audit_filter_list[i], list) { |
1472 | struct audit_rule_data *data; | 1471 | struct audit_rule_data *data; |
1473 | 1472 | ||
1474 | data = audit_krule_to_data(&e->rule); | 1473 | data = audit_krule_to_data(&e->rule); |
1475 | if (unlikely(!data)) | 1474 | if (unlikely(!data)) |
1476 | break; | 1475 | break; |
1477 | skb = audit_make_reply(pid, seq, AUDIT_LIST_RULES, 0, 1, | 1476 | skb = audit_make_reply(pid, seq, AUDIT_LIST_RULES, 0, 1, |
1478 | data, sizeof(*data) + data->buflen); | 1477 | data, sizeof(*data) + data->buflen); |
1479 | if (skb) | 1478 | if (skb) |
1480 | skb_queue_tail(q, skb); | 1479 | skb_queue_tail(q, skb); |
1481 | kfree(data); | 1480 | kfree(data); |
1482 | } | 1481 | } |
1483 | } | 1482 | } |
1484 | for (i=0; i< AUDIT_INODE_BUCKETS; i++) { | 1483 | for (i=0; i< AUDIT_INODE_BUCKETS; i++) { |
1485 | list_for_each_entry(e, &audit_inode_hash[i], list) { | 1484 | list_for_each_entry(e, &audit_inode_hash[i], list) { |
1486 | struct audit_rule_data *data; | 1485 | struct audit_rule_data *data; |
1487 | 1486 | ||
1488 | data = audit_krule_to_data(&e->rule); | 1487 | data = audit_krule_to_data(&e->rule); |
1489 | if (unlikely(!data)) | 1488 | if (unlikely(!data)) |
1490 | break; | 1489 | break; |
1491 | skb = audit_make_reply(pid, seq, AUDIT_LIST_RULES, 0, 1, | 1490 | skb = audit_make_reply(pid, seq, AUDIT_LIST_RULES, 0, 1, |
1492 | data, sizeof(*data) + data->buflen); | 1491 | data, sizeof(*data) + data->buflen); |
1493 | if (skb) | 1492 | if (skb) |
1494 | skb_queue_tail(q, skb); | 1493 | skb_queue_tail(q, skb); |
1495 | kfree(data); | 1494 | kfree(data); |
1496 | } | 1495 | } |
1497 | } | 1496 | } |
1498 | skb = audit_make_reply(pid, seq, AUDIT_LIST_RULES, 1, 1, NULL, 0); | 1497 | skb = audit_make_reply(pid, seq, AUDIT_LIST_RULES, 1, 1, NULL, 0); |
1499 | if (skb) | 1498 | if (skb) |
1500 | skb_queue_tail(q, skb); | 1499 | skb_queue_tail(q, skb); |
1501 | } | 1500 | } |
1502 | 1501 | ||
1503 | /* Log rule additions and removals */ | 1502 | /* Log rule additions and removals */ |
1504 | static void audit_log_rule_change(uid_t loginuid, u32 sid, char *action, | 1503 | static void audit_log_rule_change(uid_t loginuid, u32 sid, char *action, |
1505 | struct audit_krule *rule, int res) | 1504 | struct audit_krule *rule, int res) |
1506 | { | 1505 | { |
1507 | struct audit_buffer *ab; | 1506 | struct audit_buffer *ab; |
1508 | 1507 | ||
1509 | if (!audit_enabled) | 1508 | if (!audit_enabled) |
1510 | return; | 1509 | return; |
1511 | 1510 | ||
1512 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); | 1511 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); |
1513 | if (!ab) | 1512 | if (!ab) |
1514 | return; | 1513 | return; |
1515 | audit_log_format(ab, "auid=%u", loginuid); | 1514 | audit_log_format(ab, "auid=%u", loginuid); |
1516 | if (sid) { | 1515 | if (sid) { |
1517 | char *ctx = NULL; | 1516 | char *ctx = NULL; |
1518 | u32 len; | 1517 | u32 len; |
1519 | if (security_secid_to_secctx(sid, &ctx, &len)) | 1518 | if (security_secid_to_secctx(sid, &ctx, &len)) |
1520 | audit_log_format(ab, " ssid=%u", sid); | 1519 | audit_log_format(ab, " ssid=%u", sid); |
1521 | else { | 1520 | else { |
1522 | audit_log_format(ab, " subj=%s", ctx); | 1521 | audit_log_format(ab, " subj=%s", ctx); |
1523 | security_release_secctx(ctx, len); | 1522 | security_release_secctx(ctx, len); |
1524 | } | 1523 | } |
1525 | } | 1524 | } |
1526 | audit_log_format(ab, " op=%s rule key=", action); | 1525 | audit_log_format(ab, " op=%s rule key=", action); |
1527 | if (rule->filterkey) | 1526 | if (rule->filterkey) |
1528 | audit_log_untrustedstring(ab, rule->filterkey); | 1527 | audit_log_untrustedstring(ab, rule->filterkey); |
1529 | else | 1528 | else |
1530 | audit_log_format(ab, "(null)"); | 1529 | audit_log_format(ab, "(null)"); |
1531 | audit_log_format(ab, " list=%d res=%d", rule->listnr, res); | 1530 | audit_log_format(ab, " list=%d res=%d", rule->listnr, res); |
1532 | audit_log_end(ab); | 1531 | audit_log_end(ab); |
1533 | } | 1532 | } |
1534 | 1533 | ||
1535 | /** | 1534 | /** |
1536 | * audit_receive_filter - apply all rules to the specified message type | 1535 | * audit_receive_filter - apply all rules to the specified message type |
1537 | * @type: audit message type | 1536 | * @type: audit message type |
1538 | * @pid: target pid for netlink audit messages | 1537 | * @pid: target pid for netlink audit messages |
1539 | * @uid: target uid for netlink audit messages | 1538 | * @uid: target uid for netlink audit messages |
1540 | * @seq: netlink audit message sequence (serial) number | 1539 | * @seq: netlink audit message sequence (serial) number |
1541 | * @data: payload data | 1540 | * @data: payload data |
1542 | * @datasz: size of payload data | 1541 | * @datasz: size of payload data |
1543 | * @loginuid: loginuid of sender | 1542 | * @loginuid: loginuid of sender |
1544 | * @sid: SE Linux Security ID of sender | 1543 | * @sid: SE Linux Security ID of sender |
1545 | */ | 1544 | */ |
1546 | int audit_receive_filter(int type, int pid, int uid, int seq, void *data, | 1545 | int audit_receive_filter(int type, int pid, int uid, int seq, void *data, |
1547 | size_t datasz, uid_t loginuid, u32 sid) | 1546 | size_t datasz, uid_t loginuid, u32 sid) |
1548 | { | 1547 | { |
1549 | struct task_struct *tsk; | 1548 | struct task_struct *tsk; |
1550 | struct audit_netlink_list *dest; | 1549 | struct audit_netlink_list *dest; |
1551 | int err = 0; | 1550 | int err = 0; |
1552 | struct audit_entry *entry; | 1551 | struct audit_entry *entry; |
1553 | 1552 | ||
1554 | switch (type) { | 1553 | switch (type) { |
1555 | case AUDIT_LIST: | 1554 | case AUDIT_LIST: |
1556 | case AUDIT_LIST_RULES: | 1555 | case AUDIT_LIST_RULES: |
1557 | /* We can't just spew out the rules here because we might fill | 1556 | /* We can't just spew out the rules here because we might fill |
1558 | * the available socket buffer space and deadlock waiting for | 1557 | * the available socket buffer space and deadlock waiting for |
1559 | * auditctl to read from it... which isn't ever going to | 1558 | * auditctl to read from it... which isn't ever going to |
1560 | * happen if we're actually running in the context of auditctl | 1559 | * happen if we're actually running in the context of auditctl |
1561 | * trying to _send_ the stuff */ | 1560 | * trying to _send_ the stuff */ |
1562 | 1561 | ||
1563 | dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL); | 1562 | dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL); |
1564 | if (!dest) | 1563 | if (!dest) |
1565 | return -ENOMEM; | 1564 | return -ENOMEM; |
1566 | dest->pid = pid; | 1565 | dest->pid = pid; |
1567 | skb_queue_head_init(&dest->q); | 1566 | skb_queue_head_init(&dest->q); |
1568 | 1567 | ||
1569 | mutex_lock(&audit_filter_mutex); | 1568 | mutex_lock(&audit_filter_mutex); |
1570 | if (type == AUDIT_LIST) | 1569 | if (type == AUDIT_LIST) |
1571 | audit_list(pid, seq, &dest->q); | 1570 | audit_list(pid, seq, &dest->q); |
1572 | else | 1571 | else |
1573 | audit_list_rules(pid, seq, &dest->q); | 1572 | audit_list_rules(pid, seq, &dest->q); |
1574 | mutex_unlock(&audit_filter_mutex); | 1573 | mutex_unlock(&audit_filter_mutex); |
1575 | 1574 | ||
1576 | tsk = kthread_run(audit_send_list, dest, "audit_send_list"); | 1575 | tsk = kthread_run(audit_send_list, dest, "audit_send_list"); |
1577 | if (IS_ERR(tsk)) { | 1576 | if (IS_ERR(tsk)) { |
1578 | skb_queue_purge(&dest->q); | 1577 | skb_queue_purge(&dest->q); |
1579 | kfree(dest); | 1578 | kfree(dest); |
1580 | err = PTR_ERR(tsk); | 1579 | err = PTR_ERR(tsk); |
1581 | } | 1580 | } |
1582 | break; | 1581 | break; |
1583 | case AUDIT_ADD: | 1582 | case AUDIT_ADD: |
1584 | case AUDIT_ADD_RULE: | 1583 | case AUDIT_ADD_RULE: |
1585 | if (type == AUDIT_ADD) | 1584 | if (type == AUDIT_ADD) |
1586 | entry = audit_rule_to_entry(data); | 1585 | entry = audit_rule_to_entry(data); |
1587 | else | 1586 | else |
1588 | entry = audit_data_to_entry(data, datasz); | 1587 | entry = audit_data_to_entry(data, datasz); |
1589 | if (IS_ERR(entry)) | 1588 | if (IS_ERR(entry)) |
1590 | return PTR_ERR(entry); | 1589 | return PTR_ERR(entry); |
1591 | 1590 | ||
1592 | err = audit_add_rule(entry, | 1591 | err = audit_add_rule(entry, |
1593 | &audit_filter_list[entry->rule.listnr]); | 1592 | &audit_filter_list[entry->rule.listnr]); |
1594 | audit_log_rule_change(loginuid, sid, "add", &entry->rule, !err); | 1593 | audit_log_rule_change(loginuid, sid, "add", &entry->rule, !err); |
1595 | 1594 | ||
1596 | if (err) | 1595 | if (err) |
1597 | audit_free_rule(entry); | 1596 | audit_free_rule(entry); |
1598 | break; | 1597 | break; |
1599 | case AUDIT_DEL: | 1598 | case AUDIT_DEL: |
1600 | case AUDIT_DEL_RULE: | 1599 | case AUDIT_DEL_RULE: |
1601 | if (type == AUDIT_DEL) | 1600 | if (type == AUDIT_DEL) |
1602 | entry = audit_rule_to_entry(data); | 1601 | entry = audit_rule_to_entry(data); |
1603 | else | 1602 | else |
1604 | entry = audit_data_to_entry(data, datasz); | 1603 | entry = audit_data_to_entry(data, datasz); |
1605 | if (IS_ERR(entry)) | 1604 | if (IS_ERR(entry)) |
1606 | return PTR_ERR(entry); | 1605 | return PTR_ERR(entry); |
1607 | 1606 | ||
1608 | err = audit_del_rule(entry, | 1607 | err = audit_del_rule(entry, |
1609 | &audit_filter_list[entry->rule.listnr]); | 1608 | &audit_filter_list[entry->rule.listnr]); |
1610 | audit_log_rule_change(loginuid, sid, "remove", &entry->rule, | 1609 | audit_log_rule_change(loginuid, sid, "remove", &entry->rule, |
1611 | !err); | 1610 | !err); |
1612 | 1611 | ||
1613 | audit_free_rule(entry); | 1612 | audit_free_rule(entry); |
1614 | break; | 1613 | break; |
1615 | default: | 1614 | default: |
1616 | return -EINVAL; | 1615 | return -EINVAL; |
1617 | } | 1616 | } |
1618 | 1617 | ||
1619 | return err; | 1618 | return err; |
1620 | } | 1619 | } |
1621 | 1620 | ||
1622 | int audit_comparator(const u32 left, const u32 op, const u32 right) | 1621 | int audit_comparator(const u32 left, const u32 op, const u32 right) |
1623 | { | 1622 | { |
1624 | switch (op) { | 1623 | switch (op) { |
1625 | case AUDIT_EQUAL: | 1624 | case AUDIT_EQUAL: |
1626 | return (left == right); | 1625 | return (left == right); |
1627 | case AUDIT_NOT_EQUAL: | 1626 | case AUDIT_NOT_EQUAL: |
1628 | return (left != right); | 1627 | return (left != right); |
1629 | case AUDIT_LESS_THAN: | 1628 | case AUDIT_LESS_THAN: |
1630 | return (left < right); | 1629 | return (left < right); |
1631 | case AUDIT_LESS_THAN_OR_EQUAL: | 1630 | case AUDIT_LESS_THAN_OR_EQUAL: |
1632 | return (left <= right); | 1631 | return (left <= right); |
1633 | case AUDIT_GREATER_THAN: | 1632 | case AUDIT_GREATER_THAN: |
1634 | return (left > right); | 1633 | return (left > right); |
1635 | case AUDIT_GREATER_THAN_OR_EQUAL: | 1634 | case AUDIT_GREATER_THAN_OR_EQUAL: |
1636 | return (left >= right); | 1635 | return (left >= right); |
1637 | case AUDIT_BIT_MASK: | 1636 | case AUDIT_BIT_MASK: |
1638 | return (left & right); | 1637 | return (left & right); |
1639 | case AUDIT_BIT_TEST: | 1638 | case AUDIT_BIT_TEST: |
1640 | return ((left & right) == right); | 1639 | return ((left & right) == right); |
1641 | } | 1640 | } |
1642 | BUG(); | 1641 | BUG(); |
1643 | return 0; | 1642 | return 0; |
1644 | } | 1643 | } |
1645 | 1644 | ||
1646 | /* Compare given dentry name with last component in given path, | 1645 | /* Compare given dentry name with last component in given path, |
1647 | * return of 0 indicates a match. */ | 1646 | * return of 0 indicates a match. */ |
1648 | int audit_compare_dname_path(const char *dname, const char *path, | 1647 | int audit_compare_dname_path(const char *dname, const char *path, |
1649 | int *dirlen) | 1648 | int *dirlen) |
1650 | { | 1649 | { |
1651 | int dlen, plen; | 1650 | int dlen, plen; |
1652 | const char *p; | 1651 | const char *p; |
1653 | 1652 | ||
1654 | if (!dname || !path) | 1653 | if (!dname || !path) |
1655 | return 1; | 1654 | return 1; |
1656 | 1655 | ||
1657 | dlen = strlen(dname); | 1656 | dlen = strlen(dname); |
1658 | plen = strlen(path); | 1657 | plen = strlen(path); |
1659 | if (plen < dlen) | 1658 | if (plen < dlen) |
1660 | return 1; | 1659 | return 1; |
1661 | 1660 | ||
1662 | /* disregard trailing slashes */ | 1661 | /* disregard trailing slashes */ |
1663 | p = path + plen - 1; | 1662 | p = path + plen - 1; |
1664 | while ((*p == '/') && (p > path)) | 1663 | while ((*p == '/') && (p > path)) |
1665 | p--; | 1664 | p--; |
1666 | 1665 | ||
1667 | /* find last path component */ | 1666 | /* find last path component */ |
1668 | p = p - dlen + 1; | 1667 | p = p - dlen + 1; |
1669 | if (p < path) | 1668 | if (p < path) |
1670 | return 1; | 1669 | return 1; |
1671 | else if (p > path) { | 1670 | else if (p > path) { |
1672 | if (*--p != '/') | 1671 | if (*--p != '/') |
1673 | return 1; | 1672 | return 1; |
1674 | else | 1673 | else |
1675 | p++; | 1674 | p++; |
1676 | } | 1675 | } |
1677 | 1676 | ||
1678 | /* return length of path's directory component */ | 1677 | /* return length of path's directory component */ |
1679 | if (dirlen) | 1678 | if (dirlen) |
1680 | *dirlen = p - path; | 1679 | *dirlen = p - path; |
1681 | return strncmp(p, dname, dlen); | 1680 | return strncmp(p, dname, dlen); |
1682 | } | 1681 | } |
1683 | 1682 | ||
1684 | static int audit_filter_user_rules(struct netlink_skb_parms *cb, | 1683 | static int audit_filter_user_rules(struct netlink_skb_parms *cb, |
1685 | struct audit_krule *rule, | 1684 | struct audit_krule *rule, |
1686 | enum audit_state *state) | 1685 | enum audit_state *state) |
1687 | { | 1686 | { |
1688 | int i; | 1687 | int i; |
1689 | 1688 | ||
1690 | for (i = 0; i < rule->field_count; i++) { | 1689 | for (i = 0; i < rule->field_count; i++) { |
1691 | struct audit_field *f = &rule->fields[i]; | 1690 | struct audit_field *f = &rule->fields[i]; |
1692 | int result = 0; | 1691 | int result = 0; |
1693 | 1692 | ||
1694 | switch (f->type) { | 1693 | switch (f->type) { |
1695 | case AUDIT_PID: | 1694 | case AUDIT_PID: |
1696 | result = audit_comparator(cb->creds.pid, f->op, f->val); | 1695 | result = audit_comparator(cb->creds.pid, f->op, f->val); |
1697 | break; | 1696 | break; |
1698 | case AUDIT_UID: | 1697 | case AUDIT_UID: |
1699 | result = audit_comparator(cb->creds.uid, f->op, f->val); | 1698 | result = audit_comparator(cb->creds.uid, f->op, f->val); |
1700 | break; | 1699 | break; |
1701 | case AUDIT_GID: | 1700 | case AUDIT_GID: |
1702 | result = audit_comparator(cb->creds.gid, f->op, f->val); | 1701 | result = audit_comparator(cb->creds.gid, f->op, f->val); |
1703 | break; | 1702 | break; |
1704 | case AUDIT_LOGINUID: | 1703 | case AUDIT_LOGINUID: |
1705 | result = audit_comparator(cb->loginuid, f->op, f->val); | 1704 | result = audit_comparator(cb->loginuid, f->op, f->val); |
1706 | break; | 1705 | break; |
1707 | } | 1706 | } |
1708 | 1707 | ||
1709 | if (!result) | 1708 | if (!result) |
1710 | return 0; | 1709 | return 0; |
1711 | } | 1710 | } |
1712 | switch (rule->action) { | 1711 | switch (rule->action) { |
1713 | case AUDIT_NEVER: *state = AUDIT_DISABLED; break; | 1712 | case AUDIT_NEVER: *state = AUDIT_DISABLED; break; |
1714 | case AUDIT_ALWAYS: *state = AUDIT_RECORD_CONTEXT; break; | 1713 | case AUDIT_ALWAYS: *state = AUDIT_RECORD_CONTEXT; break; |
1715 | } | 1714 | } |
1716 | return 1; | 1715 | return 1; |
1717 | } | 1716 | } |
1718 | 1717 | ||
1719 | int audit_filter_user(struct netlink_skb_parms *cb, int type) | 1718 | int audit_filter_user(struct netlink_skb_parms *cb, int type) |
1720 | { | 1719 | { |
1721 | enum audit_state state = AUDIT_DISABLED; | 1720 | enum audit_state state = AUDIT_DISABLED; |
1722 | struct audit_entry *e; | 1721 | struct audit_entry *e; |
1723 | int ret = 1; | 1722 | int ret = 1; |
1724 | 1723 | ||
1725 | rcu_read_lock(); | 1724 | rcu_read_lock(); |
1726 | list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_USER], list) { | 1725 | list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_USER], list) { |
1727 | if (audit_filter_user_rules(cb, &e->rule, &state)) { | 1726 | if (audit_filter_user_rules(cb, &e->rule, &state)) { |
1728 | if (state == AUDIT_DISABLED) | 1727 | if (state == AUDIT_DISABLED) |
1729 | ret = 0; | 1728 | ret = 0; |
1730 | break; | 1729 | break; |
1731 | } | 1730 | } |
1732 | } | 1731 | } |
1733 | rcu_read_unlock(); | 1732 | rcu_read_unlock(); |
1734 | 1733 | ||
1735 | return ret; /* Audit by default */ | 1734 | return ret; /* Audit by default */ |
1736 | } | 1735 | } |
1737 | 1736 | ||
1738 | int audit_filter_type(int type) | 1737 | int audit_filter_type(int type) |
1739 | { | 1738 | { |
1740 | struct audit_entry *e; | 1739 | struct audit_entry *e; |
1741 | int result = 0; | 1740 | int result = 0; |
1742 | 1741 | ||
1743 | rcu_read_lock(); | 1742 | rcu_read_lock(); |
1744 | if (list_empty(&audit_filter_list[AUDIT_FILTER_TYPE])) | 1743 | if (list_empty(&audit_filter_list[AUDIT_FILTER_TYPE])) |
1745 | goto unlock_and_return; | 1744 | goto unlock_and_return; |
1746 | 1745 | ||
1747 | list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TYPE], | 1746 | list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TYPE], |
1748 | list) { | 1747 | list) { |
1749 | int i; | 1748 | int i; |
1750 | for (i = 0; i < e->rule.field_count; i++) { | 1749 | for (i = 0; i < e->rule.field_count; i++) { |
1751 | struct audit_field *f = &e->rule.fields[i]; | 1750 | struct audit_field *f = &e->rule.fields[i]; |
1752 | if (f->type == AUDIT_MSGTYPE) { | 1751 | if (f->type == AUDIT_MSGTYPE) { |
1753 | result = audit_comparator(type, f->op, f->val); | 1752 | result = audit_comparator(type, f->op, f->val); |
1754 | if (!result) | 1753 | if (!result) |
1755 | break; | 1754 | break; |
1756 | } | 1755 | } |
1757 | } | 1756 | } |
1758 | if (result) | 1757 | if (result) |
1759 | goto unlock_and_return; | 1758 | goto unlock_and_return; |
1760 | } | 1759 | } |
1761 | unlock_and_return: | 1760 | unlock_and_return: |
1762 | rcu_read_unlock(); | 1761 | rcu_read_unlock(); |
1763 | return result; | 1762 | return result; |
1764 | } | 1763 | } |
1765 | 1764 | ||
1766 | /* Check to see if the rule contains any selinux fields. Returns 1 if there | ||
1767 | are selinux fields specified in the rule, 0 otherwise. */ | ||
1768 | static inline int audit_rule_has_selinux(struct audit_krule *rule) | ||
1769 | { | ||
1770 | int i; | ||
1771 | |||
1772 | for (i = 0; i < rule->field_count; i++) { | ||
1773 | struct audit_field *f = &rule->fields[i]; | ||
1774 | switch (f->type) { | ||
1775 | case AUDIT_SUBJ_USER: | ||
1776 | case AUDIT_SUBJ_ROLE: | ||
1777 | case AUDIT_SUBJ_TYPE: | ||
1778 | case AUDIT_SUBJ_SEN: | ||
1779 | case AUDIT_SUBJ_CLR: | ||
1780 | case AUDIT_OBJ_USER: | ||
1781 | case AUDIT_OBJ_ROLE: | ||
1782 | case AUDIT_OBJ_TYPE: | ||
1783 | case AUDIT_OBJ_LEV_LOW: | ||
1784 | case AUDIT_OBJ_LEV_HIGH: | ||
1785 | return 1; | ||
1786 | } | ||
1787 | } | ||
1788 | |||
1789 | return 0; | ||
1790 | } | ||
1791 | |||
1792 | /* This function will re-initialize the se_rule field of all applicable rules. | 1765 | /* This function will re-initialize the se_rule field of all applicable rules. |
1793 | * It will traverse the filter lists serarching for rules that contain selinux | 1766 | * It will traverse the filter lists serarching for rules that contain LSM |
1794 | * specific filter fields. When such a rule is found, it is copied, the | 1767 | * specific filter fields. When such a rule is found, it is copied, the |
1795 | * selinux field is re-initialized, and the old rule is replaced with the | 1768 | * LSM field is re-initialized, and the old rule is replaced with the |
1796 | * updated rule. */ | 1769 | * updated rule. */ |
1797 | int selinux_audit_rule_update(void) | 1770 | int audit_update_lsm_rules(void) |
1798 | { | 1771 | { |
1799 | struct audit_entry *entry, *n, *nentry; | 1772 | struct audit_entry *entry, *n, *nentry; |
1800 | struct audit_watch *watch; | 1773 | struct audit_watch *watch; |
1801 | struct audit_tree *tree; | 1774 | struct audit_tree *tree; |
1802 | int i, err = 0; | 1775 | int i, err = 0; |
1803 | 1776 | ||
1804 | /* audit_filter_mutex synchronizes the writers */ | 1777 | /* audit_filter_mutex synchronizes the writers */ |
1805 | mutex_lock(&audit_filter_mutex); | 1778 | mutex_lock(&audit_filter_mutex); |
1806 | 1779 | ||
1807 | for (i = 0; i < AUDIT_NR_FILTERS; i++) { | 1780 | for (i = 0; i < AUDIT_NR_FILTERS; i++) { |
1808 | list_for_each_entry_safe(entry, n, &audit_filter_list[i], list) { | 1781 | list_for_each_entry_safe(entry, n, &audit_filter_list[i], list) { |
1809 | if (!audit_rule_has_selinux(&entry->rule)) | 1782 | if (!security_audit_rule_known(&entry->rule)) |
1810 | continue; | 1783 | continue; |
1811 | 1784 | ||
1812 | watch = entry->rule.watch; | 1785 | watch = entry->rule.watch; |
1813 | tree = entry->rule.tree; | 1786 | tree = entry->rule.tree; |
1814 | nentry = audit_dupe_rule(&entry->rule, watch); | 1787 | nentry = audit_dupe_rule(&entry->rule, watch); |
1815 | if (unlikely(IS_ERR(nentry))) { | 1788 | if (unlikely(IS_ERR(nentry))) { |
1816 | /* save the first error encountered for the | 1789 | /* save the first error encountered for the |
1817 | * return value */ | 1790 | * return value */ |
1818 | if (!err) | 1791 | if (!err) |
1819 | err = PTR_ERR(nentry); | 1792 | err = PTR_ERR(nentry); |
1820 | audit_panic("error updating selinux filters"); | 1793 | audit_panic("error updating LSM filters"); |
1821 | if (watch) | 1794 | if (watch) |
1822 | list_del(&entry->rule.rlist); | 1795 | list_del(&entry->rule.rlist); |
1823 | list_del_rcu(&entry->list); | 1796 | list_del_rcu(&entry->list); |
1824 | } else { | 1797 | } else { |
1825 | if (watch) { | 1798 | if (watch) { |
1826 | list_add(&nentry->rule.rlist, | 1799 | list_add(&nentry->rule.rlist, |
1827 | &watch->rules); | 1800 | &watch->rules); |
1828 | list_del(&entry->rule.rlist); | 1801 | list_del(&entry->rule.rlist); |
1829 | } else if (tree) | 1802 | } else if (tree) |
1830 | list_replace_init(&entry->rule.rlist, | 1803 | list_replace_init(&entry->rule.rlist, |
1831 | &nentry->rule.rlist); | 1804 | &nentry->rule.rlist); |
1832 | list_replace_rcu(&entry->list, &nentry->list); | 1805 | list_replace_rcu(&entry->list, &nentry->list); |
1833 | } | 1806 | } |
1834 | call_rcu(&entry->rcu, audit_free_rule_rcu); | 1807 | call_rcu(&entry->rcu, audit_free_rule_rcu); |
1835 | } | 1808 | } |
1836 | } | 1809 | } |
1837 | 1810 | ||
1838 | mutex_unlock(&audit_filter_mutex); | 1811 | mutex_unlock(&audit_filter_mutex); |
1839 | 1812 | ||
1840 | return err; | 1813 | return err; |
1841 | } | 1814 | } |
1842 | 1815 | ||
1843 | /* Update watch data in audit rules based on inotify events. */ | 1816 | /* Update watch data in audit rules based on inotify events. */ |
1844 | void audit_handle_ievent(struct inotify_watch *i_watch, u32 wd, u32 mask, | 1817 | void audit_handle_ievent(struct inotify_watch *i_watch, u32 wd, u32 mask, |
1845 | u32 cookie, const char *dname, struct inode *inode) | 1818 | u32 cookie, const char *dname, struct inode *inode) |
1846 | { | 1819 | { |
1847 | struct audit_parent *parent; | 1820 | struct audit_parent *parent; |
1848 | 1821 | ||
1849 | parent = container_of(i_watch, struct audit_parent, wdata); | 1822 | parent = container_of(i_watch, struct audit_parent, wdata); |
1850 | 1823 | ||
1851 | if (mask & (IN_CREATE|IN_MOVED_TO) && inode) | 1824 | if (mask & (IN_CREATE|IN_MOVED_TO) && inode) |
1852 | audit_update_watch(parent, dname, inode->i_sb->s_dev, | 1825 | audit_update_watch(parent, dname, inode->i_sb->s_dev, |
1853 | inode->i_ino, 0); | 1826 | inode->i_ino, 0); |
1854 | else if (mask & (IN_DELETE|IN_MOVED_FROM)) | 1827 | else if (mask & (IN_DELETE|IN_MOVED_FROM)) |
1855 | audit_update_watch(parent, dname, (dev_t)-1, (unsigned long)-1, 1); | 1828 | audit_update_watch(parent, dname, (dev_t)-1, (unsigned long)-1, 1); |
1856 | /* inotify automatically removes the watch and sends IN_IGNORED */ | 1829 | /* inotify automatically removes the watch and sends IN_IGNORED */ |
1857 | else if (mask & (IN_DELETE_SELF|IN_UNMOUNT)) | 1830 | else if (mask & (IN_DELETE_SELF|IN_UNMOUNT)) |
1858 | audit_remove_parent_watches(parent); | 1831 | audit_remove_parent_watches(parent); |
1859 | /* inotify does not remove the watch, so remove it manually */ | 1832 | /* inotify does not remove the watch, so remove it manually */ |
1860 | else if(mask & IN_MOVE_SELF) { | 1833 | else if(mask & IN_MOVE_SELF) { |
1861 | audit_remove_parent_watches(parent); | 1834 | audit_remove_parent_watches(parent); |
1862 | inotify_remove_watch_locked(audit_ih, i_watch); | 1835 | inotify_remove_watch_locked(audit_ih, i_watch); |
1863 | } else if (mask & IN_IGNORED) | 1836 | } else if (mask & IN_IGNORED) |
1864 | put_inotify_watch(i_watch); | 1837 | put_inotify_watch(i_watch); |
1865 | } | 1838 | } |
1866 | 1839 |
kernel/auditsc.c
1 | /* auditsc.c -- System-call auditing support | 1 | /* auditsc.c -- System-call auditing support |
2 | * Handles all system-call specific auditing features. | 2 | * Handles all system-call specific auditing features. |
3 | * | 3 | * |
4 | * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina. | 4 | * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina. |
5 | * Copyright 2005 Hewlett-Packard Development Company, L.P. | 5 | * Copyright 2005 Hewlett-Packard Development Company, L.P. |
6 | * Copyright (C) 2005, 2006 IBM Corporation | 6 | * Copyright (C) 2005, 2006 IBM Corporation |
7 | * All Rights Reserved. | 7 | * All Rights Reserved. |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License as published by | 10 | * it under the terms of the GNU General Public License as published by |
11 | * the Free Software Foundation; either version 2 of the License, or | 11 | * the Free Software Foundation; either version 2 of the License, or |
12 | * (at your option) any later version. | 12 | * (at your option) any later version. |
13 | * | 13 | * |
14 | * This program is distributed in the hope that it will be useful, | 14 | * This program is distributed in the hope that it will be useful, |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | * GNU General Public License for more details. | 17 | * GNU General Public License for more details. |
18 | * | 18 | * |
19 | * You should have received a copy of the GNU General Public License | 19 | * You should have received a copy of the GNU General Public License |
20 | * along with this program; if not, write to the Free Software | 20 | * along with this program; if not, write to the Free Software |
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
22 | * | 22 | * |
23 | * Written by Rickard E. (Rik) Faith <faith@redhat.com> | 23 | * Written by Rickard E. (Rik) Faith <faith@redhat.com> |
24 | * | 24 | * |
25 | * Many of the ideas implemented here are from Stephen C. Tweedie, | 25 | * Many of the ideas implemented here are from Stephen C. Tweedie, |
26 | * especially the idea of avoiding a copy by using getname. | 26 | * especially the idea of avoiding a copy by using getname. |
27 | * | 27 | * |
28 | * The method for actual interception of syscall entry and exit (not in | 28 | * The method for actual interception of syscall entry and exit (not in |
29 | * this file -- see entry.S) is based on a GPL'd patch written by | 29 | * this file -- see entry.S) is based on a GPL'd patch written by |
30 | * okir@suse.de and Copyright 2003 SuSE Linux AG. | 30 | * okir@suse.de and Copyright 2003 SuSE Linux AG. |
31 | * | 31 | * |
32 | * POSIX message queue support added by George Wilson <ltcgcw@us.ibm.com>, | 32 | * POSIX message queue support added by George Wilson <ltcgcw@us.ibm.com>, |
33 | * 2006. | 33 | * 2006. |
34 | * | 34 | * |
35 | * The support of additional filter rules compares (>, <, >=, <=) was | 35 | * The support of additional filter rules compares (>, <, >=, <=) was |
36 | * added by Dustin Kirkland <dustin.kirkland@us.ibm.com>, 2005. | 36 | * added by Dustin Kirkland <dustin.kirkland@us.ibm.com>, 2005. |
37 | * | 37 | * |
38 | * Modified by Amy Griffis <amy.griffis@hp.com> to collect additional | 38 | * Modified by Amy Griffis <amy.griffis@hp.com> to collect additional |
39 | * filesystem information. | 39 | * filesystem information. |
40 | * | 40 | * |
41 | * Subject and object context labeling support added by <danjones@us.ibm.com> | 41 | * Subject and object context labeling support added by <danjones@us.ibm.com> |
42 | * and <dustin.kirkland@us.ibm.com> for LSPP certification compliance. | 42 | * and <dustin.kirkland@us.ibm.com> for LSPP certification compliance. |
43 | */ | 43 | */ |
44 | 44 | ||
45 | #include <linux/init.h> | 45 | #include <linux/init.h> |
46 | #include <asm/types.h> | 46 | #include <asm/types.h> |
47 | #include <asm/atomic.h> | 47 | #include <asm/atomic.h> |
48 | #include <linux/fs.h> | 48 | #include <linux/fs.h> |
49 | #include <linux/namei.h> | 49 | #include <linux/namei.h> |
50 | #include <linux/mm.h> | 50 | #include <linux/mm.h> |
51 | #include <linux/module.h> | 51 | #include <linux/module.h> |
52 | #include <linux/mount.h> | 52 | #include <linux/mount.h> |
53 | #include <linux/socket.h> | 53 | #include <linux/socket.h> |
54 | #include <linux/mqueue.h> | 54 | #include <linux/mqueue.h> |
55 | #include <linux/audit.h> | 55 | #include <linux/audit.h> |
56 | #include <linux/personality.h> | 56 | #include <linux/personality.h> |
57 | #include <linux/time.h> | 57 | #include <linux/time.h> |
58 | #include <linux/netlink.h> | 58 | #include <linux/netlink.h> |
59 | #include <linux/compiler.h> | 59 | #include <linux/compiler.h> |
60 | #include <asm/unistd.h> | 60 | #include <asm/unistd.h> |
61 | #include <linux/security.h> | 61 | #include <linux/security.h> |
62 | #include <linux/list.h> | 62 | #include <linux/list.h> |
63 | #include <linux/tty.h> | 63 | #include <linux/tty.h> |
64 | #include <linux/selinux.h> | ||
65 | #include <linux/binfmts.h> | 64 | #include <linux/binfmts.h> |
66 | #include <linux/highmem.h> | 65 | #include <linux/highmem.h> |
67 | #include <linux/syscalls.h> | 66 | #include <linux/syscalls.h> |
68 | #include <linux/inotify.h> | 67 | #include <linux/inotify.h> |
69 | 68 | ||
70 | #include "audit.h" | 69 | #include "audit.h" |
71 | 70 | ||
72 | extern struct list_head audit_filter_list[]; | 71 | extern struct list_head audit_filter_list[]; |
73 | extern int audit_ever_enabled; | 72 | extern int audit_ever_enabled; |
74 | 73 | ||
75 | /* AUDIT_NAMES is the number of slots we reserve in the audit_context | 74 | /* AUDIT_NAMES is the number of slots we reserve in the audit_context |
76 | * for saving names from getname(). */ | 75 | * for saving names from getname(). */ |
77 | #define AUDIT_NAMES 20 | 76 | #define AUDIT_NAMES 20 |
78 | 77 | ||
79 | /* Indicates that audit should log the full pathname. */ | 78 | /* Indicates that audit should log the full pathname. */ |
80 | #define AUDIT_NAME_FULL -1 | 79 | #define AUDIT_NAME_FULL -1 |
81 | 80 | ||
82 | /* no execve audit message should be longer than this (userspace limits) */ | 81 | /* no execve audit message should be longer than this (userspace limits) */ |
83 | #define MAX_EXECVE_AUDIT_LEN 7500 | 82 | #define MAX_EXECVE_AUDIT_LEN 7500 |
84 | 83 | ||
85 | /* number of audit rules */ | 84 | /* number of audit rules */ |
86 | int audit_n_rules; | 85 | int audit_n_rules; |
87 | 86 | ||
88 | /* determines whether we collect data for signals sent */ | 87 | /* determines whether we collect data for signals sent */ |
89 | int audit_signals; | 88 | int audit_signals; |
90 | 89 | ||
91 | /* When fs/namei.c:getname() is called, we store the pointer in name and | 90 | /* When fs/namei.c:getname() is called, we store the pointer in name and |
92 | * we don't let putname() free it (instead we free all of the saved | 91 | * we don't let putname() free it (instead we free all of the saved |
93 | * pointers at syscall exit time). | 92 | * pointers at syscall exit time). |
94 | * | 93 | * |
95 | * Further, in fs/namei.c:path_lookup() we store the inode and device. */ | 94 | * Further, in fs/namei.c:path_lookup() we store the inode and device. */ |
96 | struct audit_names { | 95 | struct audit_names { |
97 | const char *name; | 96 | const char *name; |
98 | int name_len; /* number of name's characters to log */ | 97 | int name_len; /* number of name's characters to log */ |
99 | unsigned name_put; /* call __putname() for this name */ | 98 | unsigned name_put; /* call __putname() for this name */ |
100 | unsigned long ino; | 99 | unsigned long ino; |
101 | dev_t dev; | 100 | dev_t dev; |
102 | umode_t mode; | 101 | umode_t mode; |
103 | uid_t uid; | 102 | uid_t uid; |
104 | gid_t gid; | 103 | gid_t gid; |
105 | dev_t rdev; | 104 | dev_t rdev; |
106 | u32 osid; | 105 | u32 osid; |
107 | }; | 106 | }; |
108 | 107 | ||
109 | struct audit_aux_data { | 108 | struct audit_aux_data { |
110 | struct audit_aux_data *next; | 109 | struct audit_aux_data *next; |
111 | int type; | 110 | int type; |
112 | }; | 111 | }; |
113 | 112 | ||
114 | #define AUDIT_AUX_IPCPERM 0 | 113 | #define AUDIT_AUX_IPCPERM 0 |
115 | 114 | ||
116 | /* Number of target pids per aux struct. */ | 115 | /* Number of target pids per aux struct. */ |
117 | #define AUDIT_AUX_PIDS 16 | 116 | #define AUDIT_AUX_PIDS 16 |
118 | 117 | ||
119 | struct audit_aux_data_mq_open { | 118 | struct audit_aux_data_mq_open { |
120 | struct audit_aux_data d; | 119 | struct audit_aux_data d; |
121 | int oflag; | 120 | int oflag; |
122 | mode_t mode; | 121 | mode_t mode; |
123 | struct mq_attr attr; | 122 | struct mq_attr attr; |
124 | }; | 123 | }; |
125 | 124 | ||
126 | struct audit_aux_data_mq_sendrecv { | 125 | struct audit_aux_data_mq_sendrecv { |
127 | struct audit_aux_data d; | 126 | struct audit_aux_data d; |
128 | mqd_t mqdes; | 127 | mqd_t mqdes; |
129 | size_t msg_len; | 128 | size_t msg_len; |
130 | unsigned int msg_prio; | 129 | unsigned int msg_prio; |
131 | struct timespec abs_timeout; | 130 | struct timespec abs_timeout; |
132 | }; | 131 | }; |
133 | 132 | ||
134 | struct audit_aux_data_mq_notify { | 133 | struct audit_aux_data_mq_notify { |
135 | struct audit_aux_data d; | 134 | struct audit_aux_data d; |
136 | mqd_t mqdes; | 135 | mqd_t mqdes; |
137 | struct sigevent notification; | 136 | struct sigevent notification; |
138 | }; | 137 | }; |
139 | 138 | ||
140 | struct audit_aux_data_mq_getsetattr { | 139 | struct audit_aux_data_mq_getsetattr { |
141 | struct audit_aux_data d; | 140 | struct audit_aux_data d; |
142 | mqd_t mqdes; | 141 | mqd_t mqdes; |
143 | struct mq_attr mqstat; | 142 | struct mq_attr mqstat; |
144 | }; | 143 | }; |
145 | 144 | ||
146 | struct audit_aux_data_ipcctl { | 145 | struct audit_aux_data_ipcctl { |
147 | struct audit_aux_data d; | 146 | struct audit_aux_data d; |
148 | struct ipc_perm p; | 147 | struct ipc_perm p; |
149 | unsigned long qbytes; | 148 | unsigned long qbytes; |
150 | uid_t uid; | 149 | uid_t uid; |
151 | gid_t gid; | 150 | gid_t gid; |
152 | mode_t mode; | 151 | mode_t mode; |
153 | u32 osid; | 152 | u32 osid; |
154 | }; | 153 | }; |
155 | 154 | ||
156 | struct audit_aux_data_execve { | 155 | struct audit_aux_data_execve { |
157 | struct audit_aux_data d; | 156 | struct audit_aux_data d; |
158 | int argc; | 157 | int argc; |
159 | int envc; | 158 | int envc; |
160 | struct mm_struct *mm; | 159 | struct mm_struct *mm; |
161 | }; | 160 | }; |
162 | 161 | ||
163 | struct audit_aux_data_socketcall { | 162 | struct audit_aux_data_socketcall { |
164 | struct audit_aux_data d; | 163 | struct audit_aux_data d; |
165 | int nargs; | 164 | int nargs; |
166 | unsigned long args[0]; | 165 | unsigned long args[0]; |
167 | }; | 166 | }; |
168 | 167 | ||
169 | struct audit_aux_data_sockaddr { | 168 | struct audit_aux_data_sockaddr { |
170 | struct audit_aux_data d; | 169 | struct audit_aux_data d; |
171 | int len; | 170 | int len; |
172 | char a[0]; | 171 | char a[0]; |
173 | }; | 172 | }; |
174 | 173 | ||
175 | struct audit_aux_data_fd_pair { | 174 | struct audit_aux_data_fd_pair { |
176 | struct audit_aux_data d; | 175 | struct audit_aux_data d; |
177 | int fd[2]; | 176 | int fd[2]; |
178 | }; | 177 | }; |
179 | 178 | ||
180 | struct audit_aux_data_pids { | 179 | struct audit_aux_data_pids { |
181 | struct audit_aux_data d; | 180 | struct audit_aux_data d; |
182 | pid_t target_pid[AUDIT_AUX_PIDS]; | 181 | pid_t target_pid[AUDIT_AUX_PIDS]; |
183 | uid_t target_auid[AUDIT_AUX_PIDS]; | 182 | uid_t target_auid[AUDIT_AUX_PIDS]; |
184 | uid_t target_uid[AUDIT_AUX_PIDS]; | 183 | uid_t target_uid[AUDIT_AUX_PIDS]; |
185 | unsigned int target_sessionid[AUDIT_AUX_PIDS]; | 184 | unsigned int target_sessionid[AUDIT_AUX_PIDS]; |
186 | u32 target_sid[AUDIT_AUX_PIDS]; | 185 | u32 target_sid[AUDIT_AUX_PIDS]; |
187 | char target_comm[AUDIT_AUX_PIDS][TASK_COMM_LEN]; | 186 | char target_comm[AUDIT_AUX_PIDS][TASK_COMM_LEN]; |
188 | int pid_count; | 187 | int pid_count; |
189 | }; | 188 | }; |
190 | 189 | ||
191 | struct audit_tree_refs { | 190 | struct audit_tree_refs { |
192 | struct audit_tree_refs *next; | 191 | struct audit_tree_refs *next; |
193 | struct audit_chunk *c[31]; | 192 | struct audit_chunk *c[31]; |
194 | }; | 193 | }; |
195 | 194 | ||
196 | /* The per-task audit context. */ | 195 | /* The per-task audit context. */ |
197 | struct audit_context { | 196 | struct audit_context { |
198 | int dummy; /* must be the first element */ | 197 | int dummy; /* must be the first element */ |
199 | int in_syscall; /* 1 if task is in a syscall */ | 198 | int in_syscall; /* 1 if task is in a syscall */ |
200 | enum audit_state state; | 199 | enum audit_state state; |
201 | unsigned int serial; /* serial number for record */ | 200 | unsigned int serial; /* serial number for record */ |
202 | struct timespec ctime; /* time of syscall entry */ | 201 | struct timespec ctime; /* time of syscall entry */ |
203 | int major; /* syscall number */ | 202 | int major; /* syscall number */ |
204 | unsigned long argv[4]; /* syscall arguments */ | 203 | unsigned long argv[4]; /* syscall arguments */ |
205 | int return_valid; /* return code is valid */ | 204 | int return_valid; /* return code is valid */ |
206 | long return_code;/* syscall return code */ | 205 | long return_code;/* syscall return code */ |
207 | int auditable; /* 1 if record should be written */ | 206 | int auditable; /* 1 if record should be written */ |
208 | int name_count; | 207 | int name_count; |
209 | struct audit_names names[AUDIT_NAMES]; | 208 | struct audit_names names[AUDIT_NAMES]; |
210 | char * filterkey; /* key for rule that triggered record */ | 209 | char * filterkey; /* key for rule that triggered record */ |
211 | struct path pwd; | 210 | struct path pwd; |
212 | struct audit_context *previous; /* For nested syscalls */ | 211 | struct audit_context *previous; /* For nested syscalls */ |
213 | struct audit_aux_data *aux; | 212 | struct audit_aux_data *aux; |
214 | struct audit_aux_data *aux_pids; | 213 | struct audit_aux_data *aux_pids; |
215 | 214 | ||
216 | /* Save things to print about task_struct */ | 215 | /* Save things to print about task_struct */ |
217 | pid_t pid, ppid; | 216 | pid_t pid, ppid; |
218 | uid_t uid, euid, suid, fsuid; | 217 | uid_t uid, euid, suid, fsuid; |
219 | gid_t gid, egid, sgid, fsgid; | 218 | gid_t gid, egid, sgid, fsgid; |
220 | unsigned long personality; | 219 | unsigned long personality; |
221 | int arch; | 220 | int arch; |
222 | 221 | ||
223 | pid_t target_pid; | 222 | pid_t target_pid; |
224 | uid_t target_auid; | 223 | uid_t target_auid; |
225 | uid_t target_uid; | 224 | uid_t target_uid; |
226 | unsigned int target_sessionid; | 225 | unsigned int target_sessionid; |
227 | u32 target_sid; | 226 | u32 target_sid; |
228 | char target_comm[TASK_COMM_LEN]; | 227 | char target_comm[TASK_COMM_LEN]; |
229 | 228 | ||
230 | struct audit_tree_refs *trees, *first_trees; | 229 | struct audit_tree_refs *trees, *first_trees; |
231 | int tree_count; | 230 | int tree_count; |
232 | 231 | ||
233 | #if AUDIT_DEBUG | 232 | #if AUDIT_DEBUG |
234 | int put_count; | 233 | int put_count; |
235 | int ino_count; | 234 | int ino_count; |
236 | #endif | 235 | #endif |
237 | }; | 236 | }; |
238 | 237 | ||
239 | #define ACC_MODE(x) ("\004\002\006\006"[(x)&O_ACCMODE]) | 238 | #define ACC_MODE(x) ("\004\002\006\006"[(x)&O_ACCMODE]) |
240 | static inline int open_arg(int flags, int mask) | 239 | static inline int open_arg(int flags, int mask) |
241 | { | 240 | { |
242 | int n = ACC_MODE(flags); | 241 | int n = ACC_MODE(flags); |
243 | if (flags & (O_TRUNC | O_CREAT)) | 242 | if (flags & (O_TRUNC | O_CREAT)) |
244 | n |= AUDIT_PERM_WRITE; | 243 | n |= AUDIT_PERM_WRITE; |
245 | return n & mask; | 244 | return n & mask; |
246 | } | 245 | } |
247 | 246 | ||
248 | static int audit_match_perm(struct audit_context *ctx, int mask) | 247 | static int audit_match_perm(struct audit_context *ctx, int mask) |
249 | { | 248 | { |
250 | unsigned n = ctx->major; | 249 | unsigned n = ctx->major; |
251 | switch (audit_classify_syscall(ctx->arch, n)) { | 250 | switch (audit_classify_syscall(ctx->arch, n)) { |
252 | case 0: /* native */ | 251 | case 0: /* native */ |
253 | if ((mask & AUDIT_PERM_WRITE) && | 252 | if ((mask & AUDIT_PERM_WRITE) && |
254 | audit_match_class(AUDIT_CLASS_WRITE, n)) | 253 | audit_match_class(AUDIT_CLASS_WRITE, n)) |
255 | return 1; | 254 | return 1; |
256 | if ((mask & AUDIT_PERM_READ) && | 255 | if ((mask & AUDIT_PERM_READ) && |
257 | audit_match_class(AUDIT_CLASS_READ, n)) | 256 | audit_match_class(AUDIT_CLASS_READ, n)) |
258 | return 1; | 257 | return 1; |
259 | if ((mask & AUDIT_PERM_ATTR) && | 258 | if ((mask & AUDIT_PERM_ATTR) && |
260 | audit_match_class(AUDIT_CLASS_CHATTR, n)) | 259 | audit_match_class(AUDIT_CLASS_CHATTR, n)) |
261 | return 1; | 260 | return 1; |
262 | return 0; | 261 | return 0; |
263 | case 1: /* 32bit on biarch */ | 262 | case 1: /* 32bit on biarch */ |
264 | if ((mask & AUDIT_PERM_WRITE) && | 263 | if ((mask & AUDIT_PERM_WRITE) && |
265 | audit_match_class(AUDIT_CLASS_WRITE_32, n)) | 264 | audit_match_class(AUDIT_CLASS_WRITE_32, n)) |
266 | return 1; | 265 | return 1; |
267 | if ((mask & AUDIT_PERM_READ) && | 266 | if ((mask & AUDIT_PERM_READ) && |
268 | audit_match_class(AUDIT_CLASS_READ_32, n)) | 267 | audit_match_class(AUDIT_CLASS_READ_32, n)) |
269 | return 1; | 268 | return 1; |
270 | if ((mask & AUDIT_PERM_ATTR) && | 269 | if ((mask & AUDIT_PERM_ATTR) && |
271 | audit_match_class(AUDIT_CLASS_CHATTR_32, n)) | 270 | audit_match_class(AUDIT_CLASS_CHATTR_32, n)) |
272 | return 1; | 271 | return 1; |
273 | return 0; | 272 | return 0; |
274 | case 2: /* open */ | 273 | case 2: /* open */ |
275 | return mask & ACC_MODE(ctx->argv[1]); | 274 | return mask & ACC_MODE(ctx->argv[1]); |
276 | case 3: /* openat */ | 275 | case 3: /* openat */ |
277 | return mask & ACC_MODE(ctx->argv[2]); | 276 | return mask & ACC_MODE(ctx->argv[2]); |
278 | case 4: /* socketcall */ | 277 | case 4: /* socketcall */ |
279 | return ((mask & AUDIT_PERM_WRITE) && ctx->argv[0] == SYS_BIND); | 278 | return ((mask & AUDIT_PERM_WRITE) && ctx->argv[0] == SYS_BIND); |
280 | case 5: /* execve */ | 279 | case 5: /* execve */ |
281 | return mask & AUDIT_PERM_EXEC; | 280 | return mask & AUDIT_PERM_EXEC; |
282 | default: | 281 | default: |
283 | return 0; | 282 | return 0; |
284 | } | 283 | } |
285 | } | 284 | } |
286 | 285 | ||
287 | /* | 286 | /* |
288 | * We keep a linked list of fixed-sized (31 pointer) arrays of audit_chunk *; | 287 | * We keep a linked list of fixed-sized (31 pointer) arrays of audit_chunk *; |
289 | * ->first_trees points to its beginning, ->trees - to the current end of data. | 288 | * ->first_trees points to its beginning, ->trees - to the current end of data. |
290 | * ->tree_count is the number of free entries in array pointed to by ->trees. | 289 | * ->tree_count is the number of free entries in array pointed to by ->trees. |
291 | * Original condition is (NULL, NULL, 0); as soon as it grows we never revert to NULL, | 290 | * Original condition is (NULL, NULL, 0); as soon as it grows we never revert to NULL, |
292 | * "empty" becomes (p, p, 31) afterwards. We don't shrink the list (and seriously, | 291 | * "empty" becomes (p, p, 31) afterwards. We don't shrink the list (and seriously, |
293 | * it's going to remain 1-element for almost any setup) until we free context itself. | 292 | * it's going to remain 1-element for almost any setup) until we free context itself. |
294 | * References in it _are_ dropped - at the same time we free/drop aux stuff. | 293 | * References in it _are_ dropped - at the same time we free/drop aux stuff. |
295 | */ | 294 | */ |
296 | 295 | ||
297 | #ifdef CONFIG_AUDIT_TREE | 296 | #ifdef CONFIG_AUDIT_TREE |
298 | static int put_tree_ref(struct audit_context *ctx, struct audit_chunk *chunk) | 297 | static int put_tree_ref(struct audit_context *ctx, struct audit_chunk *chunk) |
299 | { | 298 | { |
300 | struct audit_tree_refs *p = ctx->trees; | 299 | struct audit_tree_refs *p = ctx->trees; |
301 | int left = ctx->tree_count; | 300 | int left = ctx->tree_count; |
302 | if (likely(left)) { | 301 | if (likely(left)) { |
303 | p->c[--left] = chunk; | 302 | p->c[--left] = chunk; |
304 | ctx->tree_count = left; | 303 | ctx->tree_count = left; |
305 | return 1; | 304 | return 1; |
306 | } | 305 | } |
307 | if (!p) | 306 | if (!p) |
308 | return 0; | 307 | return 0; |
309 | p = p->next; | 308 | p = p->next; |
310 | if (p) { | 309 | if (p) { |
311 | p->c[30] = chunk; | 310 | p->c[30] = chunk; |
312 | ctx->trees = p; | 311 | ctx->trees = p; |
313 | ctx->tree_count = 30; | 312 | ctx->tree_count = 30; |
314 | return 1; | 313 | return 1; |
315 | } | 314 | } |
316 | return 0; | 315 | return 0; |
317 | } | 316 | } |
318 | 317 | ||
319 | static int grow_tree_refs(struct audit_context *ctx) | 318 | static int grow_tree_refs(struct audit_context *ctx) |
320 | { | 319 | { |
321 | struct audit_tree_refs *p = ctx->trees; | 320 | struct audit_tree_refs *p = ctx->trees; |
322 | ctx->trees = kzalloc(sizeof(struct audit_tree_refs), GFP_KERNEL); | 321 | ctx->trees = kzalloc(sizeof(struct audit_tree_refs), GFP_KERNEL); |
323 | if (!ctx->trees) { | 322 | if (!ctx->trees) { |
324 | ctx->trees = p; | 323 | ctx->trees = p; |
325 | return 0; | 324 | return 0; |
326 | } | 325 | } |
327 | if (p) | 326 | if (p) |
328 | p->next = ctx->trees; | 327 | p->next = ctx->trees; |
329 | else | 328 | else |
330 | ctx->first_trees = ctx->trees; | 329 | ctx->first_trees = ctx->trees; |
331 | ctx->tree_count = 31; | 330 | ctx->tree_count = 31; |
332 | return 1; | 331 | return 1; |
333 | } | 332 | } |
334 | #endif | 333 | #endif |
335 | 334 | ||
336 | static void unroll_tree_refs(struct audit_context *ctx, | 335 | static void unroll_tree_refs(struct audit_context *ctx, |
337 | struct audit_tree_refs *p, int count) | 336 | struct audit_tree_refs *p, int count) |
338 | { | 337 | { |
339 | #ifdef CONFIG_AUDIT_TREE | 338 | #ifdef CONFIG_AUDIT_TREE |
340 | struct audit_tree_refs *q; | 339 | struct audit_tree_refs *q; |
341 | int n; | 340 | int n; |
342 | if (!p) { | 341 | if (!p) { |
343 | /* we started with empty chain */ | 342 | /* we started with empty chain */ |
344 | p = ctx->first_trees; | 343 | p = ctx->first_trees; |
345 | count = 31; | 344 | count = 31; |
346 | /* if the very first allocation has failed, nothing to do */ | 345 | /* if the very first allocation has failed, nothing to do */ |
347 | if (!p) | 346 | if (!p) |
348 | return; | 347 | return; |
349 | } | 348 | } |
350 | n = count; | 349 | n = count; |
351 | for (q = p; q != ctx->trees; q = q->next, n = 31) { | 350 | for (q = p; q != ctx->trees; q = q->next, n = 31) { |
352 | while (n--) { | 351 | while (n--) { |
353 | audit_put_chunk(q->c[n]); | 352 | audit_put_chunk(q->c[n]); |
354 | q->c[n] = NULL; | 353 | q->c[n] = NULL; |
355 | } | 354 | } |
356 | } | 355 | } |
357 | while (n-- > ctx->tree_count) { | 356 | while (n-- > ctx->tree_count) { |
358 | audit_put_chunk(q->c[n]); | 357 | audit_put_chunk(q->c[n]); |
359 | q->c[n] = NULL; | 358 | q->c[n] = NULL; |
360 | } | 359 | } |
361 | ctx->trees = p; | 360 | ctx->trees = p; |
362 | ctx->tree_count = count; | 361 | ctx->tree_count = count; |
363 | #endif | 362 | #endif |
364 | } | 363 | } |
365 | 364 | ||
366 | static void free_tree_refs(struct audit_context *ctx) | 365 | static void free_tree_refs(struct audit_context *ctx) |
367 | { | 366 | { |
368 | struct audit_tree_refs *p, *q; | 367 | struct audit_tree_refs *p, *q; |
369 | for (p = ctx->first_trees; p; p = q) { | 368 | for (p = ctx->first_trees; p; p = q) { |
370 | q = p->next; | 369 | q = p->next; |
371 | kfree(p); | 370 | kfree(p); |
372 | } | 371 | } |
373 | } | 372 | } |
374 | 373 | ||
375 | static int match_tree_refs(struct audit_context *ctx, struct audit_tree *tree) | 374 | static int match_tree_refs(struct audit_context *ctx, struct audit_tree *tree) |
376 | { | 375 | { |
377 | #ifdef CONFIG_AUDIT_TREE | 376 | #ifdef CONFIG_AUDIT_TREE |
378 | struct audit_tree_refs *p; | 377 | struct audit_tree_refs *p; |
379 | int n; | 378 | int n; |
380 | if (!tree) | 379 | if (!tree) |
381 | return 0; | 380 | return 0; |
382 | /* full ones */ | 381 | /* full ones */ |
383 | for (p = ctx->first_trees; p != ctx->trees; p = p->next) { | 382 | for (p = ctx->first_trees; p != ctx->trees; p = p->next) { |
384 | for (n = 0; n < 31; n++) | 383 | for (n = 0; n < 31; n++) |
385 | if (audit_tree_match(p->c[n], tree)) | 384 | if (audit_tree_match(p->c[n], tree)) |
386 | return 1; | 385 | return 1; |
387 | } | 386 | } |
388 | /* partial */ | 387 | /* partial */ |
389 | if (p) { | 388 | if (p) { |
390 | for (n = ctx->tree_count; n < 31; n++) | 389 | for (n = ctx->tree_count; n < 31; n++) |
391 | if (audit_tree_match(p->c[n], tree)) | 390 | if (audit_tree_match(p->c[n], tree)) |
392 | return 1; | 391 | return 1; |
393 | } | 392 | } |
394 | #endif | 393 | #endif |
395 | return 0; | 394 | return 0; |
396 | } | 395 | } |
397 | 396 | ||
398 | /* Determine if any context name data matches a rule's watch data */ | 397 | /* Determine if any context name data matches a rule's watch data */ |
399 | /* Compare a task_struct with an audit_rule. Return 1 on match, 0 | 398 | /* Compare a task_struct with an audit_rule. Return 1 on match, 0 |
400 | * otherwise. */ | 399 | * otherwise. */ |
401 | static int audit_filter_rules(struct task_struct *tsk, | 400 | static int audit_filter_rules(struct task_struct *tsk, |
402 | struct audit_krule *rule, | 401 | struct audit_krule *rule, |
403 | struct audit_context *ctx, | 402 | struct audit_context *ctx, |
404 | struct audit_names *name, | 403 | struct audit_names *name, |
405 | enum audit_state *state) | 404 | enum audit_state *state) |
406 | { | 405 | { |
407 | int i, j, need_sid = 1; | 406 | int i, j, need_sid = 1; |
408 | u32 sid; | 407 | u32 sid; |
409 | 408 | ||
410 | for (i = 0; i < rule->field_count; i++) { | 409 | for (i = 0; i < rule->field_count; i++) { |
411 | struct audit_field *f = &rule->fields[i]; | 410 | struct audit_field *f = &rule->fields[i]; |
412 | int result = 0; | 411 | int result = 0; |
413 | 412 | ||
414 | switch (f->type) { | 413 | switch (f->type) { |
415 | case AUDIT_PID: | 414 | case AUDIT_PID: |
416 | result = audit_comparator(tsk->pid, f->op, f->val); | 415 | result = audit_comparator(tsk->pid, f->op, f->val); |
417 | break; | 416 | break; |
418 | case AUDIT_PPID: | 417 | case AUDIT_PPID: |
419 | if (ctx) { | 418 | if (ctx) { |
420 | if (!ctx->ppid) | 419 | if (!ctx->ppid) |
421 | ctx->ppid = sys_getppid(); | 420 | ctx->ppid = sys_getppid(); |
422 | result = audit_comparator(ctx->ppid, f->op, f->val); | 421 | result = audit_comparator(ctx->ppid, f->op, f->val); |
423 | } | 422 | } |
424 | break; | 423 | break; |
425 | case AUDIT_UID: | 424 | case AUDIT_UID: |
426 | result = audit_comparator(tsk->uid, f->op, f->val); | 425 | result = audit_comparator(tsk->uid, f->op, f->val); |
427 | break; | 426 | break; |
428 | case AUDIT_EUID: | 427 | case AUDIT_EUID: |
429 | result = audit_comparator(tsk->euid, f->op, f->val); | 428 | result = audit_comparator(tsk->euid, f->op, f->val); |
430 | break; | 429 | break; |
431 | case AUDIT_SUID: | 430 | case AUDIT_SUID: |
432 | result = audit_comparator(tsk->suid, f->op, f->val); | 431 | result = audit_comparator(tsk->suid, f->op, f->val); |
433 | break; | 432 | break; |
434 | case AUDIT_FSUID: | 433 | case AUDIT_FSUID: |
435 | result = audit_comparator(tsk->fsuid, f->op, f->val); | 434 | result = audit_comparator(tsk->fsuid, f->op, f->val); |
436 | break; | 435 | break; |
437 | case AUDIT_GID: | 436 | case AUDIT_GID: |
438 | result = audit_comparator(tsk->gid, f->op, f->val); | 437 | result = audit_comparator(tsk->gid, f->op, f->val); |
439 | break; | 438 | break; |
440 | case AUDIT_EGID: | 439 | case AUDIT_EGID: |
441 | result = audit_comparator(tsk->egid, f->op, f->val); | 440 | result = audit_comparator(tsk->egid, f->op, f->val); |
442 | break; | 441 | break; |
443 | case AUDIT_SGID: | 442 | case AUDIT_SGID: |
444 | result = audit_comparator(tsk->sgid, f->op, f->val); | 443 | result = audit_comparator(tsk->sgid, f->op, f->val); |
445 | break; | 444 | break; |
446 | case AUDIT_FSGID: | 445 | case AUDIT_FSGID: |
447 | result = audit_comparator(tsk->fsgid, f->op, f->val); | 446 | result = audit_comparator(tsk->fsgid, f->op, f->val); |
448 | break; | 447 | break; |
449 | case AUDIT_PERS: | 448 | case AUDIT_PERS: |
450 | result = audit_comparator(tsk->personality, f->op, f->val); | 449 | result = audit_comparator(tsk->personality, f->op, f->val); |
451 | break; | 450 | break; |
452 | case AUDIT_ARCH: | 451 | case AUDIT_ARCH: |
453 | if (ctx) | 452 | if (ctx) |
454 | result = audit_comparator(ctx->arch, f->op, f->val); | 453 | result = audit_comparator(ctx->arch, f->op, f->val); |
455 | break; | 454 | break; |
456 | 455 | ||
457 | case AUDIT_EXIT: | 456 | case AUDIT_EXIT: |
458 | if (ctx && ctx->return_valid) | 457 | if (ctx && ctx->return_valid) |
459 | result = audit_comparator(ctx->return_code, f->op, f->val); | 458 | result = audit_comparator(ctx->return_code, f->op, f->val); |
460 | break; | 459 | break; |
461 | case AUDIT_SUCCESS: | 460 | case AUDIT_SUCCESS: |
462 | if (ctx && ctx->return_valid) { | 461 | if (ctx && ctx->return_valid) { |
463 | if (f->val) | 462 | if (f->val) |
464 | result = audit_comparator(ctx->return_valid, f->op, AUDITSC_SUCCESS); | 463 | result = audit_comparator(ctx->return_valid, f->op, AUDITSC_SUCCESS); |
465 | else | 464 | else |
466 | result = audit_comparator(ctx->return_valid, f->op, AUDITSC_FAILURE); | 465 | result = audit_comparator(ctx->return_valid, f->op, AUDITSC_FAILURE); |
467 | } | 466 | } |
468 | break; | 467 | break; |
469 | case AUDIT_DEVMAJOR: | 468 | case AUDIT_DEVMAJOR: |
470 | if (name) | 469 | if (name) |
471 | result = audit_comparator(MAJOR(name->dev), | 470 | result = audit_comparator(MAJOR(name->dev), |
472 | f->op, f->val); | 471 | f->op, f->val); |
473 | else if (ctx) { | 472 | else if (ctx) { |
474 | for (j = 0; j < ctx->name_count; j++) { | 473 | for (j = 0; j < ctx->name_count; j++) { |
475 | if (audit_comparator(MAJOR(ctx->names[j].dev), f->op, f->val)) { | 474 | if (audit_comparator(MAJOR(ctx->names[j].dev), f->op, f->val)) { |
476 | ++result; | 475 | ++result; |
477 | break; | 476 | break; |
478 | } | 477 | } |
479 | } | 478 | } |
480 | } | 479 | } |
481 | break; | 480 | break; |
482 | case AUDIT_DEVMINOR: | 481 | case AUDIT_DEVMINOR: |
483 | if (name) | 482 | if (name) |
484 | result = audit_comparator(MINOR(name->dev), | 483 | result = audit_comparator(MINOR(name->dev), |
485 | f->op, f->val); | 484 | f->op, f->val); |
486 | else if (ctx) { | 485 | else if (ctx) { |
487 | for (j = 0; j < ctx->name_count; j++) { | 486 | for (j = 0; j < ctx->name_count; j++) { |
488 | if (audit_comparator(MINOR(ctx->names[j].dev), f->op, f->val)) { | 487 | if (audit_comparator(MINOR(ctx->names[j].dev), f->op, f->val)) { |
489 | ++result; | 488 | ++result; |
490 | break; | 489 | break; |
491 | } | 490 | } |
492 | } | 491 | } |
493 | } | 492 | } |
494 | break; | 493 | break; |
495 | case AUDIT_INODE: | 494 | case AUDIT_INODE: |
496 | if (name) | 495 | if (name) |
497 | result = (name->ino == f->val); | 496 | result = (name->ino == f->val); |
498 | else if (ctx) { | 497 | else if (ctx) { |
499 | for (j = 0; j < ctx->name_count; j++) { | 498 | for (j = 0; j < ctx->name_count; j++) { |
500 | if (audit_comparator(ctx->names[j].ino, f->op, f->val)) { | 499 | if (audit_comparator(ctx->names[j].ino, f->op, f->val)) { |
501 | ++result; | 500 | ++result; |
502 | break; | 501 | break; |
503 | } | 502 | } |
504 | } | 503 | } |
505 | } | 504 | } |
506 | break; | 505 | break; |
507 | case AUDIT_WATCH: | 506 | case AUDIT_WATCH: |
508 | if (name && rule->watch->ino != (unsigned long)-1) | 507 | if (name && rule->watch->ino != (unsigned long)-1) |
509 | result = (name->dev == rule->watch->dev && | 508 | result = (name->dev == rule->watch->dev && |
510 | name->ino == rule->watch->ino); | 509 | name->ino == rule->watch->ino); |
511 | break; | 510 | break; |
512 | case AUDIT_DIR: | 511 | case AUDIT_DIR: |
513 | if (ctx) | 512 | if (ctx) |
514 | result = match_tree_refs(ctx, rule->tree); | 513 | result = match_tree_refs(ctx, rule->tree); |
515 | break; | 514 | break; |
516 | case AUDIT_LOGINUID: | 515 | case AUDIT_LOGINUID: |
517 | result = 0; | 516 | result = 0; |
518 | if (ctx) | 517 | if (ctx) |
519 | result = audit_comparator(tsk->loginuid, f->op, f->val); | 518 | result = audit_comparator(tsk->loginuid, f->op, f->val); |
520 | break; | 519 | break; |
521 | case AUDIT_SUBJ_USER: | 520 | case AUDIT_SUBJ_USER: |
522 | case AUDIT_SUBJ_ROLE: | 521 | case AUDIT_SUBJ_ROLE: |
523 | case AUDIT_SUBJ_TYPE: | 522 | case AUDIT_SUBJ_TYPE: |
524 | case AUDIT_SUBJ_SEN: | 523 | case AUDIT_SUBJ_SEN: |
525 | case AUDIT_SUBJ_CLR: | 524 | case AUDIT_SUBJ_CLR: |
526 | /* NOTE: this may return negative values indicating | 525 | /* NOTE: this may return negative values indicating |
527 | a temporary error. We simply treat this as a | 526 | a temporary error. We simply treat this as a |
528 | match for now to avoid losing information that | 527 | match for now to avoid losing information that |
529 | may be wanted. An error message will also be | 528 | may be wanted. An error message will also be |
530 | logged upon error */ | 529 | logged upon error */ |
531 | if (f->se_rule) { | 530 | if (f->se_rule) { |
532 | if (need_sid) { | 531 | if (need_sid) { |
533 | security_task_getsecid(tsk, &sid); | 532 | security_task_getsecid(tsk, &sid); |
534 | need_sid = 0; | 533 | need_sid = 0; |
535 | } | 534 | } |
536 | result = selinux_audit_rule_match(sid, f->type, | 535 | result = security_audit_rule_match(sid, f->type, |
537 | f->op, | 536 | f->op, |
538 | f->se_rule, | 537 | f->se_rule, |
539 | ctx); | 538 | ctx); |
540 | } | 539 | } |
541 | break; | 540 | break; |
542 | case AUDIT_OBJ_USER: | 541 | case AUDIT_OBJ_USER: |
543 | case AUDIT_OBJ_ROLE: | 542 | case AUDIT_OBJ_ROLE: |
544 | case AUDIT_OBJ_TYPE: | 543 | case AUDIT_OBJ_TYPE: |
545 | case AUDIT_OBJ_LEV_LOW: | 544 | case AUDIT_OBJ_LEV_LOW: |
546 | case AUDIT_OBJ_LEV_HIGH: | 545 | case AUDIT_OBJ_LEV_HIGH: |
547 | /* The above note for AUDIT_SUBJ_USER...AUDIT_SUBJ_CLR | 546 | /* The above note for AUDIT_SUBJ_USER...AUDIT_SUBJ_CLR |
548 | also applies here */ | 547 | also applies here */ |
549 | if (f->se_rule) { | 548 | if (f->se_rule) { |
550 | /* Find files that match */ | 549 | /* Find files that match */ |
551 | if (name) { | 550 | if (name) { |
552 | result = selinux_audit_rule_match( | 551 | result = security_audit_rule_match( |
553 | name->osid, f->type, f->op, | 552 | name->osid, f->type, f->op, |
554 | f->se_rule, ctx); | 553 | f->se_rule, ctx); |
555 | } else if (ctx) { | 554 | } else if (ctx) { |
556 | for (j = 0; j < ctx->name_count; j++) { | 555 | for (j = 0; j < ctx->name_count; j++) { |
557 | if (selinux_audit_rule_match( | 556 | if (security_audit_rule_match( |
558 | ctx->names[j].osid, | 557 | ctx->names[j].osid, |
559 | f->type, f->op, | 558 | f->type, f->op, |
560 | f->se_rule, ctx)) { | 559 | f->se_rule, ctx)) { |
561 | ++result; | 560 | ++result; |
562 | break; | 561 | break; |
563 | } | 562 | } |
564 | } | 563 | } |
565 | } | 564 | } |
566 | /* Find ipc objects that match */ | 565 | /* Find ipc objects that match */ |
567 | if (ctx) { | 566 | if (ctx) { |
568 | struct audit_aux_data *aux; | 567 | struct audit_aux_data *aux; |
569 | for (aux = ctx->aux; aux; | 568 | for (aux = ctx->aux; aux; |
570 | aux = aux->next) { | 569 | aux = aux->next) { |
571 | if (aux->type == AUDIT_IPC) { | 570 | if (aux->type == AUDIT_IPC) { |
572 | struct audit_aux_data_ipcctl *axi = (void *)aux; | 571 | struct audit_aux_data_ipcctl *axi = (void *)aux; |
573 | if (selinux_audit_rule_match(axi->osid, f->type, f->op, f->se_rule, ctx)) { | 572 | if (security_audit_rule_match(axi->osid, f->type, f->op, f->se_rule, ctx)) { |
574 | ++result; | 573 | ++result; |
575 | break; | 574 | break; |
576 | } | 575 | } |
577 | } | 576 | } |
578 | } | 577 | } |
579 | } | 578 | } |
580 | } | 579 | } |
581 | break; | 580 | break; |
582 | case AUDIT_ARG0: | 581 | case AUDIT_ARG0: |
583 | case AUDIT_ARG1: | 582 | case AUDIT_ARG1: |
584 | case AUDIT_ARG2: | 583 | case AUDIT_ARG2: |
585 | case AUDIT_ARG3: | 584 | case AUDIT_ARG3: |
586 | if (ctx) | 585 | if (ctx) |
587 | result = audit_comparator(ctx->argv[f->type-AUDIT_ARG0], f->op, f->val); | 586 | result = audit_comparator(ctx->argv[f->type-AUDIT_ARG0], f->op, f->val); |
588 | break; | 587 | break; |
589 | case AUDIT_FILTERKEY: | 588 | case AUDIT_FILTERKEY: |
590 | /* ignore this field for filtering */ | 589 | /* ignore this field for filtering */ |
591 | result = 1; | 590 | result = 1; |
592 | break; | 591 | break; |
593 | case AUDIT_PERM: | 592 | case AUDIT_PERM: |
594 | result = audit_match_perm(ctx, f->val); | 593 | result = audit_match_perm(ctx, f->val); |
595 | break; | 594 | break; |
596 | } | 595 | } |
597 | 596 | ||
598 | if (!result) | 597 | if (!result) |
599 | return 0; | 598 | return 0; |
600 | } | 599 | } |
601 | if (rule->filterkey) | 600 | if (rule->filterkey) |
602 | ctx->filterkey = kstrdup(rule->filterkey, GFP_ATOMIC); | 601 | ctx->filterkey = kstrdup(rule->filterkey, GFP_ATOMIC); |
603 | switch (rule->action) { | 602 | switch (rule->action) { |
604 | case AUDIT_NEVER: *state = AUDIT_DISABLED; break; | 603 | case AUDIT_NEVER: *state = AUDIT_DISABLED; break; |
605 | case AUDIT_ALWAYS: *state = AUDIT_RECORD_CONTEXT; break; | 604 | case AUDIT_ALWAYS: *state = AUDIT_RECORD_CONTEXT; break; |
606 | } | 605 | } |
607 | return 1; | 606 | return 1; |
608 | } | 607 | } |
609 | 608 | ||
610 | /* At process creation time, we can determine if system-call auditing is | 609 | /* At process creation time, we can determine if system-call auditing is |
611 | * completely disabled for this task. Since we only have the task | 610 | * completely disabled for this task. Since we only have the task |
612 | * structure at this point, we can only check uid and gid. | 611 | * structure at this point, we can only check uid and gid. |
613 | */ | 612 | */ |
614 | static enum audit_state audit_filter_task(struct task_struct *tsk) | 613 | static enum audit_state audit_filter_task(struct task_struct *tsk) |
615 | { | 614 | { |
616 | struct audit_entry *e; | 615 | struct audit_entry *e; |
617 | enum audit_state state; | 616 | enum audit_state state; |
618 | 617 | ||
619 | rcu_read_lock(); | 618 | rcu_read_lock(); |
620 | list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TASK], list) { | 619 | list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TASK], list) { |
621 | if (audit_filter_rules(tsk, &e->rule, NULL, NULL, &state)) { | 620 | if (audit_filter_rules(tsk, &e->rule, NULL, NULL, &state)) { |
622 | rcu_read_unlock(); | 621 | rcu_read_unlock(); |
623 | return state; | 622 | return state; |
624 | } | 623 | } |
625 | } | 624 | } |
626 | rcu_read_unlock(); | 625 | rcu_read_unlock(); |
627 | return AUDIT_BUILD_CONTEXT; | 626 | return AUDIT_BUILD_CONTEXT; |
628 | } | 627 | } |
629 | 628 | ||
630 | /* At syscall entry and exit time, this filter is called if the | 629 | /* At syscall entry and exit time, this filter is called if the |
631 | * audit_state is not low enough that auditing cannot take place, but is | 630 | * audit_state is not low enough that auditing cannot take place, but is |
632 | * also not high enough that we already know we have to write an audit | 631 | * also not high enough that we already know we have to write an audit |
633 | * record (i.e., the state is AUDIT_SETUP_CONTEXT or AUDIT_BUILD_CONTEXT). | 632 | * record (i.e., the state is AUDIT_SETUP_CONTEXT or AUDIT_BUILD_CONTEXT). |
634 | */ | 633 | */ |
635 | static enum audit_state audit_filter_syscall(struct task_struct *tsk, | 634 | static enum audit_state audit_filter_syscall(struct task_struct *tsk, |
636 | struct audit_context *ctx, | 635 | struct audit_context *ctx, |
637 | struct list_head *list) | 636 | struct list_head *list) |
638 | { | 637 | { |
639 | struct audit_entry *e; | 638 | struct audit_entry *e; |
640 | enum audit_state state; | 639 | enum audit_state state; |
641 | 640 | ||
642 | if (audit_pid && tsk->tgid == audit_pid) | 641 | if (audit_pid && tsk->tgid == audit_pid) |
643 | return AUDIT_DISABLED; | 642 | return AUDIT_DISABLED; |
644 | 643 | ||
645 | rcu_read_lock(); | 644 | rcu_read_lock(); |
646 | if (!list_empty(list)) { | 645 | if (!list_empty(list)) { |
647 | int word = AUDIT_WORD(ctx->major); | 646 | int word = AUDIT_WORD(ctx->major); |
648 | int bit = AUDIT_BIT(ctx->major); | 647 | int bit = AUDIT_BIT(ctx->major); |
649 | 648 | ||
650 | list_for_each_entry_rcu(e, list, list) { | 649 | list_for_each_entry_rcu(e, list, list) { |
651 | if ((e->rule.mask[word] & bit) == bit && | 650 | if ((e->rule.mask[word] & bit) == bit && |
652 | audit_filter_rules(tsk, &e->rule, ctx, NULL, | 651 | audit_filter_rules(tsk, &e->rule, ctx, NULL, |
653 | &state)) { | 652 | &state)) { |
654 | rcu_read_unlock(); | 653 | rcu_read_unlock(); |
655 | return state; | 654 | return state; |
656 | } | 655 | } |
657 | } | 656 | } |
658 | } | 657 | } |
659 | rcu_read_unlock(); | 658 | rcu_read_unlock(); |
660 | return AUDIT_BUILD_CONTEXT; | 659 | return AUDIT_BUILD_CONTEXT; |
661 | } | 660 | } |
662 | 661 | ||
663 | /* At syscall exit time, this filter is called if any audit_names[] have been | 662 | /* At syscall exit time, this filter is called if any audit_names[] have been |
664 | * collected during syscall processing. We only check rules in sublists at hash | 663 | * collected during syscall processing. We only check rules in sublists at hash |
665 | * buckets applicable to the inode numbers in audit_names[]. | 664 | * buckets applicable to the inode numbers in audit_names[]. |
666 | * Regarding audit_state, same rules apply as for audit_filter_syscall(). | 665 | * Regarding audit_state, same rules apply as for audit_filter_syscall(). |
667 | */ | 666 | */ |
668 | enum audit_state audit_filter_inodes(struct task_struct *tsk, | 667 | enum audit_state audit_filter_inodes(struct task_struct *tsk, |
669 | struct audit_context *ctx) | 668 | struct audit_context *ctx) |
670 | { | 669 | { |
671 | int i; | 670 | int i; |
672 | struct audit_entry *e; | 671 | struct audit_entry *e; |
673 | enum audit_state state; | 672 | enum audit_state state; |
674 | 673 | ||
675 | if (audit_pid && tsk->tgid == audit_pid) | 674 | if (audit_pid && tsk->tgid == audit_pid) |
676 | return AUDIT_DISABLED; | 675 | return AUDIT_DISABLED; |
677 | 676 | ||
678 | rcu_read_lock(); | 677 | rcu_read_lock(); |
679 | for (i = 0; i < ctx->name_count; i++) { | 678 | for (i = 0; i < ctx->name_count; i++) { |
680 | int word = AUDIT_WORD(ctx->major); | 679 | int word = AUDIT_WORD(ctx->major); |
681 | int bit = AUDIT_BIT(ctx->major); | 680 | int bit = AUDIT_BIT(ctx->major); |
682 | struct audit_names *n = &ctx->names[i]; | 681 | struct audit_names *n = &ctx->names[i]; |
683 | int h = audit_hash_ino((u32)n->ino); | 682 | int h = audit_hash_ino((u32)n->ino); |
684 | struct list_head *list = &audit_inode_hash[h]; | 683 | struct list_head *list = &audit_inode_hash[h]; |
685 | 684 | ||
686 | if (list_empty(list)) | 685 | if (list_empty(list)) |
687 | continue; | 686 | continue; |
688 | 687 | ||
689 | list_for_each_entry_rcu(e, list, list) { | 688 | list_for_each_entry_rcu(e, list, list) { |
690 | if ((e->rule.mask[word] & bit) == bit && | 689 | if ((e->rule.mask[word] & bit) == bit && |
691 | audit_filter_rules(tsk, &e->rule, ctx, n, &state)) { | 690 | audit_filter_rules(tsk, &e->rule, ctx, n, &state)) { |
692 | rcu_read_unlock(); | 691 | rcu_read_unlock(); |
693 | return state; | 692 | return state; |
694 | } | 693 | } |
695 | } | 694 | } |
696 | } | 695 | } |
697 | rcu_read_unlock(); | 696 | rcu_read_unlock(); |
698 | return AUDIT_BUILD_CONTEXT; | 697 | return AUDIT_BUILD_CONTEXT; |
699 | } | 698 | } |
700 | 699 | ||
701 | void audit_set_auditable(struct audit_context *ctx) | 700 | void audit_set_auditable(struct audit_context *ctx) |
702 | { | 701 | { |
703 | ctx->auditable = 1; | 702 | ctx->auditable = 1; |
704 | } | 703 | } |
705 | 704 | ||
706 | static inline struct audit_context *audit_get_context(struct task_struct *tsk, | 705 | static inline struct audit_context *audit_get_context(struct task_struct *tsk, |
707 | int return_valid, | 706 | int return_valid, |
708 | int return_code) | 707 | int return_code) |
709 | { | 708 | { |
710 | struct audit_context *context = tsk->audit_context; | 709 | struct audit_context *context = tsk->audit_context; |
711 | 710 | ||
712 | if (likely(!context)) | 711 | if (likely(!context)) |
713 | return NULL; | 712 | return NULL; |
714 | context->return_valid = return_valid; | 713 | context->return_valid = return_valid; |
715 | 714 | ||
716 | /* | 715 | /* |
717 | * we need to fix up the return code in the audit logs if the actual | 716 | * we need to fix up the return code in the audit logs if the actual |
718 | * return codes are later going to be fixed up by the arch specific | 717 | * return codes are later going to be fixed up by the arch specific |
719 | * signal handlers | 718 | * signal handlers |
720 | * | 719 | * |
721 | * This is actually a test for: | 720 | * This is actually a test for: |
722 | * (rc == ERESTARTSYS ) || (rc == ERESTARTNOINTR) || | 721 | * (rc == ERESTARTSYS ) || (rc == ERESTARTNOINTR) || |
723 | * (rc == ERESTARTNOHAND) || (rc == ERESTART_RESTARTBLOCK) | 722 | * (rc == ERESTARTNOHAND) || (rc == ERESTART_RESTARTBLOCK) |
724 | * | 723 | * |
725 | * but is faster than a bunch of || | 724 | * but is faster than a bunch of || |
726 | */ | 725 | */ |
727 | if (unlikely(return_code <= -ERESTARTSYS) && | 726 | if (unlikely(return_code <= -ERESTARTSYS) && |
728 | (return_code >= -ERESTART_RESTARTBLOCK) && | 727 | (return_code >= -ERESTART_RESTARTBLOCK) && |
729 | (return_code != -ENOIOCTLCMD)) | 728 | (return_code != -ENOIOCTLCMD)) |
730 | context->return_code = -EINTR; | 729 | context->return_code = -EINTR; |
731 | else | 730 | else |
732 | context->return_code = return_code; | 731 | context->return_code = return_code; |
733 | 732 | ||
734 | if (context->in_syscall && !context->dummy && !context->auditable) { | 733 | if (context->in_syscall && !context->dummy && !context->auditable) { |
735 | enum audit_state state; | 734 | enum audit_state state; |
736 | 735 | ||
737 | state = audit_filter_syscall(tsk, context, &audit_filter_list[AUDIT_FILTER_EXIT]); | 736 | state = audit_filter_syscall(tsk, context, &audit_filter_list[AUDIT_FILTER_EXIT]); |
738 | if (state == AUDIT_RECORD_CONTEXT) { | 737 | if (state == AUDIT_RECORD_CONTEXT) { |
739 | context->auditable = 1; | 738 | context->auditable = 1; |
740 | goto get_context; | 739 | goto get_context; |
741 | } | 740 | } |
742 | 741 | ||
743 | state = audit_filter_inodes(tsk, context); | 742 | state = audit_filter_inodes(tsk, context); |
744 | if (state == AUDIT_RECORD_CONTEXT) | 743 | if (state == AUDIT_RECORD_CONTEXT) |
745 | context->auditable = 1; | 744 | context->auditable = 1; |
746 | 745 | ||
747 | } | 746 | } |
748 | 747 | ||
749 | get_context: | 748 | get_context: |
750 | 749 | ||
751 | tsk->audit_context = NULL; | 750 | tsk->audit_context = NULL; |
752 | return context; | 751 | return context; |
753 | } | 752 | } |
754 | 753 | ||
755 | static inline void audit_free_names(struct audit_context *context) | 754 | static inline void audit_free_names(struct audit_context *context) |
756 | { | 755 | { |
757 | int i; | 756 | int i; |
758 | 757 | ||
759 | #if AUDIT_DEBUG == 2 | 758 | #if AUDIT_DEBUG == 2 |
760 | if (context->auditable | 759 | if (context->auditable |
761 | ||context->put_count + context->ino_count != context->name_count) { | 760 | ||context->put_count + context->ino_count != context->name_count) { |
762 | printk(KERN_ERR "%s:%d(:%d): major=%d in_syscall=%d" | 761 | printk(KERN_ERR "%s:%d(:%d): major=%d in_syscall=%d" |
763 | " name_count=%d put_count=%d" | 762 | " name_count=%d put_count=%d" |
764 | " ino_count=%d [NOT freeing]\n", | 763 | " ino_count=%d [NOT freeing]\n", |
765 | __FILE__, __LINE__, | 764 | __FILE__, __LINE__, |
766 | context->serial, context->major, context->in_syscall, | 765 | context->serial, context->major, context->in_syscall, |
767 | context->name_count, context->put_count, | 766 | context->name_count, context->put_count, |
768 | context->ino_count); | 767 | context->ino_count); |
769 | for (i = 0; i < context->name_count; i++) { | 768 | for (i = 0; i < context->name_count; i++) { |
770 | printk(KERN_ERR "names[%d] = %p = %s\n", i, | 769 | printk(KERN_ERR "names[%d] = %p = %s\n", i, |
771 | context->names[i].name, | 770 | context->names[i].name, |
772 | context->names[i].name ?: "(null)"); | 771 | context->names[i].name ?: "(null)"); |
773 | } | 772 | } |
774 | dump_stack(); | 773 | dump_stack(); |
775 | return; | 774 | return; |
776 | } | 775 | } |
777 | #endif | 776 | #endif |
778 | #if AUDIT_DEBUG | 777 | #if AUDIT_DEBUG |
779 | context->put_count = 0; | 778 | context->put_count = 0; |
780 | context->ino_count = 0; | 779 | context->ino_count = 0; |
781 | #endif | 780 | #endif |
782 | 781 | ||
783 | for (i = 0; i < context->name_count; i++) { | 782 | for (i = 0; i < context->name_count; i++) { |
784 | if (context->names[i].name && context->names[i].name_put) | 783 | if (context->names[i].name && context->names[i].name_put) |
785 | __putname(context->names[i].name); | 784 | __putname(context->names[i].name); |
786 | } | 785 | } |
787 | context->name_count = 0; | 786 | context->name_count = 0; |
788 | path_put(&context->pwd); | 787 | path_put(&context->pwd); |
789 | context->pwd.dentry = NULL; | 788 | context->pwd.dentry = NULL; |
790 | context->pwd.mnt = NULL; | 789 | context->pwd.mnt = NULL; |
791 | } | 790 | } |
792 | 791 | ||
793 | static inline void audit_free_aux(struct audit_context *context) | 792 | static inline void audit_free_aux(struct audit_context *context) |
794 | { | 793 | { |
795 | struct audit_aux_data *aux; | 794 | struct audit_aux_data *aux; |
796 | 795 | ||
797 | while ((aux = context->aux)) { | 796 | while ((aux = context->aux)) { |
798 | context->aux = aux->next; | 797 | context->aux = aux->next; |
799 | kfree(aux); | 798 | kfree(aux); |
800 | } | 799 | } |
801 | while ((aux = context->aux_pids)) { | 800 | while ((aux = context->aux_pids)) { |
802 | context->aux_pids = aux->next; | 801 | context->aux_pids = aux->next; |
803 | kfree(aux); | 802 | kfree(aux); |
804 | } | 803 | } |
805 | } | 804 | } |
806 | 805 | ||
807 | static inline void audit_zero_context(struct audit_context *context, | 806 | static inline void audit_zero_context(struct audit_context *context, |
808 | enum audit_state state) | 807 | enum audit_state state) |
809 | { | 808 | { |
810 | memset(context, 0, sizeof(*context)); | 809 | memset(context, 0, sizeof(*context)); |
811 | context->state = state; | 810 | context->state = state; |
812 | } | 811 | } |
813 | 812 | ||
814 | static inline struct audit_context *audit_alloc_context(enum audit_state state) | 813 | static inline struct audit_context *audit_alloc_context(enum audit_state state) |
815 | { | 814 | { |
816 | struct audit_context *context; | 815 | struct audit_context *context; |
817 | 816 | ||
818 | if (!(context = kmalloc(sizeof(*context), GFP_KERNEL))) | 817 | if (!(context = kmalloc(sizeof(*context), GFP_KERNEL))) |
819 | return NULL; | 818 | return NULL; |
820 | audit_zero_context(context, state); | 819 | audit_zero_context(context, state); |
821 | return context; | 820 | return context; |
822 | } | 821 | } |
823 | 822 | ||
824 | /** | 823 | /** |
825 | * audit_alloc - allocate an audit context block for a task | 824 | * audit_alloc - allocate an audit context block for a task |
826 | * @tsk: task | 825 | * @tsk: task |
827 | * | 826 | * |
828 | * Filter on the task information and allocate a per-task audit context | 827 | * Filter on the task information and allocate a per-task audit context |
829 | * if necessary. Doing so turns on system call auditing for the | 828 | * if necessary. Doing so turns on system call auditing for the |
830 | * specified task. This is called from copy_process, so no lock is | 829 | * specified task. This is called from copy_process, so no lock is |
831 | * needed. | 830 | * needed. |
832 | */ | 831 | */ |
833 | int audit_alloc(struct task_struct *tsk) | 832 | int audit_alloc(struct task_struct *tsk) |
834 | { | 833 | { |
835 | struct audit_context *context; | 834 | struct audit_context *context; |
836 | enum audit_state state; | 835 | enum audit_state state; |
837 | 836 | ||
838 | if (likely(!audit_ever_enabled)) | 837 | if (likely(!audit_ever_enabled)) |
839 | return 0; /* Return if not auditing. */ | 838 | return 0; /* Return if not auditing. */ |
840 | 839 | ||
841 | state = audit_filter_task(tsk); | 840 | state = audit_filter_task(tsk); |
842 | if (likely(state == AUDIT_DISABLED)) | 841 | if (likely(state == AUDIT_DISABLED)) |
843 | return 0; | 842 | return 0; |
844 | 843 | ||
845 | if (!(context = audit_alloc_context(state))) { | 844 | if (!(context = audit_alloc_context(state))) { |
846 | audit_log_lost("out of memory in audit_alloc"); | 845 | audit_log_lost("out of memory in audit_alloc"); |
847 | return -ENOMEM; | 846 | return -ENOMEM; |
848 | } | 847 | } |
849 | 848 | ||
850 | tsk->audit_context = context; | 849 | tsk->audit_context = context; |
851 | set_tsk_thread_flag(tsk, TIF_SYSCALL_AUDIT); | 850 | set_tsk_thread_flag(tsk, TIF_SYSCALL_AUDIT); |
852 | return 0; | 851 | return 0; |
853 | } | 852 | } |
854 | 853 | ||
855 | static inline void audit_free_context(struct audit_context *context) | 854 | static inline void audit_free_context(struct audit_context *context) |
856 | { | 855 | { |
857 | struct audit_context *previous; | 856 | struct audit_context *previous; |
858 | int count = 0; | 857 | int count = 0; |
859 | 858 | ||
860 | do { | 859 | do { |
861 | previous = context->previous; | 860 | previous = context->previous; |
862 | if (previous || (count && count < 10)) { | 861 | if (previous || (count && count < 10)) { |
863 | ++count; | 862 | ++count; |
864 | printk(KERN_ERR "audit(:%d): major=%d name_count=%d:" | 863 | printk(KERN_ERR "audit(:%d): major=%d name_count=%d:" |
865 | " freeing multiple contexts (%d)\n", | 864 | " freeing multiple contexts (%d)\n", |
866 | context->serial, context->major, | 865 | context->serial, context->major, |
867 | context->name_count, count); | 866 | context->name_count, count); |
868 | } | 867 | } |
869 | audit_free_names(context); | 868 | audit_free_names(context); |
870 | unroll_tree_refs(context, NULL, 0); | 869 | unroll_tree_refs(context, NULL, 0); |
871 | free_tree_refs(context); | 870 | free_tree_refs(context); |
872 | audit_free_aux(context); | 871 | audit_free_aux(context); |
873 | kfree(context->filterkey); | 872 | kfree(context->filterkey); |
874 | kfree(context); | 873 | kfree(context); |
875 | context = previous; | 874 | context = previous; |
876 | } while (context); | 875 | } while (context); |
877 | if (count >= 10) | 876 | if (count >= 10) |
878 | printk(KERN_ERR "audit: freed %d contexts\n", count); | 877 | printk(KERN_ERR "audit: freed %d contexts\n", count); |
879 | } | 878 | } |
880 | 879 | ||
881 | void audit_log_task_context(struct audit_buffer *ab) | 880 | void audit_log_task_context(struct audit_buffer *ab) |
882 | { | 881 | { |
883 | char *ctx = NULL; | 882 | char *ctx = NULL; |
884 | unsigned len; | 883 | unsigned len; |
885 | int error; | 884 | int error; |
886 | u32 sid; | 885 | u32 sid; |
887 | 886 | ||
888 | security_task_getsecid(current, &sid); | 887 | security_task_getsecid(current, &sid); |
889 | if (!sid) | 888 | if (!sid) |
890 | return; | 889 | return; |
891 | 890 | ||
892 | error = security_secid_to_secctx(sid, &ctx, &len); | 891 | error = security_secid_to_secctx(sid, &ctx, &len); |
893 | if (error) { | 892 | if (error) { |
894 | if (error != -EINVAL) | 893 | if (error != -EINVAL) |
895 | goto error_path; | 894 | goto error_path; |
896 | return; | 895 | return; |
897 | } | 896 | } |
898 | 897 | ||
899 | audit_log_format(ab, " subj=%s", ctx); | 898 | audit_log_format(ab, " subj=%s", ctx); |
900 | security_release_secctx(ctx, len); | 899 | security_release_secctx(ctx, len); |
901 | return; | 900 | return; |
902 | 901 | ||
903 | error_path: | 902 | error_path: |
904 | audit_panic("error in audit_log_task_context"); | 903 | audit_panic("error in audit_log_task_context"); |
905 | return; | 904 | return; |
906 | } | 905 | } |
907 | 906 | ||
908 | EXPORT_SYMBOL(audit_log_task_context); | 907 | EXPORT_SYMBOL(audit_log_task_context); |
909 | 908 | ||
910 | static void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk) | 909 | static void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk) |
911 | { | 910 | { |
912 | char name[sizeof(tsk->comm)]; | 911 | char name[sizeof(tsk->comm)]; |
913 | struct mm_struct *mm = tsk->mm; | 912 | struct mm_struct *mm = tsk->mm; |
914 | struct vm_area_struct *vma; | 913 | struct vm_area_struct *vma; |
915 | 914 | ||
916 | /* tsk == current */ | 915 | /* tsk == current */ |
917 | 916 | ||
918 | get_task_comm(name, tsk); | 917 | get_task_comm(name, tsk); |
919 | audit_log_format(ab, " comm="); | 918 | audit_log_format(ab, " comm="); |
920 | audit_log_untrustedstring(ab, name); | 919 | audit_log_untrustedstring(ab, name); |
921 | 920 | ||
922 | if (mm) { | 921 | if (mm) { |
923 | down_read(&mm->mmap_sem); | 922 | down_read(&mm->mmap_sem); |
924 | vma = mm->mmap; | 923 | vma = mm->mmap; |
925 | while (vma) { | 924 | while (vma) { |
926 | if ((vma->vm_flags & VM_EXECUTABLE) && | 925 | if ((vma->vm_flags & VM_EXECUTABLE) && |
927 | vma->vm_file) { | 926 | vma->vm_file) { |
928 | audit_log_d_path(ab, "exe=", | 927 | audit_log_d_path(ab, "exe=", |
929 | &vma->vm_file->f_path); | 928 | &vma->vm_file->f_path); |
930 | break; | 929 | break; |
931 | } | 930 | } |
932 | vma = vma->vm_next; | 931 | vma = vma->vm_next; |
933 | } | 932 | } |
934 | up_read(&mm->mmap_sem); | 933 | up_read(&mm->mmap_sem); |
935 | } | 934 | } |
936 | audit_log_task_context(ab); | 935 | audit_log_task_context(ab); |
937 | } | 936 | } |
938 | 937 | ||
939 | static int audit_log_pid_context(struct audit_context *context, pid_t pid, | 938 | static int audit_log_pid_context(struct audit_context *context, pid_t pid, |
940 | uid_t auid, uid_t uid, unsigned int sessionid, | 939 | uid_t auid, uid_t uid, unsigned int sessionid, |
941 | u32 sid, char *comm) | 940 | u32 sid, char *comm) |
942 | { | 941 | { |
943 | struct audit_buffer *ab; | 942 | struct audit_buffer *ab; |
944 | char *ctx = NULL; | 943 | char *ctx = NULL; |
945 | u32 len; | 944 | u32 len; |
946 | int rc = 0; | 945 | int rc = 0; |
947 | 946 | ||
948 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID); | 947 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID); |
949 | if (!ab) | 948 | if (!ab) |
950 | return rc; | 949 | return rc; |
951 | 950 | ||
952 | audit_log_format(ab, "opid=%d oauid=%d ouid=%d oses=%d", pid, auid, | 951 | audit_log_format(ab, "opid=%d oauid=%d ouid=%d oses=%d", pid, auid, |
953 | uid, sessionid); | 952 | uid, sessionid); |
954 | if (security_secid_to_secctx(sid, &ctx, &len)) { | 953 | if (security_secid_to_secctx(sid, &ctx, &len)) { |
955 | audit_log_format(ab, " obj=(none)"); | 954 | audit_log_format(ab, " obj=(none)"); |
956 | rc = 1; | 955 | rc = 1; |
957 | } else { | 956 | } else { |
958 | audit_log_format(ab, " obj=%s", ctx); | 957 | audit_log_format(ab, " obj=%s", ctx); |
959 | security_release_secctx(ctx, len); | 958 | security_release_secctx(ctx, len); |
960 | } | 959 | } |
961 | audit_log_format(ab, " ocomm="); | 960 | audit_log_format(ab, " ocomm="); |
962 | audit_log_untrustedstring(ab, comm); | 961 | audit_log_untrustedstring(ab, comm); |
963 | audit_log_end(ab); | 962 | audit_log_end(ab); |
964 | 963 | ||
965 | return rc; | 964 | return rc; |
966 | } | 965 | } |
967 | 966 | ||
968 | /* | 967 | /* |
969 | * to_send and len_sent accounting are very loose estimates. We aren't | 968 | * to_send and len_sent accounting are very loose estimates. We aren't |
970 | * really worried about a hard cap to MAX_EXECVE_AUDIT_LEN so much as being | 969 | * really worried about a hard cap to MAX_EXECVE_AUDIT_LEN so much as being |
971 | * within about 500 bytes (next page boundry) | 970 | * within about 500 bytes (next page boundry) |
972 | * | 971 | * |
973 | * why snprintf? an int is up to 12 digits long. if we just assumed when | 972 | * why snprintf? an int is up to 12 digits long. if we just assumed when |
974 | * logging that a[%d]= was going to be 16 characters long we would be wasting | 973 | * logging that a[%d]= was going to be 16 characters long we would be wasting |
975 | * space in every audit message. In one 7500 byte message we can log up to | 974 | * space in every audit message. In one 7500 byte message we can log up to |
976 | * about 1000 min size arguments. That comes down to about 50% waste of space | 975 | * about 1000 min size arguments. That comes down to about 50% waste of space |
977 | * if we didn't do the snprintf to find out how long arg_num_len was. | 976 | * if we didn't do the snprintf to find out how long arg_num_len was. |
978 | */ | 977 | */ |
979 | static int audit_log_single_execve_arg(struct audit_context *context, | 978 | static int audit_log_single_execve_arg(struct audit_context *context, |
980 | struct audit_buffer **ab, | 979 | struct audit_buffer **ab, |
981 | int arg_num, | 980 | int arg_num, |
982 | size_t *len_sent, | 981 | size_t *len_sent, |
983 | const char __user *p, | 982 | const char __user *p, |
984 | char *buf) | 983 | char *buf) |
985 | { | 984 | { |
986 | char arg_num_len_buf[12]; | 985 | char arg_num_len_buf[12]; |
987 | const char __user *tmp_p = p; | 986 | const char __user *tmp_p = p; |
988 | /* how many digits are in arg_num? 3 is the length of a=\n */ | 987 | /* how many digits are in arg_num? 3 is the length of a=\n */ |
989 | size_t arg_num_len = snprintf(arg_num_len_buf, 12, "%d", arg_num) + 3; | 988 | size_t arg_num_len = snprintf(arg_num_len_buf, 12, "%d", arg_num) + 3; |
990 | size_t len, len_left, to_send; | 989 | size_t len, len_left, to_send; |
991 | size_t max_execve_audit_len = MAX_EXECVE_AUDIT_LEN; | 990 | size_t max_execve_audit_len = MAX_EXECVE_AUDIT_LEN; |
992 | unsigned int i, has_cntl = 0, too_long = 0; | 991 | unsigned int i, has_cntl = 0, too_long = 0; |
993 | int ret; | 992 | int ret; |
994 | 993 | ||
995 | /* strnlen_user includes the null we don't want to send */ | 994 | /* strnlen_user includes the null we don't want to send */ |
996 | len_left = len = strnlen_user(p, MAX_ARG_STRLEN) - 1; | 995 | len_left = len = strnlen_user(p, MAX_ARG_STRLEN) - 1; |
997 | 996 | ||
998 | /* | 997 | /* |
999 | * We just created this mm, if we can't find the strings | 998 | * We just created this mm, if we can't find the strings |
1000 | * we just copied into it something is _very_ wrong. Similar | 999 | * we just copied into it something is _very_ wrong. Similar |
1001 | * for strings that are too long, we should not have created | 1000 | * for strings that are too long, we should not have created |
1002 | * any. | 1001 | * any. |
1003 | */ | 1002 | */ |
1004 | if (unlikely((len == -1) || len > MAX_ARG_STRLEN - 1)) { | 1003 | if (unlikely((len == -1) || len > MAX_ARG_STRLEN - 1)) { |
1005 | WARN_ON(1); | 1004 | WARN_ON(1); |
1006 | send_sig(SIGKILL, current, 0); | 1005 | send_sig(SIGKILL, current, 0); |
1007 | return -1; | 1006 | return -1; |
1008 | } | 1007 | } |
1009 | 1008 | ||
1010 | /* walk the whole argument looking for non-ascii chars */ | 1009 | /* walk the whole argument looking for non-ascii chars */ |
1011 | do { | 1010 | do { |
1012 | if (len_left > MAX_EXECVE_AUDIT_LEN) | 1011 | if (len_left > MAX_EXECVE_AUDIT_LEN) |
1013 | to_send = MAX_EXECVE_AUDIT_LEN; | 1012 | to_send = MAX_EXECVE_AUDIT_LEN; |
1014 | else | 1013 | else |
1015 | to_send = len_left; | 1014 | to_send = len_left; |
1016 | ret = copy_from_user(buf, tmp_p, to_send); | 1015 | ret = copy_from_user(buf, tmp_p, to_send); |
1017 | /* | 1016 | /* |
1018 | * There is no reason for this copy to be short. We just | 1017 | * There is no reason for this copy to be short. We just |
1019 | * copied them here, and the mm hasn't been exposed to user- | 1018 | * copied them here, and the mm hasn't been exposed to user- |
1020 | * space yet. | 1019 | * space yet. |
1021 | */ | 1020 | */ |
1022 | if (ret) { | 1021 | if (ret) { |
1023 | WARN_ON(1); | 1022 | WARN_ON(1); |
1024 | send_sig(SIGKILL, current, 0); | 1023 | send_sig(SIGKILL, current, 0); |
1025 | return -1; | 1024 | return -1; |
1026 | } | 1025 | } |
1027 | buf[to_send] = '\0'; | 1026 | buf[to_send] = '\0'; |
1028 | has_cntl = audit_string_contains_control(buf, to_send); | 1027 | has_cntl = audit_string_contains_control(buf, to_send); |
1029 | if (has_cntl) { | 1028 | if (has_cntl) { |
1030 | /* | 1029 | /* |
1031 | * hex messages get logged as 2 bytes, so we can only | 1030 | * hex messages get logged as 2 bytes, so we can only |
1032 | * send half as much in each message | 1031 | * send half as much in each message |
1033 | */ | 1032 | */ |
1034 | max_execve_audit_len = MAX_EXECVE_AUDIT_LEN / 2; | 1033 | max_execve_audit_len = MAX_EXECVE_AUDIT_LEN / 2; |
1035 | break; | 1034 | break; |
1036 | } | 1035 | } |
1037 | len_left -= to_send; | 1036 | len_left -= to_send; |
1038 | tmp_p += to_send; | 1037 | tmp_p += to_send; |
1039 | } while (len_left > 0); | 1038 | } while (len_left > 0); |
1040 | 1039 | ||
1041 | len_left = len; | 1040 | len_left = len; |
1042 | 1041 | ||
1043 | if (len > max_execve_audit_len) | 1042 | if (len > max_execve_audit_len) |
1044 | too_long = 1; | 1043 | too_long = 1; |
1045 | 1044 | ||
1046 | /* rewalk the argument actually logging the message */ | 1045 | /* rewalk the argument actually logging the message */ |
1047 | for (i = 0; len_left > 0; i++) { | 1046 | for (i = 0; len_left > 0; i++) { |
1048 | int room_left; | 1047 | int room_left; |
1049 | 1048 | ||
1050 | if (len_left > max_execve_audit_len) | 1049 | if (len_left > max_execve_audit_len) |
1051 | to_send = max_execve_audit_len; | 1050 | to_send = max_execve_audit_len; |
1052 | else | 1051 | else |
1053 | to_send = len_left; | 1052 | to_send = len_left; |
1054 | 1053 | ||
1055 | /* do we have space left to send this argument in this ab? */ | 1054 | /* do we have space left to send this argument in this ab? */ |
1056 | room_left = MAX_EXECVE_AUDIT_LEN - arg_num_len - *len_sent; | 1055 | room_left = MAX_EXECVE_AUDIT_LEN - arg_num_len - *len_sent; |
1057 | if (has_cntl) | 1056 | if (has_cntl) |
1058 | room_left -= (to_send * 2); | 1057 | room_left -= (to_send * 2); |
1059 | else | 1058 | else |
1060 | room_left -= to_send; | 1059 | room_left -= to_send; |
1061 | if (room_left < 0) { | 1060 | if (room_left < 0) { |
1062 | *len_sent = 0; | 1061 | *len_sent = 0; |
1063 | audit_log_end(*ab); | 1062 | audit_log_end(*ab); |
1064 | *ab = audit_log_start(context, GFP_KERNEL, AUDIT_EXECVE); | 1063 | *ab = audit_log_start(context, GFP_KERNEL, AUDIT_EXECVE); |
1065 | if (!*ab) | 1064 | if (!*ab) |
1066 | return 0; | 1065 | return 0; |
1067 | } | 1066 | } |
1068 | 1067 | ||
1069 | /* | 1068 | /* |
1070 | * first record needs to say how long the original string was | 1069 | * first record needs to say how long the original string was |
1071 | * so we can be sure nothing was lost. | 1070 | * so we can be sure nothing was lost. |
1072 | */ | 1071 | */ |
1073 | if ((i == 0) && (too_long)) | 1072 | if ((i == 0) && (too_long)) |
1074 | audit_log_format(*ab, "a%d_len=%zu ", arg_num, | 1073 | audit_log_format(*ab, "a%d_len=%zu ", arg_num, |
1075 | has_cntl ? 2*len : len); | 1074 | has_cntl ? 2*len : len); |
1076 | 1075 | ||
1077 | /* | 1076 | /* |
1078 | * normally arguments are small enough to fit and we already | 1077 | * normally arguments are small enough to fit and we already |
1079 | * filled buf above when we checked for control characters | 1078 | * filled buf above when we checked for control characters |
1080 | * so don't bother with another copy_from_user | 1079 | * so don't bother with another copy_from_user |
1081 | */ | 1080 | */ |
1082 | if (len >= max_execve_audit_len) | 1081 | if (len >= max_execve_audit_len) |
1083 | ret = copy_from_user(buf, p, to_send); | 1082 | ret = copy_from_user(buf, p, to_send); |
1084 | else | 1083 | else |
1085 | ret = 0; | 1084 | ret = 0; |
1086 | if (ret) { | 1085 | if (ret) { |
1087 | WARN_ON(1); | 1086 | WARN_ON(1); |
1088 | send_sig(SIGKILL, current, 0); | 1087 | send_sig(SIGKILL, current, 0); |
1089 | return -1; | 1088 | return -1; |
1090 | } | 1089 | } |
1091 | buf[to_send] = '\0'; | 1090 | buf[to_send] = '\0'; |
1092 | 1091 | ||
1093 | /* actually log it */ | 1092 | /* actually log it */ |
1094 | audit_log_format(*ab, "a%d", arg_num); | 1093 | audit_log_format(*ab, "a%d", arg_num); |
1095 | if (too_long) | 1094 | if (too_long) |
1096 | audit_log_format(*ab, "[%d]", i); | 1095 | audit_log_format(*ab, "[%d]", i); |
1097 | audit_log_format(*ab, "="); | 1096 | audit_log_format(*ab, "="); |
1098 | if (has_cntl) | 1097 | if (has_cntl) |
1099 | audit_log_hex(*ab, buf, to_send); | 1098 | audit_log_hex(*ab, buf, to_send); |
1100 | else | 1099 | else |
1101 | audit_log_format(*ab, "\"%s\"", buf); | 1100 | audit_log_format(*ab, "\"%s\"", buf); |
1102 | audit_log_format(*ab, "\n"); | 1101 | audit_log_format(*ab, "\n"); |
1103 | 1102 | ||
1104 | p += to_send; | 1103 | p += to_send; |
1105 | len_left -= to_send; | 1104 | len_left -= to_send; |
1106 | *len_sent += arg_num_len; | 1105 | *len_sent += arg_num_len; |
1107 | if (has_cntl) | 1106 | if (has_cntl) |
1108 | *len_sent += to_send * 2; | 1107 | *len_sent += to_send * 2; |
1109 | else | 1108 | else |
1110 | *len_sent += to_send; | 1109 | *len_sent += to_send; |
1111 | } | 1110 | } |
1112 | /* include the null we didn't log */ | 1111 | /* include the null we didn't log */ |
1113 | return len + 1; | 1112 | return len + 1; |
1114 | } | 1113 | } |
1115 | 1114 | ||
1116 | static void audit_log_execve_info(struct audit_context *context, | 1115 | static void audit_log_execve_info(struct audit_context *context, |
1117 | struct audit_buffer **ab, | 1116 | struct audit_buffer **ab, |
1118 | struct audit_aux_data_execve *axi) | 1117 | struct audit_aux_data_execve *axi) |
1119 | { | 1118 | { |
1120 | int i; | 1119 | int i; |
1121 | size_t len, len_sent = 0; | 1120 | size_t len, len_sent = 0; |
1122 | const char __user *p; | 1121 | const char __user *p; |
1123 | char *buf; | 1122 | char *buf; |
1124 | 1123 | ||
1125 | if (axi->mm != current->mm) | 1124 | if (axi->mm != current->mm) |
1126 | return; /* execve failed, no additional info */ | 1125 | return; /* execve failed, no additional info */ |
1127 | 1126 | ||
1128 | p = (const char __user *)axi->mm->arg_start; | 1127 | p = (const char __user *)axi->mm->arg_start; |
1129 | 1128 | ||
1130 | audit_log_format(*ab, "argc=%d ", axi->argc); | 1129 | audit_log_format(*ab, "argc=%d ", axi->argc); |
1131 | 1130 | ||
1132 | /* | 1131 | /* |
1133 | * we need some kernel buffer to hold the userspace args. Just | 1132 | * we need some kernel buffer to hold the userspace args. Just |
1134 | * allocate one big one rather than allocating one of the right size | 1133 | * allocate one big one rather than allocating one of the right size |
1135 | * for every single argument inside audit_log_single_execve_arg() | 1134 | * for every single argument inside audit_log_single_execve_arg() |
1136 | * should be <8k allocation so should be pretty safe. | 1135 | * should be <8k allocation so should be pretty safe. |
1137 | */ | 1136 | */ |
1138 | buf = kmalloc(MAX_EXECVE_AUDIT_LEN + 1, GFP_KERNEL); | 1137 | buf = kmalloc(MAX_EXECVE_AUDIT_LEN + 1, GFP_KERNEL); |
1139 | if (!buf) { | 1138 | if (!buf) { |
1140 | audit_panic("out of memory for argv string\n"); | 1139 | audit_panic("out of memory for argv string\n"); |
1141 | return; | 1140 | return; |
1142 | } | 1141 | } |
1143 | 1142 | ||
1144 | for (i = 0; i < axi->argc; i++) { | 1143 | for (i = 0; i < axi->argc; i++) { |
1145 | len = audit_log_single_execve_arg(context, ab, i, | 1144 | len = audit_log_single_execve_arg(context, ab, i, |
1146 | &len_sent, p, buf); | 1145 | &len_sent, p, buf); |
1147 | if (len <= 0) | 1146 | if (len <= 0) |
1148 | break; | 1147 | break; |
1149 | p += len; | 1148 | p += len; |
1150 | } | 1149 | } |
1151 | kfree(buf); | 1150 | kfree(buf); |
1152 | } | 1151 | } |
1153 | 1152 | ||
1154 | static void audit_log_exit(struct audit_context *context, struct task_struct *tsk) | 1153 | static void audit_log_exit(struct audit_context *context, struct task_struct *tsk) |
1155 | { | 1154 | { |
1156 | int i, call_panic = 0; | 1155 | int i, call_panic = 0; |
1157 | struct audit_buffer *ab; | 1156 | struct audit_buffer *ab; |
1158 | struct audit_aux_data *aux; | 1157 | struct audit_aux_data *aux; |
1159 | const char *tty; | 1158 | const char *tty; |
1160 | 1159 | ||
1161 | /* tsk == current */ | 1160 | /* tsk == current */ |
1162 | context->pid = tsk->pid; | 1161 | context->pid = tsk->pid; |
1163 | if (!context->ppid) | 1162 | if (!context->ppid) |
1164 | context->ppid = sys_getppid(); | 1163 | context->ppid = sys_getppid(); |
1165 | context->uid = tsk->uid; | 1164 | context->uid = tsk->uid; |
1166 | context->gid = tsk->gid; | 1165 | context->gid = tsk->gid; |
1167 | context->euid = tsk->euid; | 1166 | context->euid = tsk->euid; |
1168 | context->suid = tsk->suid; | 1167 | context->suid = tsk->suid; |
1169 | context->fsuid = tsk->fsuid; | 1168 | context->fsuid = tsk->fsuid; |
1170 | context->egid = tsk->egid; | 1169 | context->egid = tsk->egid; |
1171 | context->sgid = tsk->sgid; | 1170 | context->sgid = tsk->sgid; |
1172 | context->fsgid = tsk->fsgid; | 1171 | context->fsgid = tsk->fsgid; |
1173 | context->personality = tsk->personality; | 1172 | context->personality = tsk->personality; |
1174 | 1173 | ||
1175 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_SYSCALL); | 1174 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_SYSCALL); |
1176 | if (!ab) | 1175 | if (!ab) |
1177 | return; /* audit_panic has been called */ | 1176 | return; /* audit_panic has been called */ |
1178 | audit_log_format(ab, "arch=%x syscall=%d", | 1177 | audit_log_format(ab, "arch=%x syscall=%d", |
1179 | context->arch, context->major); | 1178 | context->arch, context->major); |
1180 | if (context->personality != PER_LINUX) | 1179 | if (context->personality != PER_LINUX) |
1181 | audit_log_format(ab, " per=%lx", context->personality); | 1180 | audit_log_format(ab, " per=%lx", context->personality); |
1182 | if (context->return_valid) | 1181 | if (context->return_valid) |
1183 | audit_log_format(ab, " success=%s exit=%ld", | 1182 | audit_log_format(ab, " success=%s exit=%ld", |
1184 | (context->return_valid==AUDITSC_SUCCESS)?"yes":"no", | 1183 | (context->return_valid==AUDITSC_SUCCESS)?"yes":"no", |
1185 | context->return_code); | 1184 | context->return_code); |
1186 | 1185 | ||
1187 | mutex_lock(&tty_mutex); | 1186 | mutex_lock(&tty_mutex); |
1188 | read_lock(&tasklist_lock); | 1187 | read_lock(&tasklist_lock); |
1189 | if (tsk->signal && tsk->signal->tty && tsk->signal->tty->name) | 1188 | if (tsk->signal && tsk->signal->tty && tsk->signal->tty->name) |
1190 | tty = tsk->signal->tty->name; | 1189 | tty = tsk->signal->tty->name; |
1191 | else | 1190 | else |
1192 | tty = "(none)"; | 1191 | tty = "(none)"; |
1193 | read_unlock(&tasklist_lock); | 1192 | read_unlock(&tasklist_lock); |
1194 | audit_log_format(ab, | 1193 | audit_log_format(ab, |
1195 | " a0=%lx a1=%lx a2=%lx a3=%lx items=%d" | 1194 | " a0=%lx a1=%lx a2=%lx a3=%lx items=%d" |
1196 | " ppid=%d pid=%d auid=%u uid=%u gid=%u" | 1195 | " ppid=%d pid=%d auid=%u uid=%u gid=%u" |
1197 | " euid=%u suid=%u fsuid=%u" | 1196 | " euid=%u suid=%u fsuid=%u" |
1198 | " egid=%u sgid=%u fsgid=%u tty=%s ses=%u", | 1197 | " egid=%u sgid=%u fsgid=%u tty=%s ses=%u", |
1199 | context->argv[0], | 1198 | context->argv[0], |
1200 | context->argv[1], | 1199 | context->argv[1], |
1201 | context->argv[2], | 1200 | context->argv[2], |
1202 | context->argv[3], | 1201 | context->argv[3], |
1203 | context->name_count, | 1202 | context->name_count, |
1204 | context->ppid, | 1203 | context->ppid, |
1205 | context->pid, | 1204 | context->pid, |
1206 | tsk->loginuid, | 1205 | tsk->loginuid, |
1207 | context->uid, | 1206 | context->uid, |
1208 | context->gid, | 1207 | context->gid, |
1209 | context->euid, context->suid, context->fsuid, | 1208 | context->euid, context->suid, context->fsuid, |
1210 | context->egid, context->sgid, context->fsgid, tty, | 1209 | context->egid, context->sgid, context->fsgid, tty, |
1211 | tsk->sessionid); | 1210 | tsk->sessionid); |
1212 | 1211 | ||
1213 | mutex_unlock(&tty_mutex); | 1212 | mutex_unlock(&tty_mutex); |
1214 | 1213 | ||
1215 | audit_log_task_info(ab, tsk); | 1214 | audit_log_task_info(ab, tsk); |
1216 | if (context->filterkey) { | 1215 | if (context->filterkey) { |
1217 | audit_log_format(ab, " key="); | 1216 | audit_log_format(ab, " key="); |
1218 | audit_log_untrustedstring(ab, context->filterkey); | 1217 | audit_log_untrustedstring(ab, context->filterkey); |
1219 | } else | 1218 | } else |
1220 | audit_log_format(ab, " key=(null)"); | 1219 | audit_log_format(ab, " key=(null)"); |
1221 | audit_log_end(ab); | 1220 | audit_log_end(ab); |
1222 | 1221 | ||
1223 | for (aux = context->aux; aux; aux = aux->next) { | 1222 | for (aux = context->aux; aux; aux = aux->next) { |
1224 | 1223 | ||
1225 | ab = audit_log_start(context, GFP_KERNEL, aux->type); | 1224 | ab = audit_log_start(context, GFP_KERNEL, aux->type); |
1226 | if (!ab) | 1225 | if (!ab) |
1227 | continue; /* audit_panic has been called */ | 1226 | continue; /* audit_panic has been called */ |
1228 | 1227 | ||
1229 | switch (aux->type) { | 1228 | switch (aux->type) { |
1230 | case AUDIT_MQ_OPEN: { | 1229 | case AUDIT_MQ_OPEN: { |
1231 | struct audit_aux_data_mq_open *axi = (void *)aux; | 1230 | struct audit_aux_data_mq_open *axi = (void *)aux; |
1232 | audit_log_format(ab, | 1231 | audit_log_format(ab, |
1233 | "oflag=0x%x mode=%#o mq_flags=0x%lx mq_maxmsg=%ld " | 1232 | "oflag=0x%x mode=%#o mq_flags=0x%lx mq_maxmsg=%ld " |
1234 | "mq_msgsize=%ld mq_curmsgs=%ld", | 1233 | "mq_msgsize=%ld mq_curmsgs=%ld", |
1235 | axi->oflag, axi->mode, axi->attr.mq_flags, | 1234 | axi->oflag, axi->mode, axi->attr.mq_flags, |
1236 | axi->attr.mq_maxmsg, axi->attr.mq_msgsize, | 1235 | axi->attr.mq_maxmsg, axi->attr.mq_msgsize, |
1237 | axi->attr.mq_curmsgs); | 1236 | axi->attr.mq_curmsgs); |
1238 | break; } | 1237 | break; } |
1239 | 1238 | ||
1240 | case AUDIT_MQ_SENDRECV: { | 1239 | case AUDIT_MQ_SENDRECV: { |
1241 | struct audit_aux_data_mq_sendrecv *axi = (void *)aux; | 1240 | struct audit_aux_data_mq_sendrecv *axi = (void *)aux; |
1242 | audit_log_format(ab, | 1241 | audit_log_format(ab, |
1243 | "mqdes=%d msg_len=%zd msg_prio=%u " | 1242 | "mqdes=%d msg_len=%zd msg_prio=%u " |
1244 | "abs_timeout_sec=%ld abs_timeout_nsec=%ld", | 1243 | "abs_timeout_sec=%ld abs_timeout_nsec=%ld", |
1245 | axi->mqdes, axi->msg_len, axi->msg_prio, | 1244 | axi->mqdes, axi->msg_len, axi->msg_prio, |
1246 | axi->abs_timeout.tv_sec, axi->abs_timeout.tv_nsec); | 1245 | axi->abs_timeout.tv_sec, axi->abs_timeout.tv_nsec); |
1247 | break; } | 1246 | break; } |
1248 | 1247 | ||
1249 | case AUDIT_MQ_NOTIFY: { | 1248 | case AUDIT_MQ_NOTIFY: { |
1250 | struct audit_aux_data_mq_notify *axi = (void *)aux; | 1249 | struct audit_aux_data_mq_notify *axi = (void *)aux; |
1251 | audit_log_format(ab, | 1250 | audit_log_format(ab, |
1252 | "mqdes=%d sigev_signo=%d", | 1251 | "mqdes=%d sigev_signo=%d", |
1253 | axi->mqdes, | 1252 | axi->mqdes, |
1254 | axi->notification.sigev_signo); | 1253 | axi->notification.sigev_signo); |
1255 | break; } | 1254 | break; } |
1256 | 1255 | ||
1257 | case AUDIT_MQ_GETSETATTR: { | 1256 | case AUDIT_MQ_GETSETATTR: { |
1258 | struct audit_aux_data_mq_getsetattr *axi = (void *)aux; | 1257 | struct audit_aux_data_mq_getsetattr *axi = (void *)aux; |
1259 | audit_log_format(ab, | 1258 | audit_log_format(ab, |
1260 | "mqdes=%d mq_flags=0x%lx mq_maxmsg=%ld mq_msgsize=%ld " | 1259 | "mqdes=%d mq_flags=0x%lx mq_maxmsg=%ld mq_msgsize=%ld " |
1261 | "mq_curmsgs=%ld ", | 1260 | "mq_curmsgs=%ld ", |
1262 | axi->mqdes, | 1261 | axi->mqdes, |
1263 | axi->mqstat.mq_flags, axi->mqstat.mq_maxmsg, | 1262 | axi->mqstat.mq_flags, axi->mqstat.mq_maxmsg, |
1264 | axi->mqstat.mq_msgsize, axi->mqstat.mq_curmsgs); | 1263 | axi->mqstat.mq_msgsize, axi->mqstat.mq_curmsgs); |
1265 | break; } | 1264 | break; } |
1266 | 1265 | ||
1267 | case AUDIT_IPC: { | 1266 | case AUDIT_IPC: { |
1268 | struct audit_aux_data_ipcctl *axi = (void *)aux; | 1267 | struct audit_aux_data_ipcctl *axi = (void *)aux; |
1269 | audit_log_format(ab, | 1268 | audit_log_format(ab, |
1270 | "ouid=%u ogid=%u mode=%#o", | 1269 | "ouid=%u ogid=%u mode=%#o", |
1271 | axi->uid, axi->gid, axi->mode); | 1270 | axi->uid, axi->gid, axi->mode); |
1272 | if (axi->osid != 0) { | 1271 | if (axi->osid != 0) { |
1273 | char *ctx = NULL; | 1272 | char *ctx = NULL; |
1274 | u32 len; | 1273 | u32 len; |
1275 | if (security_secid_to_secctx( | 1274 | if (security_secid_to_secctx( |
1276 | axi->osid, &ctx, &len)) { | 1275 | axi->osid, &ctx, &len)) { |
1277 | audit_log_format(ab, " osid=%u", | 1276 | audit_log_format(ab, " osid=%u", |
1278 | axi->osid); | 1277 | axi->osid); |
1279 | call_panic = 1; | 1278 | call_panic = 1; |
1280 | } else { | 1279 | } else { |
1281 | audit_log_format(ab, " obj=%s", ctx); | 1280 | audit_log_format(ab, " obj=%s", ctx); |
1282 | security_release_secctx(ctx, len); | 1281 | security_release_secctx(ctx, len); |
1283 | } | 1282 | } |
1284 | } | 1283 | } |
1285 | break; } | 1284 | break; } |
1286 | 1285 | ||
1287 | case AUDIT_IPC_SET_PERM: { | 1286 | case AUDIT_IPC_SET_PERM: { |
1288 | struct audit_aux_data_ipcctl *axi = (void *)aux; | 1287 | struct audit_aux_data_ipcctl *axi = (void *)aux; |
1289 | audit_log_format(ab, | 1288 | audit_log_format(ab, |
1290 | "qbytes=%lx ouid=%u ogid=%u mode=%#o", | 1289 | "qbytes=%lx ouid=%u ogid=%u mode=%#o", |
1291 | axi->qbytes, axi->uid, axi->gid, axi->mode); | 1290 | axi->qbytes, axi->uid, axi->gid, axi->mode); |
1292 | break; } | 1291 | break; } |
1293 | 1292 | ||
1294 | case AUDIT_EXECVE: { | 1293 | case AUDIT_EXECVE: { |
1295 | struct audit_aux_data_execve *axi = (void *)aux; | 1294 | struct audit_aux_data_execve *axi = (void *)aux; |
1296 | audit_log_execve_info(context, &ab, axi); | 1295 | audit_log_execve_info(context, &ab, axi); |
1297 | break; } | 1296 | break; } |
1298 | 1297 | ||
1299 | case AUDIT_SOCKETCALL: { | 1298 | case AUDIT_SOCKETCALL: { |
1300 | int i; | 1299 | int i; |
1301 | struct audit_aux_data_socketcall *axs = (void *)aux; | 1300 | struct audit_aux_data_socketcall *axs = (void *)aux; |
1302 | audit_log_format(ab, "nargs=%d", axs->nargs); | 1301 | audit_log_format(ab, "nargs=%d", axs->nargs); |
1303 | for (i=0; i<axs->nargs; i++) | 1302 | for (i=0; i<axs->nargs; i++) |
1304 | audit_log_format(ab, " a%d=%lx", i, axs->args[i]); | 1303 | audit_log_format(ab, " a%d=%lx", i, axs->args[i]); |
1305 | break; } | 1304 | break; } |
1306 | 1305 | ||
1307 | case AUDIT_SOCKADDR: { | 1306 | case AUDIT_SOCKADDR: { |
1308 | struct audit_aux_data_sockaddr *axs = (void *)aux; | 1307 | struct audit_aux_data_sockaddr *axs = (void *)aux; |
1309 | 1308 | ||
1310 | audit_log_format(ab, "saddr="); | 1309 | audit_log_format(ab, "saddr="); |
1311 | audit_log_hex(ab, axs->a, axs->len); | 1310 | audit_log_hex(ab, axs->a, axs->len); |
1312 | break; } | 1311 | break; } |
1313 | 1312 | ||
1314 | case AUDIT_FD_PAIR: { | 1313 | case AUDIT_FD_PAIR: { |
1315 | struct audit_aux_data_fd_pair *axs = (void *)aux; | 1314 | struct audit_aux_data_fd_pair *axs = (void *)aux; |
1316 | audit_log_format(ab, "fd0=%d fd1=%d", axs->fd[0], axs->fd[1]); | 1315 | audit_log_format(ab, "fd0=%d fd1=%d", axs->fd[0], axs->fd[1]); |
1317 | break; } | 1316 | break; } |
1318 | 1317 | ||
1319 | } | 1318 | } |
1320 | audit_log_end(ab); | 1319 | audit_log_end(ab); |
1321 | } | 1320 | } |
1322 | 1321 | ||
1323 | for (aux = context->aux_pids; aux; aux = aux->next) { | 1322 | for (aux = context->aux_pids; aux; aux = aux->next) { |
1324 | struct audit_aux_data_pids *axs = (void *)aux; | 1323 | struct audit_aux_data_pids *axs = (void *)aux; |
1325 | int i; | 1324 | int i; |
1326 | 1325 | ||
1327 | for (i = 0; i < axs->pid_count; i++) | 1326 | for (i = 0; i < axs->pid_count; i++) |
1328 | if (audit_log_pid_context(context, axs->target_pid[i], | 1327 | if (audit_log_pid_context(context, axs->target_pid[i], |
1329 | axs->target_auid[i], | 1328 | axs->target_auid[i], |
1330 | axs->target_uid[i], | 1329 | axs->target_uid[i], |
1331 | axs->target_sessionid[i], | 1330 | axs->target_sessionid[i], |
1332 | axs->target_sid[i], | 1331 | axs->target_sid[i], |
1333 | axs->target_comm[i])) | 1332 | axs->target_comm[i])) |
1334 | call_panic = 1; | 1333 | call_panic = 1; |
1335 | } | 1334 | } |
1336 | 1335 | ||
1337 | if (context->target_pid && | 1336 | if (context->target_pid && |
1338 | audit_log_pid_context(context, context->target_pid, | 1337 | audit_log_pid_context(context, context->target_pid, |
1339 | context->target_auid, context->target_uid, | 1338 | context->target_auid, context->target_uid, |
1340 | context->target_sessionid, | 1339 | context->target_sessionid, |
1341 | context->target_sid, context->target_comm)) | 1340 | context->target_sid, context->target_comm)) |
1342 | call_panic = 1; | 1341 | call_panic = 1; |
1343 | 1342 | ||
1344 | if (context->pwd.dentry && context->pwd.mnt) { | 1343 | if (context->pwd.dentry && context->pwd.mnt) { |
1345 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD); | 1344 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD); |
1346 | if (ab) { | 1345 | if (ab) { |
1347 | audit_log_d_path(ab, "cwd=", &context->pwd); | 1346 | audit_log_d_path(ab, "cwd=", &context->pwd); |
1348 | audit_log_end(ab); | 1347 | audit_log_end(ab); |
1349 | } | 1348 | } |
1350 | } | 1349 | } |
1351 | for (i = 0; i < context->name_count; i++) { | 1350 | for (i = 0; i < context->name_count; i++) { |
1352 | struct audit_names *n = &context->names[i]; | 1351 | struct audit_names *n = &context->names[i]; |
1353 | 1352 | ||
1354 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_PATH); | 1353 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_PATH); |
1355 | if (!ab) | 1354 | if (!ab) |
1356 | continue; /* audit_panic has been called */ | 1355 | continue; /* audit_panic has been called */ |
1357 | 1356 | ||
1358 | audit_log_format(ab, "item=%d", i); | 1357 | audit_log_format(ab, "item=%d", i); |
1359 | 1358 | ||
1360 | if (n->name) { | 1359 | if (n->name) { |
1361 | switch(n->name_len) { | 1360 | switch(n->name_len) { |
1362 | case AUDIT_NAME_FULL: | 1361 | case AUDIT_NAME_FULL: |
1363 | /* log the full path */ | 1362 | /* log the full path */ |
1364 | audit_log_format(ab, " name="); | 1363 | audit_log_format(ab, " name="); |
1365 | audit_log_untrustedstring(ab, n->name); | 1364 | audit_log_untrustedstring(ab, n->name); |
1366 | break; | 1365 | break; |
1367 | case 0: | 1366 | case 0: |
1368 | /* name was specified as a relative path and the | 1367 | /* name was specified as a relative path and the |
1369 | * directory component is the cwd */ | 1368 | * directory component is the cwd */ |
1370 | audit_log_d_path(ab, " name=", &context->pwd); | 1369 | audit_log_d_path(ab, " name=", &context->pwd); |
1371 | break; | 1370 | break; |
1372 | default: | 1371 | default: |
1373 | /* log the name's directory component */ | 1372 | /* log the name's directory component */ |
1374 | audit_log_format(ab, " name="); | 1373 | audit_log_format(ab, " name="); |
1375 | audit_log_n_untrustedstring(ab, n->name_len, | 1374 | audit_log_n_untrustedstring(ab, n->name_len, |
1376 | n->name); | 1375 | n->name); |
1377 | } | 1376 | } |
1378 | } else | 1377 | } else |
1379 | audit_log_format(ab, " name=(null)"); | 1378 | audit_log_format(ab, " name=(null)"); |
1380 | 1379 | ||
1381 | if (n->ino != (unsigned long)-1) { | 1380 | if (n->ino != (unsigned long)-1) { |
1382 | audit_log_format(ab, " inode=%lu" | 1381 | audit_log_format(ab, " inode=%lu" |
1383 | " dev=%02x:%02x mode=%#o" | 1382 | " dev=%02x:%02x mode=%#o" |
1384 | " ouid=%u ogid=%u rdev=%02x:%02x", | 1383 | " ouid=%u ogid=%u rdev=%02x:%02x", |
1385 | n->ino, | 1384 | n->ino, |
1386 | MAJOR(n->dev), | 1385 | MAJOR(n->dev), |
1387 | MINOR(n->dev), | 1386 | MINOR(n->dev), |
1388 | n->mode, | 1387 | n->mode, |
1389 | n->uid, | 1388 | n->uid, |
1390 | n->gid, | 1389 | n->gid, |
1391 | MAJOR(n->rdev), | 1390 | MAJOR(n->rdev), |
1392 | MINOR(n->rdev)); | 1391 | MINOR(n->rdev)); |
1393 | } | 1392 | } |
1394 | if (n->osid != 0) { | 1393 | if (n->osid != 0) { |
1395 | char *ctx = NULL; | 1394 | char *ctx = NULL; |
1396 | u32 len; | 1395 | u32 len; |
1397 | if (security_secid_to_secctx( | 1396 | if (security_secid_to_secctx( |
1398 | n->osid, &ctx, &len)) { | 1397 | n->osid, &ctx, &len)) { |
1399 | audit_log_format(ab, " osid=%u", n->osid); | 1398 | audit_log_format(ab, " osid=%u", n->osid); |
1400 | call_panic = 2; | 1399 | call_panic = 2; |
1401 | } else { | 1400 | } else { |
1402 | audit_log_format(ab, " obj=%s", ctx); | 1401 | audit_log_format(ab, " obj=%s", ctx); |
1403 | security_release_secctx(ctx, len); | 1402 | security_release_secctx(ctx, len); |
1404 | } | 1403 | } |
1405 | } | 1404 | } |
1406 | 1405 | ||
1407 | audit_log_end(ab); | 1406 | audit_log_end(ab); |
1408 | } | 1407 | } |
1409 | 1408 | ||
1410 | /* Send end of event record to help user space know we are finished */ | 1409 | /* Send end of event record to help user space know we are finished */ |
1411 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_EOE); | 1410 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_EOE); |
1412 | if (ab) | 1411 | if (ab) |
1413 | audit_log_end(ab); | 1412 | audit_log_end(ab); |
1414 | if (call_panic) | 1413 | if (call_panic) |
1415 | audit_panic("error converting sid to string"); | 1414 | audit_panic("error converting sid to string"); |
1416 | } | 1415 | } |
1417 | 1416 | ||
1418 | /** | 1417 | /** |
1419 | * audit_free - free a per-task audit context | 1418 | * audit_free - free a per-task audit context |
1420 | * @tsk: task whose audit context block to free | 1419 | * @tsk: task whose audit context block to free |
1421 | * | 1420 | * |
1422 | * Called from copy_process and do_exit | 1421 | * Called from copy_process and do_exit |
1423 | */ | 1422 | */ |
1424 | void audit_free(struct task_struct *tsk) | 1423 | void audit_free(struct task_struct *tsk) |
1425 | { | 1424 | { |
1426 | struct audit_context *context; | 1425 | struct audit_context *context; |
1427 | 1426 | ||
1428 | context = audit_get_context(tsk, 0, 0); | 1427 | context = audit_get_context(tsk, 0, 0); |
1429 | if (likely(!context)) | 1428 | if (likely(!context)) |
1430 | return; | 1429 | return; |
1431 | 1430 | ||
1432 | /* Check for system calls that do not go through the exit | 1431 | /* Check for system calls that do not go through the exit |
1433 | * function (e.g., exit_group), then free context block. | 1432 | * function (e.g., exit_group), then free context block. |
1434 | * We use GFP_ATOMIC here because we might be doing this | 1433 | * We use GFP_ATOMIC here because we might be doing this |
1435 | * in the context of the idle thread */ | 1434 | * in the context of the idle thread */ |
1436 | /* that can happen only if we are called from do_exit() */ | 1435 | /* that can happen only if we are called from do_exit() */ |
1437 | if (context->in_syscall && context->auditable) | 1436 | if (context->in_syscall && context->auditable) |
1438 | audit_log_exit(context, tsk); | 1437 | audit_log_exit(context, tsk); |
1439 | 1438 | ||
1440 | audit_free_context(context); | 1439 | audit_free_context(context); |
1441 | } | 1440 | } |
1442 | 1441 | ||
1443 | /** | 1442 | /** |
1444 | * audit_syscall_entry - fill in an audit record at syscall entry | 1443 | * audit_syscall_entry - fill in an audit record at syscall entry |
1445 | * @tsk: task being audited | 1444 | * @tsk: task being audited |
1446 | * @arch: architecture type | 1445 | * @arch: architecture type |
1447 | * @major: major syscall type (function) | 1446 | * @major: major syscall type (function) |
1448 | * @a1: additional syscall register 1 | 1447 | * @a1: additional syscall register 1 |
1449 | * @a2: additional syscall register 2 | 1448 | * @a2: additional syscall register 2 |
1450 | * @a3: additional syscall register 3 | 1449 | * @a3: additional syscall register 3 |
1451 | * @a4: additional syscall register 4 | 1450 | * @a4: additional syscall register 4 |
1452 | * | 1451 | * |
1453 | * Fill in audit context at syscall entry. This only happens if the | 1452 | * Fill in audit context at syscall entry. This only happens if the |
1454 | * audit context was created when the task was created and the state or | 1453 | * audit context was created when the task was created and the state or |
1455 | * filters demand the audit context be built. If the state from the | 1454 | * filters demand the audit context be built. If the state from the |
1456 | * per-task filter or from the per-syscall filter is AUDIT_RECORD_CONTEXT, | 1455 | * per-task filter or from the per-syscall filter is AUDIT_RECORD_CONTEXT, |
1457 | * then the record will be written at syscall exit time (otherwise, it | 1456 | * then the record will be written at syscall exit time (otherwise, it |
1458 | * will only be written if another part of the kernel requests that it | 1457 | * will only be written if another part of the kernel requests that it |
1459 | * be written). | 1458 | * be written). |
1460 | */ | 1459 | */ |
1461 | void audit_syscall_entry(int arch, int major, | 1460 | void audit_syscall_entry(int arch, int major, |
1462 | unsigned long a1, unsigned long a2, | 1461 | unsigned long a1, unsigned long a2, |
1463 | unsigned long a3, unsigned long a4) | 1462 | unsigned long a3, unsigned long a4) |
1464 | { | 1463 | { |
1465 | struct task_struct *tsk = current; | 1464 | struct task_struct *tsk = current; |
1466 | struct audit_context *context = tsk->audit_context; | 1465 | struct audit_context *context = tsk->audit_context; |
1467 | enum audit_state state; | 1466 | enum audit_state state; |
1468 | 1467 | ||
1469 | BUG_ON(!context); | 1468 | BUG_ON(!context); |
1470 | 1469 | ||
1471 | /* | 1470 | /* |
1472 | * This happens only on certain architectures that make system | 1471 | * This happens only on certain architectures that make system |
1473 | * calls in kernel_thread via the entry.S interface, instead of | 1472 | * calls in kernel_thread via the entry.S interface, instead of |
1474 | * with direct calls. (If you are porting to a new | 1473 | * with direct calls. (If you are porting to a new |
1475 | * architecture, hitting this condition can indicate that you | 1474 | * architecture, hitting this condition can indicate that you |
1476 | * got the _exit/_leave calls backward in entry.S.) | 1475 | * got the _exit/_leave calls backward in entry.S.) |
1477 | * | 1476 | * |
1478 | * i386 no | 1477 | * i386 no |
1479 | * x86_64 no | 1478 | * x86_64 no |
1480 | * ppc64 yes (see arch/powerpc/platforms/iseries/misc.S) | 1479 | * ppc64 yes (see arch/powerpc/platforms/iseries/misc.S) |
1481 | * | 1480 | * |
1482 | * This also happens with vm86 emulation in a non-nested manner | 1481 | * This also happens with vm86 emulation in a non-nested manner |
1483 | * (entries without exits), so this case must be caught. | 1482 | * (entries without exits), so this case must be caught. |
1484 | */ | 1483 | */ |
1485 | if (context->in_syscall) { | 1484 | if (context->in_syscall) { |
1486 | struct audit_context *newctx; | 1485 | struct audit_context *newctx; |
1487 | 1486 | ||
1488 | #if AUDIT_DEBUG | 1487 | #if AUDIT_DEBUG |
1489 | printk(KERN_ERR | 1488 | printk(KERN_ERR |
1490 | "audit(:%d) pid=%d in syscall=%d;" | 1489 | "audit(:%d) pid=%d in syscall=%d;" |
1491 | " entering syscall=%d\n", | 1490 | " entering syscall=%d\n", |
1492 | context->serial, tsk->pid, context->major, major); | 1491 | context->serial, tsk->pid, context->major, major); |
1493 | #endif | 1492 | #endif |
1494 | newctx = audit_alloc_context(context->state); | 1493 | newctx = audit_alloc_context(context->state); |
1495 | if (newctx) { | 1494 | if (newctx) { |
1496 | newctx->previous = context; | 1495 | newctx->previous = context; |
1497 | context = newctx; | 1496 | context = newctx; |
1498 | tsk->audit_context = newctx; | 1497 | tsk->audit_context = newctx; |
1499 | } else { | 1498 | } else { |
1500 | /* If we can't alloc a new context, the best we | 1499 | /* If we can't alloc a new context, the best we |
1501 | * can do is to leak memory (any pending putname | 1500 | * can do is to leak memory (any pending putname |
1502 | * will be lost). The only other alternative is | 1501 | * will be lost). The only other alternative is |
1503 | * to abandon auditing. */ | 1502 | * to abandon auditing. */ |
1504 | audit_zero_context(context, context->state); | 1503 | audit_zero_context(context, context->state); |
1505 | } | 1504 | } |
1506 | } | 1505 | } |
1507 | BUG_ON(context->in_syscall || context->name_count); | 1506 | BUG_ON(context->in_syscall || context->name_count); |
1508 | 1507 | ||
1509 | if (!audit_enabled) | 1508 | if (!audit_enabled) |
1510 | return; | 1509 | return; |
1511 | 1510 | ||
1512 | context->arch = arch; | 1511 | context->arch = arch; |
1513 | context->major = major; | 1512 | context->major = major; |
1514 | context->argv[0] = a1; | 1513 | context->argv[0] = a1; |
1515 | context->argv[1] = a2; | 1514 | context->argv[1] = a2; |
1516 | context->argv[2] = a3; | 1515 | context->argv[2] = a3; |
1517 | context->argv[3] = a4; | 1516 | context->argv[3] = a4; |
1518 | 1517 | ||
1519 | state = context->state; | 1518 | state = context->state; |
1520 | context->dummy = !audit_n_rules; | 1519 | context->dummy = !audit_n_rules; |
1521 | if (!context->dummy && (state == AUDIT_SETUP_CONTEXT || state == AUDIT_BUILD_CONTEXT)) | 1520 | if (!context->dummy && (state == AUDIT_SETUP_CONTEXT || state == AUDIT_BUILD_CONTEXT)) |
1522 | state = audit_filter_syscall(tsk, context, &audit_filter_list[AUDIT_FILTER_ENTRY]); | 1521 | state = audit_filter_syscall(tsk, context, &audit_filter_list[AUDIT_FILTER_ENTRY]); |
1523 | if (likely(state == AUDIT_DISABLED)) | 1522 | if (likely(state == AUDIT_DISABLED)) |
1524 | return; | 1523 | return; |
1525 | 1524 | ||
1526 | context->serial = 0; | 1525 | context->serial = 0; |
1527 | context->ctime = CURRENT_TIME; | 1526 | context->ctime = CURRENT_TIME; |
1528 | context->in_syscall = 1; | 1527 | context->in_syscall = 1; |
1529 | context->auditable = !!(state == AUDIT_RECORD_CONTEXT); | 1528 | context->auditable = !!(state == AUDIT_RECORD_CONTEXT); |
1530 | context->ppid = 0; | 1529 | context->ppid = 0; |
1531 | } | 1530 | } |
1532 | 1531 | ||
1533 | /** | 1532 | /** |
1534 | * audit_syscall_exit - deallocate audit context after a system call | 1533 | * audit_syscall_exit - deallocate audit context after a system call |
1535 | * @tsk: task being audited | 1534 | * @tsk: task being audited |
1536 | * @valid: success/failure flag | 1535 | * @valid: success/failure flag |
1537 | * @return_code: syscall return value | 1536 | * @return_code: syscall return value |
1538 | * | 1537 | * |
1539 | * Tear down after system call. If the audit context has been marked as | 1538 | * Tear down after system call. If the audit context has been marked as |
1540 | * auditable (either because of the AUDIT_RECORD_CONTEXT state from | 1539 | * auditable (either because of the AUDIT_RECORD_CONTEXT state from |
1541 | * filtering, or because some other part of the kernel write an audit | 1540 | * filtering, or because some other part of the kernel write an audit |
1542 | * message), then write out the syscall information. In call cases, | 1541 | * message), then write out the syscall information. In call cases, |
1543 | * free the names stored from getname(). | 1542 | * free the names stored from getname(). |
1544 | */ | 1543 | */ |
1545 | void audit_syscall_exit(int valid, long return_code) | 1544 | void audit_syscall_exit(int valid, long return_code) |
1546 | { | 1545 | { |
1547 | struct task_struct *tsk = current; | 1546 | struct task_struct *tsk = current; |
1548 | struct audit_context *context; | 1547 | struct audit_context *context; |
1549 | 1548 | ||
1550 | context = audit_get_context(tsk, valid, return_code); | 1549 | context = audit_get_context(tsk, valid, return_code); |
1551 | 1550 | ||
1552 | if (likely(!context)) | 1551 | if (likely(!context)) |
1553 | return; | 1552 | return; |
1554 | 1553 | ||
1555 | if (context->in_syscall && context->auditable) | 1554 | if (context->in_syscall && context->auditable) |
1556 | audit_log_exit(context, tsk); | 1555 | audit_log_exit(context, tsk); |
1557 | 1556 | ||
1558 | context->in_syscall = 0; | 1557 | context->in_syscall = 0; |
1559 | context->auditable = 0; | 1558 | context->auditable = 0; |
1560 | 1559 | ||
1561 | if (context->previous) { | 1560 | if (context->previous) { |
1562 | struct audit_context *new_context = context->previous; | 1561 | struct audit_context *new_context = context->previous; |
1563 | context->previous = NULL; | 1562 | context->previous = NULL; |
1564 | audit_free_context(context); | 1563 | audit_free_context(context); |
1565 | tsk->audit_context = new_context; | 1564 | tsk->audit_context = new_context; |
1566 | } else { | 1565 | } else { |
1567 | audit_free_names(context); | 1566 | audit_free_names(context); |
1568 | unroll_tree_refs(context, NULL, 0); | 1567 | unroll_tree_refs(context, NULL, 0); |
1569 | audit_free_aux(context); | 1568 | audit_free_aux(context); |
1570 | context->aux = NULL; | 1569 | context->aux = NULL; |
1571 | context->aux_pids = NULL; | 1570 | context->aux_pids = NULL; |
1572 | context->target_pid = 0; | 1571 | context->target_pid = 0; |
1573 | context->target_sid = 0; | 1572 | context->target_sid = 0; |
1574 | kfree(context->filterkey); | 1573 | kfree(context->filterkey); |
1575 | context->filterkey = NULL; | 1574 | context->filterkey = NULL; |
1576 | tsk->audit_context = context; | 1575 | tsk->audit_context = context; |
1577 | } | 1576 | } |
1578 | } | 1577 | } |
1579 | 1578 | ||
1580 | static inline void handle_one(const struct inode *inode) | 1579 | static inline void handle_one(const struct inode *inode) |
1581 | { | 1580 | { |
1582 | #ifdef CONFIG_AUDIT_TREE | 1581 | #ifdef CONFIG_AUDIT_TREE |
1583 | struct audit_context *context; | 1582 | struct audit_context *context; |
1584 | struct audit_tree_refs *p; | 1583 | struct audit_tree_refs *p; |
1585 | struct audit_chunk *chunk; | 1584 | struct audit_chunk *chunk; |
1586 | int count; | 1585 | int count; |
1587 | if (likely(list_empty(&inode->inotify_watches))) | 1586 | if (likely(list_empty(&inode->inotify_watches))) |
1588 | return; | 1587 | return; |
1589 | context = current->audit_context; | 1588 | context = current->audit_context; |
1590 | p = context->trees; | 1589 | p = context->trees; |
1591 | count = context->tree_count; | 1590 | count = context->tree_count; |
1592 | rcu_read_lock(); | 1591 | rcu_read_lock(); |
1593 | chunk = audit_tree_lookup(inode); | 1592 | chunk = audit_tree_lookup(inode); |
1594 | rcu_read_unlock(); | 1593 | rcu_read_unlock(); |
1595 | if (!chunk) | 1594 | if (!chunk) |
1596 | return; | 1595 | return; |
1597 | if (likely(put_tree_ref(context, chunk))) | 1596 | if (likely(put_tree_ref(context, chunk))) |
1598 | return; | 1597 | return; |
1599 | if (unlikely(!grow_tree_refs(context))) { | 1598 | if (unlikely(!grow_tree_refs(context))) { |
1600 | printk(KERN_WARNING "out of memory, audit has lost a tree reference"); | 1599 | printk(KERN_WARNING "out of memory, audit has lost a tree reference"); |
1601 | audit_set_auditable(context); | 1600 | audit_set_auditable(context); |
1602 | audit_put_chunk(chunk); | 1601 | audit_put_chunk(chunk); |
1603 | unroll_tree_refs(context, p, count); | 1602 | unroll_tree_refs(context, p, count); |
1604 | return; | 1603 | return; |
1605 | } | 1604 | } |
1606 | put_tree_ref(context, chunk); | 1605 | put_tree_ref(context, chunk); |
1607 | #endif | 1606 | #endif |
1608 | } | 1607 | } |
1609 | 1608 | ||
1610 | static void handle_path(const struct dentry *dentry) | 1609 | static void handle_path(const struct dentry *dentry) |
1611 | { | 1610 | { |
1612 | #ifdef CONFIG_AUDIT_TREE | 1611 | #ifdef CONFIG_AUDIT_TREE |
1613 | struct audit_context *context; | 1612 | struct audit_context *context; |
1614 | struct audit_tree_refs *p; | 1613 | struct audit_tree_refs *p; |
1615 | const struct dentry *d, *parent; | 1614 | const struct dentry *d, *parent; |
1616 | struct audit_chunk *drop; | 1615 | struct audit_chunk *drop; |
1617 | unsigned long seq; | 1616 | unsigned long seq; |
1618 | int count; | 1617 | int count; |
1619 | 1618 | ||
1620 | context = current->audit_context; | 1619 | context = current->audit_context; |
1621 | p = context->trees; | 1620 | p = context->trees; |
1622 | count = context->tree_count; | 1621 | count = context->tree_count; |
1623 | retry: | 1622 | retry: |
1624 | drop = NULL; | 1623 | drop = NULL; |
1625 | d = dentry; | 1624 | d = dentry; |
1626 | rcu_read_lock(); | 1625 | rcu_read_lock(); |
1627 | seq = read_seqbegin(&rename_lock); | 1626 | seq = read_seqbegin(&rename_lock); |
1628 | for(;;) { | 1627 | for(;;) { |
1629 | struct inode *inode = d->d_inode; | 1628 | struct inode *inode = d->d_inode; |
1630 | if (inode && unlikely(!list_empty(&inode->inotify_watches))) { | 1629 | if (inode && unlikely(!list_empty(&inode->inotify_watches))) { |
1631 | struct audit_chunk *chunk; | 1630 | struct audit_chunk *chunk; |
1632 | chunk = audit_tree_lookup(inode); | 1631 | chunk = audit_tree_lookup(inode); |
1633 | if (chunk) { | 1632 | if (chunk) { |
1634 | if (unlikely(!put_tree_ref(context, chunk))) { | 1633 | if (unlikely(!put_tree_ref(context, chunk))) { |
1635 | drop = chunk; | 1634 | drop = chunk; |
1636 | break; | 1635 | break; |
1637 | } | 1636 | } |
1638 | } | 1637 | } |
1639 | } | 1638 | } |
1640 | parent = d->d_parent; | 1639 | parent = d->d_parent; |
1641 | if (parent == d) | 1640 | if (parent == d) |
1642 | break; | 1641 | break; |
1643 | d = parent; | 1642 | d = parent; |
1644 | } | 1643 | } |
1645 | if (unlikely(read_seqretry(&rename_lock, seq) || drop)) { /* in this order */ | 1644 | if (unlikely(read_seqretry(&rename_lock, seq) || drop)) { /* in this order */ |
1646 | rcu_read_unlock(); | 1645 | rcu_read_unlock(); |
1647 | if (!drop) { | 1646 | if (!drop) { |
1648 | /* just a race with rename */ | 1647 | /* just a race with rename */ |
1649 | unroll_tree_refs(context, p, count); | 1648 | unroll_tree_refs(context, p, count); |
1650 | goto retry; | 1649 | goto retry; |
1651 | } | 1650 | } |
1652 | audit_put_chunk(drop); | 1651 | audit_put_chunk(drop); |
1653 | if (grow_tree_refs(context)) { | 1652 | if (grow_tree_refs(context)) { |
1654 | /* OK, got more space */ | 1653 | /* OK, got more space */ |
1655 | unroll_tree_refs(context, p, count); | 1654 | unroll_tree_refs(context, p, count); |
1656 | goto retry; | 1655 | goto retry; |
1657 | } | 1656 | } |
1658 | /* too bad */ | 1657 | /* too bad */ |
1659 | printk(KERN_WARNING | 1658 | printk(KERN_WARNING |
1660 | "out of memory, audit has lost a tree reference"); | 1659 | "out of memory, audit has lost a tree reference"); |
1661 | unroll_tree_refs(context, p, count); | 1660 | unroll_tree_refs(context, p, count); |
1662 | audit_set_auditable(context); | 1661 | audit_set_auditable(context); |
1663 | return; | 1662 | return; |
1664 | } | 1663 | } |
1665 | rcu_read_unlock(); | 1664 | rcu_read_unlock(); |
1666 | #endif | 1665 | #endif |
1667 | } | 1666 | } |
1668 | 1667 | ||
1669 | /** | 1668 | /** |
1670 | * audit_getname - add a name to the list | 1669 | * audit_getname - add a name to the list |
1671 | * @name: name to add | 1670 | * @name: name to add |
1672 | * | 1671 | * |
1673 | * Add a name to the list of audit names for this context. | 1672 | * Add a name to the list of audit names for this context. |
1674 | * Called from fs/namei.c:getname(). | 1673 | * Called from fs/namei.c:getname(). |
1675 | */ | 1674 | */ |
1676 | void __audit_getname(const char *name) | 1675 | void __audit_getname(const char *name) |
1677 | { | 1676 | { |
1678 | struct audit_context *context = current->audit_context; | 1677 | struct audit_context *context = current->audit_context; |
1679 | 1678 | ||
1680 | if (IS_ERR(name) || !name) | 1679 | if (IS_ERR(name) || !name) |
1681 | return; | 1680 | return; |
1682 | 1681 | ||
1683 | if (!context->in_syscall) { | 1682 | if (!context->in_syscall) { |
1684 | #if AUDIT_DEBUG == 2 | 1683 | #if AUDIT_DEBUG == 2 |
1685 | printk(KERN_ERR "%s:%d(:%d): ignoring getname(%p)\n", | 1684 | printk(KERN_ERR "%s:%d(:%d): ignoring getname(%p)\n", |
1686 | __FILE__, __LINE__, context->serial, name); | 1685 | __FILE__, __LINE__, context->serial, name); |
1687 | dump_stack(); | 1686 | dump_stack(); |
1688 | #endif | 1687 | #endif |
1689 | return; | 1688 | return; |
1690 | } | 1689 | } |
1691 | BUG_ON(context->name_count >= AUDIT_NAMES); | 1690 | BUG_ON(context->name_count >= AUDIT_NAMES); |
1692 | context->names[context->name_count].name = name; | 1691 | context->names[context->name_count].name = name; |
1693 | context->names[context->name_count].name_len = AUDIT_NAME_FULL; | 1692 | context->names[context->name_count].name_len = AUDIT_NAME_FULL; |
1694 | context->names[context->name_count].name_put = 1; | 1693 | context->names[context->name_count].name_put = 1; |
1695 | context->names[context->name_count].ino = (unsigned long)-1; | 1694 | context->names[context->name_count].ino = (unsigned long)-1; |
1696 | context->names[context->name_count].osid = 0; | 1695 | context->names[context->name_count].osid = 0; |
1697 | ++context->name_count; | 1696 | ++context->name_count; |
1698 | if (!context->pwd.dentry) { | 1697 | if (!context->pwd.dentry) { |
1699 | read_lock(¤t->fs->lock); | 1698 | read_lock(¤t->fs->lock); |
1700 | context->pwd = current->fs->pwd; | 1699 | context->pwd = current->fs->pwd; |
1701 | path_get(¤t->fs->pwd); | 1700 | path_get(¤t->fs->pwd); |
1702 | read_unlock(¤t->fs->lock); | 1701 | read_unlock(¤t->fs->lock); |
1703 | } | 1702 | } |
1704 | 1703 | ||
1705 | } | 1704 | } |
1706 | 1705 | ||
1707 | /* audit_putname - intercept a putname request | 1706 | /* audit_putname - intercept a putname request |
1708 | * @name: name to intercept and delay for putname | 1707 | * @name: name to intercept and delay for putname |
1709 | * | 1708 | * |
1710 | * If we have stored the name from getname in the audit context, | 1709 | * If we have stored the name from getname in the audit context, |
1711 | * then we delay the putname until syscall exit. | 1710 | * then we delay the putname until syscall exit. |
1712 | * Called from include/linux/fs.h:putname(). | 1711 | * Called from include/linux/fs.h:putname(). |
1713 | */ | 1712 | */ |
1714 | void audit_putname(const char *name) | 1713 | void audit_putname(const char *name) |
1715 | { | 1714 | { |
1716 | struct audit_context *context = current->audit_context; | 1715 | struct audit_context *context = current->audit_context; |
1717 | 1716 | ||
1718 | BUG_ON(!context); | 1717 | BUG_ON(!context); |
1719 | if (!context->in_syscall) { | 1718 | if (!context->in_syscall) { |
1720 | #if AUDIT_DEBUG == 2 | 1719 | #if AUDIT_DEBUG == 2 |
1721 | printk(KERN_ERR "%s:%d(:%d): __putname(%p)\n", | 1720 | printk(KERN_ERR "%s:%d(:%d): __putname(%p)\n", |
1722 | __FILE__, __LINE__, context->serial, name); | 1721 | __FILE__, __LINE__, context->serial, name); |
1723 | if (context->name_count) { | 1722 | if (context->name_count) { |
1724 | int i; | 1723 | int i; |
1725 | for (i = 0; i < context->name_count; i++) | 1724 | for (i = 0; i < context->name_count; i++) |
1726 | printk(KERN_ERR "name[%d] = %p = %s\n", i, | 1725 | printk(KERN_ERR "name[%d] = %p = %s\n", i, |
1727 | context->names[i].name, | 1726 | context->names[i].name, |
1728 | context->names[i].name ?: "(null)"); | 1727 | context->names[i].name ?: "(null)"); |
1729 | } | 1728 | } |
1730 | #endif | 1729 | #endif |
1731 | __putname(name); | 1730 | __putname(name); |
1732 | } | 1731 | } |
1733 | #if AUDIT_DEBUG | 1732 | #if AUDIT_DEBUG |
1734 | else { | 1733 | else { |
1735 | ++context->put_count; | 1734 | ++context->put_count; |
1736 | if (context->put_count > context->name_count) { | 1735 | if (context->put_count > context->name_count) { |
1737 | printk(KERN_ERR "%s:%d(:%d): major=%d" | 1736 | printk(KERN_ERR "%s:%d(:%d): major=%d" |
1738 | " in_syscall=%d putname(%p) name_count=%d" | 1737 | " in_syscall=%d putname(%p) name_count=%d" |
1739 | " put_count=%d\n", | 1738 | " put_count=%d\n", |
1740 | __FILE__, __LINE__, | 1739 | __FILE__, __LINE__, |
1741 | context->serial, context->major, | 1740 | context->serial, context->major, |
1742 | context->in_syscall, name, context->name_count, | 1741 | context->in_syscall, name, context->name_count, |
1743 | context->put_count); | 1742 | context->put_count); |
1744 | dump_stack(); | 1743 | dump_stack(); |
1745 | } | 1744 | } |
1746 | } | 1745 | } |
1747 | #endif | 1746 | #endif |
1748 | } | 1747 | } |
1749 | 1748 | ||
1750 | static int audit_inc_name_count(struct audit_context *context, | 1749 | static int audit_inc_name_count(struct audit_context *context, |
1751 | const struct inode *inode) | 1750 | const struct inode *inode) |
1752 | { | 1751 | { |
1753 | if (context->name_count >= AUDIT_NAMES) { | 1752 | if (context->name_count >= AUDIT_NAMES) { |
1754 | if (inode) | 1753 | if (inode) |
1755 | printk(KERN_DEBUG "name_count maxed, losing inode data: " | 1754 | printk(KERN_DEBUG "name_count maxed, losing inode data: " |
1756 | "dev=%02x:%02x, inode=%lu", | 1755 | "dev=%02x:%02x, inode=%lu", |
1757 | MAJOR(inode->i_sb->s_dev), | 1756 | MAJOR(inode->i_sb->s_dev), |
1758 | MINOR(inode->i_sb->s_dev), | 1757 | MINOR(inode->i_sb->s_dev), |
1759 | inode->i_ino); | 1758 | inode->i_ino); |
1760 | 1759 | ||
1761 | else | 1760 | else |
1762 | printk(KERN_DEBUG "name_count maxed, losing inode data"); | 1761 | printk(KERN_DEBUG "name_count maxed, losing inode data"); |
1763 | return 1; | 1762 | return 1; |
1764 | } | 1763 | } |
1765 | context->name_count++; | 1764 | context->name_count++; |
1766 | #if AUDIT_DEBUG | 1765 | #if AUDIT_DEBUG |
1767 | context->ino_count++; | 1766 | context->ino_count++; |
1768 | #endif | 1767 | #endif |
1769 | return 0; | 1768 | return 0; |
1770 | } | 1769 | } |
1771 | 1770 | ||
1772 | /* Copy inode data into an audit_names. */ | 1771 | /* Copy inode data into an audit_names. */ |
1773 | static void audit_copy_inode(struct audit_names *name, const struct inode *inode) | 1772 | static void audit_copy_inode(struct audit_names *name, const struct inode *inode) |
1774 | { | 1773 | { |
1775 | name->ino = inode->i_ino; | 1774 | name->ino = inode->i_ino; |
1776 | name->dev = inode->i_sb->s_dev; | 1775 | name->dev = inode->i_sb->s_dev; |
1777 | name->mode = inode->i_mode; | 1776 | name->mode = inode->i_mode; |
1778 | name->uid = inode->i_uid; | 1777 | name->uid = inode->i_uid; |
1779 | name->gid = inode->i_gid; | 1778 | name->gid = inode->i_gid; |
1780 | name->rdev = inode->i_rdev; | 1779 | name->rdev = inode->i_rdev; |
1781 | security_inode_getsecid(inode, &name->osid); | 1780 | security_inode_getsecid(inode, &name->osid); |
1782 | } | 1781 | } |
1783 | 1782 | ||
1784 | /** | 1783 | /** |
1785 | * audit_inode - store the inode and device from a lookup | 1784 | * audit_inode - store the inode and device from a lookup |
1786 | * @name: name being audited | 1785 | * @name: name being audited |
1787 | * @dentry: dentry being audited | 1786 | * @dentry: dentry being audited |
1788 | * | 1787 | * |
1789 | * Called from fs/namei.c:path_lookup(). | 1788 | * Called from fs/namei.c:path_lookup(). |
1790 | */ | 1789 | */ |
1791 | void __audit_inode(const char *name, const struct dentry *dentry) | 1790 | void __audit_inode(const char *name, const struct dentry *dentry) |
1792 | { | 1791 | { |
1793 | int idx; | 1792 | int idx; |
1794 | struct audit_context *context = current->audit_context; | 1793 | struct audit_context *context = current->audit_context; |
1795 | const struct inode *inode = dentry->d_inode; | 1794 | const struct inode *inode = dentry->d_inode; |
1796 | 1795 | ||
1797 | if (!context->in_syscall) | 1796 | if (!context->in_syscall) |
1798 | return; | 1797 | return; |
1799 | if (context->name_count | 1798 | if (context->name_count |
1800 | && context->names[context->name_count-1].name | 1799 | && context->names[context->name_count-1].name |
1801 | && context->names[context->name_count-1].name == name) | 1800 | && context->names[context->name_count-1].name == name) |
1802 | idx = context->name_count - 1; | 1801 | idx = context->name_count - 1; |
1803 | else if (context->name_count > 1 | 1802 | else if (context->name_count > 1 |
1804 | && context->names[context->name_count-2].name | 1803 | && context->names[context->name_count-2].name |
1805 | && context->names[context->name_count-2].name == name) | 1804 | && context->names[context->name_count-2].name == name) |
1806 | idx = context->name_count - 2; | 1805 | idx = context->name_count - 2; |
1807 | else { | 1806 | else { |
1808 | /* FIXME: how much do we care about inodes that have no | 1807 | /* FIXME: how much do we care about inodes that have no |
1809 | * associated name? */ | 1808 | * associated name? */ |
1810 | if (audit_inc_name_count(context, inode)) | 1809 | if (audit_inc_name_count(context, inode)) |
1811 | return; | 1810 | return; |
1812 | idx = context->name_count - 1; | 1811 | idx = context->name_count - 1; |
1813 | context->names[idx].name = NULL; | 1812 | context->names[idx].name = NULL; |
1814 | } | 1813 | } |
1815 | handle_path(dentry); | 1814 | handle_path(dentry); |
1816 | audit_copy_inode(&context->names[idx], inode); | 1815 | audit_copy_inode(&context->names[idx], inode); |
1817 | } | 1816 | } |
1818 | 1817 | ||
1819 | /** | 1818 | /** |
1820 | * audit_inode_child - collect inode info for created/removed objects | 1819 | * audit_inode_child - collect inode info for created/removed objects |
1821 | * @dname: inode's dentry name | 1820 | * @dname: inode's dentry name |
1822 | * @dentry: dentry being audited | 1821 | * @dentry: dentry being audited |
1823 | * @parent: inode of dentry parent | 1822 | * @parent: inode of dentry parent |
1824 | * | 1823 | * |
1825 | * For syscalls that create or remove filesystem objects, audit_inode | 1824 | * For syscalls that create or remove filesystem objects, audit_inode |
1826 | * can only collect information for the filesystem object's parent. | 1825 | * can only collect information for the filesystem object's parent. |
1827 | * This call updates the audit context with the child's information. | 1826 | * This call updates the audit context with the child's information. |
1828 | * Syscalls that create a new filesystem object must be hooked after | 1827 | * Syscalls that create a new filesystem object must be hooked after |
1829 | * the object is created. Syscalls that remove a filesystem object | 1828 | * the object is created. Syscalls that remove a filesystem object |
1830 | * must be hooked prior, in order to capture the target inode during | 1829 | * must be hooked prior, in order to capture the target inode during |
1831 | * unsuccessful attempts. | 1830 | * unsuccessful attempts. |
1832 | */ | 1831 | */ |
1833 | void __audit_inode_child(const char *dname, const struct dentry *dentry, | 1832 | void __audit_inode_child(const char *dname, const struct dentry *dentry, |
1834 | const struct inode *parent) | 1833 | const struct inode *parent) |
1835 | { | 1834 | { |
1836 | int idx; | 1835 | int idx; |
1837 | struct audit_context *context = current->audit_context; | 1836 | struct audit_context *context = current->audit_context; |
1838 | const char *found_parent = NULL, *found_child = NULL; | 1837 | const char *found_parent = NULL, *found_child = NULL; |
1839 | const struct inode *inode = dentry->d_inode; | 1838 | const struct inode *inode = dentry->d_inode; |
1840 | int dirlen = 0; | 1839 | int dirlen = 0; |
1841 | 1840 | ||
1842 | if (!context->in_syscall) | 1841 | if (!context->in_syscall) |
1843 | return; | 1842 | return; |
1844 | 1843 | ||
1845 | if (inode) | 1844 | if (inode) |
1846 | handle_one(inode); | 1845 | handle_one(inode); |
1847 | /* determine matching parent */ | 1846 | /* determine matching parent */ |
1848 | if (!dname) | 1847 | if (!dname) |
1849 | goto add_names; | 1848 | goto add_names; |
1850 | 1849 | ||
1851 | /* parent is more likely, look for it first */ | 1850 | /* parent is more likely, look for it first */ |
1852 | for (idx = 0; idx < context->name_count; idx++) { | 1851 | for (idx = 0; idx < context->name_count; idx++) { |
1853 | struct audit_names *n = &context->names[idx]; | 1852 | struct audit_names *n = &context->names[idx]; |
1854 | 1853 | ||
1855 | if (!n->name) | 1854 | if (!n->name) |
1856 | continue; | 1855 | continue; |
1857 | 1856 | ||
1858 | if (n->ino == parent->i_ino && | 1857 | if (n->ino == parent->i_ino && |
1859 | !audit_compare_dname_path(dname, n->name, &dirlen)) { | 1858 | !audit_compare_dname_path(dname, n->name, &dirlen)) { |
1860 | n->name_len = dirlen; /* update parent data in place */ | 1859 | n->name_len = dirlen; /* update parent data in place */ |
1861 | found_parent = n->name; | 1860 | found_parent = n->name; |
1862 | goto add_names; | 1861 | goto add_names; |
1863 | } | 1862 | } |
1864 | } | 1863 | } |
1865 | 1864 | ||
1866 | /* no matching parent, look for matching child */ | 1865 | /* no matching parent, look for matching child */ |
1867 | for (idx = 0; idx < context->name_count; idx++) { | 1866 | for (idx = 0; idx < context->name_count; idx++) { |
1868 | struct audit_names *n = &context->names[idx]; | 1867 | struct audit_names *n = &context->names[idx]; |
1869 | 1868 | ||
1870 | if (!n->name) | 1869 | if (!n->name) |
1871 | continue; | 1870 | continue; |
1872 | 1871 | ||
1873 | /* strcmp() is the more likely scenario */ | 1872 | /* strcmp() is the more likely scenario */ |
1874 | if (!strcmp(dname, n->name) || | 1873 | if (!strcmp(dname, n->name) || |
1875 | !audit_compare_dname_path(dname, n->name, &dirlen)) { | 1874 | !audit_compare_dname_path(dname, n->name, &dirlen)) { |
1876 | if (inode) | 1875 | if (inode) |
1877 | audit_copy_inode(n, inode); | 1876 | audit_copy_inode(n, inode); |
1878 | else | 1877 | else |
1879 | n->ino = (unsigned long)-1; | 1878 | n->ino = (unsigned long)-1; |
1880 | found_child = n->name; | 1879 | found_child = n->name; |
1881 | goto add_names; | 1880 | goto add_names; |
1882 | } | 1881 | } |
1883 | } | 1882 | } |
1884 | 1883 | ||
1885 | add_names: | 1884 | add_names: |
1886 | if (!found_parent) { | 1885 | if (!found_parent) { |
1887 | if (audit_inc_name_count(context, parent)) | 1886 | if (audit_inc_name_count(context, parent)) |
1888 | return; | 1887 | return; |
1889 | idx = context->name_count - 1; | 1888 | idx = context->name_count - 1; |
1890 | context->names[idx].name = NULL; | 1889 | context->names[idx].name = NULL; |
1891 | audit_copy_inode(&context->names[idx], parent); | 1890 | audit_copy_inode(&context->names[idx], parent); |
1892 | } | 1891 | } |
1893 | 1892 | ||
1894 | if (!found_child) { | 1893 | if (!found_child) { |
1895 | if (audit_inc_name_count(context, inode)) | 1894 | if (audit_inc_name_count(context, inode)) |
1896 | return; | 1895 | return; |
1897 | idx = context->name_count - 1; | 1896 | idx = context->name_count - 1; |
1898 | 1897 | ||
1899 | /* Re-use the name belonging to the slot for a matching parent | 1898 | /* Re-use the name belonging to the slot for a matching parent |
1900 | * directory. All names for this context are relinquished in | 1899 | * directory. All names for this context are relinquished in |
1901 | * audit_free_names() */ | 1900 | * audit_free_names() */ |
1902 | if (found_parent) { | 1901 | if (found_parent) { |
1903 | context->names[idx].name = found_parent; | 1902 | context->names[idx].name = found_parent; |
1904 | context->names[idx].name_len = AUDIT_NAME_FULL; | 1903 | context->names[idx].name_len = AUDIT_NAME_FULL; |
1905 | /* don't call __putname() */ | 1904 | /* don't call __putname() */ |
1906 | context->names[idx].name_put = 0; | 1905 | context->names[idx].name_put = 0; |
1907 | } else { | 1906 | } else { |
1908 | context->names[idx].name = NULL; | 1907 | context->names[idx].name = NULL; |
1909 | } | 1908 | } |
1910 | 1909 | ||
1911 | if (inode) | 1910 | if (inode) |
1912 | audit_copy_inode(&context->names[idx], inode); | 1911 | audit_copy_inode(&context->names[idx], inode); |
1913 | else | 1912 | else |
1914 | context->names[idx].ino = (unsigned long)-1; | 1913 | context->names[idx].ino = (unsigned long)-1; |
1915 | } | 1914 | } |
1916 | } | 1915 | } |
1917 | EXPORT_SYMBOL_GPL(__audit_inode_child); | 1916 | EXPORT_SYMBOL_GPL(__audit_inode_child); |
1918 | 1917 | ||
1919 | /** | 1918 | /** |
1920 | * auditsc_get_stamp - get local copies of audit_context values | 1919 | * auditsc_get_stamp - get local copies of audit_context values |
1921 | * @ctx: audit_context for the task | 1920 | * @ctx: audit_context for the task |
1922 | * @t: timespec to store time recorded in the audit_context | 1921 | * @t: timespec to store time recorded in the audit_context |
1923 | * @serial: serial value that is recorded in the audit_context | 1922 | * @serial: serial value that is recorded in the audit_context |
1924 | * | 1923 | * |
1925 | * Also sets the context as auditable. | 1924 | * Also sets the context as auditable. |
1926 | */ | 1925 | */ |
1927 | void auditsc_get_stamp(struct audit_context *ctx, | 1926 | void auditsc_get_stamp(struct audit_context *ctx, |
1928 | struct timespec *t, unsigned int *serial) | 1927 | struct timespec *t, unsigned int *serial) |
1929 | { | 1928 | { |
1930 | if (!ctx->serial) | 1929 | if (!ctx->serial) |
1931 | ctx->serial = audit_serial(); | 1930 | ctx->serial = audit_serial(); |
1932 | t->tv_sec = ctx->ctime.tv_sec; | 1931 | t->tv_sec = ctx->ctime.tv_sec; |
1933 | t->tv_nsec = ctx->ctime.tv_nsec; | 1932 | t->tv_nsec = ctx->ctime.tv_nsec; |
1934 | *serial = ctx->serial; | 1933 | *serial = ctx->serial; |
1935 | ctx->auditable = 1; | 1934 | ctx->auditable = 1; |
1936 | } | 1935 | } |
1937 | 1936 | ||
1938 | /* global counter which is incremented every time something logs in */ | 1937 | /* global counter which is incremented every time something logs in */ |
1939 | static atomic_t session_id = ATOMIC_INIT(0); | 1938 | static atomic_t session_id = ATOMIC_INIT(0); |
1940 | 1939 | ||
1941 | /** | 1940 | /** |
1942 | * audit_set_loginuid - set a task's audit_context loginuid | 1941 | * audit_set_loginuid - set a task's audit_context loginuid |
1943 | * @task: task whose audit context is being modified | 1942 | * @task: task whose audit context is being modified |
1944 | * @loginuid: loginuid value | 1943 | * @loginuid: loginuid value |
1945 | * | 1944 | * |
1946 | * Returns 0. | 1945 | * Returns 0. |
1947 | * | 1946 | * |
1948 | * Called (set) from fs/proc/base.c::proc_loginuid_write(). | 1947 | * Called (set) from fs/proc/base.c::proc_loginuid_write(). |
1949 | */ | 1948 | */ |
1950 | int audit_set_loginuid(struct task_struct *task, uid_t loginuid) | 1949 | int audit_set_loginuid(struct task_struct *task, uid_t loginuid) |
1951 | { | 1950 | { |
1952 | unsigned int sessionid = atomic_inc_return(&session_id); | 1951 | unsigned int sessionid = atomic_inc_return(&session_id); |
1953 | struct audit_context *context = task->audit_context; | 1952 | struct audit_context *context = task->audit_context; |
1954 | 1953 | ||
1955 | if (context && context->in_syscall) { | 1954 | if (context && context->in_syscall) { |
1956 | struct audit_buffer *ab; | 1955 | struct audit_buffer *ab; |
1957 | 1956 | ||
1958 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN); | 1957 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN); |
1959 | if (ab) { | 1958 | if (ab) { |
1960 | audit_log_format(ab, "login pid=%d uid=%u " | 1959 | audit_log_format(ab, "login pid=%d uid=%u " |
1961 | "old auid=%u new auid=%u" | 1960 | "old auid=%u new auid=%u" |
1962 | " old ses=%u new ses=%u", | 1961 | " old ses=%u new ses=%u", |
1963 | task->pid, task->uid, | 1962 | task->pid, task->uid, |
1964 | task->loginuid, loginuid, | 1963 | task->loginuid, loginuid, |
1965 | task->sessionid, sessionid); | 1964 | task->sessionid, sessionid); |
1966 | audit_log_end(ab); | 1965 | audit_log_end(ab); |
1967 | } | 1966 | } |
1968 | } | 1967 | } |
1969 | task->sessionid = sessionid; | 1968 | task->sessionid = sessionid; |
1970 | task->loginuid = loginuid; | 1969 | task->loginuid = loginuid; |
1971 | return 0; | 1970 | return 0; |
1972 | } | 1971 | } |
1973 | 1972 | ||
1974 | /** | 1973 | /** |
1975 | * __audit_mq_open - record audit data for a POSIX MQ open | 1974 | * __audit_mq_open - record audit data for a POSIX MQ open |
1976 | * @oflag: open flag | 1975 | * @oflag: open flag |
1977 | * @mode: mode bits | 1976 | * @mode: mode bits |
1978 | * @u_attr: queue attributes | 1977 | * @u_attr: queue attributes |
1979 | * | 1978 | * |
1980 | * Returns 0 for success or NULL context or < 0 on error. | 1979 | * Returns 0 for success or NULL context or < 0 on error. |
1981 | */ | 1980 | */ |
1982 | int __audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr) | 1981 | int __audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr) |
1983 | { | 1982 | { |
1984 | struct audit_aux_data_mq_open *ax; | 1983 | struct audit_aux_data_mq_open *ax; |
1985 | struct audit_context *context = current->audit_context; | 1984 | struct audit_context *context = current->audit_context; |
1986 | 1985 | ||
1987 | if (!audit_enabled) | 1986 | if (!audit_enabled) |
1988 | return 0; | 1987 | return 0; |
1989 | 1988 | ||
1990 | if (likely(!context)) | 1989 | if (likely(!context)) |
1991 | return 0; | 1990 | return 0; |
1992 | 1991 | ||
1993 | ax = kmalloc(sizeof(*ax), GFP_ATOMIC); | 1992 | ax = kmalloc(sizeof(*ax), GFP_ATOMIC); |
1994 | if (!ax) | 1993 | if (!ax) |
1995 | return -ENOMEM; | 1994 | return -ENOMEM; |
1996 | 1995 | ||
1997 | if (u_attr != NULL) { | 1996 | if (u_attr != NULL) { |
1998 | if (copy_from_user(&ax->attr, u_attr, sizeof(ax->attr))) { | 1997 | if (copy_from_user(&ax->attr, u_attr, sizeof(ax->attr))) { |
1999 | kfree(ax); | 1998 | kfree(ax); |
2000 | return -EFAULT; | 1999 | return -EFAULT; |
2001 | } | 2000 | } |
2002 | } else | 2001 | } else |
2003 | memset(&ax->attr, 0, sizeof(ax->attr)); | 2002 | memset(&ax->attr, 0, sizeof(ax->attr)); |
2004 | 2003 | ||
2005 | ax->oflag = oflag; | 2004 | ax->oflag = oflag; |
2006 | ax->mode = mode; | 2005 | ax->mode = mode; |
2007 | 2006 | ||
2008 | ax->d.type = AUDIT_MQ_OPEN; | 2007 | ax->d.type = AUDIT_MQ_OPEN; |
2009 | ax->d.next = context->aux; | 2008 | ax->d.next = context->aux; |
2010 | context->aux = (void *)ax; | 2009 | context->aux = (void *)ax; |
2011 | return 0; | 2010 | return 0; |
2012 | } | 2011 | } |
2013 | 2012 | ||
2014 | /** | 2013 | /** |
2015 | * __audit_mq_timedsend - record audit data for a POSIX MQ timed send | 2014 | * __audit_mq_timedsend - record audit data for a POSIX MQ timed send |
2016 | * @mqdes: MQ descriptor | 2015 | * @mqdes: MQ descriptor |
2017 | * @msg_len: Message length | 2016 | * @msg_len: Message length |
2018 | * @msg_prio: Message priority | 2017 | * @msg_prio: Message priority |
2019 | * @u_abs_timeout: Message timeout in absolute time | 2018 | * @u_abs_timeout: Message timeout in absolute time |
2020 | * | 2019 | * |
2021 | * Returns 0 for success or NULL context or < 0 on error. | 2020 | * Returns 0 for success or NULL context or < 0 on error. |
2022 | */ | 2021 | */ |
2023 | int __audit_mq_timedsend(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, | 2022 | int __audit_mq_timedsend(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, |
2024 | const struct timespec __user *u_abs_timeout) | 2023 | const struct timespec __user *u_abs_timeout) |
2025 | { | 2024 | { |
2026 | struct audit_aux_data_mq_sendrecv *ax; | 2025 | struct audit_aux_data_mq_sendrecv *ax; |
2027 | struct audit_context *context = current->audit_context; | 2026 | struct audit_context *context = current->audit_context; |
2028 | 2027 | ||
2029 | if (!audit_enabled) | 2028 | if (!audit_enabled) |
2030 | return 0; | 2029 | return 0; |
2031 | 2030 | ||
2032 | if (likely(!context)) | 2031 | if (likely(!context)) |
2033 | return 0; | 2032 | return 0; |
2034 | 2033 | ||
2035 | ax = kmalloc(sizeof(*ax), GFP_ATOMIC); | 2034 | ax = kmalloc(sizeof(*ax), GFP_ATOMIC); |
2036 | if (!ax) | 2035 | if (!ax) |
2037 | return -ENOMEM; | 2036 | return -ENOMEM; |
2038 | 2037 | ||
2039 | if (u_abs_timeout != NULL) { | 2038 | if (u_abs_timeout != NULL) { |
2040 | if (copy_from_user(&ax->abs_timeout, u_abs_timeout, sizeof(ax->abs_timeout))) { | 2039 | if (copy_from_user(&ax->abs_timeout, u_abs_timeout, sizeof(ax->abs_timeout))) { |
2041 | kfree(ax); | 2040 | kfree(ax); |
2042 | return -EFAULT; | 2041 | return -EFAULT; |
2043 | } | 2042 | } |
2044 | } else | 2043 | } else |
2045 | memset(&ax->abs_timeout, 0, sizeof(ax->abs_timeout)); | 2044 | memset(&ax->abs_timeout, 0, sizeof(ax->abs_timeout)); |
2046 | 2045 | ||
2047 | ax->mqdes = mqdes; | 2046 | ax->mqdes = mqdes; |
2048 | ax->msg_len = msg_len; | 2047 | ax->msg_len = msg_len; |
2049 | ax->msg_prio = msg_prio; | 2048 | ax->msg_prio = msg_prio; |
2050 | 2049 | ||
2051 | ax->d.type = AUDIT_MQ_SENDRECV; | 2050 | ax->d.type = AUDIT_MQ_SENDRECV; |
2052 | ax->d.next = context->aux; | 2051 | ax->d.next = context->aux; |
2053 | context->aux = (void *)ax; | 2052 | context->aux = (void *)ax; |
2054 | return 0; | 2053 | return 0; |
2055 | } | 2054 | } |
2056 | 2055 | ||
2057 | /** | 2056 | /** |
2058 | * __audit_mq_timedreceive - record audit data for a POSIX MQ timed receive | 2057 | * __audit_mq_timedreceive - record audit data for a POSIX MQ timed receive |
2059 | * @mqdes: MQ descriptor | 2058 | * @mqdes: MQ descriptor |
2060 | * @msg_len: Message length | 2059 | * @msg_len: Message length |
2061 | * @u_msg_prio: Message priority | 2060 | * @u_msg_prio: Message priority |
2062 | * @u_abs_timeout: Message timeout in absolute time | 2061 | * @u_abs_timeout: Message timeout in absolute time |
2063 | * | 2062 | * |
2064 | * Returns 0 for success or NULL context or < 0 on error. | 2063 | * Returns 0 for success or NULL context or < 0 on error. |
2065 | */ | 2064 | */ |
2066 | int __audit_mq_timedreceive(mqd_t mqdes, size_t msg_len, | 2065 | int __audit_mq_timedreceive(mqd_t mqdes, size_t msg_len, |
2067 | unsigned int __user *u_msg_prio, | 2066 | unsigned int __user *u_msg_prio, |
2068 | const struct timespec __user *u_abs_timeout) | 2067 | const struct timespec __user *u_abs_timeout) |
2069 | { | 2068 | { |
2070 | struct audit_aux_data_mq_sendrecv *ax; | 2069 | struct audit_aux_data_mq_sendrecv *ax; |
2071 | struct audit_context *context = current->audit_context; | 2070 | struct audit_context *context = current->audit_context; |
2072 | 2071 | ||
2073 | if (!audit_enabled) | 2072 | if (!audit_enabled) |
2074 | return 0; | 2073 | return 0; |
2075 | 2074 | ||
2076 | if (likely(!context)) | 2075 | if (likely(!context)) |
2077 | return 0; | 2076 | return 0; |
2078 | 2077 | ||
2079 | ax = kmalloc(sizeof(*ax), GFP_ATOMIC); | 2078 | ax = kmalloc(sizeof(*ax), GFP_ATOMIC); |
2080 | if (!ax) | 2079 | if (!ax) |
2081 | return -ENOMEM; | 2080 | return -ENOMEM; |
2082 | 2081 | ||
2083 | if (u_msg_prio != NULL) { | 2082 | if (u_msg_prio != NULL) { |
2084 | if (get_user(ax->msg_prio, u_msg_prio)) { | 2083 | if (get_user(ax->msg_prio, u_msg_prio)) { |
2085 | kfree(ax); | 2084 | kfree(ax); |
2086 | return -EFAULT; | 2085 | return -EFAULT; |
2087 | } | 2086 | } |
2088 | } else | 2087 | } else |
2089 | ax->msg_prio = 0; | 2088 | ax->msg_prio = 0; |
2090 | 2089 | ||
2091 | if (u_abs_timeout != NULL) { | 2090 | if (u_abs_timeout != NULL) { |
2092 | if (copy_from_user(&ax->abs_timeout, u_abs_timeout, sizeof(ax->abs_timeout))) { | 2091 | if (copy_from_user(&ax->abs_timeout, u_abs_timeout, sizeof(ax->abs_timeout))) { |
2093 | kfree(ax); | 2092 | kfree(ax); |
2094 | return -EFAULT; | 2093 | return -EFAULT; |
2095 | } | 2094 | } |
2096 | } else | 2095 | } else |
2097 | memset(&ax->abs_timeout, 0, sizeof(ax->abs_timeout)); | 2096 | memset(&ax->abs_timeout, 0, sizeof(ax->abs_timeout)); |
2098 | 2097 | ||
2099 | ax->mqdes = mqdes; | 2098 | ax->mqdes = mqdes; |
2100 | ax->msg_len = msg_len; | 2099 | ax->msg_len = msg_len; |
2101 | 2100 | ||
2102 | ax->d.type = AUDIT_MQ_SENDRECV; | 2101 | ax->d.type = AUDIT_MQ_SENDRECV; |
2103 | ax->d.next = context->aux; | 2102 | ax->d.next = context->aux; |
2104 | context->aux = (void *)ax; | 2103 | context->aux = (void *)ax; |
2105 | return 0; | 2104 | return 0; |
2106 | } | 2105 | } |
2107 | 2106 | ||
2108 | /** | 2107 | /** |
2109 | * __audit_mq_notify - record audit data for a POSIX MQ notify | 2108 | * __audit_mq_notify - record audit data for a POSIX MQ notify |
2110 | * @mqdes: MQ descriptor | 2109 | * @mqdes: MQ descriptor |
2111 | * @u_notification: Notification event | 2110 | * @u_notification: Notification event |
2112 | * | 2111 | * |
2113 | * Returns 0 for success or NULL context or < 0 on error. | 2112 | * Returns 0 for success or NULL context or < 0 on error. |
2114 | */ | 2113 | */ |
2115 | 2114 | ||
2116 | int __audit_mq_notify(mqd_t mqdes, const struct sigevent __user *u_notification) | 2115 | int __audit_mq_notify(mqd_t mqdes, const struct sigevent __user *u_notification) |
2117 | { | 2116 | { |
2118 | struct audit_aux_data_mq_notify *ax; | 2117 | struct audit_aux_data_mq_notify *ax; |
2119 | struct audit_context *context = current->audit_context; | 2118 | struct audit_context *context = current->audit_context; |
2120 | 2119 | ||
2121 | if (!audit_enabled) | 2120 | if (!audit_enabled) |
2122 | return 0; | 2121 | return 0; |
2123 | 2122 | ||
2124 | if (likely(!context)) | 2123 | if (likely(!context)) |
2125 | return 0; | 2124 | return 0; |
2126 | 2125 | ||
2127 | ax = kmalloc(sizeof(*ax), GFP_ATOMIC); | 2126 | ax = kmalloc(sizeof(*ax), GFP_ATOMIC); |
2128 | if (!ax) | 2127 | if (!ax) |
2129 | return -ENOMEM; | 2128 | return -ENOMEM; |
2130 | 2129 | ||
2131 | if (u_notification != NULL) { | 2130 | if (u_notification != NULL) { |
2132 | if (copy_from_user(&ax->notification, u_notification, sizeof(ax->notification))) { | 2131 | if (copy_from_user(&ax->notification, u_notification, sizeof(ax->notification))) { |
2133 | kfree(ax); | 2132 | kfree(ax); |
2134 | return -EFAULT; | 2133 | return -EFAULT; |
2135 | } | 2134 | } |
2136 | } else | 2135 | } else |
2137 | memset(&ax->notification, 0, sizeof(ax->notification)); | 2136 | memset(&ax->notification, 0, sizeof(ax->notification)); |
2138 | 2137 | ||
2139 | ax->mqdes = mqdes; | 2138 | ax->mqdes = mqdes; |
2140 | 2139 | ||
2141 | ax->d.type = AUDIT_MQ_NOTIFY; | 2140 | ax->d.type = AUDIT_MQ_NOTIFY; |
2142 | ax->d.next = context->aux; | 2141 | ax->d.next = context->aux; |
2143 | context->aux = (void *)ax; | 2142 | context->aux = (void *)ax; |
2144 | return 0; | 2143 | return 0; |
2145 | } | 2144 | } |
2146 | 2145 | ||
2147 | /** | 2146 | /** |
2148 | * __audit_mq_getsetattr - record audit data for a POSIX MQ get/set attribute | 2147 | * __audit_mq_getsetattr - record audit data for a POSIX MQ get/set attribute |
2149 | * @mqdes: MQ descriptor | 2148 | * @mqdes: MQ descriptor |
2150 | * @mqstat: MQ flags | 2149 | * @mqstat: MQ flags |
2151 | * | 2150 | * |
2152 | * Returns 0 for success or NULL context or < 0 on error. | 2151 | * Returns 0 for success or NULL context or < 0 on error. |
2153 | */ | 2152 | */ |
2154 | int __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat) | 2153 | int __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat) |
2155 | { | 2154 | { |
2156 | struct audit_aux_data_mq_getsetattr *ax; | 2155 | struct audit_aux_data_mq_getsetattr *ax; |
2157 | struct audit_context *context = current->audit_context; | 2156 | struct audit_context *context = current->audit_context; |
2158 | 2157 | ||
2159 | if (!audit_enabled) | 2158 | if (!audit_enabled) |
2160 | return 0; | 2159 | return 0; |
2161 | 2160 | ||
2162 | if (likely(!context)) | 2161 | if (likely(!context)) |
2163 | return 0; | 2162 | return 0; |
2164 | 2163 | ||
2165 | ax = kmalloc(sizeof(*ax), GFP_ATOMIC); | 2164 | ax = kmalloc(sizeof(*ax), GFP_ATOMIC); |
2166 | if (!ax) | 2165 | if (!ax) |
2167 | return -ENOMEM; | 2166 | return -ENOMEM; |
2168 | 2167 | ||
2169 | ax->mqdes = mqdes; | 2168 | ax->mqdes = mqdes; |
2170 | ax->mqstat = *mqstat; | 2169 | ax->mqstat = *mqstat; |
2171 | 2170 | ||
2172 | ax->d.type = AUDIT_MQ_GETSETATTR; | 2171 | ax->d.type = AUDIT_MQ_GETSETATTR; |
2173 | ax->d.next = context->aux; | 2172 | ax->d.next = context->aux; |
2174 | context->aux = (void *)ax; | 2173 | context->aux = (void *)ax; |
2175 | return 0; | 2174 | return 0; |
2176 | } | 2175 | } |
2177 | 2176 | ||
2178 | /** | 2177 | /** |
2179 | * audit_ipc_obj - record audit data for ipc object | 2178 | * audit_ipc_obj - record audit data for ipc object |
2180 | * @ipcp: ipc permissions | 2179 | * @ipcp: ipc permissions |
2181 | * | 2180 | * |
2182 | * Returns 0 for success or NULL context or < 0 on error. | 2181 | * Returns 0 for success or NULL context or < 0 on error. |
2183 | */ | 2182 | */ |
2184 | int __audit_ipc_obj(struct kern_ipc_perm *ipcp) | 2183 | int __audit_ipc_obj(struct kern_ipc_perm *ipcp) |
2185 | { | 2184 | { |
2186 | struct audit_aux_data_ipcctl *ax; | 2185 | struct audit_aux_data_ipcctl *ax; |
2187 | struct audit_context *context = current->audit_context; | 2186 | struct audit_context *context = current->audit_context; |
2188 | 2187 | ||
2189 | ax = kmalloc(sizeof(*ax), GFP_ATOMIC); | 2188 | ax = kmalloc(sizeof(*ax), GFP_ATOMIC); |
2190 | if (!ax) | 2189 | if (!ax) |
2191 | return -ENOMEM; | 2190 | return -ENOMEM; |
2192 | 2191 | ||
2193 | ax->uid = ipcp->uid; | 2192 | ax->uid = ipcp->uid; |
2194 | ax->gid = ipcp->gid; | 2193 | ax->gid = ipcp->gid; |
2195 | ax->mode = ipcp->mode; | 2194 | ax->mode = ipcp->mode; |
2196 | security_ipc_getsecid(ipcp, &ax->osid); | 2195 | security_ipc_getsecid(ipcp, &ax->osid); |
2197 | ax->d.type = AUDIT_IPC; | 2196 | ax->d.type = AUDIT_IPC; |
2198 | ax->d.next = context->aux; | 2197 | ax->d.next = context->aux; |
2199 | context->aux = (void *)ax; | 2198 | context->aux = (void *)ax; |
2200 | return 0; | 2199 | return 0; |
2201 | } | 2200 | } |
2202 | 2201 | ||
2203 | /** | 2202 | /** |
2204 | * audit_ipc_set_perm - record audit data for new ipc permissions | 2203 | * audit_ipc_set_perm - record audit data for new ipc permissions |
2205 | * @qbytes: msgq bytes | 2204 | * @qbytes: msgq bytes |
2206 | * @uid: msgq user id | 2205 | * @uid: msgq user id |
2207 | * @gid: msgq group id | 2206 | * @gid: msgq group id |
2208 | * @mode: msgq mode (permissions) | 2207 | * @mode: msgq mode (permissions) |
2209 | * | 2208 | * |
2210 | * Returns 0 for success or NULL context or < 0 on error. | 2209 | * Returns 0 for success or NULL context or < 0 on error. |
2211 | */ | 2210 | */ |
2212 | int __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode) | 2211 | int __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode) |
2213 | { | 2212 | { |
2214 | struct audit_aux_data_ipcctl *ax; | 2213 | struct audit_aux_data_ipcctl *ax; |
2215 | struct audit_context *context = current->audit_context; | 2214 | struct audit_context *context = current->audit_context; |
2216 | 2215 | ||
2217 | ax = kmalloc(sizeof(*ax), GFP_ATOMIC); | 2216 | ax = kmalloc(sizeof(*ax), GFP_ATOMIC); |
2218 | if (!ax) | 2217 | if (!ax) |
2219 | return -ENOMEM; | 2218 | return -ENOMEM; |
2220 | 2219 | ||
2221 | ax->qbytes = qbytes; | 2220 | ax->qbytes = qbytes; |
2222 | ax->uid = uid; | 2221 | ax->uid = uid; |
2223 | ax->gid = gid; | 2222 | ax->gid = gid; |
2224 | ax->mode = mode; | 2223 | ax->mode = mode; |
2225 | 2224 | ||
2226 | ax->d.type = AUDIT_IPC_SET_PERM; | 2225 | ax->d.type = AUDIT_IPC_SET_PERM; |
2227 | ax->d.next = context->aux; | 2226 | ax->d.next = context->aux; |
2228 | context->aux = (void *)ax; | 2227 | context->aux = (void *)ax; |
2229 | return 0; | 2228 | return 0; |
2230 | } | 2229 | } |
2231 | 2230 | ||
2232 | int audit_bprm(struct linux_binprm *bprm) | 2231 | int audit_bprm(struct linux_binprm *bprm) |
2233 | { | 2232 | { |
2234 | struct audit_aux_data_execve *ax; | 2233 | struct audit_aux_data_execve *ax; |
2235 | struct audit_context *context = current->audit_context; | 2234 | struct audit_context *context = current->audit_context; |
2236 | 2235 | ||
2237 | if (likely(!audit_enabled || !context || context->dummy)) | 2236 | if (likely(!audit_enabled || !context || context->dummy)) |
2238 | return 0; | 2237 | return 0; |
2239 | 2238 | ||
2240 | ax = kmalloc(sizeof(*ax), GFP_KERNEL); | 2239 | ax = kmalloc(sizeof(*ax), GFP_KERNEL); |
2241 | if (!ax) | 2240 | if (!ax) |
2242 | return -ENOMEM; | 2241 | return -ENOMEM; |
2243 | 2242 | ||
2244 | ax->argc = bprm->argc; | 2243 | ax->argc = bprm->argc; |
2245 | ax->envc = bprm->envc; | 2244 | ax->envc = bprm->envc; |
2246 | ax->mm = bprm->mm; | 2245 | ax->mm = bprm->mm; |
2247 | ax->d.type = AUDIT_EXECVE; | 2246 | ax->d.type = AUDIT_EXECVE; |
2248 | ax->d.next = context->aux; | 2247 | ax->d.next = context->aux; |
2249 | context->aux = (void *)ax; | 2248 | context->aux = (void *)ax; |
2250 | return 0; | 2249 | return 0; |
2251 | } | 2250 | } |
2252 | 2251 | ||
2253 | 2252 | ||
2254 | /** | 2253 | /** |
2255 | * audit_socketcall - record audit data for sys_socketcall | 2254 | * audit_socketcall - record audit data for sys_socketcall |
2256 | * @nargs: number of args | 2255 | * @nargs: number of args |
2257 | * @args: args array | 2256 | * @args: args array |
2258 | * | 2257 | * |
2259 | * Returns 0 for success or NULL context or < 0 on error. | 2258 | * Returns 0 for success or NULL context or < 0 on error. |
2260 | */ | 2259 | */ |
2261 | int audit_socketcall(int nargs, unsigned long *args) | 2260 | int audit_socketcall(int nargs, unsigned long *args) |
2262 | { | 2261 | { |
2263 | struct audit_aux_data_socketcall *ax; | 2262 | struct audit_aux_data_socketcall *ax; |
2264 | struct audit_context *context = current->audit_context; | 2263 | struct audit_context *context = current->audit_context; |
2265 | 2264 | ||
2266 | if (likely(!context || context->dummy)) | 2265 | if (likely(!context || context->dummy)) |
2267 | return 0; | 2266 | return 0; |
2268 | 2267 | ||
2269 | ax = kmalloc(sizeof(*ax) + nargs * sizeof(unsigned long), GFP_KERNEL); | 2268 | ax = kmalloc(sizeof(*ax) + nargs * sizeof(unsigned long), GFP_KERNEL); |
2270 | if (!ax) | 2269 | if (!ax) |
2271 | return -ENOMEM; | 2270 | return -ENOMEM; |
2272 | 2271 | ||
2273 | ax->nargs = nargs; | 2272 | ax->nargs = nargs; |
2274 | memcpy(ax->args, args, nargs * sizeof(unsigned long)); | 2273 | memcpy(ax->args, args, nargs * sizeof(unsigned long)); |
2275 | 2274 | ||
2276 | ax->d.type = AUDIT_SOCKETCALL; | 2275 | ax->d.type = AUDIT_SOCKETCALL; |
2277 | ax->d.next = context->aux; | 2276 | ax->d.next = context->aux; |
2278 | context->aux = (void *)ax; | 2277 | context->aux = (void *)ax; |
2279 | return 0; | 2278 | return 0; |
2280 | } | 2279 | } |
2281 | 2280 | ||
2282 | /** | 2281 | /** |
2283 | * __audit_fd_pair - record audit data for pipe and socketpair | 2282 | * __audit_fd_pair - record audit data for pipe and socketpair |
2284 | * @fd1: the first file descriptor | 2283 | * @fd1: the first file descriptor |
2285 | * @fd2: the second file descriptor | 2284 | * @fd2: the second file descriptor |
2286 | * | 2285 | * |
2287 | * Returns 0 for success or NULL context or < 0 on error. | 2286 | * Returns 0 for success or NULL context or < 0 on error. |
2288 | */ | 2287 | */ |
2289 | int __audit_fd_pair(int fd1, int fd2) | 2288 | int __audit_fd_pair(int fd1, int fd2) |
2290 | { | 2289 | { |
2291 | struct audit_context *context = current->audit_context; | 2290 | struct audit_context *context = current->audit_context; |
2292 | struct audit_aux_data_fd_pair *ax; | 2291 | struct audit_aux_data_fd_pair *ax; |
2293 | 2292 | ||
2294 | if (likely(!context)) { | 2293 | if (likely(!context)) { |
2295 | return 0; | 2294 | return 0; |
2296 | } | 2295 | } |
2297 | 2296 | ||
2298 | ax = kmalloc(sizeof(*ax), GFP_KERNEL); | 2297 | ax = kmalloc(sizeof(*ax), GFP_KERNEL); |
2299 | if (!ax) { | 2298 | if (!ax) { |
2300 | return -ENOMEM; | 2299 | return -ENOMEM; |
2301 | } | 2300 | } |
2302 | 2301 | ||
2303 | ax->fd[0] = fd1; | 2302 | ax->fd[0] = fd1; |
2304 | ax->fd[1] = fd2; | 2303 | ax->fd[1] = fd2; |
2305 | 2304 | ||
2306 | ax->d.type = AUDIT_FD_PAIR; | 2305 | ax->d.type = AUDIT_FD_PAIR; |
2307 | ax->d.next = context->aux; | 2306 | ax->d.next = context->aux; |
2308 | context->aux = (void *)ax; | 2307 | context->aux = (void *)ax; |
2309 | return 0; | 2308 | return 0; |
2310 | } | 2309 | } |
2311 | 2310 | ||
2312 | /** | 2311 | /** |
2313 | * audit_sockaddr - record audit data for sys_bind, sys_connect, sys_sendto | 2312 | * audit_sockaddr - record audit data for sys_bind, sys_connect, sys_sendto |
2314 | * @len: data length in user space | 2313 | * @len: data length in user space |
2315 | * @a: data address in kernel space | 2314 | * @a: data address in kernel space |
2316 | * | 2315 | * |
2317 | * Returns 0 for success or NULL context or < 0 on error. | 2316 | * Returns 0 for success or NULL context or < 0 on error. |
2318 | */ | 2317 | */ |
2319 | int audit_sockaddr(int len, void *a) | 2318 | int audit_sockaddr(int len, void *a) |
2320 | { | 2319 | { |
2321 | struct audit_aux_data_sockaddr *ax; | 2320 | struct audit_aux_data_sockaddr *ax; |
2322 | struct audit_context *context = current->audit_context; | 2321 | struct audit_context *context = current->audit_context; |
2323 | 2322 | ||
2324 | if (likely(!context || context->dummy)) | 2323 | if (likely(!context || context->dummy)) |
2325 | return 0; | 2324 | return 0; |
2326 | 2325 | ||
2327 | ax = kmalloc(sizeof(*ax) + len, GFP_KERNEL); | 2326 | ax = kmalloc(sizeof(*ax) + len, GFP_KERNEL); |
2328 | if (!ax) | 2327 | if (!ax) |
2329 | return -ENOMEM; | 2328 | return -ENOMEM; |
2330 | 2329 | ||
2331 | ax->len = len; | 2330 | ax->len = len; |
2332 | memcpy(ax->a, a, len); | 2331 | memcpy(ax->a, a, len); |
2333 | 2332 | ||
2334 | ax->d.type = AUDIT_SOCKADDR; | 2333 | ax->d.type = AUDIT_SOCKADDR; |
2335 | ax->d.next = context->aux; | 2334 | ax->d.next = context->aux; |
2336 | context->aux = (void *)ax; | 2335 | context->aux = (void *)ax; |
2337 | return 0; | 2336 | return 0; |
2338 | } | 2337 | } |
2339 | 2338 | ||
2340 | void __audit_ptrace(struct task_struct *t) | 2339 | void __audit_ptrace(struct task_struct *t) |
2341 | { | 2340 | { |
2342 | struct audit_context *context = current->audit_context; | 2341 | struct audit_context *context = current->audit_context; |
2343 | 2342 | ||
2344 | context->target_pid = t->pid; | 2343 | context->target_pid = t->pid; |
2345 | context->target_auid = audit_get_loginuid(t); | 2344 | context->target_auid = audit_get_loginuid(t); |
2346 | context->target_uid = t->uid; | 2345 | context->target_uid = t->uid; |
2347 | context->target_sessionid = audit_get_sessionid(t); | 2346 | context->target_sessionid = audit_get_sessionid(t); |
2348 | security_task_getsecid(t, &context->target_sid); | 2347 | security_task_getsecid(t, &context->target_sid); |
2349 | memcpy(context->target_comm, t->comm, TASK_COMM_LEN); | 2348 | memcpy(context->target_comm, t->comm, TASK_COMM_LEN); |
2350 | } | 2349 | } |
2351 | 2350 | ||
2352 | /** | 2351 | /** |
2353 | * audit_signal_info - record signal info for shutting down audit subsystem | 2352 | * audit_signal_info - record signal info for shutting down audit subsystem |
2354 | * @sig: signal value | 2353 | * @sig: signal value |
2355 | * @t: task being signaled | 2354 | * @t: task being signaled |
2356 | * | 2355 | * |
2357 | * If the audit subsystem is being terminated, record the task (pid) | 2356 | * If the audit subsystem is being terminated, record the task (pid) |
2358 | * and uid that is doing that. | 2357 | * and uid that is doing that. |
2359 | */ | 2358 | */ |
2360 | int __audit_signal_info(int sig, struct task_struct *t) | 2359 | int __audit_signal_info(int sig, struct task_struct *t) |
2361 | { | 2360 | { |
2362 | struct audit_aux_data_pids *axp; | 2361 | struct audit_aux_data_pids *axp; |
2363 | struct task_struct *tsk = current; | 2362 | struct task_struct *tsk = current; |
2364 | struct audit_context *ctx = tsk->audit_context; | 2363 | struct audit_context *ctx = tsk->audit_context; |
2365 | extern pid_t audit_sig_pid; | 2364 | extern pid_t audit_sig_pid; |
2366 | extern uid_t audit_sig_uid; | 2365 | extern uid_t audit_sig_uid; |
2367 | extern u32 audit_sig_sid; | 2366 | extern u32 audit_sig_sid; |
2368 | 2367 | ||
2369 | if (audit_pid && t->tgid == audit_pid) { | 2368 | if (audit_pid && t->tgid == audit_pid) { |
2370 | if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1) { | 2369 | if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1) { |
2371 | audit_sig_pid = tsk->pid; | 2370 | audit_sig_pid = tsk->pid; |
2372 | if (tsk->loginuid != -1) | 2371 | if (tsk->loginuid != -1) |
2373 | audit_sig_uid = tsk->loginuid; | 2372 | audit_sig_uid = tsk->loginuid; |
2374 | else | 2373 | else |
2375 | audit_sig_uid = tsk->uid; | 2374 | audit_sig_uid = tsk->uid; |
2376 | security_task_getsecid(tsk, &audit_sig_sid); | 2375 | security_task_getsecid(tsk, &audit_sig_sid); |
2377 | } | 2376 | } |
2378 | if (!audit_signals || audit_dummy_context()) | 2377 | if (!audit_signals || audit_dummy_context()) |
2379 | return 0; | 2378 | return 0; |
2380 | } | 2379 | } |
2381 | 2380 | ||
2382 | /* optimize the common case by putting first signal recipient directly | 2381 | /* optimize the common case by putting first signal recipient directly |
2383 | * in audit_context */ | 2382 | * in audit_context */ |
2384 | if (!ctx->target_pid) { | 2383 | if (!ctx->target_pid) { |
2385 | ctx->target_pid = t->tgid; | 2384 | ctx->target_pid = t->tgid; |
2386 | ctx->target_auid = audit_get_loginuid(t); | 2385 | ctx->target_auid = audit_get_loginuid(t); |
2387 | ctx->target_uid = t->uid; | 2386 | ctx->target_uid = t->uid; |
2388 | ctx->target_sessionid = audit_get_sessionid(t); | 2387 | ctx->target_sessionid = audit_get_sessionid(t); |
2389 | security_task_getsecid(t, &ctx->target_sid); | 2388 | security_task_getsecid(t, &ctx->target_sid); |
2390 | memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN); | 2389 | memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN); |
2391 | return 0; | 2390 | return 0; |
2392 | } | 2391 | } |
2393 | 2392 | ||
2394 | axp = (void *)ctx->aux_pids; | 2393 | axp = (void *)ctx->aux_pids; |
2395 | if (!axp || axp->pid_count == AUDIT_AUX_PIDS) { | 2394 | if (!axp || axp->pid_count == AUDIT_AUX_PIDS) { |
2396 | axp = kzalloc(sizeof(*axp), GFP_ATOMIC); | 2395 | axp = kzalloc(sizeof(*axp), GFP_ATOMIC); |
2397 | if (!axp) | 2396 | if (!axp) |
2398 | return -ENOMEM; | 2397 | return -ENOMEM; |
2399 | 2398 | ||
2400 | axp->d.type = AUDIT_OBJ_PID; | 2399 | axp->d.type = AUDIT_OBJ_PID; |
2401 | axp->d.next = ctx->aux_pids; | 2400 | axp->d.next = ctx->aux_pids; |
2402 | ctx->aux_pids = (void *)axp; | 2401 | ctx->aux_pids = (void *)axp; |
2403 | } | 2402 | } |
2404 | BUG_ON(axp->pid_count >= AUDIT_AUX_PIDS); | 2403 | BUG_ON(axp->pid_count >= AUDIT_AUX_PIDS); |
2405 | 2404 | ||
2406 | axp->target_pid[axp->pid_count] = t->tgid; | 2405 | axp->target_pid[axp->pid_count] = t->tgid; |
2407 | axp->target_auid[axp->pid_count] = audit_get_loginuid(t); | 2406 | axp->target_auid[axp->pid_count] = audit_get_loginuid(t); |
2408 | axp->target_uid[axp->pid_count] = t->uid; | 2407 | axp->target_uid[axp->pid_count] = t->uid; |
2409 | axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t); | 2408 | axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t); |
2410 | security_task_getsecid(t, &axp->target_sid[axp->pid_count]); | 2409 | security_task_getsecid(t, &axp->target_sid[axp->pid_count]); |
2411 | memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN); | 2410 | memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN); |
2412 | axp->pid_count++; | 2411 | axp->pid_count++; |
2413 | 2412 | ||
2414 | return 0; | 2413 | return 0; |
2415 | } | 2414 | } |
2416 | 2415 | ||
2417 | /** | 2416 | /** |
2418 | * audit_core_dumps - record information about processes that end abnormally | 2417 | * audit_core_dumps - record information about processes that end abnormally |
2419 | * @signr: signal value | 2418 | * @signr: signal value |
2420 | * | 2419 | * |
2421 | * If a process ends with a core dump, something fishy is going on and we | 2420 | * If a process ends with a core dump, something fishy is going on and we |
2422 | * should record the event for investigation. | 2421 | * should record the event for investigation. |
2423 | */ | 2422 | */ |
2424 | void audit_core_dumps(long signr) | 2423 | void audit_core_dumps(long signr) |
2425 | { | 2424 | { |
2426 | struct audit_buffer *ab; | 2425 | struct audit_buffer *ab; |
2427 | u32 sid; | 2426 | u32 sid; |
2428 | uid_t auid = audit_get_loginuid(current); | 2427 | uid_t auid = audit_get_loginuid(current); |
2429 | unsigned int sessionid = audit_get_sessionid(current); | 2428 | unsigned int sessionid = audit_get_sessionid(current); |
2430 | 2429 | ||
2431 | if (!audit_enabled) | 2430 | if (!audit_enabled) |
2432 | return; | 2431 | return; |
2433 | 2432 | ||
2434 | if (signr == SIGQUIT) /* don't care for those */ | 2433 | if (signr == SIGQUIT) /* don't care for those */ |
2435 | return; | 2434 | return; |
2436 | 2435 | ||
2437 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND); | 2436 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND); |
2438 | audit_log_format(ab, "auid=%u uid=%u gid=%u ses=%u", | 2437 | audit_log_format(ab, "auid=%u uid=%u gid=%u ses=%u", |
2439 | auid, current->uid, current->gid, sessionid); | 2438 | auid, current->uid, current->gid, sessionid); |
2440 | security_task_getsecid(current, &sid); | 2439 | security_task_getsecid(current, &sid); |
2441 | if (sid) { | 2440 | if (sid) { |
2442 | char *ctx = NULL; | 2441 | char *ctx = NULL; |
2443 | u32 len; | 2442 | u32 len; |
2444 | 2443 | ||
2445 | if (security_secid_to_secctx(sid, &ctx, &len)) | 2444 | if (security_secid_to_secctx(sid, &ctx, &len)) |
2446 | audit_log_format(ab, " ssid=%u", sid); | 2445 | audit_log_format(ab, " ssid=%u", sid); |
2447 | else { | 2446 | else { |
2448 | audit_log_format(ab, " subj=%s", ctx); | 2447 | audit_log_format(ab, " subj=%s", ctx); |
2449 | security_release_secctx(ctx, len); | 2448 | security_release_secctx(ctx, len); |
2450 | } | 2449 | } |
2451 | } | 2450 | } |
2452 | audit_log_format(ab, " pid=%d comm=", current->pid); | 2451 | audit_log_format(ab, " pid=%d comm=", current->pid); |
2453 | audit_log_untrustedstring(ab, current->comm); | 2452 | audit_log_untrustedstring(ab, current->comm); |
2454 | audit_log_format(ab, " sig=%ld", signr); | 2453 | audit_log_format(ab, " sig=%ld", signr); |
2455 | audit_log_end(ab); | 2454 | audit_log_end(ab); |
2456 | } | 2455 | } |
2457 | 2456 |