Commit 35fe4d0b1b12286a81938e9c5fdfaf639ac0ce5b

Authored by Eric Paris
Committed by Al Viro
1 parent cfcad62c74

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>

Showing 3 changed files with 23 additions and 24 deletions Side-by-side Diff

... ... @@ -109,10 +109,7 @@
109 109 extern void audit_put_watch(struct audit_watch *watch);
110 110 extern void audit_get_watch(struct audit_watch *watch);
111 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);
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);
  112 +extern int audit_add_watch(struct audit_krule *krule);
116 113 extern void audit_remove_watch(struct audit_watch *watch);
117 114 extern void audit_remove_watch_rule(struct audit_krule *krule, struct list_head *list);
118 115 extern void audit_inotify_unregister(struct list_head *in_list);
kernel/audit_watch.c
... ... @@ -345,7 +345,7 @@
345 345 }
346 346  
347 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 350 struct nameidata *ndparent, *ndwatch;
351 351 int err;
... ... @@ -380,7 +380,7 @@
380 380 }
381 381  
382 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 385 if (ndp) {
386 386 path_put(&ndp->path);
387 387  
388 388  
... ... @@ -426,14 +426,24 @@
426 426  
427 427 /* Find a matching watch entry, or add this one.
428 428 * Caller must hold audit_filter_mutex. */
429   -int audit_add_watch(struct audit_krule *krule, struct nameidata *ndp,
430   - struct nameidata *ndw)
  429 +int audit_add_watch(struct audit_krule *krule)
431 430 {
432 431 struct audit_watch *watch = krule->watch;
433 432 struct inotify_watch *i_watch;
434 433 struct audit_parent *parent;
  434 + struct nameidata *ndp = NULL, *ndw = NULL;
435 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 447 /* update watch filter fields */
438 448 if (ndw) {
439 449 watch->dev = ndw->path.dentry->d_inode->i_sb->s_dev;
440 450  
... ... @@ -445,15 +455,14 @@
445 455 * inotify watch is found, inotify_find_watch() grabs a reference before
446 456 * returning.
447 457 */
448   - mutex_unlock(&audit_filter_mutex);
449   -
450 458 if (inotify_find_watch(audit_ih, ndp->path.dentry->d_inode,
451 459 &i_watch) < 0) {
452 460 parent = audit_init_parent(ndp);
453 461 if (IS_ERR(parent)) {
454 462 /* caller expects mutex locked */
455 463 mutex_lock(&audit_filter_mutex);
456   - return PTR_ERR(parent);
  464 + ret = PTR_ERR(parent);
  465 + goto error;
457 466 }
458 467 } else
459 468 parent = container_of(i_watch, struct audit_parent, wdata);
460 469  
... ... @@ -468,7 +477,11 @@
468 477  
469 478 /* match get in audit_init_parent or inotify_find_watch */
470 479 put_inotify_watch(&parent->wdata);
  480 +
  481 +error:
  482 + audit_put_nd(ndp, ndw); /* NULL args OK */
471 483 return ret;
  484 +
472 485 }
473 486  
474 487 void audit_remove_watch_rule(struct audit_krule *krule, struct list_head *list)
kernel/auditfilter.c
... ... @@ -864,7 +864,6 @@
864 864 struct audit_entry *e;
865 865 struct audit_watch *watch = entry->rule.watch;
866 866 struct audit_tree *tree = entry->rule.tree;
867   - struct nameidata *ndp = NULL, *ndw = NULL;
868 867 struct list_head *list;
869 868 int h, err;
870 869 #ifdef CONFIG_AUDITSYSCALL
871 870  
... ... @@ -878,8 +877,8 @@
878 877  
879 878 mutex_lock(&audit_filter_mutex);
880 879 e = audit_find_rule(entry, &list);
881   - mutex_unlock(&audit_filter_mutex);
882 880 if (e) {
  881 + mutex_unlock(&audit_filter_mutex);
883 882 err = -EEXIST;
884 883 /* normally audit_add_tree_rule() will free it on failure */
885 884 if (tree)
886 885  
887 886  
... ... @@ -887,17 +886,9 @@
887 886 goto error;
888 887 }
889 888  
890   - /* Avoid calling path_lookup under audit_filter_mutex. */
891 889 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) {
899 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 892 if (err) {
902 893 mutex_unlock(&audit_filter_mutex);
903 894 goto error;
904 895  
... ... @@ -942,11 +933,9 @@
942 933 #endif
943 934 mutex_unlock(&audit_filter_mutex);
944 935  
945   - audit_put_nd(ndp, ndw); /* NULL args OK */
946 936 return 0;
947 937  
948 938 error:
949   - audit_put_nd(ndp, ndw); /* NULL args OK */
950 939 if (watch)
951 940 audit_put_watch(watch); /* tmp watch, matches initial get */
952 941 return err;