aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorAmy Griffis <amy.griffis@hp.com>2006-04-07 16:55:56 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2006-06-20 05:25:27 -0400
commitf368c07d7214a7c41dfceb76c8db473b850f0229 (patch)
treee3f1e2d1a6ffbe61bf99ece51b906654728db4c9 /kernel
parent20ca73bc792be9625af184cbec36e1372611d1c3 (diff)
[PATCH] audit: path-based rules
In this implementation, audit registers inotify watches on the parent directories of paths specified in audit rules. When audit's inotify event handler is called, it updates any affected rules based on the filesystem event. If the parent directory is renamed, removed, or its filesystem is unmounted, audit removes all rules referencing that inotify watch. To keep things simple, this implementation limits location-based auditing to the directory entries in an existing directory. Given a path-based rule for /foo/bar/passwd, the following table applies: passwd modified -- audit event logged passwd replaced -- audit event logged, rules list updated bar renamed -- rule removed foo renamed -- untracked, meaning that the rule now applies to the new location Audit users typically want to have many rules referencing filesystem objects, which can significantly impact filtering performance. This patch also adds an inode-number-based rule hash to mitigate this situation. The patch is relative to the audit git tree: http://kernel.org/git/?p=linux/kernel/git/viro/audit-current.git;a=summary and uses the inotify kernel API: http://lkml.org/lkml/2006/6/1/145 Signed-off-by: Amy Griffis <amy.griffis@hp.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/audit.c41
-rw-r--r--kernel/audit.h38
-rw-r--r--kernel/auditfilter.c785
-rw-r--r--kernel/auditsc.c124
4 files changed, 900 insertions, 88 deletions
diff --git a/kernel/audit.c b/kernel/audit.c
index 0738a4b290e6..0fbf1c116363 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -56,6 +56,7 @@
56#include <linux/skbuff.h> 56#include <linux/skbuff.h>
57#include <linux/netlink.h> 57#include <linux/netlink.h>
58#include <linux/selinux.h> 58#include <linux/selinux.h>
59#include <linux/inotify.h>
59 60
60#include "audit.h" 61#include "audit.h"
61 62
@@ -103,6 +104,12 @@ static atomic_t audit_lost = ATOMIC_INIT(0);
103/* The netlink socket. */ 104/* The netlink socket. */
104static struct sock *audit_sock; 105static struct sock *audit_sock;
105 106
107/* Inotify handle. */
108struct inotify_handle *audit_ih;
109
110/* Hash for inode-based rules */
111struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS];
112
106/* The audit_freelist is a list of pre-allocated audit buffers (if more 113/* The audit_freelist is a list of pre-allocated audit buffers (if more
107 * than AUDIT_MAXFREE are in use, the audit buffer is freed instead of 114 * than AUDIT_MAXFREE are in use, the audit buffer is freed instead of
108 * being placed on the freelist). */ 115 * being placed on the freelist). */
@@ -115,10 +122,8 @@ static struct task_struct *kauditd_task;
115static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait); 122static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait);
116static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait); 123static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait);
117 124
118/* The netlink socket is only to be read by 1 CPU, which lets us assume 125/* Serialize requests from userspace. */
119 * that list additions and deletions never happen simultaneously in 126static DEFINE_MUTEX(audit_cmd_mutex);
120 * auditsc.c */
121DEFINE_MUTEX(audit_netlink_mutex);
122 127
123/* AUDIT_BUFSIZ is the size of the temporary buffer used for formatting 128/* AUDIT_BUFSIZ is the size of the temporary buffer used for formatting
124 * audit records. Since printk uses a 1024 byte buffer, this buffer 129 * audit records. Since printk uses a 1024 byte buffer, this buffer
@@ -373,8 +378,8 @@ int audit_send_list(void *_dest)
373 struct sk_buff *skb; 378 struct sk_buff *skb;
374 379
375 /* wait for parent to finish and send an ACK */ 380 /* wait for parent to finish and send an ACK */
376 mutex_lock(&audit_netlink_mutex); 381 mutex_lock(&audit_cmd_mutex);
377 mutex_unlock(&audit_netlink_mutex); 382 mutex_unlock(&audit_cmd_mutex);
378 383
379 while ((skb = __skb_dequeue(&dest->q)) != NULL) 384 while ((skb = __skb_dequeue(&dest->q)) != NULL)
380 netlink_unicast(audit_sock, skb, pid, 0); 385 netlink_unicast(audit_sock, skb, pid, 0);
@@ -665,20 +670,30 @@ static void audit_receive(struct sock *sk, int length)
665 struct sk_buff *skb; 670 struct sk_buff *skb;
666 unsigned int qlen; 671 unsigned int qlen;
667 672
668 mutex_lock(&audit_netlink_mutex); 673 mutex_lock(&audit_cmd_mutex);
669 674
670 for (qlen = skb_queue_len(&sk->sk_receive_queue); qlen; qlen--) { 675 for (qlen = skb_queue_len(&sk->sk_receive_queue); qlen; qlen--) {
671 skb = skb_dequeue(&sk->sk_receive_queue); 676 skb = skb_dequeue(&sk->sk_receive_queue);
672 audit_receive_skb(skb); 677 audit_receive_skb(skb);
673 kfree_skb(skb); 678 kfree_skb(skb);
674 } 679 }
675 mutex_unlock(&audit_netlink_mutex); 680 mutex_unlock(&audit_cmd_mutex);
676} 681}
677 682
683#ifdef CONFIG_AUDITSYSCALL
684static const struct inotify_operations audit_inotify_ops = {
685 .handle_event = audit_handle_ievent,
686 .destroy_watch = audit_free_parent,
687};
688#endif
678 689
679/* Initialize audit support at boot time. */ 690/* Initialize audit support at boot time. */
680static int __init audit_init(void) 691static int __init audit_init(void)
681{ 692{
693#ifdef CONFIG_AUDITSYSCALL
694 int i;
695#endif
696
682 printk(KERN_INFO "audit: initializing netlink socket (%s)\n", 697 printk(KERN_INFO "audit: initializing netlink socket (%s)\n",
683 audit_default ? "enabled" : "disabled"); 698 audit_default ? "enabled" : "disabled");
684 audit_sock = netlink_kernel_create(NETLINK_AUDIT, 0, audit_receive, 699 audit_sock = netlink_kernel_create(NETLINK_AUDIT, 0, audit_receive,
@@ -697,6 +712,16 @@ static int __init audit_init(void)
697 selinux_audit_set_callback(&selinux_audit_rule_update); 712 selinux_audit_set_callback(&selinux_audit_rule_update);
698 713
699 audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized"); 714 audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized");
715
716#ifdef CONFIG_AUDITSYSCALL
717 audit_ih = inotify_init(&audit_inotify_ops);
718 if (IS_ERR(audit_ih))
719 audit_panic("cannot initialize inotify handle");
720
721 for (i = 0; i < AUDIT_INODE_BUCKETS; i++)
722 INIT_LIST_HEAD(&audit_inode_hash[i]);
723#endif
724
700 return 0; 725 return 0;
701} 726}
702__initcall(audit_init); 727__initcall(audit_init);
diff --git a/kernel/audit.h b/kernel/audit.h
index 52cb1e31d522..58fa44cb8d01 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -19,7 +19,6 @@
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21 21
22#include <linux/mutex.h>
23#include <linux/fs.h> 22#include <linux/fs.h>
24#include <linux/audit.h> 23#include <linux/audit.h>
25#include <linux/skbuff.h> 24#include <linux/skbuff.h>
@@ -54,6 +53,18 @@ enum audit_state {
54}; 53};
55 54
56/* Rule lists */ 55/* Rule lists */
56struct audit_parent;
57
58struct audit_watch {
59 atomic_t count; /* reference count */
60 char *path; /* insertion path */
61 dev_t dev; /* associated superblock device */
62 unsigned long ino; /* associated inode number */
63 struct audit_parent *parent; /* associated parent */
64 struct list_head wlist; /* entry in parent->watches list */
65 struct list_head rules; /* associated rules */
66};
67
57struct audit_field { 68struct audit_field {
58 u32 type; 69 u32 type;
59 u32 val; 70 u32 val;
@@ -71,6 +82,9 @@ struct audit_krule {
71 u32 buflen; /* for data alloc on list rules */ 82 u32 buflen; /* for data alloc on list rules */
72 u32 field_count; 83 u32 field_count;
73 struct audit_field *fields; 84 struct audit_field *fields;
85 struct audit_field *inode_f; /* quick access to an inode field */
86 struct audit_watch *watch; /* associated watch */
87 struct list_head rlist; /* entry in audit_watch.rules list */
74}; 88};
75 89
76struct audit_entry { 90struct audit_entry {
@@ -79,10 +93,18 @@ struct audit_entry {
79 struct audit_krule rule; 93 struct audit_krule rule;
80}; 94};
81 95
82
83extern int audit_pid; 96extern int audit_pid;
84extern int audit_comparator(const u32 left, const u32 op, const u32 right);
85 97
98#define AUDIT_INODE_BUCKETS 32
99extern struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS];
100
101static inline int audit_hash_ino(u32 ino)
102{
103 return (ino & (AUDIT_INODE_BUCKETS-1));
104}
105
106extern int audit_comparator(const u32 left, const u32 op, const u32 right);
107extern int audit_compare_dname_path(const char *dname, const char *path);
86extern struct sk_buff * audit_make_reply(int pid, int seq, int type, 108extern struct sk_buff * audit_make_reply(int pid, int seq, int type,
87 int done, int multi, 109 int done, int multi,
88 void *payload, int size); 110 void *payload, int size);
@@ -91,7 +113,6 @@ extern void audit_send_reply(int pid, int seq, int type,
91 void *payload, int size); 113 void *payload, int size);
92extern void audit_log_lost(const char *message); 114extern void audit_log_lost(const char *message);
93extern void audit_panic(const char *message); 115extern void audit_panic(const char *message);
94extern struct mutex audit_netlink_mutex;
95 116
96struct audit_netlink_list { 117struct audit_netlink_list {
97 int pid; 118 int pid;
@@ -100,6 +121,10 @@ struct audit_netlink_list {
100 121
101int audit_send_list(void *); 122int audit_send_list(void *);
102 123
124struct inotify_watch;
125extern void audit_free_parent(struct inotify_watch *);
126extern void audit_handle_ievent(struct inotify_watch *, u32, u32, u32,
127 const char *, struct inode *);
103extern int selinux_audit_rule_update(void); 128extern int selinux_audit_rule_update(void);
104 129
105#ifdef CONFIG_AUDITSYSCALL 130#ifdef CONFIG_AUDITSYSCALL
@@ -109,6 +134,11 @@ static inline void audit_signal_info(int sig, struct task_struct *t)
109 if (unlikely(audit_pid && t->tgid == audit_pid)) 134 if (unlikely(audit_pid && t->tgid == audit_pid))
110 __audit_signal_info(sig, t); 135 __audit_signal_info(sig, t);
111} 136}
137extern enum audit_state audit_filter_inodes(struct task_struct *,
138 struct audit_context *);
139extern void audit_set_auditable(struct audit_context *);
112#else 140#else
113#define audit_signal_info(s,t) 141#define audit_signal_info(s,t)
142#define audit_filter_inodes(t,c) AUDIT_DISABLED
143#define audit_set_auditable(c)
114#endif 144#endif
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index df9503da40fb..03a6919103d4 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -22,13 +22,59 @@
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/audit.h> 23#include <linux/audit.h>
24#include <linux/kthread.h> 24#include <linux/kthread.h>
25#include <linux/mutex.h>
26#include <linux/fs.h>
27#include <linux/namei.h>
25#include <linux/netlink.h> 28#include <linux/netlink.h>
29#include <linux/sched.h>
30#include <linux/inotify.h>
26#include <linux/selinux.h> 31#include <linux/selinux.h>
27#include "audit.h" 32#include "audit.h"
28 33
29/* There are three lists of rules -- one to search at task creation 34/*
30 * time, one to search at syscall entry time, and another to search at 35 * Locking model:
31 * syscall exit time. */ 36 *
37 * audit_filter_mutex:
38 * Synchronizes writes and blocking reads of audit's filterlist
39 * data. Rcu is used to traverse the filterlist and access
40 * contents of structs audit_entry, audit_watch and opaque
41 * selinux rules during filtering. If modified, these structures
42 * must be copied and replace their counterparts in the filterlist.
43 * An audit_parent struct is not accessed during filtering, so may
44 * be written directly provided audit_filter_mutex is held.
45 */
46
47/*
48 * Reference counting:
49 *
50 * audit_parent: lifetime is from audit_init_parent() to receipt of an IN_IGNORED
51 * event. Each audit_watch holds a reference to its associated parent.
52 *
53 * audit_watch: if added to lists, lifetime is from audit_init_watch() to
54 * audit_remove_watch(). Additionally, an audit_watch may exist
55 * temporarily to assist in searching existing filter data. Each
56 * audit_krule holds a reference to its associated watch.
57 */
58
59struct audit_parent {
60 struct list_head ilist; /* entry in inotify registration list */
61 struct list_head watches; /* associated watches */
62 struct inotify_watch wdata; /* inotify watch data */
63 unsigned flags; /* status flags */
64};
65
66/*
67 * audit_parent status flags:
68 *
69 * AUDIT_PARENT_INVALID - set anytime rules/watches are auto-removed due to
70 * a filesystem event to ensure we're adding audit watches to a valid parent.
71 * Technically not needed for IN_DELETE_SELF or IN_UNMOUNT events, as we cannot
72 * receive them while we have nameidata, but must be used for IN_MOVE_SELF which
73 * we can receive while holding nameidata.
74 */
75#define AUDIT_PARENT_INVALID 0x001
76
77/* Audit filter lists, defined in <linux/audit.h> */
32struct list_head audit_filter_list[AUDIT_NR_FILTERS] = { 78struct list_head audit_filter_list[AUDIT_NR_FILTERS] = {
33 LIST_HEAD_INIT(audit_filter_list[0]), 79 LIST_HEAD_INIT(audit_filter_list[0]),
34 LIST_HEAD_INIT(audit_filter_list[1]), 80 LIST_HEAD_INIT(audit_filter_list[1]),
@@ -41,9 +87,53 @@ struct list_head audit_filter_list[AUDIT_NR_FILTERS] = {
41#endif 87#endif
42}; 88};
43 89
90static DEFINE_MUTEX(audit_filter_mutex);
91
92/* Inotify handle */
93extern struct inotify_handle *audit_ih;
94
95/* Inotify events we care about. */
96#define AUDIT_IN_WATCH IN_MOVE|IN_CREATE|IN_DELETE|IN_DELETE_SELF|IN_MOVE_SELF
97
98void audit_free_parent(struct inotify_watch *i_watch)
99{
100 struct audit_parent *parent;
101
102 parent = container_of(i_watch, struct audit_parent, wdata);
103 WARN_ON(!list_empty(&parent->watches));
104 kfree(parent);
105}
106
107static inline void audit_get_watch(struct audit_watch *watch)
108{
109 atomic_inc(&watch->count);
110}
111
112static void audit_put_watch(struct audit_watch *watch)
113{
114 if (atomic_dec_and_test(&watch->count)) {
115 WARN_ON(watch->parent);
116 WARN_ON(!list_empty(&watch->rules));
117 kfree(watch->path);
118 kfree(watch);
119 }
120}
121
122static void audit_remove_watch(struct audit_watch *watch)
123{
124 list_del(&watch->wlist);
125 put_inotify_watch(&watch->parent->wdata);
126 watch->parent = NULL;
127 audit_put_watch(watch); /* match initial get */
128}
129
44static inline void audit_free_rule(struct audit_entry *e) 130static inline void audit_free_rule(struct audit_entry *e)
45{ 131{
46 int i; 132 int i;
133
134 /* some rules don't have associated watches */
135 if (e->rule.watch)
136 audit_put_watch(e->rule.watch);
47 if (e->rule.fields) 137 if (e->rule.fields)
48 for (i = 0; i < e->rule.field_count; i++) { 138 for (i = 0; i < e->rule.field_count; i++) {
49 struct audit_field *f = &e->rule.fields[i]; 139 struct audit_field *f = &e->rule.fields[i];
@@ -60,6 +150,50 @@ static inline void audit_free_rule_rcu(struct rcu_head *head)
60 audit_free_rule(e); 150 audit_free_rule(e);
61} 151}
62 152
153/* Initialize a parent watch entry. */
154static struct audit_parent *audit_init_parent(struct nameidata *ndp)
155{
156 struct audit_parent *parent;
157 s32 wd;
158
159 parent = kzalloc(sizeof(*parent), GFP_KERNEL);
160 if (unlikely(!parent))
161 return ERR_PTR(-ENOMEM);
162
163 INIT_LIST_HEAD(&parent->watches);
164 parent->flags = 0;
165
166 inotify_init_watch(&parent->wdata);
167 /* grab a ref so inotify watch hangs around until we take audit_filter_mutex */
168 get_inotify_watch(&parent->wdata);
169 wd = inotify_add_watch(audit_ih, &parent->wdata, ndp->dentry->d_inode,
170 AUDIT_IN_WATCH);
171 if (wd < 0) {
172 audit_free_parent(&parent->wdata);
173 return ERR_PTR(wd);
174 }
175
176 return parent;
177}
178
179/* Initialize a watch entry. */
180static struct audit_watch *audit_init_watch(char *path)
181{
182 struct audit_watch *watch;
183
184 watch = kzalloc(sizeof(*watch), GFP_KERNEL);
185 if (unlikely(!watch))
186 return ERR_PTR(-ENOMEM);
187
188 INIT_LIST_HEAD(&watch->rules);
189 atomic_set(&watch->count, 1);
190 watch->path = path;
191 watch->dev = (dev_t)-1;
192 watch->ino = (unsigned long)-1;
193
194 return watch;
195}
196
63/* Initialize an audit filterlist entry. */ 197/* Initialize an audit filterlist entry. */
64static inline struct audit_entry *audit_init_entry(u32 field_count) 198static inline struct audit_entry *audit_init_entry(u32 field_count)
65{ 199{
@@ -107,6 +241,43 @@ static char *audit_unpack_string(void **bufp, size_t *remain, size_t len)
107 return str; 241 return str;
108} 242}
109 243
244/* Translate an inode field to kernel respresentation. */
245static inline int audit_to_inode(struct audit_krule *krule,
246 struct audit_field *f)
247{
248 if (krule->listnr != AUDIT_FILTER_EXIT ||
249 krule->watch || krule->inode_f)
250 return -EINVAL;
251
252 krule->inode_f = f;
253 return 0;
254}
255
256/* Translate a watch string to kernel respresentation. */
257static int audit_to_watch(struct audit_krule *krule, char *path, int len,
258 u32 op)
259{
260 struct audit_watch *watch;
261
262 if (!audit_ih)
263 return -EOPNOTSUPP;
264
265 if (path[0] != '/' || path[len-1] == '/' ||
266 krule->listnr != AUDIT_FILTER_EXIT ||
267 op & ~AUDIT_EQUAL ||
268 krule->inode_f || krule->watch) /* 1 inode # per rule, for hash */
269 return -EINVAL;
270
271 watch = audit_init_watch(path);
272 if (unlikely(IS_ERR(watch)))
273 return PTR_ERR(watch);
274
275 audit_get_watch(watch);
276 krule->watch = watch;
277
278 return 0;
279}
280
110/* Common user-space to kernel rule translation. */ 281/* Common user-space to kernel rule translation. */
111static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule) 282static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule)
112{ 283{
@@ -161,6 +332,7 @@ exit_err:
161static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule) 332static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
162{ 333{
163 struct audit_entry *entry; 334 struct audit_entry *entry;
335 struct audit_field *f;
164 int err = 0; 336 int err = 0;
165 int i; 337 int i;
166 338
@@ -175,14 +347,23 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
175 f->type = rule->fields[i] & ~(AUDIT_NEGATE|AUDIT_OPERATORS); 347 f->type = rule->fields[i] & ~(AUDIT_NEGATE|AUDIT_OPERATORS);
176 f->val = rule->values[i]; 348 f->val = rule->values[i];
177 349
178 if (f->type & AUDIT_UNUSED_BITS || 350 err = -EINVAL;
179 f->type == AUDIT_SE_USER || 351 if (f->type & AUDIT_UNUSED_BITS)
180 f->type == AUDIT_SE_ROLE || 352 goto exit_free;
181 f->type == AUDIT_SE_TYPE || 353
182 f->type == AUDIT_SE_SEN || 354 switch(f->type) {
183 f->type == AUDIT_SE_CLR) { 355 case AUDIT_SE_USER:
184 err = -EINVAL; 356 case AUDIT_SE_ROLE:
357 case AUDIT_SE_TYPE:
358 case AUDIT_SE_SEN:
359 case AUDIT_SE_CLR:
360 case AUDIT_WATCH:
185 goto exit_free; 361 goto exit_free;
362 case AUDIT_INODE:
363 err = audit_to_inode(&entry->rule, f);
364 if (err)
365 goto exit_free;
366 break;
186 } 367 }
187 368
188 entry->rule.vers_ops = (f->op & AUDIT_OPERATORS) ? 2 : 1; 369 entry->rule.vers_ops = (f->op & AUDIT_OPERATORS) ? 2 : 1;
@@ -199,6 +380,18 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
199 } 380 }
200 } 381 }
201 382
383 f = entry->rule.inode_f;
384 if (f) {
385 switch(f->op) {
386 case AUDIT_NOT_EQUAL:
387 entry->rule.inode_f = NULL;
388 case AUDIT_EQUAL:
389 break;
390 default:
391 goto exit_free;
392 }
393 }
394
202exit_nofree: 395exit_nofree:
203 return entry; 396 return entry;
204 397
@@ -213,6 +406,7 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
213{ 406{
214 int err = 0; 407 int err = 0;
215 struct audit_entry *entry; 408 struct audit_entry *entry;
409 struct audit_field *f;
216 void *bufp; 410 void *bufp;
217 size_t remain = datasz - sizeof(struct audit_rule_data); 411 size_t remain = datasz - sizeof(struct audit_rule_data);
218 int i; 412 int i;
@@ -263,6 +457,35 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
263 } else 457 } else
264 f->se_str = str; 458 f->se_str = str;
265 break; 459 break;
460 case AUDIT_WATCH:
461 str = audit_unpack_string(&bufp, &remain, f->val);
462 if (IS_ERR(str))
463 goto exit_free;
464 entry->rule.buflen += f->val;
465
466 err = audit_to_watch(&entry->rule, str, f->val, f->op);
467 if (err) {
468 kfree(str);
469 goto exit_free;
470 }
471 break;
472 case AUDIT_INODE:
473 err = audit_to_inode(&entry->rule, f);
474 if (err)
475 goto exit_free;
476 break;
477 }
478 }
479
480 f = entry->rule.inode_f;
481 if (f) {
482 switch(f->op) {
483 case AUDIT_NOT_EQUAL:
484 entry->rule.inode_f = NULL;
485 case AUDIT_EQUAL:
486 break;
487 default:
488 goto exit_free;
266 } 489 }
267 } 490 }
268 491
@@ -346,6 +569,10 @@ static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule)
346 data->buflen += data->values[i] = 569 data->buflen += data->values[i] =
347 audit_pack_string(&bufp, f->se_str); 570 audit_pack_string(&bufp, f->se_str);
348 break; 571 break;
572 case AUDIT_WATCH:
573 data->buflen += data->values[i] =
574 audit_pack_string(&bufp, krule->watch->path);
575 break;
349 default: 576 default:
350 data->values[i] = f->val; 577 data->values[i] = f->val;
351 } 578 }
@@ -381,6 +608,10 @@ static int audit_compare_rule(struct audit_krule *a, struct audit_krule *b)
381 if (strcmp(a->fields[i].se_str, b->fields[i].se_str)) 608 if (strcmp(a->fields[i].se_str, b->fields[i].se_str))
382 return 1; 609 return 1;
383 break; 610 break;
611 case AUDIT_WATCH:
612 if (strcmp(a->watch->path, b->watch->path))
613 return 1;
614 break;
384 default: 615 default:
385 if (a->fields[i].val != b->fields[i].val) 616 if (a->fields[i].val != b->fields[i].val)
386 return 1; 617 return 1;
@@ -394,6 +625,32 @@ static int audit_compare_rule(struct audit_krule *a, struct audit_krule *b)
394 return 0; 625 return 0;
395} 626}
396 627
628/* Duplicate the given audit watch. The new watch's rules list is initialized
629 * to an empty list and wlist is undefined. */
630static struct audit_watch *audit_dupe_watch(struct audit_watch *old)
631{
632 char *path;
633 struct audit_watch *new;
634
635 path = kstrdup(old->path, GFP_KERNEL);
636 if (unlikely(!path))
637 return ERR_PTR(-ENOMEM);
638
639 new = audit_init_watch(path);
640 if (unlikely(IS_ERR(new))) {
641 kfree(path);
642 goto out;
643 }
644
645 new->dev = old->dev;
646 new->ino = old->ino;
647 get_inotify_watch(&old->parent->wdata);
648 new->parent = old->parent;
649
650out:
651 return new;
652}
653
397/* Duplicate selinux field information. The se_rule is opaque, so must be 654/* Duplicate selinux field information. The se_rule is opaque, so must be
398 * re-initialized. */ 655 * re-initialized. */
399static inline int audit_dupe_selinux_field(struct audit_field *df, 656static inline int audit_dupe_selinux_field(struct audit_field *df,
@@ -425,8 +682,11 @@ static inline int audit_dupe_selinux_field(struct audit_field *df,
425/* Duplicate an audit rule. This will be a deep copy with the exception 682/* Duplicate an audit rule. This will be a deep copy with the exception
426 * of the watch - that pointer is carried over. The selinux specific fields 683 * of the watch - that pointer is carried over. The selinux specific fields
427 * will be updated in the copy. The point is to be able to replace the old 684 * will be updated in the copy. The point is to be able to replace the old
428 * rule with the new rule in the filterlist, then free the old rule. */ 685 * rule with the new rule in the filterlist, then free the old rule.
429static struct audit_entry *audit_dupe_rule(struct audit_krule *old) 686 * The rlist element is undefined; list manipulations are handled apart from
687 * the initial copy. */
688static struct audit_entry *audit_dupe_rule(struct audit_krule *old,
689 struct audit_watch *watch)
430{ 690{
431 u32 fcount = old->field_count; 691 u32 fcount = old->field_count;
432 struct audit_entry *entry; 692 struct audit_entry *entry;
@@ -445,6 +705,8 @@ static struct audit_entry *audit_dupe_rule(struct audit_krule *old)
445 for (i = 0; i < AUDIT_BITMASK_SIZE; i++) 705 for (i = 0; i < AUDIT_BITMASK_SIZE; i++)
446 new->mask[i] = old->mask[i]; 706 new->mask[i] = old->mask[i];
447 new->buflen = old->buflen; 707 new->buflen = old->buflen;
708 new->inode_f = old->inode_f;
709 new->watch = NULL;
448 new->field_count = old->field_count; 710 new->field_count = old->field_count;
449 memcpy(new->fields, old->fields, sizeof(struct audit_field) * fcount); 711 memcpy(new->fields, old->fields, sizeof(struct audit_field) * fcount);
450 712
@@ -466,21 +728,318 @@ static struct audit_entry *audit_dupe_rule(struct audit_krule *old)
466 } 728 }
467 } 729 }
468 730
731 if (watch) {
732 audit_get_watch(watch);
733 new->watch = watch;
734 }
735
469 return entry; 736 return entry;
470} 737}
471 738
472/* Add rule to given filterlist if not a duplicate. Protected by 739/* Update inode info in audit rules based on filesystem event. */
473 * audit_netlink_mutex. */ 740static void audit_update_watch(struct audit_parent *parent,
741 const char *dname, dev_t dev,
742 unsigned long ino, unsigned invalidating)
743{
744 struct audit_watch *owatch, *nwatch, *nextw;
745 struct audit_krule *r, *nextr;
746 struct audit_entry *oentry, *nentry;
747 struct audit_buffer *ab;
748
749 mutex_lock(&audit_filter_mutex);
750 list_for_each_entry_safe(owatch, nextw, &parent->watches, wlist) {
751 if (audit_compare_dname_path(dname, owatch->path))
752 continue;
753
754 /* If the update involves invalidating rules, do the inode-based
755 * filtering now, so we don't omit records. */
756 if (invalidating &&
757 audit_filter_inodes(current, current->audit_context) == AUDIT_RECORD_CONTEXT)
758 audit_set_auditable(current->audit_context);
759
760 nwatch = audit_dupe_watch(owatch);
761 if (unlikely(IS_ERR(nwatch))) {
762 mutex_unlock(&audit_filter_mutex);
763 audit_panic("error updating watch, skipping");
764 return;
765 }
766 nwatch->dev = dev;
767 nwatch->ino = ino;
768
769 list_for_each_entry_safe(r, nextr, &owatch->rules, rlist) {
770
771 oentry = container_of(r, struct audit_entry, rule);
772 list_del(&oentry->rule.rlist);
773 list_del_rcu(&oentry->list);
774
775 nentry = audit_dupe_rule(&oentry->rule, nwatch);
776 if (unlikely(IS_ERR(nentry)))
777 audit_panic("error updating watch, removing");
778 else {
779 int h = audit_hash_ino((u32)ino);
780 list_add(&nentry->rule.rlist, &nwatch->rules);
781 list_add_rcu(&nentry->list, &audit_inode_hash[h]);
782 }
783
784 call_rcu(&oentry->rcu, audit_free_rule_rcu);
785 }
786
787 ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
788 audit_log_format(ab, "audit updated rules specifying watch=");
789 audit_log_untrustedstring(ab, owatch->path);
790 audit_log_format(ab, " with dev=%u ino=%lu\n", dev, ino);
791 audit_log_end(ab);
792
793 audit_remove_watch(owatch);
794 goto add_watch_to_parent; /* event applies to a single watch */
795 }
796 mutex_unlock(&audit_filter_mutex);
797 return;
798
799add_watch_to_parent:
800 list_add(&nwatch->wlist, &parent->watches);
801 mutex_unlock(&audit_filter_mutex);
802 return;
803}
804
805/* Remove all watches & rules associated with a parent that is going away. */
806static void audit_remove_parent_watches(struct audit_parent *parent)
807{
808 struct audit_watch *w, *nextw;
809 struct audit_krule *r, *nextr;
810 struct audit_entry *e;
811
812 mutex_lock(&audit_filter_mutex);
813 parent->flags |= AUDIT_PARENT_INVALID;
814 list_for_each_entry_safe(w, nextw, &parent->watches, wlist) {
815 list_for_each_entry_safe(r, nextr, &w->rules, rlist) {
816 e = container_of(r, struct audit_entry, rule);
817 list_del(&r->rlist);
818 list_del_rcu(&e->list);
819 call_rcu(&e->rcu, audit_free_rule_rcu);
820
821 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
822 "audit implicitly removed rule from list=%d\n",
823 AUDIT_FILTER_EXIT);
824 }
825 audit_remove_watch(w);
826 }
827 mutex_unlock(&audit_filter_mutex);
828}
829
830/* Unregister inotify watches for parents on in_list.
831 * Generates an IN_IGNORED event. */
832static void audit_inotify_unregister(struct list_head *in_list)
833{
834 struct audit_parent *p, *n;
835
836 list_for_each_entry_safe(p, n, in_list, ilist) {
837 list_del(&p->ilist);
838 inotify_rm_watch(audit_ih, &p->wdata);
839 /* the put matching the get in audit_do_del_rule() */
840 put_inotify_watch(&p->wdata);
841 }
842}
843
844/* Find an existing audit rule.
845 * Caller must hold audit_filter_mutex to prevent stale rule data. */
846static struct audit_entry *audit_find_rule(struct audit_entry *entry,
847 struct list_head *list)
848{
849 struct audit_entry *e, *found = NULL;
850 int h;
851
852 if (entry->rule.watch) {
853 /* we don't know the inode number, so must walk entire hash */
854 for (h = 0; h < AUDIT_INODE_BUCKETS; h++) {
855 list = &audit_inode_hash[h];
856 list_for_each_entry(e, list, list)
857 if (!audit_compare_rule(&entry->rule, &e->rule)) {
858 found = e;
859 goto out;
860 }
861 }
862 goto out;
863 }
864
865 list_for_each_entry(e, list, list)
866 if (!audit_compare_rule(&entry->rule, &e->rule)) {
867 found = e;
868 goto out;
869 }
870
871out:
872 return found;
873}
874
875/* Get path information necessary for adding watches. */
876static int audit_get_nd(char *path, struct nameidata **ndp,
877 struct nameidata **ndw)
878{
879 struct nameidata *ndparent, *ndwatch;
880 int err;
881
882 ndparent = kmalloc(sizeof(*ndparent), GFP_KERNEL);
883 if (unlikely(!ndparent))
884 return -ENOMEM;
885
886 ndwatch = kmalloc(sizeof(*ndwatch), GFP_KERNEL);
887 if (unlikely(!ndwatch)) {
888 kfree(ndparent);
889 return -ENOMEM;
890 }
891
892 err = path_lookup(path, LOOKUP_PARENT, ndparent);
893 if (err) {
894 kfree(ndparent);
895 kfree(ndwatch);
896 return err;
897 }
898
899 err = path_lookup(path, 0, ndwatch);
900 if (err) {
901 kfree(ndwatch);
902 ndwatch = NULL;
903 }
904
905 *ndp = ndparent;
906 *ndw = ndwatch;
907
908 return 0;
909}
910
911/* Release resources used for watch path information. */
912static void audit_put_nd(struct nameidata *ndp, struct nameidata *ndw)
913{
914 if (ndp) {
915 path_release(ndp);
916 kfree(ndp);
917 }
918 if (ndw) {
919 path_release(ndw);
920 kfree(ndw);
921 }
922}
923
924/* Associate the given rule with an existing parent inotify_watch.
925 * Caller must hold audit_filter_mutex. */
926static void audit_add_to_parent(struct audit_krule *krule,
927 struct audit_parent *parent)
928{
929 struct audit_watch *w, *watch = krule->watch;
930 int watch_found = 0;
931
932 list_for_each_entry(w, &parent->watches, wlist) {
933 if (strcmp(watch->path, w->path))
934 continue;
935
936 watch_found = 1;
937
938 /* put krule's and initial refs to temporary watch */
939 audit_put_watch(watch);
940 audit_put_watch(watch);
941
942 audit_get_watch(w);
943 krule->watch = watch = w;
944 break;
945 }
946
947 if (!watch_found) {
948 get_inotify_watch(&parent->wdata);
949 watch->parent = parent;
950
951 list_add(&watch->wlist, &parent->watches);
952 }
953 list_add(&krule->rlist, &watch->rules);
954}
955
956/* Find a matching watch entry, or add this one.
957 * Caller must hold audit_filter_mutex. */
958static int audit_add_watch(struct audit_krule *krule, struct nameidata *ndp,
959 struct nameidata *ndw)
960{
961 struct audit_watch *watch = krule->watch;
962 struct inotify_watch *i_watch;
963 struct audit_parent *parent;
964 int ret = 0;
965
966 /* update watch filter fields */
967 if (ndw) {
968 watch->dev = ndw->dentry->d_inode->i_sb->s_dev;
969 watch->ino = ndw->dentry->d_inode->i_ino;
970 }
971
972 /* The audit_filter_mutex must not be held during inotify calls because
973 * we hold it during inotify event callback processing. If an existing
974 * inotify watch is found, inotify_find_watch() grabs a reference before
975 * returning.
976 */
977 mutex_unlock(&audit_filter_mutex);
978
979 if (inotify_find_watch(audit_ih, ndp->dentry->d_inode, &i_watch) < 0) {
980 parent = audit_init_parent(ndp);
981 if (IS_ERR(parent)) {
982 /* caller expects mutex locked */
983 mutex_lock(&audit_filter_mutex);
984 return PTR_ERR(parent);
985 }
986 } else
987 parent = container_of(i_watch, struct audit_parent, wdata);
988
989 mutex_lock(&audit_filter_mutex);
990
991 /* parent was moved before we took audit_filter_mutex */
992 if (parent->flags & AUDIT_PARENT_INVALID)
993 ret = -ENOENT;
994 else
995 audit_add_to_parent(krule, parent);
996
997 /* match get in audit_init_parent or inotify_find_watch */
998 put_inotify_watch(&parent->wdata);
999 return ret;
1000}
1001
1002/* Add rule to given filterlist if not a duplicate. */
474static inline int audit_add_rule(struct audit_entry *entry, 1003static inline int audit_add_rule(struct audit_entry *entry,
475 struct list_head *list) 1004 struct list_head *list)
476{ 1005{
477 struct audit_entry *e; 1006 struct audit_entry *e;
1007 struct audit_field *inode_f = entry->rule.inode_f;
1008 struct audit_watch *watch = entry->rule.watch;
1009 struct nameidata *ndp, *ndw;
1010 int h, err, putnd_needed = 0;
1011
1012 if (inode_f) {
1013 h = audit_hash_ino(inode_f->val);
1014 list = &audit_inode_hash[h];
1015 }
1016
1017 mutex_lock(&audit_filter_mutex);
1018 e = audit_find_rule(entry, list);
1019 mutex_unlock(&audit_filter_mutex);
1020 if (e) {
1021 err = -EEXIST;
1022 goto error;
1023 }
478 1024
479 /* Do not use the _rcu iterator here, since this is the only 1025 /* Avoid calling path_lookup under audit_filter_mutex. */
480 * addition routine. */ 1026 if (watch) {
481 list_for_each_entry(e, list, list) { 1027 err = audit_get_nd(watch->path, &ndp, &ndw);
482 if (!audit_compare_rule(&entry->rule, &e->rule)) 1028 if (err)
483 return -EEXIST; 1029 goto error;
1030 putnd_needed = 1;
1031 }
1032
1033 mutex_lock(&audit_filter_mutex);
1034 if (watch) {
1035 /* audit_filter_mutex is dropped and re-taken during this call */
1036 err = audit_add_watch(&entry->rule, ndp, ndw);
1037 if (err) {
1038 mutex_unlock(&audit_filter_mutex);
1039 goto error;
1040 }
1041 h = audit_hash_ino((u32)watch->ino);
1042 list = &audit_inode_hash[h];
484 } 1043 }
485 1044
486 if (entry->rule.flags & AUDIT_FILTER_PREPEND) { 1045 if (entry->rule.flags & AUDIT_FILTER_PREPEND) {
@@ -488,27 +1047,77 @@ static inline int audit_add_rule(struct audit_entry *entry,
488 } else { 1047 } else {
489 list_add_tail_rcu(&entry->list, list); 1048 list_add_tail_rcu(&entry->list, list);
490 } 1049 }
1050 mutex_unlock(&audit_filter_mutex);
491 1051
492 return 0; 1052 if (putnd_needed)
1053 audit_put_nd(ndp, ndw);
1054
1055 return 0;
1056
1057error:
1058 if (putnd_needed)
1059 audit_put_nd(ndp, ndw);
1060 if (watch)
1061 audit_put_watch(watch); /* tmp watch, matches initial get */
1062 return err;
493} 1063}
494 1064
495/* Remove an existing rule from filterlist. Protected by 1065/* Remove an existing rule from filterlist. */
496 * audit_netlink_mutex. */
497static inline int audit_del_rule(struct audit_entry *entry, 1066static inline int audit_del_rule(struct audit_entry *entry,
498 struct list_head *list) 1067 struct list_head *list)
499{ 1068{
500 struct audit_entry *e; 1069 struct audit_entry *e;
1070 struct audit_field *inode_f = entry->rule.inode_f;
1071 struct audit_watch *watch, *tmp_watch = entry->rule.watch;
1072 LIST_HEAD(inotify_list);
1073 int h, ret = 0;
1074
1075 if (inode_f) {
1076 h = audit_hash_ino(inode_f->val);
1077 list = &audit_inode_hash[h];
1078 }
501 1079
502 /* Do not use the _rcu iterator here, since this is the only 1080 mutex_lock(&audit_filter_mutex);
503 * deletion routine. */ 1081 e = audit_find_rule(entry, list);
504 list_for_each_entry(e, list, list) { 1082 if (!e) {
505 if (!audit_compare_rule(&entry->rule, &e->rule)) { 1083 mutex_unlock(&audit_filter_mutex);
506 list_del_rcu(&e->list); 1084 ret = -ENOENT;
507 call_rcu(&e->rcu, audit_free_rule_rcu); 1085 goto out;
508 return 0; 1086 }
1087
1088 watch = e->rule.watch;
1089 if (watch) {
1090 struct audit_parent *parent = watch->parent;
1091
1092 list_del(&e->rule.rlist);
1093
1094 if (list_empty(&watch->rules)) {
1095 audit_remove_watch(watch);
1096
1097 if (list_empty(&parent->watches)) {
1098 /* Put parent on the inotify un-registration
1099 * list. Grab a reference before releasing
1100 * audit_filter_mutex, to be released in
1101 * audit_inotify_unregister(). */
1102 list_add(&parent->ilist, &inotify_list);
1103 get_inotify_watch(&parent->wdata);
1104 }
509 } 1105 }
510 } 1106 }
511 return -ENOENT; /* No matching rule */ 1107
1108 list_del_rcu(&e->list);
1109 call_rcu(&e->rcu, audit_free_rule_rcu);
1110
1111 mutex_unlock(&audit_filter_mutex);
1112
1113 if (!list_empty(&inotify_list))
1114 audit_inotify_unregister(&inotify_list);
1115
1116out:
1117 if (tmp_watch)
1118 audit_put_watch(tmp_watch); /* match initial get */
1119
1120 return ret;
512} 1121}
513 1122
514/* List rules using struct audit_rule. Exists for backward 1123/* List rules using struct audit_rule. Exists for backward
@@ -519,8 +1128,8 @@ static void audit_list(int pid, int seq, struct sk_buff_head *q)
519 struct audit_entry *entry; 1128 struct audit_entry *entry;
520 int i; 1129 int i;
521 1130
522 /* The *_rcu iterators not needed here because we are 1131 /* This is a blocking read, so use audit_filter_mutex instead of rcu
523 always called with audit_netlink_mutex held. */ 1132 * iterator to sync with list writers. */
524 for (i=0; i<AUDIT_NR_FILTERS; i++) { 1133 for (i=0; i<AUDIT_NR_FILTERS; i++) {
525 list_for_each_entry(entry, &audit_filter_list[i], list) { 1134 list_for_each_entry(entry, &audit_filter_list[i], list) {
526 struct audit_rule *rule; 1135 struct audit_rule *rule;
@@ -535,6 +1144,20 @@ static void audit_list(int pid, int seq, struct sk_buff_head *q)
535 kfree(rule); 1144 kfree(rule);
536 } 1145 }
537 } 1146 }
1147 for (i = 0; i < AUDIT_INODE_BUCKETS; i++) {
1148 list_for_each_entry(entry, &audit_inode_hash[i], list) {
1149 struct audit_rule *rule;
1150
1151 rule = audit_krule_to_rule(&entry->rule);
1152 if (unlikely(!rule))
1153 break;
1154 skb = audit_make_reply(pid, seq, AUDIT_LIST, 0, 1,
1155 rule, sizeof(*rule));
1156 if (skb)
1157 skb_queue_tail(q, skb);
1158 kfree(rule);
1159 }
1160 }
538 skb = audit_make_reply(pid, seq, AUDIT_LIST, 1, 1, NULL, 0); 1161 skb = audit_make_reply(pid, seq, AUDIT_LIST, 1, 1, NULL, 0);
539 if (skb) 1162 if (skb)
540 skb_queue_tail(q, skb); 1163 skb_queue_tail(q, skb);
@@ -547,8 +1170,8 @@ static void audit_list_rules(int pid, int seq, struct sk_buff_head *q)
547 struct audit_entry *e; 1170 struct audit_entry *e;
548 int i; 1171 int i;
549 1172
550 /* The *_rcu iterators not needed here because we are 1173 /* This is a blocking read, so use audit_filter_mutex instead of rcu
551 always called with audit_netlink_mutex held. */ 1174 * iterator to sync with list writers. */
552 for (i=0; i<AUDIT_NR_FILTERS; i++) { 1175 for (i=0; i<AUDIT_NR_FILTERS; i++) {
553 list_for_each_entry(e, &audit_filter_list[i], list) { 1176 list_for_each_entry(e, &audit_filter_list[i], list) {
554 struct audit_rule_data *data; 1177 struct audit_rule_data *data;
@@ -557,7 +1180,21 @@ static void audit_list_rules(int pid, int seq, struct sk_buff_head *q)
557 if (unlikely(!data)) 1180 if (unlikely(!data))
558 break; 1181 break;
559 skb = audit_make_reply(pid, seq, AUDIT_LIST_RULES, 0, 1, 1182 skb = audit_make_reply(pid, seq, AUDIT_LIST_RULES, 0, 1,
560 data, sizeof(*data)); 1183 data, sizeof(*data) + data->buflen);
1184 if (skb)
1185 skb_queue_tail(q, skb);
1186 kfree(data);
1187 }
1188 }
1189 for (i=0; i< AUDIT_INODE_BUCKETS; i++) {
1190 list_for_each_entry(e, &audit_inode_hash[i], list) {
1191 struct audit_rule_data *data;
1192
1193 data = audit_krule_to_data(&e->rule);
1194 if (unlikely(!data))
1195 break;
1196 skb = audit_make_reply(pid, seq, AUDIT_LIST_RULES, 0, 1,
1197 data, sizeof(*data) + data->buflen);
561 if (skb) 1198 if (skb)
562 skb_queue_tail(q, skb); 1199 skb_queue_tail(q, skb);
563 kfree(data); 1200 kfree(data);
@@ -602,10 +1239,12 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
602 dest->pid = pid; 1239 dest->pid = pid;
603 skb_queue_head_init(&dest->q); 1240 skb_queue_head_init(&dest->q);
604 1241
1242 mutex_lock(&audit_filter_mutex);
605 if (type == AUDIT_LIST) 1243 if (type == AUDIT_LIST)
606 audit_list(pid, seq, &dest->q); 1244 audit_list(pid, seq, &dest->q);
607 else 1245 else
608 audit_list_rules(pid, seq, &dest->q); 1246 audit_list_rules(pid, seq, &dest->q);
1247 mutex_unlock(&audit_filter_mutex);
609 1248
610 tsk = kthread_run(audit_send_list, dest, "audit_send_list"); 1249 tsk = kthread_run(audit_send_list, dest, "audit_send_list");
611 if (IS_ERR(tsk)) { 1250 if (IS_ERR(tsk)) {
@@ -625,6 +1264,7 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
625 1264
626 err = audit_add_rule(entry, 1265 err = audit_add_rule(entry,
627 &audit_filter_list[entry->rule.listnr]); 1266 &audit_filter_list[entry->rule.listnr]);
1267
628 if (sid) { 1268 if (sid) {
629 char *ctx = NULL; 1269 char *ctx = NULL;
630 u32 len; 1270 u32 len;
@@ -705,7 +1345,39 @@ int audit_comparator(const u32 left, const u32 op, const u32 right)
705 return 0; 1345 return 0;
706} 1346}
707 1347
1348/* Compare given dentry name with last component in given path,
1349 * return of 0 indicates a match. */
1350int audit_compare_dname_path(const char *dname, const char *path)
1351{
1352 int dlen, plen;
1353 const char *p;
1354
1355 if (!dname || !path)
1356 return 1;
1357
1358 dlen = strlen(dname);
1359 plen = strlen(path);
1360 if (plen < dlen)
1361 return 1;
1362
1363 /* disregard trailing slashes */
1364 p = path + plen - 1;
1365 while ((*p == '/') && (p > path))
1366 p--;
1367
1368 /* find last path component */
1369 p = p - dlen + 1;
1370 if (p < path)
1371 return 1;
1372 else if (p > path) {
1373 if (*--p != '/')
1374 return 1;
1375 else
1376 p++;
1377 }
708 1378
1379 return strncmp(p, dname, dlen);
1380}
709 1381
710static int audit_filter_user_rules(struct netlink_skb_parms *cb, 1382static int audit_filter_user_rules(struct netlink_skb_parms *cb,
711 struct audit_krule *rule, 1383 struct audit_krule *rule,
@@ -818,32 +1490,65 @@ static inline int audit_rule_has_selinux(struct audit_krule *rule)
818int selinux_audit_rule_update(void) 1490int selinux_audit_rule_update(void)
819{ 1491{
820 struct audit_entry *entry, *n, *nentry; 1492 struct audit_entry *entry, *n, *nentry;
1493 struct audit_watch *watch;
821 int i, err = 0; 1494 int i, err = 0;
822 1495
823 /* audit_netlink_mutex synchronizes the writers */ 1496 /* audit_filter_mutex synchronizes the writers */
824 mutex_lock(&audit_netlink_mutex); 1497 mutex_lock(&audit_filter_mutex);
825 1498
826 for (i = 0; i < AUDIT_NR_FILTERS; i++) { 1499 for (i = 0; i < AUDIT_NR_FILTERS; i++) {
827 list_for_each_entry_safe(entry, n, &audit_filter_list[i], list) { 1500 list_for_each_entry_safe(entry, n, &audit_filter_list[i], list) {
828 if (!audit_rule_has_selinux(&entry->rule)) 1501 if (!audit_rule_has_selinux(&entry->rule))
829 continue; 1502 continue;
830 1503
831 nentry = audit_dupe_rule(&entry->rule); 1504 watch = entry->rule.watch;
1505 nentry = audit_dupe_rule(&entry->rule, watch);
832 if (unlikely(IS_ERR(nentry))) { 1506 if (unlikely(IS_ERR(nentry))) {
833 /* save the first error encountered for the 1507 /* save the first error encountered for the
834 * return value */ 1508 * return value */
835 if (!err) 1509 if (!err)
836 err = PTR_ERR(nentry); 1510 err = PTR_ERR(nentry);
837 audit_panic("error updating selinux filters"); 1511 audit_panic("error updating selinux filters");
1512 if (watch)
1513 list_del(&entry->rule.rlist);
838 list_del_rcu(&entry->list); 1514 list_del_rcu(&entry->list);
839 } else { 1515 } else {
1516 if (watch) {
1517 list_add(&nentry->rule.rlist,
1518 &watch->rules);
1519 list_del(&entry->rule.rlist);
1520 }
840 list_replace_rcu(&entry->list, &nentry->list); 1521 list_replace_rcu(&entry->list, &nentry->list);
841 } 1522 }
842 call_rcu(&entry->rcu, audit_free_rule_rcu); 1523 call_rcu(&entry->rcu, audit_free_rule_rcu);
843 } 1524 }
844 } 1525 }
845 1526
846 mutex_unlock(&audit_netlink_mutex); 1527 mutex_unlock(&audit_filter_mutex);
847 1528
848 return err; 1529 return err;
849} 1530}
1531
1532/* Update watch data in audit rules based on inotify events. */
1533void audit_handle_ievent(struct inotify_watch *i_watch, u32 wd, u32 mask,
1534 u32 cookie, const char *dname, struct inode *inode)
1535{
1536 struct audit_parent *parent;
1537
1538 parent = container_of(i_watch, struct audit_parent, wdata);
1539
1540 if (mask & (IN_CREATE|IN_MOVED_TO) && inode)
1541 audit_update_watch(parent, dname, inode->i_sb->s_dev,
1542 inode->i_ino, 0);
1543 else if (mask & (IN_DELETE|IN_MOVED_FROM))
1544 audit_update_watch(parent, dname, (dev_t)-1, (unsigned long)-1, 1);
1545 /* inotify automatically removes the watch and sends IN_IGNORED */
1546 else if (mask & (IN_DELETE_SELF|IN_UNMOUNT))
1547 audit_remove_parent_watches(parent);
1548 /* inotify does not remove the watch, so remove it manually */
1549 else if(mask & IN_MOVE_SELF) {
1550 audit_remove_parent_watches(parent);
1551 inotify_remove_watch_locked(audit_ih, i_watch);
1552 } else if (mask & IN_IGNORED)
1553 put_inotify_watch(i_watch);
1554}
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 14e295a4121b..174a3f624892 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -200,12 +200,13 @@ struct audit_context {
200#endif 200#endif
201}; 201};
202 202
203 203/* Determine if any context name data matches a rule's watch data */
204/* Compare a task_struct with an audit_rule. Return 1 on match, 0 204/* Compare a task_struct with an audit_rule. Return 1 on match, 0
205 * otherwise. */ 205 * otherwise. */
206static int audit_filter_rules(struct task_struct *tsk, 206static int audit_filter_rules(struct task_struct *tsk,
207 struct audit_krule *rule, 207 struct audit_krule *rule,
208 struct audit_context *ctx, 208 struct audit_context *ctx,
209 struct audit_names *name,
209 enum audit_state *state) 210 enum audit_state *state)
210{ 211{
211 int i, j, need_sid = 1; 212 int i, j, need_sid = 1;
@@ -268,7 +269,10 @@ static int audit_filter_rules(struct task_struct *tsk,
268 } 269 }
269 break; 270 break;
270 case AUDIT_DEVMAJOR: 271 case AUDIT_DEVMAJOR:
271 if (ctx) { 272 if (name)
273 result = audit_comparator(MAJOR(name->dev),
274 f->op, f->val);
275 else if (ctx) {
272 for (j = 0; j < ctx->name_count; j++) { 276 for (j = 0; j < ctx->name_count; j++) {
273 if (audit_comparator(MAJOR(ctx->names[j].dev), f->op, f->val)) { 277 if (audit_comparator(MAJOR(ctx->names[j].dev), f->op, f->val)) {
274 ++result; 278 ++result;
@@ -278,7 +282,10 @@ static int audit_filter_rules(struct task_struct *tsk,
278 } 282 }
279 break; 283 break;
280 case AUDIT_DEVMINOR: 284 case AUDIT_DEVMINOR:
281 if (ctx) { 285 if (name)
286 result = audit_comparator(MINOR(name->dev),
287 f->op, f->val);
288 else if (ctx) {
282 for (j = 0; j < ctx->name_count; j++) { 289 for (j = 0; j < ctx->name_count; j++) {
283 if (audit_comparator(MINOR(ctx->names[j].dev), f->op, f->val)) { 290 if (audit_comparator(MINOR(ctx->names[j].dev), f->op, f->val)) {
284 ++result; 291 ++result;
@@ -288,7 +295,10 @@ static int audit_filter_rules(struct task_struct *tsk,
288 } 295 }
289 break; 296 break;
290 case AUDIT_INODE: 297 case AUDIT_INODE:
291 if (ctx) { 298 if (name)
299 result = (name->ino == f->val ||
300 name->pino == f->val);
301 else if (ctx) {
292 for (j = 0; j < ctx->name_count; j++) { 302 for (j = 0; j < ctx->name_count; j++) {
293 if (audit_comparator(ctx->names[j].ino, f->op, f->val) || 303 if (audit_comparator(ctx->names[j].ino, f->op, f->val) ||
294 audit_comparator(ctx->names[j].pino, f->op, f->val)) { 304 audit_comparator(ctx->names[j].pino, f->op, f->val)) {
@@ -298,6 +308,12 @@ static int audit_filter_rules(struct task_struct *tsk,
298 } 308 }
299 } 309 }
300 break; 310 break;
311 case AUDIT_WATCH:
312 if (name && rule->watch->ino != (unsigned long)-1)
313 result = (name->dev == rule->watch->dev &&
314 (name->ino == rule->watch->ino ||
315 name->pino == rule->watch->ino));
316 break;
301 case AUDIT_LOGINUID: 317 case AUDIT_LOGINUID:
302 result = 0; 318 result = 0;
303 if (ctx) 319 if (ctx)
@@ -354,7 +370,7 @@ static enum audit_state audit_filter_task(struct task_struct *tsk)
354 370
355 rcu_read_lock(); 371 rcu_read_lock();
356 list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TASK], list) { 372 list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TASK], list) {
357 if (audit_filter_rules(tsk, &e->rule, NULL, &state)) { 373 if (audit_filter_rules(tsk, &e->rule, NULL, NULL, &state)) {
358 rcu_read_unlock(); 374 rcu_read_unlock();
359 return state; 375 return state;
360 } 376 }
@@ -384,8 +400,9 @@ static enum audit_state audit_filter_syscall(struct task_struct *tsk,
384 int bit = AUDIT_BIT(ctx->major); 400 int bit = AUDIT_BIT(ctx->major);
385 401
386 list_for_each_entry_rcu(e, list, list) { 402 list_for_each_entry_rcu(e, list, list) {
387 if ((e->rule.mask[word] & bit) == bit 403 if ((e->rule.mask[word] & bit) == bit &&
388 && audit_filter_rules(tsk, &e->rule, ctx, &state)) { 404 audit_filter_rules(tsk, &e->rule, ctx, NULL,
405 &state)) {
389 rcu_read_unlock(); 406 rcu_read_unlock();
390 return state; 407 return state;
391 } 408 }
@@ -395,6 +412,49 @@ static enum audit_state audit_filter_syscall(struct task_struct *tsk,
395 return AUDIT_BUILD_CONTEXT; 412 return AUDIT_BUILD_CONTEXT;
396} 413}
397 414
415/* At syscall exit time, this filter is called if any audit_names[] have been
416 * collected during syscall processing. We only check rules in sublists at hash
417 * buckets applicable to the inode numbers in audit_names[].
418 * Regarding audit_state, same rules apply as for audit_filter_syscall().
419 */
420enum audit_state audit_filter_inodes(struct task_struct *tsk,
421 struct audit_context *ctx)
422{
423 int i;
424 struct audit_entry *e;
425 enum audit_state state;
426
427 if (audit_pid && tsk->tgid == audit_pid)
428 return AUDIT_DISABLED;
429
430 rcu_read_lock();
431 for (i = 0; i < ctx->name_count; i++) {
432 int word = AUDIT_WORD(ctx->major);
433 int bit = AUDIT_BIT(ctx->major);
434 struct audit_names *n = &ctx->names[i];
435 int h = audit_hash_ino((u32)n->ino);
436 struct list_head *list = &audit_inode_hash[h];
437
438 if (list_empty(list))
439 continue;
440
441 list_for_each_entry_rcu(e, list, list) {
442 if ((e->rule.mask[word] & bit) == bit &&
443 audit_filter_rules(tsk, &e->rule, ctx, n, &state)) {
444 rcu_read_unlock();
445 return state;
446 }
447 }
448 }
449 rcu_read_unlock();
450 return AUDIT_BUILD_CONTEXT;
451}
452
453void audit_set_auditable(struct audit_context *ctx)
454{
455 ctx->auditable = 1;
456}
457
398static inline struct audit_context *audit_get_context(struct task_struct *tsk, 458static inline struct audit_context *audit_get_context(struct task_struct *tsk,
399 int return_valid, 459 int return_valid,
400 int return_code) 460 int return_code)
@@ -408,11 +468,20 @@ static inline struct audit_context *audit_get_context(struct task_struct *tsk,
408 468
409 if (context->in_syscall && !context->auditable) { 469 if (context->in_syscall && !context->auditable) {
410 enum audit_state state; 470 enum audit_state state;
471
411 state = audit_filter_syscall(tsk, context, &audit_filter_list[AUDIT_FILTER_EXIT]); 472 state = audit_filter_syscall(tsk, context, &audit_filter_list[AUDIT_FILTER_EXIT]);
473 if (state == AUDIT_RECORD_CONTEXT) {
474 context->auditable = 1;
475 goto get_context;
476 }
477
478 state = audit_filter_inodes(tsk, context);
412 if (state == AUDIT_RECORD_CONTEXT) 479 if (state == AUDIT_RECORD_CONTEXT)
413 context->auditable = 1; 480 context->auditable = 1;
481
414 } 482 }
415 483
484get_context:
416 context->pid = tsk->pid; 485 context->pid = tsk->pid;
417 context->ppid = sys_getppid(); /* sic. tsk == current in all cases */ 486 context->ppid = sys_getppid(); /* sic. tsk == current in all cases */
418 context->uid = tsk->uid; 487 context->uid = tsk->uid;
@@ -1142,37 +1211,20 @@ void __audit_inode_child(const char *dname, const struct inode *inode,
1142 return; 1211 return;
1143 1212
1144 /* determine matching parent */ 1213 /* determine matching parent */
1145 if (dname) 1214 if (!dname)
1146 for (idx = 0; idx < context->name_count; idx++) 1215 goto no_match;
1147 if (context->names[idx].pino == pino) { 1216 for (idx = 0; idx < context->name_count; idx++)
1148 const char *n; 1217 if (context->names[idx].pino == pino) {
1149 const char *name = context->names[idx].name; 1218 const char *name = context->names[idx].name;
1150 int dlen = strlen(dname);
1151 int nlen = name ? strlen(name) : 0;
1152
1153 if (nlen < dlen)
1154 continue;
1155
1156 /* disregard trailing slashes */
1157 n = name + nlen - 1;
1158 while ((*n == '/') && (n > name))
1159 n--;
1160
1161 /* find last path component */
1162 n = n - dlen + 1;
1163 if (n < name)
1164 continue;
1165 else if (n > name) {
1166 if (*--n != '/')
1167 continue;
1168 else
1169 n++;
1170 }
1171 1219
1172 if (strncmp(n, dname, dlen) == 0) 1220 if (!name)
1173 goto update_context; 1221 continue;
1174 } 1222
1223 if (audit_compare_dname_path(dname, name) == 0)
1224 goto update_context;
1225 }
1175 1226
1227no_match:
1176 /* catch-all in case match not found */ 1228 /* catch-all in case match not found */
1177 idx = context->name_count++; 1229 idx = context->name_count++;
1178 context->names[idx].name = NULL; 1230 context->names[idx].name = NULL;