aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2006-05-06 14:59:18 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2006-05-06 14:59:18 -0400
commit5047f09b56d0bc3c21aec9cb16de60283da645c6 (patch)
tree09a07554b933c3bb912ce3bfc0ea7c7e1f16041c /kernel
parentc0f1fe00c3923135b2c2f443448585482da8a53e (diff)
parent5528e568a760442e0ec8fd2dea1f0791875a066b (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/audit.c160
-rw-r--r--kernel/audit.h10
-rw-r--r--kernel/auditfilter.c289
-rw-r--r--kernel/auditsc.c269
-rw-r--r--kernel/exit.c3
-rw-r--r--kernel/fork.c2
6 files changed, 536 insertions, 197 deletions
diff --git a/kernel/audit.c b/kernel/audit.c
index c8ccbd09048..df57b493e1c 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -55,6 +55,9 @@
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
60#include "audit.h"
58 61
59/* No auditing will take place until audit_initialized != 0. 62/* No auditing will take place until audit_initialized != 0.
60 * (Initialization happens after skb_init is called.) */ 63 * (Initialization happens after skb_init is called.) */
@@ -227,49 +230,103 @@ void audit_log_lost(const char *message)
227 } 230 }
228} 231}
229 232
230static int audit_set_rate_limit(int limit, uid_t loginuid) 233static int audit_set_rate_limit(int limit, uid_t loginuid, u32 sid)
231{ 234{
232 int old = audit_rate_limit; 235 int old = audit_rate_limit;
233 audit_rate_limit = limit; 236
234 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, 237 if (sid) {
238 char *ctx = NULL;
239 u32 len;
240 int rc;
241 if ((rc = selinux_ctxid_to_string(sid, &ctx, &len)))
242 return rc;
243 else
244 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
245 "audit_rate_limit=%d old=%d by auid=%u subj=%s",
246 limit, old, loginuid, ctx);
247 kfree(ctx);
248 } else
249 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
235 "audit_rate_limit=%d old=%d by auid=%u", 250 "audit_rate_limit=%d old=%d by auid=%u",
236 audit_rate_limit, old, loginuid); 251 limit, old, loginuid);
252 audit_rate_limit = limit;
237 return old; 253 return old;
238} 254}
239 255
240static int audit_set_backlog_limit(int limit, uid_t loginuid) 256static int audit_set_backlog_limit(int limit, uid_t loginuid, u32 sid)
241{ 257{
242 int old = audit_backlog_limit; 258 int old = audit_backlog_limit;
243 audit_backlog_limit = limit; 259
244 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, 260 if (sid) {
261 char *ctx = NULL;
262 u32 len;
263 int rc;
264 if ((rc = selinux_ctxid_to_string(sid, &ctx, &len)))
265 return rc;
266 else
267 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
268 "audit_backlog_limit=%d old=%d by auid=%u subj=%s",
269 limit, old, loginuid, ctx);
270 kfree(ctx);
271 } else
272 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
245 "audit_backlog_limit=%d old=%d by auid=%u", 273 "audit_backlog_limit=%d old=%d by auid=%u",
246 audit_backlog_limit, old, loginuid); 274 limit, old, loginuid);
275 audit_backlog_limit = limit;
247 return old; 276 return old;
248} 277}
249 278
250static int audit_set_enabled(int state, uid_t loginuid) 279static int audit_set_enabled(int state, uid_t loginuid, u32 sid)
251{ 280{
252 int old = audit_enabled; 281 int old = audit_enabled;
282
253 if (state != 0 && state != 1) 283 if (state != 0 && state != 1)
254 return -EINVAL; 284 return -EINVAL;
255 audit_enabled = state; 285
256 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, 286 if (sid) {
287 char *ctx = NULL;
288 u32 len;
289 int rc;
290 if ((rc = selinux_ctxid_to_string(sid, &ctx, &len)))
291 return rc;
292 else
293 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
294 "audit_enabled=%d old=%d by auid=%u subj=%s",
295 state, old, loginuid, ctx);
296 kfree(ctx);
297 } else
298 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
257 "audit_enabled=%d old=%d by auid=%u", 299 "audit_enabled=%d old=%d by auid=%u",
258 audit_enabled, old, loginuid); 300 state, old, loginuid);
301 audit_enabled = state;
259 return old; 302 return old;
260} 303}
261 304
262static int audit_set_failure(int state, uid_t loginuid) 305static int audit_set_failure(int state, uid_t loginuid, u32 sid)
263{ 306{
264 int old = audit_failure; 307 int old = audit_failure;
308
265 if (state != AUDIT_FAIL_SILENT 309 if (state != AUDIT_FAIL_SILENT
266 && state != AUDIT_FAIL_PRINTK 310 && state != AUDIT_FAIL_PRINTK
267 && state != AUDIT_FAIL_PANIC) 311 && state != AUDIT_FAIL_PANIC)
268 return -EINVAL; 312 return -EINVAL;
269 audit_failure = state; 313
270 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, 314 if (sid) {
315 char *ctx = NULL;
316 u32 len;
317 int rc;
318 if ((rc = selinux_ctxid_to_string(sid, &ctx, &len)))
319 return rc;
320 else
321 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
322 "audit_failure=%d old=%d by auid=%u subj=%s",
323 state, old, loginuid, ctx);
324 kfree(ctx);
325 } else
326 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
271 "audit_failure=%d old=%d by auid=%u", 327 "audit_failure=%d old=%d by auid=%u",
272 audit_failure, old, loginuid); 328 state, old, loginuid);
329 audit_failure = state;
273 return old; 330 return old;
274} 331}
275 332
@@ -387,7 +444,7 @@ static int audit_netlink_ok(kernel_cap_t eff_cap, u16 msg_type)
387 444
388static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) 445static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
389{ 446{
390 u32 uid, pid, seq; 447 u32 uid, pid, seq, sid;
391 void *data; 448 void *data;
392 struct audit_status *status_get, status_set; 449 struct audit_status *status_get, status_set;
393 int err; 450 int err;
@@ -413,6 +470,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
413 pid = NETLINK_CREDS(skb)->pid; 470 pid = NETLINK_CREDS(skb)->pid;
414 uid = NETLINK_CREDS(skb)->uid; 471 uid = NETLINK_CREDS(skb)->uid;
415 loginuid = NETLINK_CB(skb).loginuid; 472 loginuid = NETLINK_CB(skb).loginuid;
473 sid = NETLINK_CB(skb).sid;
416 seq = nlh->nlmsg_seq; 474 seq = nlh->nlmsg_seq;
417 data = NLMSG_DATA(nlh); 475 data = NLMSG_DATA(nlh);
418 476
@@ -433,25 +491,43 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
433 return -EINVAL; 491 return -EINVAL;
434 status_get = (struct audit_status *)data; 492 status_get = (struct audit_status *)data;
435 if (status_get->mask & AUDIT_STATUS_ENABLED) { 493 if (status_get->mask & AUDIT_STATUS_ENABLED) {
436 err = audit_set_enabled(status_get->enabled, loginuid); 494 err = audit_set_enabled(status_get->enabled,
495 loginuid, sid);
437 if (err < 0) return err; 496 if (err < 0) return err;
438 } 497 }
439 if (status_get->mask & AUDIT_STATUS_FAILURE) { 498 if (status_get->mask & AUDIT_STATUS_FAILURE) {
440 err = audit_set_failure(status_get->failure, loginuid); 499 err = audit_set_failure(status_get->failure,
500 loginuid, sid);
441 if (err < 0) return err; 501 if (err < 0) return err;
442 } 502 }
443 if (status_get->mask & AUDIT_STATUS_PID) { 503 if (status_get->mask & AUDIT_STATUS_PID) {
444 int old = audit_pid; 504 int old = audit_pid;
505 if (sid) {
506 char *ctx = NULL;
507 u32 len;
508 int rc;
509 if ((rc = selinux_ctxid_to_string(
510 sid, &ctx, &len)))
511 return rc;
512 else
513 audit_log(NULL, GFP_KERNEL,
514 AUDIT_CONFIG_CHANGE,
515 "audit_pid=%d old=%d by auid=%u subj=%s",
516 status_get->pid, old,
517 loginuid, ctx);
518 kfree(ctx);
519 } else
520 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
521 "audit_pid=%d old=%d by auid=%u",
522 status_get->pid, old, loginuid);
445 audit_pid = status_get->pid; 523 audit_pid = status_get->pid;
446 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
447 "audit_pid=%d old=%d by auid=%u",
448 audit_pid, old, loginuid);
449 } 524 }
450 if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) 525 if (status_get->mask & AUDIT_STATUS_RATE_LIMIT)
451 audit_set_rate_limit(status_get->rate_limit, loginuid); 526 audit_set_rate_limit(status_get->rate_limit,
527 loginuid, sid);
452 if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT) 528 if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT)
453 audit_set_backlog_limit(status_get->backlog_limit, 529 audit_set_backlog_limit(status_get->backlog_limit,
454 loginuid); 530 loginuid, sid);
455 break; 531 break;
456 case AUDIT_USER: 532 case AUDIT_USER:
457 case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG: 533 case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG:
@@ -465,8 +541,23 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
465 ab = audit_log_start(NULL, GFP_KERNEL, msg_type); 541 ab = audit_log_start(NULL, GFP_KERNEL, msg_type);
466 if (ab) { 542 if (ab) {
467 audit_log_format(ab, 543 audit_log_format(ab,
468 "user pid=%d uid=%u auid=%u msg='%.1024s'", 544 "user pid=%d uid=%u auid=%u",
469 pid, uid, loginuid, (char *)data); 545 pid, uid, loginuid);
546 if (sid) {
547 char *ctx = NULL;
548 u32 len;
549 if (selinux_ctxid_to_string(
550 sid, &ctx, &len)) {
551 audit_log_format(ab,
552 " ssid=%u", sid);
553 /* Maybe call audit_panic? */
554 } else
555 audit_log_format(ab,
556 " subj=%s", ctx);
557 kfree(ctx);
558 }
559 audit_log_format(ab, " msg='%.1024s'",
560 (char *)data);
470 audit_set_pid(ab, pid); 561 audit_set_pid(ab, pid);
471 audit_log_end(ab); 562 audit_log_end(ab);
472 } 563 }
@@ -480,7 +571,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
480 case AUDIT_LIST: 571 case AUDIT_LIST:
481 err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, 572 err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid,
482 uid, seq, data, nlmsg_len(nlh), 573 uid, seq, data, nlmsg_len(nlh),
483 loginuid); 574 loginuid, sid);
484 break; 575 break;
485 case AUDIT_ADD_RULE: 576 case AUDIT_ADD_RULE:
486 case AUDIT_DEL_RULE: 577 case AUDIT_DEL_RULE:
@@ -490,7 +581,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
490 case AUDIT_LIST_RULES: 581 case AUDIT_LIST_RULES:
491 err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, 582 err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid,
492 uid, seq, data, nlmsg_len(nlh), 583 uid, seq, data, nlmsg_len(nlh),
493 loginuid); 584 loginuid, sid);
494 break; 585 break;
495 case AUDIT_SIGNAL_INFO: 586 case AUDIT_SIGNAL_INFO:
496 sig_data.uid = audit_sig_uid; 587 sig_data.uid = audit_sig_uid;
@@ -564,6 +655,11 @@ static int __init audit_init(void)
564 skb_queue_head_init(&audit_skb_queue); 655 skb_queue_head_init(&audit_skb_queue);
565 audit_initialized = 1; 656 audit_initialized = 1;
566 audit_enabled = audit_default; 657 audit_enabled = audit_default;
658
659 /* Register the callback with selinux. This callback will be invoked
660 * when a new policy is loaded. */
661 selinux_audit_set_callback(&selinux_audit_rule_update);
662
567 audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized"); 663 audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized");
568 return 0; 664 return 0;
569} 665}
diff --git a/kernel/audit.h b/kernel/audit.h
index bc5392076e2..6f733920fd3 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -54,9 +54,11 @@ enum audit_state {
54 54
55/* Rule lists */ 55/* Rule lists */
56struct audit_field { 56struct audit_field {
57 u32 type; 57 u32 type;
58 u32 val; 58 u32 val;
59 u32 op; 59 u32 op;
60 char *se_str;
61 struct selinux_audit_rule *se_rule;
60}; 62};
61 63
62struct audit_krule { 64struct audit_krule {
@@ -86,3 +88,5 @@ extern void audit_send_reply(int pid, int seq, int type,
86extern void audit_log_lost(const char *message); 88extern void audit_log_lost(const char *message);
87extern void audit_panic(const char *message); 89extern void audit_panic(const char *message);
88extern struct mutex audit_netlink_mutex; 90extern struct mutex audit_netlink_mutex;
91
92extern int selinux_audit_rule_update(void);
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index d3a8539f3a8..7c134906d68 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -23,6 +23,7 @@
23#include <linux/audit.h> 23#include <linux/audit.h>
24#include <linux/kthread.h> 24#include <linux/kthread.h>
25#include <linux/netlink.h> 25#include <linux/netlink.h>
26#include <linux/selinux.h>
26#include "audit.h" 27#include "audit.h"
27 28
28/* There are three lists of rules -- one to search at task creation 29/* There are three lists of rules -- one to search at task creation
@@ -42,6 +43,13 @@ struct list_head audit_filter_list[AUDIT_NR_FILTERS] = {
42 43
43static inline void audit_free_rule(struct audit_entry *e) 44static inline void audit_free_rule(struct audit_entry *e)
44{ 45{
46 int i;
47 if (e->rule.fields)
48 for (i = 0; i < e->rule.field_count; i++) {
49 struct audit_field *f = &e->rule.fields[i];
50 kfree(f->se_str);
51 selinux_audit_rule_free(f->se_rule);
52 }
45 kfree(e->rule.fields); 53 kfree(e->rule.fields);
46 kfree(e); 54 kfree(e);
47} 55}
@@ -52,9 +60,29 @@ static inline void audit_free_rule_rcu(struct rcu_head *head)
52 audit_free_rule(e); 60 audit_free_rule(e);
53} 61}
54 62
63/* Initialize an audit filterlist entry. */
64static inline struct audit_entry *audit_init_entry(u32 field_count)
65{
66 struct audit_entry *entry;
67 struct audit_field *fields;
68
69 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
70 if (unlikely(!entry))
71 return NULL;
72
73 fields = kzalloc(sizeof(*fields) * field_count, GFP_KERNEL);
74 if (unlikely(!fields)) {
75 kfree(entry);
76 return NULL;
77 }
78 entry->rule.fields = fields;
79
80 return entry;
81}
82
55/* Unpack a filter field's string representation from user-space 83/* Unpack a filter field's string representation from user-space
56 * buffer. */ 84 * buffer. */
57static __attribute__((unused)) char *audit_unpack_string(void **bufp, size_t *remain, size_t len) 85static char *audit_unpack_string(void **bufp, size_t *remain, size_t len)
58{ 86{
59 char *str; 87 char *str;
60 88
@@ -84,7 +112,6 @@ static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule)
84{ 112{
85 unsigned listnr; 113 unsigned listnr;
86 struct audit_entry *entry; 114 struct audit_entry *entry;
87 struct audit_field *fields;
88 int i, err; 115 int i, err;
89 116
90 err = -EINVAL; 117 err = -EINVAL;
@@ -108,23 +135,14 @@ static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule)
108 goto exit_err; 135 goto exit_err;
109 136
110 err = -ENOMEM; 137 err = -ENOMEM;
111 entry = kmalloc(sizeof(*entry), GFP_KERNEL); 138 entry = audit_init_entry(rule->field_count);
112 if (unlikely(!entry)) 139 if (!entry)
113 goto exit_err;
114 fields = kmalloc(sizeof(*fields) * rule->field_count, GFP_KERNEL);
115 if (unlikely(!fields)) {
116 kfree(entry);
117 goto exit_err; 140 goto exit_err;
118 }
119
120 memset(&entry->rule, 0, sizeof(struct audit_krule));
121 memset(fields, 0, sizeof(struct audit_field));
122 141
123 entry->rule.flags = rule->flags & AUDIT_FILTER_PREPEND; 142 entry->rule.flags = rule->flags & AUDIT_FILTER_PREPEND;
124 entry->rule.listnr = listnr; 143 entry->rule.listnr = listnr;
125 entry->rule.action = rule->action; 144 entry->rule.action = rule->action;
126 entry->rule.field_count = rule->field_count; 145 entry->rule.field_count = rule->field_count;
127 entry->rule.fields = fields;
128 146
129 for (i = 0; i < AUDIT_BITMASK_SIZE; i++) 147 for (i = 0; i < AUDIT_BITMASK_SIZE; i++)
130 entry->rule.mask[i] = rule->mask[i]; 148 entry->rule.mask[i] = rule->mask[i];
@@ -150,15 +168,20 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
150 for (i = 0; i < rule->field_count; i++) { 168 for (i = 0; i < rule->field_count; i++) {
151 struct audit_field *f = &entry->rule.fields[i]; 169 struct audit_field *f = &entry->rule.fields[i];
152 170
153 if (rule->fields[i] & AUDIT_UNUSED_BITS) {
154 err = -EINVAL;
155 goto exit_free;
156 }
157
158 f->op = rule->fields[i] & (AUDIT_NEGATE|AUDIT_OPERATORS); 171 f->op = rule->fields[i] & (AUDIT_NEGATE|AUDIT_OPERATORS);
159 f->type = rule->fields[i] & ~(AUDIT_NEGATE|AUDIT_OPERATORS); 172 f->type = rule->fields[i] & ~(AUDIT_NEGATE|AUDIT_OPERATORS);
160 f->val = rule->values[i]; 173 f->val = rule->values[i];
161 174
175 if (f->type & AUDIT_UNUSED_BITS ||
176 f->type == AUDIT_SE_USER ||
177 f->type == AUDIT_SE_ROLE ||
178 f->type == AUDIT_SE_TYPE ||
179 f->type == AUDIT_SE_SEN ||
180 f->type == AUDIT_SE_CLR) {
181 err = -EINVAL;
182 goto exit_free;
183 }
184
162 entry->rule.vers_ops = (f->op & AUDIT_OPERATORS) ? 2 : 1; 185 entry->rule.vers_ops = (f->op & AUDIT_OPERATORS) ? 2 : 1;
163 186
164 /* Support for legacy operators where 187 /* Support for legacy operators where
@@ -188,8 +211,9 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
188 int err = 0; 211 int err = 0;
189 struct audit_entry *entry; 212 struct audit_entry *entry;
190 void *bufp; 213 void *bufp;
191 /* size_t remain = datasz - sizeof(struct audit_rule_data); */ 214 size_t remain = datasz - sizeof(struct audit_rule_data);
192 int i; 215 int i;
216 char *str;
193 217
194 entry = audit_to_entry_common((struct audit_rule *)data); 218 entry = audit_to_entry_common((struct audit_rule *)data);
195 if (IS_ERR(entry)) 219 if (IS_ERR(entry))
@@ -207,10 +231,35 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
207 231
208 f->op = data->fieldflags[i] & AUDIT_OPERATORS; 232 f->op = data->fieldflags[i] & AUDIT_OPERATORS;
209 f->type = data->fields[i]; 233 f->type = data->fields[i];
234 f->val = data->values[i];
235 f->se_str = NULL;
236 f->se_rule = NULL;
210 switch(f->type) { 237 switch(f->type) {
211 /* call type-specific conversion routines here */ 238 case AUDIT_SE_USER:
212 default: 239 case AUDIT_SE_ROLE:
213 f->val = data->values[i]; 240 case AUDIT_SE_TYPE:
241 case AUDIT_SE_SEN:
242 case AUDIT_SE_CLR:
243 str = audit_unpack_string(&bufp, &remain, f->val);
244 if (IS_ERR(str))
245 goto exit_free;
246 entry->rule.buflen += f->val;
247
248 err = selinux_audit_rule_init(f->type, f->op, str,
249 &f->se_rule);
250 /* Keep currently invalid fields around in case they
251 * become valid after a policy reload. */
252 if (err == -EINVAL) {
253 printk(KERN_WARNING "audit rule for selinux "
254 "\'%s\' is invalid\n", str);
255 err = 0;
256 }
257 if (err) {
258 kfree(str);
259 goto exit_free;
260 } else
261 f->se_str = str;
262 break;
214 } 263 }
215 } 264 }
216 265
@@ -286,7 +335,14 @@ static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule)
286 data->fields[i] = f->type; 335 data->fields[i] = f->type;
287 data->fieldflags[i] = f->op; 336 data->fieldflags[i] = f->op;
288 switch(f->type) { 337 switch(f->type) {
289 /* call type-specific conversion routines here */ 338 case AUDIT_SE_USER:
339 case AUDIT_SE_ROLE:
340 case AUDIT_SE_TYPE:
341 case AUDIT_SE_SEN:
342 case AUDIT_SE_CLR:
343 data->buflen += data->values[i] =
344 audit_pack_string(&bufp, f->se_str);
345 break;
290 default: 346 default:
291 data->values[i] = f->val; 347 data->values[i] = f->val;
292 } 348 }
@@ -314,7 +370,14 @@ static int audit_compare_rule(struct audit_krule *a, struct audit_krule *b)
314 return 1; 370 return 1;
315 371
316 switch(a->fields[i].type) { 372 switch(a->fields[i].type) {
317 /* call type-specific comparison routines here */ 373 case AUDIT_SE_USER:
374 case AUDIT_SE_ROLE:
375 case AUDIT_SE_TYPE:
376 case AUDIT_SE_SEN:
377 case AUDIT_SE_CLR:
378 if (strcmp(a->fields[i].se_str, b->fields[i].se_str))
379 return 1;
380 break;
318 default: 381 default:
319 if (a->fields[i].val != b->fields[i].val) 382 if (a->fields[i].val != b->fields[i].val)
320 return 1; 383 return 1;
@@ -328,6 +391,81 @@ static int audit_compare_rule(struct audit_krule *a, struct audit_krule *b)
328 return 0; 391 return 0;
329} 392}
330 393
394/* Duplicate selinux field information. The se_rule is opaque, so must be
395 * re-initialized. */
396static inline int audit_dupe_selinux_field(struct audit_field *df,
397 struct audit_field *sf)
398{
399 int ret = 0;
400 char *se_str;
401
402 /* our own copy of se_str */
403 se_str = kstrdup(sf->se_str, GFP_KERNEL);
404 if (unlikely(IS_ERR(se_str)))
405 return -ENOMEM;
406 df->se_str = se_str;
407
408 /* our own (refreshed) copy of se_rule */
409 ret = selinux_audit_rule_init(df->type, df->op, df->se_str,
410 &df->se_rule);
411 /* Keep currently invalid fields around in case they
412 * become valid after a policy reload. */
413 if (ret == -EINVAL) {
414 printk(KERN_WARNING "audit rule for selinux \'%s\' is "
415 "invalid\n", df->se_str);
416 ret = 0;
417 }
418
419 return ret;
420}
421
422/* Duplicate an audit rule. This will be a deep copy with the exception
423 * of the watch - that pointer is carried over. The selinux specific fields
424 * will be updated in the copy. The point is to be able to replace the old
425 * rule with the new rule in the filterlist, then free the old rule. */
426static struct audit_entry *audit_dupe_rule(struct audit_krule *old)
427{
428 u32 fcount = old->field_count;
429 struct audit_entry *entry;
430 struct audit_krule *new;
431 int i, err = 0;
432
433 entry = audit_init_entry(fcount);
434 if (unlikely(!entry))
435 return ERR_PTR(-ENOMEM);
436
437 new = &entry->rule;
438 new->vers_ops = old->vers_ops;
439 new->flags = old->flags;
440 new->listnr = old->listnr;
441 new->action = old->action;
442 for (i = 0; i < AUDIT_BITMASK_SIZE; i++)
443 new->mask[i] = old->mask[i];
444 new->buflen = old->buflen;
445 new->field_count = old->field_count;
446 memcpy(new->fields, old->fields, sizeof(struct audit_field) * fcount);
447
448 /* deep copy this information, updating the se_rule fields, because
449 * the originals will all be freed when the old rule is freed. */
450 for (i = 0; i < fcount; i++) {
451 switch (new->fields[i].type) {
452 case AUDIT_SE_USER:
453 case AUDIT_SE_ROLE:
454 case AUDIT_SE_TYPE:
455 case AUDIT_SE_SEN:
456 case AUDIT_SE_CLR:
457 err = audit_dupe_selinux_field(&new->fields[i],
458 &old->fields[i]);
459 }
460 if (err) {
461 audit_free_rule(entry);
462 return ERR_PTR(err);
463 }
464 }
465
466 return entry;
467}
468
331/* Add rule to given filterlist if not a duplicate. Protected by 469/* Add rule to given filterlist if not a duplicate. Protected by
332 * audit_netlink_mutex. */ 470 * audit_netlink_mutex. */
333static inline int audit_add_rule(struct audit_entry *entry, 471static inline int audit_add_rule(struct audit_entry *entry,
@@ -448,9 +586,10 @@ static int audit_list_rules(void *_dest)
448 * @data: payload data 586 * @data: payload data
449 * @datasz: size of payload data 587 * @datasz: size of payload data
450 * @loginuid: loginuid of sender 588 * @loginuid: loginuid of sender
589 * @sid: SE Linux Security ID of sender
451 */ 590 */
452int audit_receive_filter(int type, int pid, int uid, int seq, void *data, 591int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
453 size_t datasz, uid_t loginuid) 592 size_t datasz, uid_t loginuid, u32 sid)
454{ 593{
455 struct task_struct *tsk; 594 struct task_struct *tsk;
456 int *dest; 595 int *dest;
@@ -493,9 +632,23 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
493 632
494 err = audit_add_rule(entry, 633 err = audit_add_rule(entry,
495 &audit_filter_list[entry->rule.listnr]); 634 &audit_filter_list[entry->rule.listnr]);
496 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, 635 if (sid) {
497 "auid=%u add rule to list=%d res=%d\n", 636 char *ctx = NULL;
498 loginuid, entry->rule.listnr, !err); 637 u32 len;
638 if (selinux_ctxid_to_string(sid, &ctx, &len)) {
639 /* Maybe call audit_panic? */
640 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
641 "auid=%u ssid=%u add rule to list=%d res=%d",
642 loginuid, sid, entry->rule.listnr, !err);
643 } else
644 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
645 "auid=%u subj=%s add rule to list=%d res=%d",
646 loginuid, ctx, entry->rule.listnr, !err);
647 kfree(ctx);
648 } else
649 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
650 "auid=%u add rule to list=%d res=%d",
651 loginuid, entry->rule.listnr, !err);
499 652
500 if (err) 653 if (err)
501 audit_free_rule(entry); 654 audit_free_rule(entry);
@@ -511,9 +664,24 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
511 664
512 err = audit_del_rule(entry, 665 err = audit_del_rule(entry,
513 &audit_filter_list[entry->rule.listnr]); 666 &audit_filter_list[entry->rule.listnr]);
514 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, 667
515 "auid=%u remove rule from list=%d res=%d\n", 668 if (sid) {
516 loginuid, entry->rule.listnr, !err); 669 char *ctx = NULL;
670 u32 len;
671 if (selinux_ctxid_to_string(sid, &ctx, &len)) {
672 /* Maybe call audit_panic? */
673 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
674 "auid=%u ssid=%u remove rule from list=%d res=%d",
675 loginuid, sid, entry->rule.listnr, !err);
676 } else
677 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
678 "auid=%u subj=%s remove rule from list=%d res=%d",
679 loginuid, ctx, entry->rule.listnr, !err);
680 kfree(ctx);
681 } else
682 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
683 "auid=%u remove rule from list=%d res=%d",
684 loginuid, entry->rule.listnr, !err);
517 685
518 audit_free_rule(entry); 686 audit_free_rule(entry);
519 break; 687 break;
@@ -628,3 +796,62 @@ unlock_and_return:
628 rcu_read_unlock(); 796 rcu_read_unlock();
629 return result; 797 return result;
630} 798}
799
800/* Check to see if the rule contains any selinux fields. Returns 1 if there
801 are selinux fields specified in the rule, 0 otherwise. */
802static inline int audit_rule_has_selinux(struct audit_krule *rule)
803{
804 int i;
805
806 for (i = 0; i < rule->field_count; i++) {
807 struct audit_field *f = &rule->fields[i];
808 switch (f->type) {
809 case AUDIT_SE_USER:
810 case AUDIT_SE_ROLE:
811 case AUDIT_SE_TYPE:
812 case AUDIT_SE_SEN:
813 case AUDIT_SE_CLR:
814 return 1;
815 }
816 }
817
818 return 0;
819}
820
821/* This function will re-initialize the se_rule field of all applicable rules.
822 * It will traverse the filter lists serarching for rules that contain selinux
823 * specific filter fields. When such a rule is found, it is copied, the
824 * selinux field is re-initialized, and the old rule is replaced with the
825 * updated rule. */
826int selinux_audit_rule_update(void)
827{
828 struct audit_entry *entry, *n, *nentry;
829 int i, err = 0;
830
831 /* audit_netlink_mutex synchronizes the writers */
832 mutex_lock(&audit_netlink_mutex);
833
834 for (i = 0; i < AUDIT_NR_FILTERS; i++) {
835 list_for_each_entry_safe(entry, n, &audit_filter_list[i], list) {
836 if (!audit_rule_has_selinux(&entry->rule))
837 continue;
838
839 nentry = audit_dupe_rule(&entry->rule);
840 if (unlikely(IS_ERR(nentry))) {
841 /* save the first error encountered for the
842 * return value */
843 if (!err)
844 err = PTR_ERR(nentry);
845 audit_panic("error updating selinux filters");
846 list_del_rcu(&entry->list);
847 } else {
848 list_replace_rcu(&entry->list, &nentry->list);
849 }
850 call_rcu(&entry->rcu, audit_free_rule_rcu);
851 }
852 }
853
854 mutex_unlock(&audit_netlink_mutex);
855
856 return err;
857}
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 7f160df21a2..1c03a4ed1b2 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -58,6 +58,7 @@
58#include <linux/security.h> 58#include <linux/security.h>
59#include <linux/list.h> 59#include <linux/list.h>
60#include <linux/tty.h> 60#include <linux/tty.h>
61#include <linux/selinux.h>
61 62
62#include "audit.h" 63#include "audit.h"
63 64
@@ -89,7 +90,7 @@ struct audit_names {
89 uid_t uid; 90 uid_t uid;
90 gid_t gid; 91 gid_t gid;
91 dev_t rdev; 92 dev_t rdev;
92 char *ctx; 93 u32 osid;
93}; 94};
94 95
95struct audit_aux_data { 96struct audit_aux_data {
@@ -106,7 +107,7 @@ struct audit_aux_data_ipcctl {
106 uid_t uid; 107 uid_t uid;
107 gid_t gid; 108 gid_t gid;
108 mode_t mode; 109 mode_t mode;
109 char *ctx; 110 u32 osid;
110}; 111};
111 112
112struct audit_aux_data_socketcall { 113struct audit_aux_data_socketcall {
@@ -167,7 +168,8 @@ static int audit_filter_rules(struct task_struct *tsk,
167 struct audit_context *ctx, 168 struct audit_context *ctx,
168 enum audit_state *state) 169 enum audit_state *state)
169{ 170{
170 int i, j; 171 int i, j, need_sid = 1;
172 u32 sid;
171 173
172 for (i = 0; i < rule->field_count; i++) { 174 for (i = 0; i < rule->field_count; i++) {
173 struct audit_field *f = &rule->fields[i]; 175 struct audit_field *f = &rule->fields[i];
@@ -257,6 +259,27 @@ static int audit_filter_rules(struct task_struct *tsk,
257 if (ctx) 259 if (ctx)
258 result = audit_comparator(ctx->loginuid, f->op, f->val); 260 result = audit_comparator(ctx->loginuid, f->op, f->val);
259 break; 261 break;
262 case AUDIT_SE_USER:
263 case AUDIT_SE_ROLE:
264 case AUDIT_SE_TYPE:
265 case AUDIT_SE_SEN:
266 case AUDIT_SE_CLR:
267 /* NOTE: this may return negative values indicating
268 a temporary error. We simply treat this as a
269 match for now to avoid losing information that
270 may be wanted. An error message will also be
271 logged upon error */
272 if (f->se_rule) {
273 if (need_sid) {
274 selinux_task_ctxid(tsk, &sid);
275 need_sid = 0;
276 }
277 result = selinux_audit_rule_match(sid, f->type,
278 f->op,
279 f->se_rule,
280 ctx);
281 }
282 break;
260 case AUDIT_ARG0: 283 case AUDIT_ARG0:
261 case AUDIT_ARG1: 284 case AUDIT_ARG1:
262 case AUDIT_ARG2: 285 case AUDIT_ARG2:
@@ -329,7 +352,6 @@ static enum audit_state audit_filter_syscall(struct task_struct *tsk,
329 return AUDIT_BUILD_CONTEXT; 352 return AUDIT_BUILD_CONTEXT;
330} 353}
331 354
332/* This should be called with task_lock() held. */
333static inline struct audit_context *audit_get_context(struct task_struct *tsk, 355static inline struct audit_context *audit_get_context(struct task_struct *tsk,
334 int return_valid, 356 int return_valid,
335 int return_code) 357 int return_code)
@@ -391,9 +413,6 @@ static inline void audit_free_names(struct audit_context *context)
391#endif 413#endif
392 414
393 for (i = 0; i < context->name_count; i++) { 415 for (i = 0; i < context->name_count; i++) {
394 char *p = context->names[i].ctx;
395 context->names[i].ctx = NULL;
396 kfree(p);
397 if (context->names[i].name) 416 if (context->names[i].name)
398 __putname(context->names[i].name); 417 __putname(context->names[i].name);
399 } 418 }
@@ -416,11 +435,6 @@ static inline void audit_free_aux(struct audit_context *context)
416 dput(axi->dentry); 435 dput(axi->dentry);
417 mntput(axi->mnt); 436 mntput(axi->mnt);
418 } 437 }
419 if ( aux->type == AUDIT_IPC ) {
420 struct audit_aux_data_ipcctl *axi = (void *)aux;
421 if (axi->ctx)
422 kfree(axi->ctx);
423 }
424 438
425 context->aux = aux->next; 439 context->aux = aux->next;
426 kfree(aux); 440 kfree(aux);
@@ -506,7 +520,7 @@ static inline void audit_free_context(struct audit_context *context)
506 printk(KERN_ERR "audit: freed %d contexts\n", count); 520 printk(KERN_ERR "audit: freed %d contexts\n", count);
507} 521}
508 522
509static void audit_log_task_context(struct audit_buffer *ab, gfp_t gfp_mask) 523static void audit_log_task_context(struct audit_buffer *ab)
510{ 524{
511 char *ctx = NULL; 525 char *ctx = NULL;
512 ssize_t len = 0; 526 ssize_t len = 0;
@@ -518,7 +532,7 @@ static void audit_log_task_context(struct audit_buffer *ab, gfp_t gfp_mask)
518 return; 532 return;
519 } 533 }
520 534
521 ctx = kmalloc(len, gfp_mask); 535 ctx = kmalloc(len, GFP_KERNEL);
522 if (!ctx) 536 if (!ctx)
523 goto error_path; 537 goto error_path;
524 538
@@ -536,47 +550,46 @@ error_path:
536 return; 550 return;
537} 551}
538 552
539static void audit_log_task_info(struct audit_buffer *ab, gfp_t gfp_mask) 553static void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk)
540{ 554{
541 char name[sizeof(current->comm)]; 555 char name[sizeof(tsk->comm)];
542 struct mm_struct *mm = current->mm; 556 struct mm_struct *mm = tsk->mm;
543 struct vm_area_struct *vma; 557 struct vm_area_struct *vma;
544 558
545 get_task_comm(name, current); 559 /* tsk == current */
560
561 get_task_comm(name, tsk);
546 audit_log_format(ab, " comm="); 562 audit_log_format(ab, " comm=");
547 audit_log_untrustedstring(ab, name); 563 audit_log_untrustedstring(ab, name);
548 564
549 if (!mm) 565 if (mm) {
550 return; 566 down_read(&mm->mmap_sem);
551 567 vma = mm->mmap;
552 /* 568 while (vma) {
553 * this is brittle; all callers that pass GFP_ATOMIC will have 569 if ((vma->vm_flags & VM_EXECUTABLE) &&
554 * NULL current->mm and we won't get here. 570 vma->vm_file) {
555 */ 571 audit_log_d_path(ab, "exe=",
556 down_read(&mm->mmap_sem); 572 vma->vm_file->f_dentry,
557 vma = mm->mmap; 573 vma->vm_file->f_vfsmnt);
558 while (vma) { 574 break;
559 if ((vma->vm_flags & VM_EXECUTABLE) && 575 }
560 vma->vm_file) { 576 vma = vma->vm_next;
561 audit_log_d_path(ab, "exe=",
562 vma->vm_file->f_dentry,
563 vma->vm_file->f_vfsmnt);
564 break;
565 } 577 }
566 vma = vma->vm_next; 578 up_read(&mm->mmap_sem);
567 } 579 }
568 up_read(&mm->mmap_sem); 580 audit_log_task_context(ab);
569 audit_log_task_context(ab, gfp_mask);
570} 581}
571 582
572static void audit_log_exit(struct audit_context *context, gfp_t gfp_mask) 583static void audit_log_exit(struct audit_context *context, struct task_struct *tsk)
573{ 584{
574 int i; 585 int i, call_panic = 0;
575 struct audit_buffer *ab; 586 struct audit_buffer *ab;
576 struct audit_aux_data *aux; 587 struct audit_aux_data *aux;
577 const char *tty; 588 const char *tty;
578 589
579 ab = audit_log_start(context, gfp_mask, AUDIT_SYSCALL); 590 /* tsk == current */
591
592 ab = audit_log_start(context, GFP_KERNEL, AUDIT_SYSCALL);
580 if (!ab) 593 if (!ab)
581 return; /* audit_panic has been called */ 594 return; /* audit_panic has been called */
582 audit_log_format(ab, "arch=%x syscall=%d", 595 audit_log_format(ab, "arch=%x syscall=%d",
@@ -587,8 +600,8 @@ static void audit_log_exit(struct audit_context *context, gfp_t gfp_mask)
587 audit_log_format(ab, " success=%s exit=%ld", 600 audit_log_format(ab, " success=%s exit=%ld",
588 (context->return_valid==AUDITSC_SUCCESS)?"yes":"no", 601 (context->return_valid==AUDITSC_SUCCESS)?"yes":"no",
589 context->return_code); 602 context->return_code);
590 if (current->signal->tty && current->signal->tty->name) 603 if (tsk->signal && tsk->signal->tty && tsk->signal->tty->name)
591 tty = current->signal->tty->name; 604 tty = tsk->signal->tty->name;
592 else 605 else
593 tty = "(none)"; 606 tty = "(none)";
594 audit_log_format(ab, 607 audit_log_format(ab,
@@ -607,12 +620,12 @@ static void audit_log_exit(struct audit_context *context, gfp_t gfp_mask)
607 context->gid, 620 context->gid,
608 context->euid, context->suid, context->fsuid, 621 context->euid, context->suid, context->fsuid,
609 context->egid, context->sgid, context->fsgid, tty); 622 context->egid, context->sgid, context->fsgid, tty);
610 audit_log_task_info(ab, gfp_mask); 623 audit_log_task_info(ab, tsk);
611 audit_log_end(ab); 624 audit_log_end(ab);
612 625
613 for (aux = context->aux; aux; aux = aux->next) { 626 for (aux = context->aux; aux; aux = aux->next) {
614 627
615 ab = audit_log_start(context, gfp_mask, aux->type); 628 ab = audit_log_start(context, GFP_KERNEL, aux->type);
616 if (!ab) 629 if (!ab)
617 continue; /* audit_panic has been called */ 630 continue; /* audit_panic has been called */
618 631
@@ -620,8 +633,39 @@ static void audit_log_exit(struct audit_context *context, gfp_t gfp_mask)
620 case AUDIT_IPC: { 633 case AUDIT_IPC: {
621 struct audit_aux_data_ipcctl *axi = (void *)aux; 634 struct audit_aux_data_ipcctl *axi = (void *)aux;
622 audit_log_format(ab, 635 audit_log_format(ab,
623 " qbytes=%lx iuid=%u igid=%u mode=%x obj=%s", 636 " qbytes=%lx iuid=%u igid=%u mode=%x",
624 axi->qbytes, axi->uid, axi->gid, axi->mode, axi->ctx); 637 axi->qbytes, axi->uid, axi->gid, axi->mode);
638 if (axi->osid != 0) {
639 char *ctx = NULL;
640 u32 len;
641 if (selinux_ctxid_to_string(
642 axi->osid, &ctx, &len)) {
643 audit_log_format(ab, " osid=%u",
644 axi->osid);
645 call_panic = 1;
646 } else
647 audit_log_format(ab, " obj=%s", ctx);
648 kfree(ctx);
649 }
650 break; }
651
652 case AUDIT_IPC_SET_PERM: {
653 struct audit_aux_data_ipcctl *axi = (void *)aux;
654 audit_log_format(ab,
655 " new qbytes=%lx new iuid=%u new igid=%u new mode=%x",
656 axi->qbytes, axi->uid, axi->gid, axi->mode);
657 if (axi->osid != 0) {
658 char *ctx = NULL;
659 u32 len;
660 if (selinux_ctxid_to_string(
661 axi->osid, &ctx, &len)) {
662 audit_log_format(ab, " osid=%u",
663 axi->osid);
664 call_panic = 1;
665 } else
666 audit_log_format(ab, " obj=%s", ctx);
667 kfree(ctx);
668 }
625 break; } 669 break; }
626 670
627 case AUDIT_SOCKETCALL: { 671 case AUDIT_SOCKETCALL: {
@@ -649,7 +693,7 @@ static void audit_log_exit(struct audit_context *context, gfp_t gfp_mask)
649 } 693 }
650 694
651 if (context->pwd && context->pwdmnt) { 695 if (context->pwd && context->pwdmnt) {
652 ab = audit_log_start(context, gfp_mask, AUDIT_CWD); 696 ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD);
653 if (ab) { 697 if (ab) {
654 audit_log_d_path(ab, "cwd=", context->pwd, context->pwdmnt); 698 audit_log_d_path(ab, "cwd=", context->pwd, context->pwdmnt);
655 audit_log_end(ab); 699 audit_log_end(ab);
@@ -659,7 +703,7 @@ static void audit_log_exit(struct audit_context *context, gfp_t gfp_mask)
659 unsigned long ino = context->names[i].ino; 703 unsigned long ino = context->names[i].ino;
660 unsigned long pino = context->names[i].pino; 704 unsigned long pino = context->names[i].pino;
661 705
662 ab = audit_log_start(context, gfp_mask, AUDIT_PATH); 706 ab = audit_log_start(context, GFP_KERNEL, AUDIT_PATH);
663 if (!ab) 707 if (!ab)
664 continue; /* audit_panic has been called */ 708 continue; /* audit_panic has been called */
665 709
@@ -685,32 +729,35 @@ static void audit_log_exit(struct audit_context *context, gfp_t gfp_mask)
685 context->names[i].gid, 729 context->names[i].gid,
686 MAJOR(context->names[i].rdev), 730 MAJOR(context->names[i].rdev),
687 MINOR(context->names[i].rdev)); 731 MINOR(context->names[i].rdev));
688 if (context->names[i].ctx) { 732 if (context->names[i].osid != 0) {
689 audit_log_format(ab, " obj=%s", 733 char *ctx = NULL;
690 context->names[i].ctx); 734 u32 len;
735 if (selinux_ctxid_to_string(
736 context->names[i].osid, &ctx, &len)) {
737 audit_log_format(ab, " osid=%u",
738 context->names[i].osid);
739 call_panic = 2;
740 } else
741 audit_log_format(ab, " obj=%s", ctx);
742 kfree(ctx);
691 } 743 }
692 744
693 audit_log_end(ab); 745 audit_log_end(ab);
694 } 746 }
747 if (call_panic)
748 audit_panic("error converting sid to string");
695} 749}
696 750
697/** 751/**
698 * audit_free - free a per-task audit context 752 * audit_free - free a per-task audit context
699 * @tsk: task whose audit context block to free 753 * @tsk: task whose audit context block to free
700 * 754 *
701 * Called from copy_process and __put_task_struct. 755 * Called from copy_process and do_exit
702 */ 756 */
703void audit_free(struct task_struct *tsk) 757void audit_free(struct task_struct *tsk)
704{ 758{
705 struct audit_context *context; 759 struct audit_context *context;
706 760
707 /*
708 * No need to lock the task - when we execute audit_free()
709 * then the task has no external references anymore, and
710 * we are tearing it down. (The locking also confuses
711 * DEBUG_LOCKDEP - this freeing may occur in softirq
712 * contexts as well, via RCU.)
713 */
714 context = audit_get_context(tsk, 0, 0); 761 context = audit_get_context(tsk, 0, 0);
715 if (likely(!context)) 762 if (likely(!context))
716 return; 763 return;
@@ -719,8 +766,9 @@ void audit_free(struct task_struct *tsk)
719 * function (e.g., exit_group), then free context block. 766 * function (e.g., exit_group), then free context block.
720 * We use GFP_ATOMIC here because we might be doing this 767 * We use GFP_ATOMIC here because we might be doing this
721 * in the context of the idle thread */ 768 * in the context of the idle thread */
769 /* that can happen only if we are called from do_exit() */
722 if (context->in_syscall && context->auditable) 770 if (context->in_syscall && context->auditable)
723 audit_log_exit(context, GFP_ATOMIC); 771 audit_log_exit(context, tsk);
724 772
725 audit_free_context(context); 773 audit_free_context(context);
726} 774}
@@ -743,10 +791,11 @@ void audit_free(struct task_struct *tsk)
743 * will only be written if another part of the kernel requests that it 791 * will only be written if another part of the kernel requests that it
744 * be written). 792 * be written).
745 */ 793 */
746void audit_syscall_entry(struct task_struct *tsk, int arch, int major, 794void audit_syscall_entry(int arch, int major,
747 unsigned long a1, unsigned long a2, 795 unsigned long a1, unsigned long a2,
748 unsigned long a3, unsigned long a4) 796 unsigned long a3, unsigned long a4)
749{ 797{
798 struct task_struct *tsk = current;
750 struct audit_context *context = tsk->audit_context; 799 struct audit_context *context = tsk->audit_context;
751 enum audit_state state; 800 enum audit_state state;
752 801
@@ -824,22 +873,18 @@ void audit_syscall_entry(struct task_struct *tsk, int arch, int major,
824 * message), then write out the syscall information. In call cases, 873 * message), then write out the syscall information. In call cases,
825 * free the names stored from getname(). 874 * free the names stored from getname().
826 */ 875 */
827void audit_syscall_exit(struct task_struct *tsk, int valid, long return_code) 876void audit_syscall_exit(int valid, long return_code)
828{ 877{
878 struct task_struct *tsk = current;
829 struct audit_context *context; 879 struct audit_context *context;
830 880
831 get_task_struct(tsk);
832 task_lock(tsk);
833 context = audit_get_context(tsk, valid, return_code); 881 context = audit_get_context(tsk, valid, return_code);
834 task_unlock(tsk);
835 882
836 /* Not having a context here is ok, since the parent may have
837 * called __put_task_struct. */
838 if (likely(!context)) 883 if (likely(!context))
839 goto out; 884 return;
840 885
841 if (context->in_syscall && context->auditable) 886 if (context->in_syscall && context->auditable)
842 audit_log_exit(context, GFP_KERNEL); 887 audit_log_exit(context, tsk);
843 888
844 context->in_syscall = 0; 889 context->in_syscall = 0;
845 context->auditable = 0; 890 context->auditable = 0;
@@ -854,8 +899,6 @@ void audit_syscall_exit(struct task_struct *tsk, int valid, long return_code)
854 audit_free_aux(context); 899 audit_free_aux(context);
855 tsk->audit_context = context; 900 tsk->audit_context = context;
856 } 901 }
857 out:
858 put_task_struct(tsk);
859} 902}
860 903
861/** 904/**
@@ -936,40 +979,11 @@ void audit_putname(const char *name)
936#endif 979#endif
937} 980}
938 981
939void audit_inode_context(int idx, const struct inode *inode) 982static void audit_inode_context(int idx, const struct inode *inode)
940{ 983{
941 struct audit_context *context = current->audit_context; 984 struct audit_context *context = current->audit_context;
942 const char *suffix = security_inode_xattr_getsuffix();
943 char *ctx = NULL;
944 int len = 0;
945
946 if (!suffix)
947 goto ret;
948
949 len = security_inode_getsecurity(inode, suffix, NULL, 0, 0);
950 if (len == -EOPNOTSUPP)
951 goto ret;
952 if (len < 0)
953 goto error_path;
954
955 ctx = kmalloc(len, GFP_KERNEL);
956 if (!ctx)
957 goto error_path;
958 985
959 len = security_inode_getsecurity(inode, suffix, ctx, len, 0); 986 selinux_get_inode_sid(inode, &context->names[idx].osid);
960 if (len < 0)
961 goto error_path;
962
963 kfree(context->names[idx].ctx);
964 context->names[idx].ctx = ctx;
965 goto ret;
966
967error_path:
968 if (ctx)
969 kfree(ctx);
970 audit_panic("error in audit_inode_context");
971ret:
972 return;
973} 987}
974 988
975 989
@@ -1155,40 +1169,37 @@ uid_t audit_get_loginuid(struct audit_context *ctx)
1155 return ctx ? ctx->loginuid : -1; 1169 return ctx ? ctx->loginuid : -1;
1156} 1170}
1157 1171
1158static char *audit_ipc_context(struct kern_ipc_perm *ipcp) 1172/**
1173 * audit_ipc_obj - record audit data for ipc object
1174 * @ipcp: ipc permissions
1175 *
1176 * Returns 0 for success or NULL context or < 0 on error.
1177 */
1178int audit_ipc_obj(struct kern_ipc_perm *ipcp)
1159{ 1179{
1180 struct audit_aux_data_ipcctl *ax;
1160 struct audit_context *context = current->audit_context; 1181 struct audit_context *context = current->audit_context;
1161 char *ctx = NULL;
1162 int len = 0;
1163 1182
1164 if (likely(!context)) 1183 if (likely(!context))
1165 return NULL; 1184 return 0;
1166
1167 len = security_ipc_getsecurity(ipcp, NULL, 0);
1168 if (len == -EOPNOTSUPP)
1169 goto ret;
1170 if (len < 0)
1171 goto error_path;
1172
1173 ctx = kmalloc(len, GFP_ATOMIC);
1174 if (!ctx)
1175 goto error_path;
1176 1185
1177 len = security_ipc_getsecurity(ipcp, ctx, len); 1186 ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
1178 if (len < 0) 1187 if (!ax)
1179 goto error_path; 1188 return -ENOMEM;
1180 1189
1181 return ctx; 1190 ax->uid = ipcp->uid;
1191 ax->gid = ipcp->gid;
1192 ax->mode = ipcp->mode;
1193 selinux_get_ipc_sid(ipcp, &ax->osid);
1182 1194
1183error_path: 1195 ax->d.type = AUDIT_IPC;
1184 kfree(ctx); 1196 ax->d.next = context->aux;
1185 audit_panic("error in audit_ipc_context"); 1197 context->aux = (void *)ax;
1186ret: 1198 return 0;
1187 return NULL;
1188} 1199}
1189 1200
1190/** 1201/**
1191 * audit_ipc_perms - record audit data for ipc 1202 * audit_ipc_set_perm - record audit data for new ipc permissions
1192 * @qbytes: msgq bytes 1203 * @qbytes: msgq bytes
1193 * @uid: msgq user id 1204 * @uid: msgq user id
1194 * @gid: msgq group id 1205 * @gid: msgq group id
@@ -1196,7 +1207,7 @@ ret:
1196 * 1207 *
1197 * Returns 0 for success or NULL context or < 0 on error. 1208 * Returns 0 for success or NULL context or < 0 on error.
1198 */ 1209 */
1199int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode, struct kern_ipc_perm *ipcp) 1210int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode, struct kern_ipc_perm *ipcp)
1200{ 1211{
1201 struct audit_aux_data_ipcctl *ax; 1212 struct audit_aux_data_ipcctl *ax;
1202 struct audit_context *context = current->audit_context; 1213 struct audit_context *context = current->audit_context;
@@ -1212,9 +1223,9 @@ int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode, str
1212 ax->uid = uid; 1223 ax->uid = uid;
1213 ax->gid = gid; 1224 ax->gid = gid;
1214 ax->mode = mode; 1225 ax->mode = mode;
1215 ax->ctx = audit_ipc_context(ipcp); 1226 selinux_get_ipc_sid(ipcp, &ax->osid);
1216 1227
1217 ax->d.type = AUDIT_IPC; 1228 ax->d.type = AUDIT_IPC_SET_PERM;
1218 ax->d.next = context->aux; 1229 ax->d.next = context->aux;
1219 context->aux = (void *)ax; 1230 context->aux = (void *)ax;
1220 return 0; 1231 return 0;
diff --git a/kernel/exit.c b/kernel/exit.c
index f86434d7b3d..e95b9328221 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -35,6 +35,7 @@
35#include <linux/futex.h> 35#include <linux/futex.h>
36#include <linux/compat.h> 36#include <linux/compat.h>
37#include <linux/pipe_fs_i.h> 37#include <linux/pipe_fs_i.h>
38#include <linux/audit.h> /* for audit_free() */
38 39
39#include <asm/uaccess.h> 40#include <asm/uaccess.h>
40#include <asm/unistd.h> 41#include <asm/unistd.h>
@@ -910,6 +911,8 @@ fastcall NORET_TYPE void do_exit(long code)
910 if (unlikely(tsk->compat_robust_list)) 911 if (unlikely(tsk->compat_robust_list))
911 compat_exit_robust_list(tsk); 912 compat_exit_robust_list(tsk);
912#endif 913#endif
914 if (unlikely(tsk->audit_context))
915 audit_free(tsk);
913 exit_mm(tsk); 916 exit_mm(tsk);
914 917
915 exit_sem(tsk); 918 exit_sem(tsk);
diff --git a/kernel/fork.c b/kernel/fork.c
index d2fa57d480d..ac8100e3088 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -114,8 +114,6 @@ void __put_task_struct(struct task_struct *tsk)
114 WARN_ON(atomic_read(&tsk->usage)); 114 WARN_ON(atomic_read(&tsk->usage));
115 WARN_ON(tsk == current); 115 WARN_ON(tsk == current);
116 116
117 if (unlikely(tsk->audit_context))
118 audit_free(tsk);
119 security_task_free(tsk); 117 security_task_free(tsk);
120 free_uid(tsk->user); 118 free_uid(tsk->user);
121 put_group_info(tsk->group_info); 119 put_group_info(tsk->group_info);