diff options
Diffstat (limited to 'kernel/auditsc.c')
-rw-r--r-- | kernel/auditsc.c | 45 |
1 files changed, 34 insertions, 11 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 1b31c130d034..00d79df03e76 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -241,6 +241,10 @@ struct audit_context { | |||
241 | pid_t pid; | 241 | pid_t pid; |
242 | struct audit_cap_data cap; | 242 | struct audit_cap_data cap; |
243 | } capset; | 243 | } capset; |
244 | struct { | ||
245 | int fd; | ||
246 | int flags; | ||
247 | } mmap; | ||
244 | }; | 248 | }; |
245 | int fds[2]; | 249 | int fds[2]; |
246 | 250 | ||
@@ -439,17 +443,25 @@ static int match_tree_refs(struct audit_context *ctx, struct audit_tree *tree) | |||
439 | 443 | ||
440 | /* Determine if any context name data matches a rule's watch data */ | 444 | /* Determine if any context name data matches a rule's watch data */ |
441 | /* Compare a task_struct with an audit_rule. Return 1 on match, 0 | 445 | /* Compare a task_struct with an audit_rule. Return 1 on match, 0 |
442 | * otherwise. */ | 446 | * otherwise. |
447 | * | ||
448 | * If task_creation is true, this is an explicit indication that we are | ||
449 | * filtering a task rule at task creation time. This and tsk == current are | ||
450 | * the only situations where tsk->cred may be accessed without an rcu read lock. | ||
451 | */ | ||
443 | static int audit_filter_rules(struct task_struct *tsk, | 452 | static int audit_filter_rules(struct task_struct *tsk, |
444 | struct audit_krule *rule, | 453 | struct audit_krule *rule, |
445 | struct audit_context *ctx, | 454 | struct audit_context *ctx, |
446 | struct audit_names *name, | 455 | struct audit_names *name, |
447 | enum audit_state *state) | 456 | enum audit_state *state, |
457 | bool task_creation) | ||
448 | { | 458 | { |
449 | const struct cred *cred = get_task_cred(tsk); | 459 | const struct cred *cred; |
450 | int i, j, need_sid = 1; | 460 | int i, j, need_sid = 1; |
451 | u32 sid; | 461 | u32 sid; |
452 | 462 | ||
463 | cred = rcu_dereference_check(tsk->cred, tsk == current || task_creation); | ||
464 | |||
453 | for (i = 0; i < rule->field_count; i++) { | 465 | for (i = 0; i < rule->field_count; i++) { |
454 | struct audit_field *f = &rule->fields[i]; | 466 | struct audit_field *f = &rule->fields[i]; |
455 | int result = 0; | 467 | int result = 0; |
@@ -633,10 +645,8 @@ static int audit_filter_rules(struct task_struct *tsk, | |||
633 | break; | 645 | break; |
634 | } | 646 | } |
635 | 647 | ||
636 | if (!result) { | 648 | if (!result) |
637 | put_cred(cred); | ||
638 | return 0; | 649 | return 0; |
639 | } | ||
640 | } | 650 | } |
641 | 651 | ||
642 | if (ctx) { | 652 | if (ctx) { |
@@ -652,7 +662,6 @@ static int audit_filter_rules(struct task_struct *tsk, | |||
652 | case AUDIT_NEVER: *state = AUDIT_DISABLED; break; | 662 | case AUDIT_NEVER: *state = AUDIT_DISABLED; break; |
653 | case AUDIT_ALWAYS: *state = AUDIT_RECORD_CONTEXT; break; | 663 | case AUDIT_ALWAYS: *state = AUDIT_RECORD_CONTEXT; break; |
654 | } | 664 | } |
655 | put_cred(cred); | ||
656 | return 1; | 665 | return 1; |
657 | } | 666 | } |
658 | 667 | ||
@@ -667,7 +676,8 @@ static enum audit_state audit_filter_task(struct task_struct *tsk, char **key) | |||
667 | 676 | ||
668 | rcu_read_lock(); | 677 | rcu_read_lock(); |
669 | list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TASK], list) { | 678 | list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TASK], list) { |
670 | if (audit_filter_rules(tsk, &e->rule, NULL, NULL, &state)) { | 679 | if (audit_filter_rules(tsk, &e->rule, NULL, NULL, |
680 | &state, true)) { | ||
671 | if (state == AUDIT_RECORD_CONTEXT) | 681 | if (state == AUDIT_RECORD_CONTEXT) |
672 | *key = kstrdup(e->rule.filterkey, GFP_ATOMIC); | 682 | *key = kstrdup(e->rule.filterkey, GFP_ATOMIC); |
673 | rcu_read_unlock(); | 683 | rcu_read_unlock(); |
@@ -701,7 +711,7 @@ static enum audit_state audit_filter_syscall(struct task_struct *tsk, | |||
701 | list_for_each_entry_rcu(e, list, list) { | 711 | list_for_each_entry_rcu(e, list, list) { |
702 | if ((e->rule.mask[word] & bit) == bit && | 712 | if ((e->rule.mask[word] & bit) == bit && |
703 | audit_filter_rules(tsk, &e->rule, ctx, NULL, | 713 | audit_filter_rules(tsk, &e->rule, ctx, NULL, |
704 | &state)) { | 714 | &state, false)) { |
705 | rcu_read_unlock(); | 715 | rcu_read_unlock(); |
706 | ctx->current_state = state; | 716 | ctx->current_state = state; |
707 | return state; | 717 | return state; |
@@ -739,7 +749,8 @@ void audit_filter_inodes(struct task_struct *tsk, struct audit_context *ctx) | |||
739 | 749 | ||
740 | list_for_each_entry_rcu(e, list, list) { | 750 | list_for_each_entry_rcu(e, list, list) { |
741 | if ((e->rule.mask[word] & bit) == bit && | 751 | if ((e->rule.mask[word] & bit) == bit && |
742 | audit_filter_rules(tsk, &e->rule, ctx, n, &state)) { | 752 | audit_filter_rules(tsk, &e->rule, ctx, n, |
753 | &state, false)) { | ||
743 | rcu_read_unlock(); | 754 | rcu_read_unlock(); |
744 | ctx->current_state = state; | 755 | ctx->current_state = state; |
745 | return; | 756 | return; |
@@ -1007,7 +1018,7 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, | |||
1007 | /* | 1018 | /* |
1008 | * to_send and len_sent accounting are very loose estimates. We aren't | 1019 | * to_send and len_sent accounting are very loose estimates. We aren't |
1009 | * really worried about a hard cap to MAX_EXECVE_AUDIT_LEN so much as being | 1020 | * really worried about a hard cap to MAX_EXECVE_AUDIT_LEN so much as being |
1010 | * within about 500 bytes (next page boundry) | 1021 | * within about 500 bytes (next page boundary) |
1011 | * | 1022 | * |
1012 | * why snprintf? an int is up to 12 digits long. if we just assumed when | 1023 | * why snprintf? an int is up to 12 digits long. if we just assumed when |
1013 | * logging that a[%d]= was going to be 16 characters long we would be wasting | 1024 | * logging that a[%d]= was going to be 16 characters long we would be wasting |
@@ -1305,6 +1316,10 @@ static void show_special(struct audit_context *context, int *call_panic) | |||
1305 | audit_log_cap(ab, "cap_pp", &context->capset.cap.permitted); | 1316 | audit_log_cap(ab, "cap_pp", &context->capset.cap.permitted); |
1306 | audit_log_cap(ab, "cap_pe", &context->capset.cap.effective); | 1317 | audit_log_cap(ab, "cap_pe", &context->capset.cap.effective); |
1307 | break; } | 1318 | break; } |
1319 | case AUDIT_MMAP: { | ||
1320 | audit_log_format(ab, "fd=%d flags=0x%x", context->mmap.fd, | ||
1321 | context->mmap.flags); | ||
1322 | break; } | ||
1308 | } | 1323 | } |
1309 | audit_log_end(ab); | 1324 | audit_log_end(ab); |
1310 | } | 1325 | } |
@@ -2476,6 +2491,14 @@ void __audit_log_capset(pid_t pid, | |||
2476 | context->type = AUDIT_CAPSET; | 2491 | context->type = AUDIT_CAPSET; |
2477 | } | 2492 | } |
2478 | 2493 | ||
2494 | void __audit_mmap_fd(int fd, int flags) | ||
2495 | { | ||
2496 | struct audit_context *context = current->audit_context; | ||
2497 | context->mmap.fd = fd; | ||
2498 | context->mmap.flags = flags; | ||
2499 | context->type = AUDIT_MMAP; | ||
2500 | } | ||
2501 | |||
2479 | /** | 2502 | /** |
2480 | * audit_core_dumps - record information about processes that end abnormally | 2503 | * audit_core_dumps - record information about processes that end abnormally |
2481 | * @signr: signal value | 2504 | * @signr: signal value |