diff options
author | Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> | 2010-05-05 11:18:15 -0400 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2010-05-05 23:19:18 -0400 |
commit | 292823814261e085cdcef06b6b691e6c2563fbd4 (patch) | |
tree | 8c1eaebcf8f698ea13ac2a9291b9769abde1905e | |
parent | 2b9e4688fad8867b6e918610f396af3ab9246898 (diff) |
TOMOYO: Use mutex_lock_interruptible.
Some of TOMOYO's functions may sleep after mutex_lock(). If OOM-killer selected
a process which is waiting at mutex_lock(), the to-be-killed process can't be
killed. Thus, replace mutex_lock() with mutex_lock_interruptible() so that the
to-be-killed process can immediately return from TOMOYO's functions.
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: James Morris <jmorris@namei.org>
-rw-r--r-- | security/tomoyo/common.c | 13 | ||||
-rw-r--r-- | security/tomoyo/common.h | 1 | ||||
-rw-r--r-- | security/tomoyo/domain.c | 15 | ||||
-rw-r--r-- | security/tomoyo/file.c | 18 | ||||
-rw-r--r-- | security/tomoyo/gc.c | 7 | ||||
-rw-r--r-- | security/tomoyo/realpath.c | 7 |
6 files changed, 37 insertions, 24 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index 3c86bbc33aeb..8f34036fd31c 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c | |||
@@ -874,13 +874,13 @@ bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain) | |||
874 | static struct tomoyo_profile *tomoyo_find_or_assign_new_profile(const unsigned | 874 | static struct tomoyo_profile *tomoyo_find_or_assign_new_profile(const unsigned |
875 | int profile) | 875 | int profile) |
876 | { | 876 | { |
877 | static DEFINE_MUTEX(lock); | ||
878 | struct tomoyo_profile *ptr = NULL; | 877 | struct tomoyo_profile *ptr = NULL; |
879 | int i; | 878 | int i; |
880 | 879 | ||
881 | if (profile >= TOMOYO_MAX_PROFILES) | 880 | if (profile >= TOMOYO_MAX_PROFILES) |
882 | return NULL; | 881 | return NULL; |
883 | mutex_lock(&lock); | 882 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) |
883 | return NULL; | ||
884 | ptr = tomoyo_profile_ptr[profile]; | 884 | ptr = tomoyo_profile_ptr[profile]; |
885 | if (ptr) | 885 | if (ptr) |
886 | goto ok; | 886 | goto ok; |
@@ -895,7 +895,7 @@ static struct tomoyo_profile *tomoyo_find_or_assign_new_profile(const unsigned | |||
895 | mb(); /* Avoid out-of-order execution. */ | 895 | mb(); /* Avoid out-of-order execution. */ |
896 | tomoyo_profile_ptr[profile] = ptr; | 896 | tomoyo_profile_ptr[profile] = ptr; |
897 | ok: | 897 | ok: |
898 | mutex_unlock(&lock); | 898 | mutex_unlock(&tomoyo_policy_lock); |
899 | return ptr; | 899 | return ptr; |
900 | } | 900 | } |
901 | 901 | ||
@@ -1090,7 +1090,8 @@ static int tomoyo_update_manager_entry(const char *manager, | |||
1090 | return -ENOMEM; | 1090 | return -ENOMEM; |
1091 | if (!is_delete) | 1091 | if (!is_delete) |
1092 | entry = kmalloc(sizeof(*entry), GFP_NOFS); | 1092 | entry = kmalloc(sizeof(*entry), GFP_NOFS); |
1093 | mutex_lock(&tomoyo_policy_lock); | 1093 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) |
1094 | goto out; | ||
1094 | list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) { | 1095 | list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) { |
1095 | if (ptr->manager != saved_manager) | 1096 | if (ptr->manager != saved_manager) |
1096 | continue; | 1097 | continue; |
@@ -1107,6 +1108,7 @@ static int tomoyo_update_manager_entry(const char *manager, | |||
1107 | error = 0; | 1108 | error = 0; |
1108 | } | 1109 | } |
1109 | mutex_unlock(&tomoyo_policy_lock); | 1110 | mutex_unlock(&tomoyo_policy_lock); |
1111 | out: | ||
1110 | tomoyo_put_name(saved_manager); | 1112 | tomoyo_put_name(saved_manager); |
1111 | kfree(entry); | 1113 | kfree(entry); |
1112 | return error; | 1114 | return error; |
@@ -1287,7 +1289,8 @@ static int tomoyo_delete_domain(char *domainname) | |||
1287 | 1289 | ||
1288 | name.name = domainname; | 1290 | name.name = domainname; |
1289 | tomoyo_fill_path_info(&name); | 1291 | tomoyo_fill_path_info(&name); |
1290 | mutex_lock(&tomoyo_policy_lock); | 1292 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) |
1293 | return 0; | ||
1291 | /* Is there an active domain? */ | 1294 | /* Is there an active domain? */ |
1292 | list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { | 1295 | list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { |
1293 | /* Never delete tomoyo_kernel_domain */ | 1296 | /* Never delete tomoyo_kernel_domain */ |
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h index 67bd22dd3e68..52c9502ed675 100644 --- a/security/tomoyo/common.h +++ b/security/tomoyo/common.h | |||
@@ -662,7 +662,6 @@ extern struct list_head tomoyo_pattern_list; | |||
662 | extern struct list_head tomoyo_no_rewrite_list; | 662 | extern struct list_head tomoyo_no_rewrite_list; |
663 | extern struct list_head tomoyo_policy_manager_list; | 663 | extern struct list_head tomoyo_policy_manager_list; |
664 | extern struct list_head tomoyo_name_list[TOMOYO_MAX_HASH]; | 664 | extern struct list_head tomoyo_name_list[TOMOYO_MAX_HASH]; |
665 | extern struct mutex tomoyo_name_list_lock; | ||
666 | 665 | ||
667 | /* Lock for protecting policy. */ | 666 | /* Lock for protecting policy. */ |
668 | extern struct mutex tomoyo_policy_lock; | 667 | extern struct mutex tomoyo_policy_lock; |
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c index e1edec4a9b9d..a1723bbcde0e 100644 --- a/security/tomoyo/domain.c +++ b/security/tomoyo/domain.c | |||
@@ -154,7 +154,8 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname, | |||
154 | goto out; | 154 | goto out; |
155 | if (!is_delete) | 155 | if (!is_delete) |
156 | entry = kmalloc(sizeof(*entry), GFP_NOFS); | 156 | entry = kmalloc(sizeof(*entry), GFP_NOFS); |
157 | mutex_lock(&tomoyo_policy_lock); | 157 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) |
158 | goto out; | ||
158 | list_for_each_entry_rcu(ptr, &tomoyo_domain_initializer_list, list) { | 159 | list_for_each_entry_rcu(ptr, &tomoyo_domain_initializer_list, list) { |
159 | if (ptr->is_not != is_not || | 160 | if (ptr->is_not != is_not || |
160 | ptr->domainname != saved_domainname || | 161 | ptr->domainname != saved_domainname || |
@@ -374,7 +375,8 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname, | |||
374 | goto out; | 375 | goto out; |
375 | if (!is_delete) | 376 | if (!is_delete) |
376 | entry = kmalloc(sizeof(*entry), GFP_NOFS); | 377 | entry = kmalloc(sizeof(*entry), GFP_NOFS); |
377 | mutex_lock(&tomoyo_policy_lock); | 378 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) |
379 | goto out; | ||
378 | list_for_each_entry_rcu(ptr, &tomoyo_domain_keeper_list, list) { | 380 | list_for_each_entry_rcu(ptr, &tomoyo_domain_keeper_list, list) { |
379 | if (ptr->is_not != is_not || | 381 | if (ptr->is_not != is_not || |
380 | ptr->domainname != saved_domainname || | 382 | ptr->domainname != saved_domainname || |
@@ -566,7 +568,8 @@ static int tomoyo_update_alias_entry(const char *original_name, | |||
566 | goto out; | 568 | goto out; |
567 | if (!is_delete) | 569 | if (!is_delete) |
568 | entry = kmalloc(sizeof(*entry), GFP_NOFS); | 570 | entry = kmalloc(sizeof(*entry), GFP_NOFS); |
569 | mutex_lock(&tomoyo_policy_lock); | 571 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) |
572 | goto out; | ||
570 | list_for_each_entry_rcu(ptr, &tomoyo_alias_list, list) { | 573 | list_for_each_entry_rcu(ptr, &tomoyo_alias_list, list) { |
571 | if (ptr->original_name != saved_original_name || | 574 | if (ptr->original_name != saved_original_name || |
572 | ptr->aliased_name != saved_aliased_name) | 575 | ptr->aliased_name != saved_aliased_name) |
@@ -656,7 +659,7 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char * | |||
656 | const u8 profile) | 659 | const u8 profile) |
657 | { | 660 | { |
658 | struct tomoyo_domain_info *entry; | 661 | struct tomoyo_domain_info *entry; |
659 | struct tomoyo_domain_info *domain; | 662 | struct tomoyo_domain_info *domain = NULL; |
660 | const struct tomoyo_path_info *saved_domainname; | 663 | const struct tomoyo_path_info *saved_domainname; |
661 | bool found = false; | 664 | bool found = false; |
662 | 665 | ||
@@ -666,7 +669,8 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char * | |||
666 | if (!saved_domainname) | 669 | if (!saved_domainname) |
667 | return NULL; | 670 | return NULL; |
668 | entry = kzalloc(sizeof(*entry), GFP_NOFS); | 671 | entry = kzalloc(sizeof(*entry), GFP_NOFS); |
669 | mutex_lock(&tomoyo_policy_lock); | 672 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) |
673 | goto out; | ||
670 | list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { | 674 | list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { |
671 | if (domain->is_deleted || | 675 | if (domain->is_deleted || |
672 | tomoyo_pathcmp(saved_domainname, domain->domainname)) | 676 | tomoyo_pathcmp(saved_domainname, domain->domainname)) |
@@ -685,6 +689,7 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char * | |||
685 | found = true; | 689 | found = true; |
686 | } | 690 | } |
687 | mutex_unlock(&tomoyo_policy_lock); | 691 | mutex_unlock(&tomoyo_policy_lock); |
692 | out: | ||
688 | tomoyo_put_name(saved_domainname); | 693 | tomoyo_put_name(saved_domainname); |
689 | kfree(entry); | 694 | kfree(entry); |
690 | return found ? domain : NULL; | 695 | return found ? domain : NULL; |
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c index 0687ada28e82..060bbf3870ce 100644 --- a/security/tomoyo/file.c +++ b/security/tomoyo/file.c | |||
@@ -176,7 +176,8 @@ static int tomoyo_update_globally_readable_entry(const char *filename, | |||
176 | return -ENOMEM; | 176 | return -ENOMEM; |
177 | if (!is_delete) | 177 | if (!is_delete) |
178 | entry = kmalloc(sizeof(*entry), GFP_NOFS); | 178 | entry = kmalloc(sizeof(*entry), GFP_NOFS); |
179 | mutex_lock(&tomoyo_policy_lock); | 179 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) |
180 | goto out; | ||
180 | list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) { | 181 | list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) { |
181 | if (ptr->filename != saved_filename) | 182 | if (ptr->filename != saved_filename) |
182 | continue; | 183 | continue; |
@@ -192,6 +193,7 @@ static int tomoyo_update_globally_readable_entry(const char *filename, | |||
192 | error = 0; | 193 | error = 0; |
193 | } | 194 | } |
194 | mutex_unlock(&tomoyo_policy_lock); | 195 | mutex_unlock(&tomoyo_policy_lock); |
196 | out: | ||
195 | tomoyo_put_name(saved_filename); | 197 | tomoyo_put_name(saved_filename); |
196 | kfree(entry); | 198 | kfree(entry); |
197 | return error; | 199 | return error; |
@@ -323,7 +325,8 @@ static int tomoyo_update_file_pattern_entry(const char *pattern, | |||
323 | goto out; | 325 | goto out; |
324 | if (!is_delete) | 326 | if (!is_delete) |
325 | entry = kmalloc(sizeof(*entry), GFP_NOFS); | 327 | entry = kmalloc(sizeof(*entry), GFP_NOFS); |
326 | mutex_lock(&tomoyo_policy_lock); | 328 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) |
329 | goto out; | ||
327 | list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) { | 330 | list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) { |
328 | if (saved_pattern != ptr->pattern) | 331 | if (saved_pattern != ptr->pattern) |
329 | continue; | 332 | continue; |
@@ -476,7 +479,8 @@ static int tomoyo_update_no_rewrite_entry(const char *pattern, | |||
476 | return error; | 479 | return error; |
477 | if (!is_delete) | 480 | if (!is_delete) |
478 | entry = kmalloc(sizeof(*entry), GFP_NOFS); | 481 | entry = kmalloc(sizeof(*entry), GFP_NOFS); |
479 | mutex_lock(&tomoyo_policy_lock); | 482 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) |
483 | goto out; | ||
480 | list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) { | 484 | list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) { |
481 | if (ptr->pattern != saved_pattern) | 485 | if (ptr->pattern != saved_pattern) |
482 | continue; | 486 | continue; |
@@ -492,6 +496,7 @@ static int tomoyo_update_no_rewrite_entry(const char *pattern, | |||
492 | error = 0; | 496 | error = 0; |
493 | } | 497 | } |
494 | mutex_unlock(&tomoyo_policy_lock); | 498 | mutex_unlock(&tomoyo_policy_lock); |
499 | out: | ||
495 | tomoyo_put_name(saved_pattern); | 500 | tomoyo_put_name(saved_pattern); |
496 | kfree(entry); | 501 | kfree(entry); |
497 | return error; | 502 | return error; |
@@ -822,7 +827,8 @@ static int tomoyo_update_path_acl(const u8 type, const char *filename, | |||
822 | return -ENOMEM; | 827 | return -ENOMEM; |
823 | if (!is_delete) | 828 | if (!is_delete) |
824 | entry = kmalloc(sizeof(*entry), GFP_NOFS); | 829 | entry = kmalloc(sizeof(*entry), GFP_NOFS); |
825 | mutex_lock(&tomoyo_policy_lock); | 830 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) |
831 | goto out; | ||
826 | list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { | 832 | list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { |
827 | struct tomoyo_path_acl *acl = | 833 | struct tomoyo_path_acl *acl = |
828 | container_of(ptr, struct tomoyo_path_acl, head); | 834 | container_of(ptr, struct tomoyo_path_acl, head); |
@@ -867,6 +873,7 @@ static int tomoyo_update_path_acl(const u8 type, const char *filename, | |||
867 | error = 0; | 873 | error = 0; |
868 | } | 874 | } |
869 | mutex_unlock(&tomoyo_policy_lock); | 875 | mutex_unlock(&tomoyo_policy_lock); |
876 | out: | ||
870 | kfree(entry); | 877 | kfree(entry); |
871 | tomoyo_put_name(saved_filename); | 878 | tomoyo_put_name(saved_filename); |
872 | return error; | 879 | return error; |
@@ -908,7 +915,8 @@ static int tomoyo_update_path2_acl(const u8 type, const char *filename1, | |||
908 | goto out; | 915 | goto out; |
909 | if (!is_delete) | 916 | if (!is_delete) |
910 | entry = kmalloc(sizeof(*entry), GFP_NOFS); | 917 | entry = kmalloc(sizeof(*entry), GFP_NOFS); |
911 | mutex_lock(&tomoyo_policy_lock); | 918 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) |
919 | goto out; | ||
912 | list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { | 920 | list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { |
913 | struct tomoyo_path2_acl *acl = | 921 | struct tomoyo_path2_acl *acl = |
914 | container_of(ptr, struct tomoyo_path2_acl, head); | 922 | container_of(ptr, struct tomoyo_path2_acl, head); |
diff --git a/security/tomoyo/gc.c b/security/tomoyo/gc.c index d9ad35bc7fa8..245bf422e3a5 100644 --- a/security/tomoyo/gc.c +++ b/security/tomoyo/gc.c | |||
@@ -151,7 +151,8 @@ static void tomoyo_del_name(const struct tomoyo_name_entry *ptr) | |||
151 | 151 | ||
152 | static void tomoyo_collect_entry(void) | 152 | static void tomoyo_collect_entry(void) |
153 | { | 153 | { |
154 | mutex_lock(&tomoyo_policy_lock); | 154 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) |
155 | return; | ||
155 | { | 156 | { |
156 | struct tomoyo_globally_readable_file_entry *ptr; | 157 | struct tomoyo_globally_readable_file_entry *ptr; |
157 | list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, | 158 | list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, |
@@ -275,8 +276,6 @@ static void tomoyo_collect_entry(void) | |||
275 | break; | 276 | break; |
276 | } | 277 | } |
277 | } | 278 | } |
278 | mutex_unlock(&tomoyo_policy_lock); | ||
279 | mutex_lock(&tomoyo_name_list_lock); | ||
280 | { | 279 | { |
281 | int i; | 280 | int i; |
282 | for (i = 0; i < TOMOYO_MAX_HASH; i++) { | 281 | for (i = 0; i < TOMOYO_MAX_HASH; i++) { |
@@ -294,7 +293,7 @@ static void tomoyo_collect_entry(void) | |||
294 | } | 293 | } |
295 | } | 294 | } |
296 | } | 295 | } |
297 | mutex_unlock(&tomoyo_name_list_lock); | 296 | mutex_unlock(&tomoyo_policy_lock); |
298 | } | 297 | } |
299 | 298 | ||
300 | static void tomoyo_kfree_entry(void) | 299 | static void tomoyo_kfree_entry(void) |
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c index 6a51e0af2417..62062a68525a 100644 --- a/security/tomoyo/realpath.c +++ b/security/tomoyo/realpath.c | |||
@@ -240,8 +240,6 @@ void tomoyo_memory_free(void *ptr) | |||
240 | * "const struct tomoyo_path_info *". | 240 | * "const struct tomoyo_path_info *". |
241 | */ | 241 | */ |
242 | struct list_head tomoyo_name_list[TOMOYO_MAX_HASH]; | 242 | struct list_head tomoyo_name_list[TOMOYO_MAX_HASH]; |
243 | /* Lock for protecting tomoyo_name_list . */ | ||
244 | DEFINE_MUTEX(tomoyo_name_list_lock); | ||
245 | 243 | ||
246 | /** | 244 | /** |
247 | * tomoyo_get_name - Allocate permanent memory for string data. | 245 | * tomoyo_get_name - Allocate permanent memory for string data. |
@@ -263,7 +261,8 @@ const struct tomoyo_path_info *tomoyo_get_name(const char *name) | |||
263 | len = strlen(name) + 1; | 261 | len = strlen(name) + 1; |
264 | hash = full_name_hash((const unsigned char *) name, len - 1); | 262 | hash = full_name_hash((const unsigned char *) name, len - 1); |
265 | head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)]; | 263 | head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)]; |
266 | mutex_lock(&tomoyo_name_list_lock); | 264 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) |
265 | return NULL; | ||
267 | list_for_each_entry(ptr, head, list) { | 266 | list_for_each_entry(ptr, head, list) { |
268 | if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name)) | 267 | if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name)) |
269 | continue; | 268 | continue; |
@@ -290,7 +289,7 @@ const struct tomoyo_path_info *tomoyo_get_name(const char *name) | |||
290 | tomoyo_fill_path_info(&ptr->entry); | 289 | tomoyo_fill_path_info(&ptr->entry); |
291 | list_add_tail(&ptr->list, head); | 290 | list_add_tail(&ptr->list, head); |
292 | out: | 291 | out: |
293 | mutex_unlock(&tomoyo_name_list_lock); | 292 | mutex_unlock(&tomoyo_policy_lock); |
294 | return ptr ? &ptr->entry : NULL; | 293 | return ptr ? &ptr->entry : NULL; |
295 | } | 294 | } |
296 | 295 | ||