diff options
Diffstat (limited to 'security/tomoyo/file.c')
-rw-r--r-- | security/tomoyo/file.c | 71 |
1 files changed, 43 insertions, 28 deletions
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c index 6651cac87625..1c6f8238ec47 100644 --- a/security/tomoyo/file.c +++ b/security/tomoyo/file.c | |||
@@ -45,6 +45,37 @@ static const char *tomoyo_path2_keyword[TOMOYO_MAX_PATH2_OPERATION] = { | |||
45 | [TOMOYO_TYPE_PIVOT_ROOT] = "pivot_root", | 45 | [TOMOYO_TYPE_PIVOT_ROOT] = "pivot_root", |
46 | }; | 46 | }; |
47 | 47 | ||
48 | void tomoyo_put_name_union(struct tomoyo_name_union *ptr) | ||
49 | { | ||
50 | if (!ptr) | ||
51 | return; | ||
52 | if (ptr->is_group) | ||
53 | tomoyo_put_path_group(ptr->group); | ||
54 | else | ||
55 | tomoyo_put_name(ptr->filename); | ||
56 | } | ||
57 | |||
58 | bool tomoyo_compare_name_union(const struct tomoyo_path_info *name, | ||
59 | const struct tomoyo_name_union *ptr) | ||
60 | { | ||
61 | if (ptr->is_group) | ||
62 | return tomoyo_path_matches_group(name, ptr->group, 1); | ||
63 | return tomoyo_path_matches_pattern(name, ptr->filename); | ||
64 | } | ||
65 | |||
66 | static bool tomoyo_compare_name_union_pattern(const struct tomoyo_path_info | ||
67 | *name, | ||
68 | const struct tomoyo_name_union | ||
69 | *ptr, const bool may_use_pattern) | ||
70 | { | ||
71 | if (ptr->is_group) | ||
72 | return tomoyo_path_matches_group(name, ptr->group, | ||
73 | may_use_pattern); | ||
74 | if (may_use_pattern || !ptr->filename->is_patterned) | ||
75 | return tomoyo_path_matches_pattern(name, ptr->filename); | ||
76 | return false; | ||
77 | } | ||
78 | |||
48 | /** | 79 | /** |
49 | * tomoyo_path2keyword - Get the name of single path operation. | 80 | * tomoyo_path2keyword - Get the name of single path operation. |
50 | * | 81 | * |
@@ -637,13 +668,9 @@ static int tomoyo_path_acl2(const struct tomoyo_domain_info *domain, | |||
637 | if (!(acl->perm_high & (perm >> 16))) | 668 | if (!(acl->perm_high & (perm >> 16))) |
638 | continue; | 669 | continue; |
639 | } | 670 | } |
640 | if (may_use_pattern || !acl->filename->is_patterned) { | 671 | if (!tomoyo_compare_name_union_pattern(filename, &acl->name, |
641 | if (!tomoyo_path_matches_pattern(filename, | 672 | may_use_pattern)) |
642 | acl->filename)) | ||
643 | continue; | ||
644 | } else { | ||
645 | continue; | 673 | continue; |
646 | } | ||
647 | error = 0; | 674 | error = 0; |
648 | break; | 675 | break; |
649 | } | 676 | } |
@@ -817,19 +844,14 @@ static int tomoyo_update_path_acl(const u8 type, const char *filename, | |||
817 | e.perm |= tomoyo_rw_mask; | 844 | e.perm |= tomoyo_rw_mask; |
818 | if (!domain) | 845 | if (!domain) |
819 | return -EINVAL; | 846 | return -EINVAL; |
820 | if (!tomoyo_is_correct_path(filename, 0, 0, 0)) | 847 | if (!tomoyo_parse_name_union(filename, &e.name)) |
821 | return -EINVAL; | 848 | return -EINVAL; |
822 | e.filename = tomoyo_get_name(filename); | ||
823 | if (!e.filename) | ||
824 | return -ENOMEM; | ||
825 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) | 849 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) |
826 | goto out; | 850 | goto out; |
827 | list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { | 851 | list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { |
828 | struct tomoyo_path_acl *acl = | 852 | struct tomoyo_path_acl *acl = |
829 | container_of(ptr, struct tomoyo_path_acl, head); | 853 | container_of(ptr, struct tomoyo_path_acl, head); |
830 | if (ptr->type != TOMOYO_TYPE_PATH_ACL) | 854 | if (!tomoyo_is_same_path_acl(acl, &e)) |
831 | continue; | ||
832 | if (acl->filename != e.filename) | ||
833 | continue; | 855 | continue; |
834 | if (is_delete) { | 856 | if (is_delete) { |
835 | if (perm <= 0xFFFF) | 857 | if (perm <= 0xFFFF) |
@@ -864,7 +886,7 @@ static int tomoyo_update_path_acl(const u8 type, const char *filename, | |||
864 | } | 886 | } |
865 | mutex_unlock(&tomoyo_policy_lock); | 887 | mutex_unlock(&tomoyo_policy_lock); |
866 | out: | 888 | out: |
867 | tomoyo_put_name(e.filename); | 889 | tomoyo_put_name_union(&e.name); |
868 | return error; | 890 | return error; |
869 | } | 891 | } |
870 | 892 | ||
@@ -896,22 +918,15 @@ static int tomoyo_update_path2_acl(const u8 type, const char *filename1, | |||
896 | 918 | ||
897 | if (!domain) | 919 | if (!domain) |
898 | return -EINVAL; | 920 | return -EINVAL; |
899 | if (!tomoyo_is_correct_path(filename1, 0, 0, 0) || | 921 | if (!tomoyo_parse_name_union(filename1, &e.name1) || |
900 | !tomoyo_is_correct_path(filename2, 0, 0, 0)) | 922 | !tomoyo_parse_name_union(filename2, &e.name2)) |
901 | return -EINVAL; | ||
902 | e.filename1 = tomoyo_get_name(filename1); | ||
903 | e.filename2 = tomoyo_get_name(filename2); | ||
904 | if (!e.filename1 || !e.filename2) | ||
905 | goto out; | 923 | goto out; |
906 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) | 924 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) |
907 | goto out; | 925 | goto out; |
908 | list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { | 926 | list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { |
909 | struct tomoyo_path2_acl *acl = | 927 | struct tomoyo_path2_acl *acl = |
910 | container_of(ptr, struct tomoyo_path2_acl, head); | 928 | container_of(ptr, struct tomoyo_path2_acl, head); |
911 | if (ptr->type != TOMOYO_TYPE_PATH2_ACL) | 929 | if (!tomoyo_is_same_path2_acl(acl, &e)) |
912 | continue; | ||
913 | if (acl->filename1 != e.filename1 || | ||
914 | acl->filename2 != e.filename2) | ||
915 | continue; | 930 | continue; |
916 | if (is_delete) | 931 | if (is_delete) |
917 | acl->perm &= ~perm; | 932 | acl->perm &= ~perm; |
@@ -931,8 +946,8 @@ static int tomoyo_update_path2_acl(const u8 type, const char *filename1, | |||
931 | } | 946 | } |
932 | mutex_unlock(&tomoyo_policy_lock); | 947 | mutex_unlock(&tomoyo_policy_lock); |
933 | out: | 948 | out: |
934 | tomoyo_put_name(e.filename1); | 949 | tomoyo_put_name_union(&e.name1); |
935 | tomoyo_put_name(e.filename2); | 950 | tomoyo_put_name_union(&e.name2); |
936 | return error; | 951 | return error; |
937 | } | 952 | } |
938 | 953 | ||
@@ -985,9 +1000,9 @@ static int tomoyo_path2_acl(const struct tomoyo_domain_info *domain, | |||
985 | acl = container_of(ptr, struct tomoyo_path2_acl, head); | 1000 | acl = container_of(ptr, struct tomoyo_path2_acl, head); |
986 | if (!(acl->perm & perm)) | 1001 | if (!(acl->perm & perm)) |
987 | continue; | 1002 | continue; |
988 | if (!tomoyo_path_matches_pattern(filename1, acl->filename1)) | 1003 | if (!tomoyo_compare_name_union(filename1, &acl->name1)) |
989 | continue; | 1004 | continue; |
990 | if (!tomoyo_path_matches_pattern(filename2, acl->filename2)) | 1005 | if (!tomoyo_compare_name_union(filename2, &acl->name2)) |
991 | continue; | 1006 | continue; |
992 | error = 0; | 1007 | error = 0; |
993 | break; | 1008 | break; |