aboutsummaryrefslogtreecommitdiffstats
path: root/security/tomoyo/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/tomoyo/file.c')
-rw-r--r--security/tomoyo/file.c181
1 files changed, 83 insertions, 98 deletions
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c
index 060bbf3870ce..6651cac87625 100644
--- a/security/tomoyo/file.c
+++ b/security/tomoyo/file.c
@@ -164,38 +164,36 @@ LIST_HEAD(tomoyo_globally_readable_list);
164static int tomoyo_update_globally_readable_entry(const char *filename, 164static int tomoyo_update_globally_readable_entry(const char *filename,
165 const bool is_delete) 165 const bool is_delete)
166{ 166{
167 struct tomoyo_globally_readable_file_entry *entry = NULL;
168 struct tomoyo_globally_readable_file_entry *ptr; 167 struct tomoyo_globally_readable_file_entry *ptr;
169 const struct tomoyo_path_info *saved_filename; 168 struct tomoyo_globally_readable_file_entry e = { };
170 int error = is_delete ? -ENOENT : -ENOMEM; 169 int error = is_delete ? -ENOENT : -ENOMEM;
171 170
172 if (!tomoyo_is_correct_path(filename, 1, 0, -1)) 171 if (!tomoyo_is_correct_path(filename, 1, 0, -1))
173 return -EINVAL; 172 return -EINVAL;
174 saved_filename = tomoyo_get_name(filename); 173 e.filename = tomoyo_get_name(filename);
175 if (!saved_filename) 174 if (!e.filename)
176 return -ENOMEM; 175 return -ENOMEM;
177 if (!is_delete)
178 entry = kmalloc(sizeof(*entry), GFP_NOFS);
179 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 176 if (mutex_lock_interruptible(&tomoyo_policy_lock))
180 goto out; 177 goto out;
181 list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) { 178 list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) {
182 if (ptr->filename != saved_filename) 179 if (ptr->filename != e.filename)
183 continue; 180 continue;
184 ptr->is_deleted = is_delete; 181 ptr->is_deleted = is_delete;
185 error = 0; 182 error = 0;
186 break; 183 break;
187 } 184 }
188 if (!is_delete && error && tomoyo_memory_ok(entry)) { 185 if (!is_delete && error) {
189 entry->filename = saved_filename; 186 struct tomoyo_globally_readable_file_entry *entry =
190 saved_filename = NULL; 187 tomoyo_commit_ok(&e, sizeof(e));
191 list_add_tail_rcu(&entry->list, &tomoyo_globally_readable_list); 188 if (entry) {
192 entry = NULL; 189 list_add_tail_rcu(&entry->list,
193 error = 0; 190 &tomoyo_globally_readable_list);
191 error = 0;
192 }
194 } 193 }
195 mutex_unlock(&tomoyo_policy_lock); 194 mutex_unlock(&tomoyo_policy_lock);
196 out: 195 out:
197 tomoyo_put_name(saved_filename); 196 tomoyo_put_name(e.filename);
198 kfree(entry);
199 return error; 197 return error;
200} 198}
201 199
@@ -313,38 +311,34 @@ LIST_HEAD(tomoyo_pattern_list);
313static int tomoyo_update_file_pattern_entry(const char *pattern, 311static int tomoyo_update_file_pattern_entry(const char *pattern,
314 const bool is_delete) 312 const bool is_delete)
315{ 313{
316 struct tomoyo_pattern_entry *entry = NULL;
317 struct tomoyo_pattern_entry *ptr; 314 struct tomoyo_pattern_entry *ptr;
318 const struct tomoyo_path_info *saved_pattern; 315 struct tomoyo_pattern_entry e = { .pattern = tomoyo_get_name(pattern) };
319 int error = is_delete ? -ENOENT : -ENOMEM; 316 int error = is_delete ? -ENOENT : -ENOMEM;
320 317
321 saved_pattern = tomoyo_get_name(pattern); 318 if (!e.pattern)
322 if (!saved_pattern)
323 return error; 319 return error;
324 if (!saved_pattern->is_patterned) 320 if (!e.pattern->is_patterned)
325 goto out; 321 goto out;
326 if (!is_delete)
327 entry = kmalloc(sizeof(*entry), GFP_NOFS);
328 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 322 if (mutex_lock_interruptible(&tomoyo_policy_lock))
329 goto out; 323 goto out;
330 list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) { 324 list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) {
331 if (saved_pattern != ptr->pattern) 325 if (e.pattern != ptr->pattern)
332 continue; 326 continue;
333 ptr->is_deleted = is_delete; 327 ptr->is_deleted = is_delete;
334 error = 0; 328 error = 0;
335 break; 329 break;
336 } 330 }
337 if (!is_delete && error && tomoyo_memory_ok(entry)) { 331 if (!is_delete && error) {
338 entry->pattern = saved_pattern; 332 struct tomoyo_pattern_entry *entry =
339 saved_pattern = NULL; 333 tomoyo_commit_ok(&e, sizeof(e));
340 list_add_tail_rcu(&entry->list, &tomoyo_pattern_list); 334 if (entry) {
341 entry = NULL; 335 list_add_tail_rcu(&entry->list, &tomoyo_pattern_list);
342 error = 0; 336 error = 0;
337 }
343 } 338 }
344 mutex_unlock(&tomoyo_policy_lock); 339 mutex_unlock(&tomoyo_policy_lock);
345 out: 340 out:
346 kfree(entry); 341 tomoyo_put_name(e.pattern);
347 tomoyo_put_name(saved_pattern);
348 return error; 342 return error;
349} 343}
350 344
@@ -467,38 +461,36 @@ LIST_HEAD(tomoyo_no_rewrite_list);
467static int tomoyo_update_no_rewrite_entry(const char *pattern, 461static int tomoyo_update_no_rewrite_entry(const char *pattern,
468 const bool is_delete) 462 const bool is_delete)
469{ 463{
470 struct tomoyo_no_rewrite_entry *entry = NULL;
471 struct tomoyo_no_rewrite_entry *ptr; 464 struct tomoyo_no_rewrite_entry *ptr;
472 const struct tomoyo_path_info *saved_pattern; 465 struct tomoyo_no_rewrite_entry e = { };
473 int error = is_delete ? -ENOENT : -ENOMEM; 466 int error = is_delete ? -ENOENT : -ENOMEM;
474 467
475 if (!tomoyo_is_correct_path(pattern, 0, 0, 0)) 468 if (!tomoyo_is_correct_path(pattern, 0, 0, 0))
476 return -EINVAL; 469 return -EINVAL;
477 saved_pattern = tomoyo_get_name(pattern); 470 e.pattern = tomoyo_get_name(pattern);
478 if (!saved_pattern) 471 if (!e.pattern)
479 return error; 472 return error;
480 if (!is_delete)
481 entry = kmalloc(sizeof(*entry), GFP_NOFS);
482 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 473 if (mutex_lock_interruptible(&tomoyo_policy_lock))
483 goto out; 474 goto out;
484 list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) { 475 list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) {
485 if (ptr->pattern != saved_pattern) 476 if (ptr->pattern != e.pattern)
486 continue; 477 continue;
487 ptr->is_deleted = is_delete; 478 ptr->is_deleted = is_delete;
488 error = 0; 479 error = 0;
489 break; 480 break;
490 } 481 }
491 if (!is_delete && error && tomoyo_memory_ok(entry)) { 482 if (!is_delete && error) {
492 entry->pattern = saved_pattern; 483 struct tomoyo_no_rewrite_entry *entry =
493 saved_pattern = NULL; 484 tomoyo_commit_ok(&e, sizeof(e));
494 list_add_tail_rcu(&entry->list, &tomoyo_no_rewrite_list); 485 if (entry) {
495 entry = NULL; 486 list_add_tail_rcu(&entry->list,
496 error = 0; 487 &tomoyo_no_rewrite_list);
488 error = 0;
489 }
497 } 490 }
498 mutex_unlock(&tomoyo_policy_lock); 491 mutex_unlock(&tomoyo_policy_lock);
499 out: 492 out:
500 tomoyo_put_name(saved_pattern); 493 tomoyo_put_name(e.pattern);
501 kfree(entry);
502 return error; 494 return error;
503} 495}
504 496
@@ -810,23 +802,26 @@ static int tomoyo_update_path_acl(const u8 type, const char *filename,
810 struct tomoyo_domain_info *const domain, 802 struct tomoyo_domain_info *const domain,
811 const bool is_delete) 803 const bool is_delete)
812{ 804{
813 static const u32 rw_mask = 805 static const u32 tomoyo_rw_mask =
814 (1 << TOMOYO_TYPE_READ) | (1 << TOMOYO_TYPE_WRITE); 806 (1 << TOMOYO_TYPE_READ) | (1 << TOMOYO_TYPE_WRITE);
815 const struct tomoyo_path_info *saved_filename; 807 const u32 perm = 1 << type;
816 struct tomoyo_acl_info *ptr; 808 struct tomoyo_acl_info *ptr;
817 struct tomoyo_path_acl *entry = NULL; 809 struct tomoyo_path_acl e = {
810 .head.type = TOMOYO_TYPE_PATH_ACL,
811 .perm_high = perm >> 16,
812 .perm = perm
813 };
818 int error = is_delete ? -ENOENT : -ENOMEM; 814 int error = is_delete ? -ENOENT : -ENOMEM;
819 const u32 perm = 1 << type;
820 815
816 if (type == TOMOYO_TYPE_READ_WRITE)
817 e.perm |= tomoyo_rw_mask;
821 if (!domain) 818 if (!domain)
822 return -EINVAL; 819 return -EINVAL;
823 if (!tomoyo_is_correct_path(filename, 0, 0, 0)) 820 if (!tomoyo_is_correct_path(filename, 0, 0, 0))
824 return -EINVAL; 821 return -EINVAL;
825 saved_filename = tomoyo_get_name(filename); 822 e.filename = tomoyo_get_name(filename);
826 if (!saved_filename) 823 if (!e.filename)
827 return -ENOMEM; 824 return -ENOMEM;
828 if (!is_delete)
829 entry = kmalloc(sizeof(*entry), GFP_NOFS);
830 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 825 if (mutex_lock_interruptible(&tomoyo_policy_lock))
831 goto out; 826 goto out;
832 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { 827 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
@@ -834,48 +829,42 @@ static int tomoyo_update_path_acl(const u8 type, const char *filename,
834 container_of(ptr, struct tomoyo_path_acl, head); 829 container_of(ptr, struct tomoyo_path_acl, head);
835 if (ptr->type != TOMOYO_TYPE_PATH_ACL) 830 if (ptr->type != TOMOYO_TYPE_PATH_ACL)
836 continue; 831 continue;
837 if (acl->filename != saved_filename) 832 if (acl->filename != e.filename)
838 continue; 833 continue;
839 if (is_delete) { 834 if (is_delete) {
840 if (perm <= 0xFFFF) 835 if (perm <= 0xFFFF)
841 acl->perm &= ~perm; 836 acl->perm &= ~perm;
842 else 837 else
843 acl->perm_high &= ~(perm >> 16); 838 acl->perm_high &= ~(perm >> 16);
844 if ((acl->perm & rw_mask) != rw_mask) 839 if ((acl->perm & tomoyo_rw_mask) != tomoyo_rw_mask)
845 acl->perm &= ~(1 << TOMOYO_TYPE_READ_WRITE); 840 acl->perm &= ~(1 << TOMOYO_TYPE_READ_WRITE);
846 else if (!(acl->perm & (1 << TOMOYO_TYPE_READ_WRITE))) 841 else if (!(acl->perm & (1 << TOMOYO_TYPE_READ_WRITE)))
847 acl->perm &= ~rw_mask; 842 acl->perm &= ~tomoyo_rw_mask;
848 } else { 843 } else {
849 if (perm <= 0xFFFF) 844 if (perm <= 0xFFFF)
850 acl->perm |= perm; 845 acl->perm |= perm;
851 else 846 else
852 acl->perm_high |= (perm >> 16); 847 acl->perm_high |= (perm >> 16);
853 if ((acl->perm & rw_mask) == rw_mask) 848 if ((acl->perm & tomoyo_rw_mask) == tomoyo_rw_mask)
854 acl->perm |= 1 << TOMOYO_TYPE_READ_WRITE; 849 acl->perm |= 1 << TOMOYO_TYPE_READ_WRITE;
855 else if (acl->perm & (1 << TOMOYO_TYPE_READ_WRITE)) 850 else if (acl->perm & (1 << TOMOYO_TYPE_READ_WRITE))
856 acl->perm |= rw_mask; 851 acl->perm |= tomoyo_rw_mask;
857 } 852 }
858 error = 0; 853 error = 0;
859 break; 854 break;
860 } 855 }
861 if (!is_delete && error && tomoyo_memory_ok(entry)) { 856 if (!is_delete && error) {
862 entry->head.type = TOMOYO_TYPE_PATH_ACL; 857 struct tomoyo_path_acl *entry =
863 if (perm <= 0xFFFF) 858 tomoyo_commit_ok(&e, sizeof(e));
864 entry->perm = perm; 859 if (entry) {
865 else 860 list_add_tail_rcu(&entry->head.list,
866 entry->perm_high = (perm >> 16); 861 &domain->acl_info_list);
867 if (perm == (1 << TOMOYO_TYPE_READ_WRITE)) 862 error = 0;
868 entry->perm |= rw_mask; 863 }
869 entry->filename = saved_filename;
870 saved_filename = NULL;
871 list_add_tail_rcu(&entry->head.list, &domain->acl_info_list);
872 entry = NULL;
873 error = 0;
874 } 864 }
875 mutex_unlock(&tomoyo_policy_lock); 865 mutex_unlock(&tomoyo_policy_lock);
876 out: 866 out:
877 kfree(entry); 867 tomoyo_put_name(e.filename);
878 tomoyo_put_name(saved_filename);
879 return error; 868 return error;
880} 869}
881 870
@@ -897,24 +886,23 @@ static int tomoyo_update_path2_acl(const u8 type, const char *filename1,
897 struct tomoyo_domain_info *const domain, 886 struct tomoyo_domain_info *const domain,
898 const bool is_delete) 887 const bool is_delete)
899{ 888{
900 const struct tomoyo_path_info *saved_filename1; 889 const u8 perm = 1 << type;
901 const struct tomoyo_path_info *saved_filename2; 890 struct tomoyo_path2_acl e = {
891 .head.type = TOMOYO_TYPE_PATH2_ACL,
892 .perm = perm
893 };
902 struct tomoyo_acl_info *ptr; 894 struct tomoyo_acl_info *ptr;
903 struct tomoyo_path2_acl *entry = NULL;
904 int error = is_delete ? -ENOENT : -ENOMEM; 895 int error = is_delete ? -ENOENT : -ENOMEM;
905 const u8 perm = 1 << type;
906 896
907 if (!domain) 897 if (!domain)
908 return -EINVAL; 898 return -EINVAL;
909 if (!tomoyo_is_correct_path(filename1, 0, 0, 0) || 899 if (!tomoyo_is_correct_path(filename1, 0, 0, 0) ||
910 !tomoyo_is_correct_path(filename2, 0, 0, 0)) 900 !tomoyo_is_correct_path(filename2, 0, 0, 0))
911 return -EINVAL; 901 return -EINVAL;
912 saved_filename1 = tomoyo_get_name(filename1); 902 e.filename1 = tomoyo_get_name(filename1);
913 saved_filename2 = tomoyo_get_name(filename2); 903 e.filename2 = tomoyo_get_name(filename2);
914 if (!saved_filename1 || !saved_filename2) 904 if (!e.filename1 || !e.filename2)
915 goto out; 905 goto out;
916 if (!is_delete)
917 entry = kmalloc(sizeof(*entry), GFP_NOFS);
918 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 906 if (mutex_lock_interruptible(&tomoyo_policy_lock))
919 goto out; 907 goto out;
920 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { 908 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
@@ -922,8 +910,8 @@ static int tomoyo_update_path2_acl(const u8 type, const char *filename1,
922 container_of(ptr, struct tomoyo_path2_acl, head); 910 container_of(ptr, struct tomoyo_path2_acl, head);
923 if (ptr->type != TOMOYO_TYPE_PATH2_ACL) 911 if (ptr->type != TOMOYO_TYPE_PATH2_ACL)
924 continue; 912 continue;
925 if (acl->filename1 != saved_filename1 || 913 if (acl->filename1 != e.filename1 ||
926 acl->filename2 != saved_filename2) 914 acl->filename2 != e.filename2)
927 continue; 915 continue;
928 if (is_delete) 916 if (is_delete)
929 acl->perm &= ~perm; 917 acl->perm &= ~perm;
@@ -932,22 +920,19 @@ static int tomoyo_update_path2_acl(const u8 type, const char *filename1,
932 error = 0; 920 error = 0;
933 break; 921 break;
934 } 922 }
935 if (!is_delete && error && tomoyo_memory_ok(entry)) { 923 if (!is_delete && error) {
936 entry->head.type = TOMOYO_TYPE_PATH2_ACL; 924 struct tomoyo_path2_acl *entry =
937 entry->perm = perm; 925 tomoyo_commit_ok(&e, sizeof(e));
938 entry->filename1 = saved_filename1; 926 if (entry) {
939 saved_filename1 = NULL; 927 list_add_tail_rcu(&entry->head.list,
940 entry->filename2 = saved_filename2; 928 &domain->acl_info_list);
941 saved_filename2 = NULL; 929 error = 0;
942 list_add_tail_rcu(&entry->head.list, &domain->acl_info_list); 930 }
943 entry = NULL;
944 error = 0;
945 } 931 }
946 mutex_unlock(&tomoyo_policy_lock); 932 mutex_unlock(&tomoyo_policy_lock);
947 out: 933 out:
948 tomoyo_put_name(saved_filename1); 934 tomoyo_put_name(e.filename1);
949 tomoyo_put_name(saved_filename2); 935 tomoyo_put_name(e.filename2);
950 kfree(entry);
951 return error; 936 return error;
952} 937}
953 938