aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/audit_tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/audit_tree.c')
-rw-r--r--kernel/audit_tree.c101
1 files changed, 29 insertions, 72 deletions
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c
index 4b05bd9479db..46a57b57a335 100644
--- a/kernel/audit_tree.c
+++ b/kernel/audit_tree.c
@@ -3,6 +3,7 @@
3#include <linux/namei.h> 3#include <linux/namei.h>
4#include <linux/mount.h> 4#include <linux/mount.h>
5#include <linux/kthread.h> 5#include <linux/kthread.h>
6#include <linux/slab.h>
6 7
7struct audit_tree; 8struct audit_tree;
8struct audit_chunk; 9struct audit_chunk;
@@ -548,6 +549,11 @@ int audit_remove_tree_rule(struct audit_krule *rule)
548 return 0; 549 return 0;
549} 550}
550 551
552static int compare_root(struct vfsmount *mnt, void *arg)
553{
554 return mnt->mnt_root->d_inode == arg;
555}
556
551void audit_trim_trees(void) 557void audit_trim_trees(void)
552{ 558{
553 struct list_head cursor; 559 struct list_head cursor;
@@ -559,7 +565,6 @@ void audit_trim_trees(void)
559 struct path path; 565 struct path path;
560 struct vfsmount *root_mnt; 566 struct vfsmount *root_mnt;
561 struct node *node; 567 struct node *node;
562 struct list_head list;
563 int err; 568 int err;
564 569
565 tree = container_of(cursor.next, struct audit_tree, list); 570 tree = container_of(cursor.next, struct audit_tree, list);
@@ -577,24 +582,16 @@ void audit_trim_trees(void)
577 if (!root_mnt) 582 if (!root_mnt)
578 goto skip_it; 583 goto skip_it;
579 584
580 list_add_tail(&list, &root_mnt->mnt_list);
581 spin_lock(&hash_lock); 585 spin_lock(&hash_lock);
582 list_for_each_entry(node, &tree->chunks, list) { 586 list_for_each_entry(node, &tree->chunks, list) {
583 struct audit_chunk *chunk = find_chunk(node); 587 struct inode *inode = find_chunk(node)->watch.inode;
584 struct inode *inode = chunk->watch.inode;
585 struct vfsmount *mnt;
586 node->index |= 1U<<31; 588 node->index |= 1U<<31;
587 list_for_each_entry(mnt, &list, mnt_list) { 589 if (iterate_mounts(compare_root, inode, root_mnt))
588 if (mnt->mnt_root->d_inode == inode) { 590 node->index &= ~(1U<<31);
589 node->index &= ~(1U<<31);
590 break;
591 }
592 }
593 } 591 }
594 spin_unlock(&hash_lock); 592 spin_unlock(&hash_lock);
595 trim_marked(tree); 593 trim_marked(tree);
596 put_tree(tree); 594 put_tree(tree);
597 list_del_init(&list);
598 drop_collected_mounts(root_mnt); 595 drop_collected_mounts(root_mnt);
599skip_it: 596skip_it:
600 mutex_lock(&audit_filter_mutex); 597 mutex_lock(&audit_filter_mutex);
@@ -603,22 +600,6 @@ skip_it:
603 mutex_unlock(&audit_filter_mutex); 600 mutex_unlock(&audit_filter_mutex);
604} 601}
605 602
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) 603int audit_make_tree(struct audit_krule *rule, char *pathname, u32 op)
623{ 604{
624 605
@@ -638,13 +619,17 @@ void audit_put_tree(struct audit_tree *tree)
638 put_tree(tree); 619 put_tree(tree);
639} 620}
640 621
622static int tag_mount(struct vfsmount *mnt, void *arg)
623{
624 return tag_chunk(mnt->mnt_root->d_inode, arg);
625}
626
641/* called with audit_filter_mutex */ 627/* called with audit_filter_mutex */
642int audit_add_tree_rule(struct audit_krule *rule) 628int audit_add_tree_rule(struct audit_krule *rule)
643{ 629{
644 struct audit_tree *seed = rule->tree, *tree; 630 struct audit_tree *seed = rule->tree, *tree;
645 struct path path; 631 struct path path;
646 struct vfsmount *mnt, *p; 632 struct vfsmount *mnt;
647 struct list_head list;
648 int err; 633 int err;
649 634
650 list_for_each_entry(tree, &tree_list, list) { 635 list_for_each_entry(tree, &tree_list, list) {
@@ -670,16 +655,9 @@ int audit_add_tree_rule(struct audit_krule *rule)
670 err = -ENOMEM; 655 err = -ENOMEM;
671 goto Err; 656 goto Err;
672 } 657 }
673 list_add_tail(&list, &mnt->mnt_list);
674 658
675 get_tree(tree); 659 get_tree(tree);
676 list_for_each_entry(p, &list, mnt_list) { 660 err = iterate_mounts(tag_mount, tree, mnt);
677 err = tag_chunk(p->mnt_root->d_inode, tree);
678 if (err)
679 break;
680 }
681
682 list_del(&list);
683 drop_collected_mounts(mnt); 661 drop_collected_mounts(mnt);
684 662
685 if (!err) { 663 if (!err) {
@@ -714,31 +692,23 @@ int audit_tag_tree(char *old, char *new)
714{ 692{
715 struct list_head cursor, barrier; 693 struct list_head cursor, barrier;
716 int failed = 0; 694 int failed = 0;
717 struct path path; 695 struct path path1, path2;
718 struct vfsmount *tagged; 696 struct vfsmount *tagged;
719 struct list_head list;
720 struct vfsmount *mnt;
721 struct dentry *dentry;
722 int err; 697 int err;
723 698
724 err = kern_path(new, 0, &path); 699 err = kern_path(new, 0, &path2);
725 if (err) 700 if (err)
726 return err; 701 return err;
727 tagged = collect_mounts(&path); 702 tagged = collect_mounts(&path2);
728 path_put(&path); 703 path_put(&path2);
729 if (!tagged) 704 if (!tagged)
730 return -ENOMEM; 705 return -ENOMEM;
731 706
732 err = kern_path(old, 0, &path); 707 err = kern_path(old, 0, &path1);
733 if (err) { 708 if (err) {
734 drop_collected_mounts(tagged); 709 drop_collected_mounts(tagged);
735 return err; 710 return err;
736 } 711 }
737 mnt = mntget(path.mnt);
738 dentry = dget(path.dentry);
739 path_put(&path);
740
741 list_add_tail(&list, &tagged->mnt_list);
742 712
743 mutex_lock(&audit_filter_mutex); 713 mutex_lock(&audit_filter_mutex);
744 list_add(&barrier, &tree_list); 714 list_add(&barrier, &tree_list);
@@ -746,7 +716,7 @@ int audit_tag_tree(char *old, char *new)
746 716
747 while (cursor.next != &tree_list) { 717 while (cursor.next != &tree_list) {
748 struct audit_tree *tree; 718 struct audit_tree *tree;
749 struct vfsmount *p; 719 int good_one = 0;
750 720
751 tree = container_of(cursor.next, struct audit_tree, list); 721 tree = container_of(cursor.next, struct audit_tree, list);
752 get_tree(tree); 722 get_tree(tree);
@@ -754,30 +724,19 @@ int audit_tag_tree(char *old, char *new)
754 list_add(&cursor, &tree->list); 724 list_add(&cursor, &tree->list);
755 mutex_unlock(&audit_filter_mutex); 725 mutex_unlock(&audit_filter_mutex);
756 726
757 err = kern_path(tree->pathname, 0, &path); 727 err = kern_path(tree->pathname, 0, &path2);
758 if (err) { 728 if (!err) {
759 put_tree(tree); 729 good_one = path_is_under(&path1, &path2);
760 mutex_lock(&audit_filter_mutex); 730 path_put(&path2);
761 continue;
762 } 731 }
763 732
764 spin_lock(&vfsmount_lock); 733 if (!good_one) {
765 if (!is_under(mnt, dentry, &path)) {
766 spin_unlock(&vfsmount_lock);
767 path_put(&path);
768 put_tree(tree); 734 put_tree(tree);
769 mutex_lock(&audit_filter_mutex); 735 mutex_lock(&audit_filter_mutex);
770 continue; 736 continue;
771 } 737 }
772 spin_unlock(&vfsmount_lock);
773 path_put(&path);
774
775 list_for_each_entry(p, &list, mnt_list) {
776 failed = tag_chunk(p->mnt_root->d_inode, tree);
777 if (failed)
778 break;
779 }
780 738
739 failed = iterate_mounts(tag_mount, tree, tagged);
781 if (failed) { 740 if (failed) {
782 put_tree(tree); 741 put_tree(tree);
783 mutex_lock(&audit_filter_mutex); 742 mutex_lock(&audit_filter_mutex);
@@ -818,10 +777,8 @@ int audit_tag_tree(char *old, char *new)
818 } 777 }
819 list_del(&barrier); 778 list_del(&barrier);
820 list_del(&cursor); 779 list_del(&cursor);
821 list_del(&list);
822 mutex_unlock(&audit_filter_mutex); 780 mutex_unlock(&audit_filter_mutex);
823 dput(dentry); 781 path_put(&path1);
824 mntput(mnt);
825 drop_collected_mounts(tagged); 782 drop_collected_mounts(tagged);
826 return failed; 783 return failed;
827} 784}