diff options
-rw-r--r-- | include/linux/audit.h | 5 | ||||
-rw-r--r-- | kernel/audit.c | 2 | ||||
-rw-r--r-- | kernel/auditsc.c | 56 |
3 files changed, 46 insertions, 17 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h index 2f56546eb248..38999f827a36 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h | |||
@@ -205,6 +205,7 @@ struct audit_sig_info { | |||
205 | struct audit_buffer; | 205 | struct audit_buffer; |
206 | struct audit_context; | 206 | struct audit_context; |
207 | struct inode; | 207 | struct inode; |
208 | struct netlink_skb_parms; | ||
208 | 209 | ||
209 | #define AUDITSC_INVALID 0 | 210 | #define AUDITSC_INVALID 0 |
210 | #define AUDITSC_SUCCESS 1 | 211 | #define AUDITSC_SUCCESS 1 |
@@ -236,7 +237,7 @@ extern int audit_socketcall(int nargs, unsigned long *args); | |||
236 | extern int audit_sockaddr(int len, void *addr); | 237 | extern int audit_sockaddr(int len, void *addr); |
237 | extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt); | 238 | extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt); |
238 | extern void audit_signal_info(int sig, struct task_struct *t); | 239 | extern void audit_signal_info(int sig, struct task_struct *t); |
239 | extern int audit_filter_user(int pid, int type); | 240 | extern int audit_filter_user(struct netlink_skb_parms *cb, int type); |
240 | #else | 241 | #else |
241 | #define audit_alloc(t) ({ 0; }) | 242 | #define audit_alloc(t) ({ 0; }) |
242 | #define audit_free(t) do { ; } while (0) | 243 | #define audit_free(t) do { ; } while (0) |
@@ -253,7 +254,7 @@ extern int audit_filter_user(int pid, int type); | |||
253 | #define audit_sockaddr(len, addr) ({ 0; }) | 254 | #define audit_sockaddr(len, addr) ({ 0; }) |
254 | #define audit_avc_path(dentry, mnt) ({ 0; }) | 255 | #define audit_avc_path(dentry, mnt) ({ 0; }) |
255 | #define audit_signal_info(s,t) do { ; } while (0) | 256 | #define audit_signal_info(s,t) do { ; } while (0) |
256 | #define audit_filter_user(p,t) ({ 1; }) | 257 | #define audit_filter_user(cb,t) ({ 1; }) |
257 | #endif | 258 | #endif |
258 | 259 | ||
259 | #ifdef CONFIG_AUDIT | 260 | #ifdef CONFIG_AUDIT |
diff --git a/kernel/audit.c b/kernel/audit.c index 9af947a63ed1..6f1784dd80af 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
@@ -434,7 +434,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
434 | if (!audit_enabled && msg_type != AUDIT_USER_AVC) | 434 | if (!audit_enabled && msg_type != AUDIT_USER_AVC) |
435 | return 0; | 435 | return 0; |
436 | 436 | ||
437 | err = audit_filter_user(pid, msg_type); | 437 | err = audit_filter_user(&NETLINK_CB(skb), msg_type); |
438 | if (err == 1) { | 438 | if (err == 1) { |
439 | err = 0; | 439 | err = 0; |
440 | ab = audit_log_start(NULL, GFP_KERNEL, msg_type); | 440 | ab = audit_log_start(NULL, GFP_KERNEL, msg_type); |
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. */ |