aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2009-06-11 14:31:36 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2009-06-23 23:51:05 -0400
commit35fe4d0b1b12286a81938e9c5fdfaf639ac0ce5b (patch)
treec520706593fd33748944315bb87d789a7f31960e /kernel
parentcfcad62c74abfef83762dc05a556d21bdf3980a2 (diff)
Audit: move audit_get_nd completely into audit_watch
audit_get_nd() is only used by audit_watch and could be more cleanly implemented by having the audit watch functions call it when needed rather than making the generic audit rule parsing code deal with those objects. Signed-off-by: Eric Paris <eparis@redhat.com>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/audit.h5
-rw-r--r--kernel/audit_watch.c27
-rw-r--r--kernel/auditfilter.c15
3 files changed, 23 insertions, 24 deletions
diff --git a/kernel/audit.h b/kernel/audit.h
index 704d5b01d9fd..bb1c0d69db08 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -109,10 +109,7 @@ extern dev_t audit_watch_dev(struct audit_watch *watch);
109extern void audit_put_watch(struct audit_watch *watch); 109extern void audit_put_watch(struct audit_watch *watch);
110extern void audit_get_watch(struct audit_watch *watch); 110extern void audit_get_watch(struct audit_watch *watch);
111extern int audit_to_watch(struct audit_krule *krule, char *path, int len, u32 op); 111extern int audit_to_watch(struct audit_krule *krule, char *path, int len, u32 op);
112extern int audit_get_nd(char *path, struct nameidata **ndp, struct nameidata **ndw); 112extern int audit_add_watch(struct audit_krule *krule);
113extern void audit_put_nd(struct nameidata *ndp, struct nameidata *ndw);
114extern int audit_add_watch(struct audit_krule *krule, struct nameidata *ndp,
115 struct nameidata *ndw);
116extern void audit_remove_watch(struct audit_watch *watch); 113extern void audit_remove_watch(struct audit_watch *watch);
117extern void audit_remove_watch_rule(struct audit_krule *krule, struct list_head *list); 114extern void audit_remove_watch_rule(struct audit_krule *krule, struct list_head *list);
118extern void audit_inotify_unregister(struct list_head *in_list); 115extern void audit_inotify_unregister(struct list_head *in_list);
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c
index da8be6d39c1a..b49ab019fdff 100644
--- a/kernel/audit_watch.c
+++ b/kernel/audit_watch.c
@@ -345,7 +345,7 @@ void audit_inotify_unregister(struct list_head *in_list)
345} 345}
346 346
347/* Get path information necessary for adding watches. */ 347/* Get path information necessary for adding watches. */
348int audit_get_nd(char *path, struct nameidata **ndp, struct nameidata **ndw) 348static int audit_get_nd(char *path, struct nameidata **ndp, struct nameidata **ndw)
349{ 349{
350 struct nameidata *ndparent, *ndwatch; 350 struct nameidata *ndparent, *ndwatch;
351 int err; 351 int err;
@@ -380,7 +380,7 @@ int audit_get_nd(char *path, struct nameidata **ndp, struct nameidata **ndw)
380} 380}
381 381
382/* Release resources used for watch path information. */ 382/* Release resources used for watch path information. */
383void audit_put_nd(struct nameidata *ndp, struct nameidata *ndw) 383static void audit_put_nd(struct nameidata *ndp, struct nameidata *ndw)
384{ 384{
385 if (ndp) { 385 if (ndp) {
386 path_put(&ndp->path); 386 path_put(&ndp->path);
@@ -426,14 +426,24 @@ static void audit_add_to_parent(struct audit_krule *krule,
426 426
427/* Find a matching watch entry, or add this one. 427/* Find a matching watch entry, or add this one.
428 * Caller must hold audit_filter_mutex. */ 428 * Caller must hold audit_filter_mutex. */
429int audit_add_watch(struct audit_krule *krule, struct nameidata *ndp, 429int audit_add_watch(struct audit_krule *krule)
430 struct nameidata *ndw)
431{ 430{
432 struct audit_watch *watch = krule->watch; 431 struct audit_watch *watch = krule->watch;
433 struct inotify_watch *i_watch; 432 struct inotify_watch *i_watch;
434 struct audit_parent *parent; 433 struct audit_parent *parent;
434 struct nameidata *ndp = NULL, *ndw = NULL;
435 int ret = 0; 435 int ret = 0;
436 436
437 mutex_unlock(&audit_filter_mutex);
438
439 /* Avoid calling path_lookup under audit_filter_mutex. */
440 ret = audit_get_nd(watch->path, &ndp, &ndw);
441 if (ret) {
442 /* caller expects mutex locked */
443 mutex_lock(&audit_filter_mutex);
444 goto error;
445 }
446
437 /* update watch filter fields */ 447 /* update watch filter fields */
438 if (ndw) { 448 if (ndw) {
439 watch->dev = ndw->path.dentry->d_inode->i_sb->s_dev; 449 watch->dev = ndw->path.dentry->d_inode->i_sb->s_dev;
@@ -445,15 +455,14 @@ int audit_add_watch(struct audit_krule *krule, struct nameidata *ndp,
445 * inotify watch is found, inotify_find_watch() grabs a reference before 455 * inotify watch is found, inotify_find_watch() grabs a reference before
446 * returning. 456 * returning.
447 */ 457 */
448 mutex_unlock(&audit_filter_mutex);
449
450 if (inotify_find_watch(audit_ih, ndp->path.dentry->d_inode, 458 if (inotify_find_watch(audit_ih, ndp->path.dentry->d_inode,
451 &i_watch) < 0) { 459 &i_watch) < 0) {
452 parent = audit_init_parent(ndp); 460 parent = audit_init_parent(ndp);
453 if (IS_ERR(parent)) { 461 if (IS_ERR(parent)) {
454 /* caller expects mutex locked */ 462 /* caller expects mutex locked */
455 mutex_lock(&audit_filter_mutex); 463 mutex_lock(&audit_filter_mutex);
456 return PTR_ERR(parent); 464 ret = PTR_ERR(parent);
465 goto error;
457 } 466 }
458 } else 467 } else
459 parent = container_of(i_watch, struct audit_parent, wdata); 468 parent = container_of(i_watch, struct audit_parent, wdata);
@@ -468,7 +477,11 @@ int audit_add_watch(struct audit_krule *krule, struct nameidata *ndp,
468 477
469 /* match get in audit_init_parent or inotify_find_watch */ 478 /* match get in audit_init_parent or inotify_find_watch */
470 put_inotify_watch(&parent->wdata); 479 put_inotify_watch(&parent->wdata);
480
481error:
482 audit_put_nd(ndp, ndw); /* NULL args OK */
471 return ret; 483 return ret;
484
472} 485}
473 486
474void audit_remove_watch_rule(struct audit_krule *krule, struct list_head *list) 487void audit_remove_watch_rule(struct audit_krule *krule, struct list_head *list)
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 9d4c93437de6..21b623595aad 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -864,7 +864,6 @@ static inline int audit_add_rule(struct audit_entry *entry)
864 struct audit_entry *e; 864 struct audit_entry *e;
865 struct audit_watch *watch = entry->rule.watch; 865 struct audit_watch *watch = entry->rule.watch;
866 struct audit_tree *tree = entry->rule.tree; 866 struct audit_tree *tree = entry->rule.tree;
867 struct nameidata *ndp = NULL, *ndw = NULL;
868 struct list_head *list; 867 struct list_head *list;
869 int h, err; 868 int h, err;
870#ifdef CONFIG_AUDITSYSCALL 869#ifdef CONFIG_AUDITSYSCALL
@@ -878,8 +877,8 @@ static inline int audit_add_rule(struct audit_entry *entry)
878 877
879 mutex_lock(&audit_filter_mutex); 878 mutex_lock(&audit_filter_mutex);
880 e = audit_find_rule(entry, &list); 879 e = audit_find_rule(entry, &list);
881 mutex_unlock(&audit_filter_mutex);
882 if (e) { 880 if (e) {
881 mutex_unlock(&audit_filter_mutex);
883 err = -EEXIST; 882 err = -EEXIST;
884 /* normally audit_add_tree_rule() will free it on failure */ 883 /* normally audit_add_tree_rule() will free it on failure */
885 if (tree) 884 if (tree)
@@ -887,17 +886,9 @@ static inline int audit_add_rule(struct audit_entry *entry)
887 goto error; 886 goto error;
888 } 887 }
889 888
890 /* Avoid calling path_lookup under audit_filter_mutex. */
891 if (watch) {
892 err = audit_get_nd(audit_watch_path(watch), &ndp, &ndw);
893 if (err)
894 goto error;
895 }
896
897 mutex_lock(&audit_filter_mutex);
898 if (watch) { 889 if (watch) {
899 /* audit_filter_mutex is dropped and re-taken during this call */ 890 /* audit_filter_mutex is dropped and re-taken during this call */
900 err = audit_add_watch(&entry->rule, ndp, ndw); 891 err = audit_add_watch(&entry->rule);
901 if (err) { 892 if (err) {
902 mutex_unlock(&audit_filter_mutex); 893 mutex_unlock(&audit_filter_mutex);
903 goto error; 894 goto error;
@@ -942,11 +933,9 @@ static inline int audit_add_rule(struct audit_entry *entry)
942#endif 933#endif
943 mutex_unlock(&audit_filter_mutex); 934 mutex_unlock(&audit_filter_mutex);
944 935
945 audit_put_nd(ndp, ndw); /* NULL args OK */
946 return 0; 936 return 0;
947 937
948error: 938error:
949 audit_put_nd(ndp, ndw); /* NULL args OK */
950 if (watch) 939 if (watch)
951 audit_put_watch(watch); /* tmp watch, matches initial get */ 940 audit_put_watch(watch); /* tmp watch, matches initial get */
952 return err; 941 return err;