diff options
-rw-r--r-- | include/linux/audit.h | 2 | ||||
-rw-r--r-- | kernel/audit.c | 132 | ||||
-rw-r--r-- | kernel/auditfilter.c | 44 | ||||
-rw-r--r-- | kernel/auditsc.c | 4 |
4 files changed, 142 insertions, 40 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h index 740f950397b7..d5c40823e166 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h | |||
@@ -371,7 +371,7 @@ extern void audit_log_d_path(struct audit_buffer *ab, | |||
371 | extern int audit_filter_user(struct netlink_skb_parms *cb, int type); | 371 | extern int audit_filter_user(struct netlink_skb_parms *cb, int type); |
372 | extern int audit_filter_type(int type); | 372 | extern int audit_filter_type(int type); |
373 | extern int audit_receive_filter(int type, int pid, int uid, int seq, | 373 | extern int audit_receive_filter(int type, int pid, int uid, int seq, |
374 | void *data, size_t datasz, uid_t loginuid); | 374 | void *data, size_t datasz, uid_t loginuid, u32 sid); |
375 | #else | 375 | #else |
376 | #define audit_log(c,g,t,f,...) do { ; } while (0) | 376 | #define audit_log(c,g,t,f,...) do { ; } while (0) |
377 | #define audit_log_start(c,g,t) ({ NULL; }) | 377 | #define audit_log_start(c,g,t) ({ NULL; }) |
diff --git a/kernel/audit.c b/kernel/audit.c index 7ec9ccae1299..df57b493e1cb 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
@@ -230,49 +230,103 @@ void audit_log_lost(const char *message) | |||
230 | } | 230 | } |
231 | } | 231 | } |
232 | 232 | ||
233 | static int audit_set_rate_limit(int limit, uid_t loginuid) | 233 | static int audit_set_rate_limit(int limit, uid_t loginuid, u32 sid) |
234 | { | 234 | { |
235 | int old = audit_rate_limit; | 235 | int old = audit_rate_limit; |
236 | audit_rate_limit = limit; | 236 | |
237 | 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, | ||
238 | "audit_rate_limit=%d old=%d by auid=%u", | 250 | "audit_rate_limit=%d old=%d by auid=%u", |
239 | audit_rate_limit, old, loginuid); | 251 | limit, old, loginuid); |
252 | audit_rate_limit = limit; | ||
240 | return old; | 253 | return old; |
241 | } | 254 | } |
242 | 255 | ||
243 | static int audit_set_backlog_limit(int limit, uid_t loginuid) | 256 | static int audit_set_backlog_limit(int limit, uid_t loginuid, u32 sid) |
244 | { | 257 | { |
245 | int old = audit_backlog_limit; | 258 | int old = audit_backlog_limit; |
246 | audit_backlog_limit = limit; | 259 | |
247 | 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, | ||
248 | "audit_backlog_limit=%d old=%d by auid=%u", | 273 | "audit_backlog_limit=%d old=%d by auid=%u", |
249 | audit_backlog_limit, old, loginuid); | 274 | limit, old, loginuid); |
275 | audit_backlog_limit = limit; | ||
250 | return old; | 276 | return old; |
251 | } | 277 | } |
252 | 278 | ||
253 | static int audit_set_enabled(int state, uid_t loginuid) | 279 | static int audit_set_enabled(int state, uid_t loginuid, u32 sid) |
254 | { | 280 | { |
255 | int old = audit_enabled; | 281 | int old = audit_enabled; |
282 | |||
256 | if (state != 0 && state != 1) | 283 | if (state != 0 && state != 1) |
257 | return -EINVAL; | 284 | return -EINVAL; |
258 | audit_enabled = state; | 285 | |
259 | 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, | ||
260 | "audit_enabled=%d old=%d by auid=%u", | 299 | "audit_enabled=%d old=%d by auid=%u", |
261 | audit_enabled, old, loginuid); | 300 | state, old, loginuid); |
301 | audit_enabled = state; | ||
262 | return old; | 302 | return old; |
263 | } | 303 | } |
264 | 304 | ||
265 | static int audit_set_failure(int state, uid_t loginuid) | 305 | static int audit_set_failure(int state, uid_t loginuid, u32 sid) |
266 | { | 306 | { |
267 | int old = audit_failure; | 307 | int old = audit_failure; |
308 | |||
268 | if (state != AUDIT_FAIL_SILENT | 309 | if (state != AUDIT_FAIL_SILENT |
269 | && state != AUDIT_FAIL_PRINTK | 310 | && state != AUDIT_FAIL_PRINTK |
270 | && state != AUDIT_FAIL_PANIC) | 311 | && state != AUDIT_FAIL_PANIC) |
271 | return -EINVAL; | 312 | return -EINVAL; |
272 | audit_failure = state; | 313 | |
273 | 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, | ||
274 | "audit_failure=%d old=%d by auid=%u", | 327 | "audit_failure=%d old=%d by auid=%u", |
275 | audit_failure, old, loginuid); | 328 | state, old, loginuid); |
329 | audit_failure = state; | ||
276 | return old; | 330 | return old; |
277 | } | 331 | } |
278 | 332 | ||
@@ -437,25 +491,43 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
437 | return -EINVAL; | 491 | return -EINVAL; |
438 | status_get = (struct audit_status *)data; | 492 | status_get = (struct audit_status *)data; |
439 | if (status_get->mask & AUDIT_STATUS_ENABLED) { | 493 | if (status_get->mask & AUDIT_STATUS_ENABLED) { |
440 | err = audit_set_enabled(status_get->enabled, loginuid); | 494 | err = audit_set_enabled(status_get->enabled, |
495 | loginuid, sid); | ||
441 | if (err < 0) return err; | 496 | if (err < 0) return err; |
442 | } | 497 | } |
443 | if (status_get->mask & AUDIT_STATUS_FAILURE) { | 498 | if (status_get->mask & AUDIT_STATUS_FAILURE) { |
444 | err = audit_set_failure(status_get->failure, loginuid); | 499 | err = audit_set_failure(status_get->failure, |
500 | loginuid, sid); | ||
445 | if (err < 0) return err; | 501 | if (err < 0) return err; |
446 | } | 502 | } |
447 | if (status_get->mask & AUDIT_STATUS_PID) { | 503 | if (status_get->mask & AUDIT_STATUS_PID) { |
448 | 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); | ||
449 | audit_pid = status_get->pid; | 523 | audit_pid = status_get->pid; |
450 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
451 | "audit_pid=%d old=%d by auid=%u", | ||
452 | audit_pid, old, loginuid); | ||
453 | } | 524 | } |
454 | if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) | 525 | if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) |
455 | audit_set_rate_limit(status_get->rate_limit, loginuid); | 526 | audit_set_rate_limit(status_get->rate_limit, |
527 | loginuid, sid); | ||
456 | if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT) | 528 | if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT) |
457 | audit_set_backlog_limit(status_get->backlog_limit, | 529 | audit_set_backlog_limit(status_get->backlog_limit, |
458 | loginuid); | 530 | loginuid, sid); |
459 | break; | 531 | break; |
460 | case AUDIT_USER: | 532 | case AUDIT_USER: |
461 | case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG: | 533 | case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG: |
@@ -477,7 +549,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
477 | if (selinux_ctxid_to_string( | 549 | if (selinux_ctxid_to_string( |
478 | sid, &ctx, &len)) { | 550 | sid, &ctx, &len)) { |
479 | audit_log_format(ab, | 551 | audit_log_format(ab, |
480 | " subj=%u", sid); | 552 | " ssid=%u", sid); |
481 | /* Maybe call audit_panic? */ | 553 | /* Maybe call audit_panic? */ |
482 | } else | 554 | } else |
483 | audit_log_format(ab, | 555 | audit_log_format(ab, |
@@ -499,7 +571,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
499 | case AUDIT_LIST: | 571 | case AUDIT_LIST: |
500 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, | 572 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, |
501 | uid, seq, data, nlmsg_len(nlh), | 573 | uid, seq, data, nlmsg_len(nlh), |
502 | loginuid); | 574 | loginuid, sid); |
503 | break; | 575 | break; |
504 | case AUDIT_ADD_RULE: | 576 | case AUDIT_ADD_RULE: |
505 | case AUDIT_DEL_RULE: | 577 | case AUDIT_DEL_RULE: |
@@ -509,7 +581,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
509 | case AUDIT_LIST_RULES: | 581 | case AUDIT_LIST_RULES: |
510 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, | 582 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, |
511 | uid, seq, data, nlmsg_len(nlh), | 583 | uid, seq, data, nlmsg_len(nlh), |
512 | loginuid); | 584 | loginuid, sid); |
513 | break; | 585 | break; |
514 | case AUDIT_SIGNAL_INFO: | 586 | case AUDIT_SIGNAL_INFO: |
515 | sig_data.uid = audit_sig_uid; | 587 | sig_data.uid = audit_sig_uid; |
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 85a7862143a1..7c134906d689 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c | |||
@@ -586,9 +586,10 @@ static int audit_list_rules(void *_dest) | |||
586 | * @data: payload data | 586 | * @data: payload data |
587 | * @datasz: size of payload data | 587 | * @datasz: size of payload data |
588 | * @loginuid: loginuid of sender | 588 | * @loginuid: loginuid of sender |
589 | * @sid: SE Linux Security ID of sender | ||
589 | */ | 590 | */ |
590 | int audit_receive_filter(int type, int pid, int uid, int seq, void *data, | 591 | int audit_receive_filter(int type, int pid, int uid, int seq, void *data, |
591 | size_t datasz, uid_t loginuid) | 592 | size_t datasz, uid_t loginuid, u32 sid) |
592 | { | 593 | { |
593 | struct task_struct *tsk; | 594 | struct task_struct *tsk; |
594 | int *dest; | 595 | int *dest; |
@@ -631,9 +632,23 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data, | |||
631 | 632 | ||
632 | err = audit_add_rule(entry, | 633 | err = audit_add_rule(entry, |
633 | &audit_filter_list[entry->rule.listnr]); | 634 | &audit_filter_list[entry->rule.listnr]); |
634 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | 635 | if (sid) { |
635 | "auid=%u add rule to list=%d res=%d\n", | 636 | char *ctx = NULL; |
636 | 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); | ||
637 | 652 | ||
638 | if (err) | 653 | if (err) |
639 | audit_free_rule(entry); | 654 | audit_free_rule(entry); |
@@ -649,9 +664,24 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data, | |||
649 | 664 | ||
650 | err = audit_del_rule(entry, | 665 | err = audit_del_rule(entry, |
651 | &audit_filter_list[entry->rule.listnr]); | 666 | &audit_filter_list[entry->rule.listnr]); |
652 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | 667 | |
653 | "auid=%u remove rule from list=%d res=%d\n", | 668 | if (sid) { |
654 | 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); | ||
655 | 685 | ||
656 | audit_free_rule(entry); | 686 | audit_free_rule(entry); |
657 | break; | 687 | break; |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index b4f7223811fe..d94e0404113c 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -637,7 +637,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
637 | u32 len; | 637 | u32 len; |
638 | if (selinux_ctxid_to_string( | 638 | if (selinux_ctxid_to_string( |
639 | axi->osid, &ctx, &len)) { | 639 | axi->osid, &ctx, &len)) { |
640 | audit_log_format(ab, " obj=%u", | 640 | audit_log_format(ab, " osid=%u", |
641 | axi->osid); | 641 | axi->osid); |
642 | call_panic = 1; | 642 | call_panic = 1; |
643 | } else | 643 | } else |
@@ -712,7 +712,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
712 | u32 len; | 712 | u32 len; |
713 | if (selinux_ctxid_to_string( | 713 | if (selinux_ctxid_to_string( |
714 | context->names[i].osid, &ctx, &len)) { | 714 | context->names[i].osid, &ctx, &len)) { |
715 | audit_log_format(ab, " obj=%u", | 715 | audit_log_format(ab, " osid=%u", |
716 | context->names[i].osid); | 716 | context->names[i].osid); |
717 | call_panic = 2; | 717 | call_panic = 2; |
718 | } else | 718 | } else |