Commit 2096f759abcb42200a81d776f597362fd9265024

Authored by Al Viro
1 parent 495d6c9c65

New helper: path_is_under(path1, path2)

Analog of is_subdir for vfsmount,dentry pairs, moved from audit_tree.c

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Showing 3 changed files with 37 additions and 39 deletions Side-by-side Diff

... ... @@ -2191,6 +2191,30 @@
2191 2191 return result;
2192 2192 }
2193 2193  
  2194 +int path_is_under(struct path *path1, struct path *path2)
  2195 +{
  2196 + struct vfsmount *mnt = path1->mnt;
  2197 + struct dentry *dentry = path1->dentry;
  2198 + int res;
  2199 + spin_lock(&vfsmount_lock);
  2200 + if (mnt != path2->mnt) {
  2201 + for (;;) {
  2202 + if (mnt->mnt_parent == mnt) {
  2203 + spin_unlock(&vfsmount_lock);
  2204 + return 0;
  2205 + }
  2206 + if (mnt->mnt_parent == path2->mnt)
  2207 + break;
  2208 + mnt = mnt->mnt_parent;
  2209 + }
  2210 + dentry = mnt->mnt_mountpoint;
  2211 + }
  2212 + res = is_subdir(dentry, path2->dentry);
  2213 + spin_unlock(&vfsmount_lock);
  2214 + return res;
  2215 +}
  2216 +EXPORT_SYMBOL(path_is_under);
  2217 +
2194 2218 void d_genocide(struct dentry *root)
2195 2219 {
2196 2220 struct dentry *this_parent = root;
... ... @@ -2126,6 +2126,7 @@
2126 2126  
2127 2127 /* fs/dcache.c -- generic fs support functions */
2128 2128 extern int is_subdir(struct dentry *, struct dentry *);
  2129 +extern int path_is_under(struct path *, struct path *);
2129 2130 extern ino_t find_inode_number(struct dentry *, struct qstr *);
2130 2131  
2131 2132 #include <linux/err.h>
... ... @@ -603,22 +603,6 @@
603 603 mutex_unlock(&audit_filter_mutex);
604 604 }
605 605  
606   -static int is_under(struct vfsmount *mnt, struct dentry *dentry,
607   - struct path *path)
608   -{
609   - if (mnt != path->mnt) {
610   - for (;;) {
611   - if (mnt->mnt_parent == mnt)
612   - return 0;
613   - if (mnt->mnt_parent == path->mnt)
614   - break;
615   - mnt = mnt->mnt_parent;
616   - }
617   - dentry = mnt->mnt_mountpoint;
618   - }
619   - return is_subdir(dentry, path->dentry);
620   -}
621   -
622 606 int audit_make_tree(struct audit_krule *rule, char *pathname, u32 op)
623 607 {
624 608  
625 609  
626 610  
627 611  
628 612  
629 613  
... ... @@ -714,29 +698,24 @@
714 698 {
715 699 struct list_head cursor, barrier;
716 700 int failed = 0;
717   - struct path path;
  701 + struct path path1, path2;
718 702 struct vfsmount *tagged;
719 703 struct list_head list;
720   - struct vfsmount *mnt;
721   - struct dentry *dentry;
722 704 int err;
723 705  
724   - err = kern_path(new, 0, &path);
  706 + err = kern_path(new, 0, &path2);
725 707 if (err)
726 708 return err;
727   - tagged = collect_mounts(&path);
728   - path_put(&path);
  709 + tagged = collect_mounts(&path2);
  710 + path_put(&path2);
729 711 if (!tagged)
730 712 return -ENOMEM;
731 713  
732   - err = kern_path(old, 0, &path);
  714 + err = kern_path(old, 0, &path1);
733 715 if (err) {
734 716 drop_collected_mounts(tagged);
735 717 return err;
736 718 }
737   - mnt = mntget(path.mnt);
738   - dentry = dget(path.dentry);
739   - path_put(&path);
740 719  
741 720 list_add_tail(&list, &tagged->mnt_list);
742 721  
... ... @@ -747,6 +726,7 @@
747 726 while (cursor.next != &tree_list) {
748 727 struct audit_tree *tree;
749 728 struct vfsmount *p;
  729 + int good_one = 0;
750 730  
751 731 tree = container_of(cursor.next, struct audit_tree, list);
752 732 get_tree(tree);
753 733  
754 734  
... ... @@ -754,23 +734,17 @@
754 734 list_add(&cursor, &tree->list);
755 735 mutex_unlock(&audit_filter_mutex);
756 736  
757   - err = kern_path(tree->pathname, 0, &path);
758   - if (err) {
759   - put_tree(tree);
760   - mutex_lock(&audit_filter_mutex);
761   - continue;
  737 + err = kern_path(tree->pathname, 0, &path2);
  738 + if (!err) {
  739 + good_one = path_is_under(&path1, &path2);
  740 + path_put(&path2);
762 741 }
763 742  
764   - spin_lock(&vfsmount_lock);
765   - if (!is_under(mnt, dentry, &path)) {
766   - spin_unlock(&vfsmount_lock);
767   - path_put(&path);
  743 + if (!good_one) {
768 744 put_tree(tree);
769 745 mutex_lock(&audit_filter_mutex);
770 746 continue;
771 747 }
772   - spin_unlock(&vfsmount_lock);
773   - path_put(&path);
774 748  
775 749 list_for_each_entry(p, &list, mnt_list) {
776 750 failed = tag_chunk(p->mnt_root->d_inode, tree);
... ... @@ -820,8 +794,7 @@
820 794 list_del(&cursor);
821 795 list_del(&list);
822 796 mutex_unlock(&audit_filter_mutex);
823   - dput(dentry);
824   - mntput(mnt);
  797 + path_put(&path1);
825 798 drop_collected_mounts(tagged);
826 799 return failed;
827 800 }