aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/audit.h5
-rw-r--r--kernel/audit.c2
-rw-r--r--kernel/auditsc.c56
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 {
205struct audit_buffer; 205struct audit_buffer;
206struct audit_context; 206struct audit_context;
207struct inode; 207struct inode;
208struct 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);
236extern int audit_sockaddr(int len, void *addr); 237extern int audit_sockaddr(int len, void *addr);
237extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt); 238extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt);
238extern void audit_signal_info(int sig, struct task_struct *t); 239extern void audit_signal_info(int sig, struct task_struct *t);
239extern int audit_filter_user(int pid, int type); 240extern 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
533int audit_filter_user(int pid, int type) 534static 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
573int 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. */