diff options
author | Eric Paris <eparis@redhat.com> | 2009-06-11 14:31:36 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2009-06-23 23:51:05 -0400 |
commit | 35fe4d0b1b12286a81938e9c5fdfaf639ac0ce5b (patch) | |
tree | c520706593fd33748944315bb87d789a7f31960e /kernel | |
parent | cfcad62c74abfef83762dc05a556d21bdf3980a2 (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.h | 5 | ||||
-rw-r--r-- | kernel/audit_watch.c | 27 | ||||
-rw-r--r-- | kernel/auditfilter.c | 15 |
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); | |||
109 | extern void audit_put_watch(struct audit_watch *watch); | 109 | extern void audit_put_watch(struct audit_watch *watch); |
110 | extern void audit_get_watch(struct audit_watch *watch); | 110 | extern void audit_get_watch(struct audit_watch *watch); |
111 | extern int audit_to_watch(struct audit_krule *krule, char *path, int len, u32 op); | 111 | extern int audit_to_watch(struct audit_krule *krule, char *path, int len, u32 op); |
112 | extern int audit_get_nd(char *path, struct nameidata **ndp, struct nameidata **ndw); | 112 | extern int audit_add_watch(struct audit_krule *krule); |
113 | extern void audit_put_nd(struct nameidata *ndp, struct nameidata *ndw); | ||
114 | extern int audit_add_watch(struct audit_krule *krule, struct nameidata *ndp, | ||
115 | struct nameidata *ndw); | ||
116 | extern void audit_remove_watch(struct audit_watch *watch); | 113 | extern void audit_remove_watch(struct audit_watch *watch); |
117 | extern void audit_remove_watch_rule(struct audit_krule *krule, struct list_head *list); | 114 | extern void audit_remove_watch_rule(struct audit_krule *krule, struct list_head *list); |
118 | extern void audit_inotify_unregister(struct list_head *in_list); | 115 | extern 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. */ |
348 | int audit_get_nd(char *path, struct nameidata **ndp, struct nameidata **ndw) | 348 | static 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. */ |
383 | void audit_put_nd(struct nameidata *ndp, struct nameidata *ndw) | 383 | static 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. */ |
429 | int audit_add_watch(struct audit_krule *krule, struct nameidata *ndp, | 429 | int 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 | |||
481 | error: | ||
482 | audit_put_nd(ndp, ndw); /* NULL args OK */ | ||
471 | return ret; | 483 | return ret; |
484 | |||
472 | } | 485 | } |
473 | 486 | ||
474 | void audit_remove_watch_rule(struct audit_krule *krule, struct list_head *list) | 487 | void 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 | ||
948 | error: | 938 | error: |
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; |