aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/dcache.c24
-rw-r--r--include/linux/fs.h1
-rw-r--r--kernel/audit_tree.c51
3 files changed, 37 insertions, 39 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index 4365998b8df4..74da947b160b 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -2191,6 +2191,30 @@ int is_subdir(struct dentry *new_dentry, struct dentry *old_dentry)
2191 return result; 2191 return result;
2192} 2192}
2193 2193
2194int 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}
2216EXPORT_SYMBOL(path_is_under);
2217
2194void d_genocide(struct dentry *root) 2218void d_genocide(struct dentry *root)
2195{ 2219{
2196 struct dentry *this_parent = root; 2220 struct dentry *this_parent = root;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index d443c9dd3caa..8d53bc17f93f 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2126,6 +2126,7 @@ extern struct file * open_exec(const char *);
2126 2126
2127/* fs/dcache.c -- generic fs support functions */ 2127/* fs/dcache.c -- generic fs support functions */
2128extern int is_subdir(struct dentry *, struct dentry *); 2128extern int is_subdir(struct dentry *, struct dentry *);
2129extern int path_is_under(struct path *, struct path *);
2129extern ino_t find_inode_number(struct dentry *, struct qstr *); 2130extern ino_t find_inode_number(struct dentry *, struct qstr *);
2130 2131
2131#include <linux/err.h> 2132#include <linux/err.h>
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c
index 4b05bd9479db..f09b42d9c32d 100644
--- a/kernel/audit_tree.c
+++ b/kernel/audit_tree.c
@@ -603,22 +603,6 @@ skip_it:
603 mutex_unlock(&audit_filter_mutex); 603 mutex_unlock(&audit_filter_mutex);
604} 604}
605 605
606static 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
622int audit_make_tree(struct audit_krule *rule, char *pathname, u32 op) 606int audit_make_tree(struct audit_krule *rule, char *pathname, u32 op)
623{ 607{
624 608
@@ -714,29 +698,24 @@ int audit_tag_tree(char *old, char *new)
714{ 698{
715 struct list_head cursor, barrier; 699 struct list_head cursor, barrier;
716 int failed = 0; 700 int failed = 0;
717 struct path path; 701 struct path path1, path2;
718 struct vfsmount *tagged; 702 struct vfsmount *tagged;
719 struct list_head list; 703 struct list_head list;
720 struct vfsmount *mnt;
721 struct dentry *dentry;
722 int err; 704 int err;
723 705
724 err = kern_path(new, 0, &path); 706 err = kern_path(new, 0, &path2);
725 if (err) 707 if (err)
726 return err; 708 return err;
727 tagged = collect_mounts(&path); 709 tagged = collect_mounts(&path2);
728 path_put(&path); 710 path_put(&path2);
729 if (!tagged) 711 if (!tagged)
730 return -ENOMEM; 712 return -ENOMEM;
731 713
732 err = kern_path(old, 0, &path); 714 err = kern_path(old, 0, &path1);
733 if (err) { 715 if (err) {
734 drop_collected_mounts(tagged); 716 drop_collected_mounts(tagged);
735 return err; 717 return err;
736 } 718 }
737 mnt = mntget(path.mnt);
738 dentry = dget(path.dentry);
739 path_put(&path);
740 719
741 list_add_tail(&list, &tagged->mnt_list); 720 list_add_tail(&list, &tagged->mnt_list);
742 721
@@ -747,6 +726,7 @@ int audit_tag_tree(char *old, char *new)
747 while (cursor.next != &tree_list) { 726 while (cursor.next != &tree_list) {
748 struct audit_tree *tree; 727 struct audit_tree *tree;
749 struct vfsmount *p; 728 struct vfsmount *p;
729 int good_one = 0;
750 730
751 tree = container_of(cursor.next, struct audit_tree, list); 731 tree = container_of(cursor.next, struct audit_tree, list);
752 get_tree(tree); 732 get_tree(tree);
@@ -754,23 +734,17 @@ int audit_tag_tree(char *old, char *new)
754 list_add(&cursor, &tree->list); 734 list_add(&cursor, &tree->list);
755 mutex_unlock(&audit_filter_mutex); 735 mutex_unlock(&audit_filter_mutex);
756 736
757 err = kern_path(tree->pathname, 0, &path); 737 err = kern_path(tree->pathname, 0, &path2);
758 if (err) { 738 if (!err) {
759 put_tree(tree); 739 good_one = path_is_under(&path1, &path2);
760 mutex_lock(&audit_filter_mutex); 740 path_put(&path2);
761 continue;
762 } 741 }
763 742
764 spin_lock(&vfsmount_lock); 743 if (!good_one) {
765 if (!is_under(mnt, dentry, &path)) {
766 spin_unlock(&vfsmount_lock);
767 path_put(&path);
768 put_tree(tree); 744 put_tree(tree);
769 mutex_lock(&audit_filter_mutex); 745 mutex_lock(&audit_filter_mutex);
770 continue; 746 continue;
771 } 747 }
772 spin_unlock(&vfsmount_lock);
773 path_put(&path);
774 748
775 list_for_each_entry(p, &list, mnt_list) { 749 list_for_each_entry(p, &list, mnt_list) {
776 failed = tag_chunk(p->mnt_root->d_inode, tree); 750 failed = tag_chunk(p->mnt_root->d_inode, tree);
@@ -820,8 +794,7 @@ int audit_tag_tree(char *old, char *new)
820 list_del(&cursor); 794 list_del(&cursor);
821 list_del(&list); 795 list_del(&list);
822 mutex_unlock(&audit_filter_mutex); 796 mutex_unlock(&audit_filter_mutex);
823 dput(dentry); 797 path_put(&path1);
824 mntput(mnt);
825 drop_collected_mounts(tagged); 798 drop_collected_mounts(tagged);
826 return failed; 799 return failed;
827} 800}