diff options
Diffstat (limited to 'kernel/auditsc.c')
-rw-r--r-- | kernel/auditsc.c | 56 |
1 files changed, 42 insertions, 14 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 7b123f0a9481..34a990223c9e 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/personality.h> | 40 | #include <linux/personality.h> |
41 | #include <linux/time.h> | 41 | #include <linux/time.h> |
42 | #include <linux/kthread.h> | 42 | #include <linux/kthread.h> |
43 | #include <linux/netlink.h> | ||
43 | #include <asm/unistd.h> | 44 | #include <asm/unistd.h> |
44 | 45 | ||
45 | /* 0 = no checking | 46 | /* 0 = no checking |
@@ -530,35 +531,62 @@ static enum audit_state audit_filter_syscall(struct task_struct *tsk, | |||
530 | return AUDIT_BUILD_CONTEXT; | 531 | return AUDIT_BUILD_CONTEXT; |
531 | } | 532 | } |
532 | 533 | ||
533 | int audit_filter_user(int pid, int type) | 534 | static int audit_filter_user_rules(struct netlink_skb_parms *cb, |
535 | struct audit_rule *rule, | ||
536 | enum audit_state *state) | ||
537 | { | ||
538 | int i; | ||
539 | |||
540 | for (i = 0; i < rule->field_count; i++) { | ||
541 | u32 field = rule->fields[i] & ~AUDIT_NEGATE; | ||
542 | u32 value = rule->values[i]; | ||
543 | int result = 0; | ||
544 | |||
545 | switch (field) { | ||
546 | case AUDIT_PID: | ||
547 | result = (cb->creds.pid == value); | ||
548 | break; | ||
549 | case AUDIT_UID: | ||
550 | result = (cb->creds.uid == value); | ||
551 | break; | ||
552 | case AUDIT_GID: | ||
553 | result = (cb->creds.gid == value); | ||
554 | break; | ||
555 | case AUDIT_LOGINUID: | ||
556 | result = (cb->loginuid == value); | ||
557 | break; | ||
558 | } | ||
559 | |||
560 | if (rule->fields[i] & AUDIT_NEGATE) | ||
561 | result = !result; | ||
562 | if (!result) | ||
563 | return 0; | ||
564 | } | ||
565 | switch (rule->action) { | ||
566 | case AUDIT_NEVER: *state = AUDIT_DISABLED; break; | ||
567 | case AUDIT_POSSIBLE: *state = AUDIT_BUILD_CONTEXT; break; | ||
568 | case AUDIT_ALWAYS: *state = AUDIT_RECORD_CONTEXT; break; | ||
569 | } | ||
570 | return 1; | ||
571 | } | ||
572 | |||
573 | int audit_filter_user(struct netlink_skb_parms *cb, int type) | ||
534 | { | 574 | { |
535 | struct task_struct *tsk; | ||
536 | struct audit_entry *e; | 575 | struct audit_entry *e; |
537 | enum audit_state state; | 576 | enum audit_state state; |
538 | int ret = 1; | 577 | int ret = 1; |
539 | 578 | ||
540 | read_lock(&tasklist_lock); | ||
541 | tsk = find_task_by_pid(pid); | ||
542 | if (tsk) | ||
543 | get_task_struct(tsk); | ||
544 | read_unlock(&tasklist_lock); | ||
545 | |||
546 | if (!tsk) | ||
547 | return -ESRCH; | ||
548 | |||
549 | rcu_read_lock(); | 579 | rcu_read_lock(); |
550 | list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_USER], list) { | 580 | list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_USER], list) { |
551 | if (audit_filter_rules(tsk, &e->rule, NULL, &state)) { | 581 | if (audit_filter_user_rules(cb, &e->rule, &state)) { |
552 | if (state == AUDIT_DISABLED) | 582 | if (state == AUDIT_DISABLED) |
553 | ret = 0; | 583 | ret = 0; |
554 | break; | 584 | break; |
555 | } | 585 | } |
556 | } | 586 | } |
557 | rcu_read_unlock(); | 587 | rcu_read_unlock(); |
558 | put_task_struct(tsk); | ||
559 | 588 | ||
560 | return ret; /* Audit by default */ | 589 | return ret; /* Audit by default */ |
561 | |||
562 | } | 590 | } |
563 | 591 | ||
564 | /* This should be called with task_lock() held. */ | 592 | /* This should be called with task_lock() held. */ |