aboutsummaryrefslogtreecommitdiffstats
path: root/security/tomoyo
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2010-02-10 19:41:58 -0500
committerJames Morris <jmorris@namei.org>2010-02-14 17:00:16 -0500
commitbf24fb016c861b7f52be0c36c4cedd3e89afa2e2 (patch)
treef485ca2e70d8305d9aaecf45b5fd929b68b971b2 /security/tomoyo
parentca0b7df3374c5566468c17f26fa2dfd3fe3c6a37 (diff)
TOMOYO: Add refcounter on string data.
Add refcounter to "struct tomoyo_name_entry" and replace tomoyo_save_name() with tomoyo_get_name()/tomoyo_put_name() pair so that we can kfree() when garbage collector is added. Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Acked-by: Serge Hallyn <serue@us.ibm.com> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/tomoyo')
-rw-r--r--security/tomoyo/common.c10
-rw-r--r--security/tomoyo/domain.c32
-rw-r--r--security/tomoyo/file.c24
-rw-r--r--security/tomoyo/realpath.c30
-rw-r--r--security/tomoyo/realpath.h21
5 files changed, 77 insertions, 40 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index a53ee059da48..0c7ea51e7a45 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -12,8 +12,8 @@
12#include <linux/uaccess.h> 12#include <linux/uaccess.h>
13#include <linux/security.h> 13#include <linux/security.h>
14#include <linux/hardirq.h> 14#include <linux/hardirq.h>
15#include "realpath.h"
16#include "common.h" 15#include "common.h"
16#include "realpath.h"
17#include "tomoyo.h" 17#include "tomoyo.h"
18 18
19/* Lock for protecting policy. */ 19/* Lock for protecting policy. */
@@ -943,7 +943,9 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head)
943 return -EINVAL; 943 return -EINVAL;
944 *cp = '\0'; 944 *cp = '\0';
945 if (!strcmp(data, "COMMENT")) { 945 if (!strcmp(data, "COMMENT")) {
946 profile->comment = tomoyo_save_name(cp + 1); 946 const struct tomoyo_path_info *old_comment = profile->comment;
947 profile->comment = tomoyo_get_name(cp + 1);
948 tomoyo_put_name(old_comment);
947 return 0; 949 return 0;
948 } 950 }
949 for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++) { 951 for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++) {
@@ -1117,7 +1119,7 @@ static int tomoyo_update_manager_entry(const char *manager,
1117 if (!tomoyo_is_correct_path(manager, 1, -1, -1, __func__)) 1119 if (!tomoyo_is_correct_path(manager, 1, -1, -1, __func__))
1118 return -EINVAL; 1120 return -EINVAL;
1119 } 1121 }
1120 saved_manager = tomoyo_save_name(manager); 1122 saved_manager = tomoyo_get_name(manager);
1121 if (!saved_manager) 1123 if (!saved_manager)
1122 return -ENOMEM; 1124 return -ENOMEM;
1123 if (!is_delete) 1125 if (!is_delete)
@@ -1132,12 +1134,14 @@ static int tomoyo_update_manager_entry(const char *manager,
1132 } 1134 }
1133 if (!is_delete && error && tomoyo_memory_ok(entry)) { 1135 if (!is_delete && error && tomoyo_memory_ok(entry)) {
1134 entry->manager = saved_manager; 1136 entry->manager = saved_manager;
1137 saved_manager = NULL;
1135 entry->is_domain = is_domain; 1138 entry->is_domain = is_domain;
1136 list_add_tail_rcu(&entry->list, &tomoyo_policy_manager_list); 1139 list_add_tail_rcu(&entry->list, &tomoyo_policy_manager_list);
1137 entry = NULL; 1140 entry = NULL;
1138 error = 0; 1141 error = 0;
1139 } 1142 }
1140 mutex_unlock(&tomoyo_policy_lock); 1143 mutex_unlock(&tomoyo_policy_lock);
1144 tomoyo_put_name(saved_manager);
1141 kfree(entry); 1145 kfree(entry);
1142 return error; 1146 return error;
1143} 1147}
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index 229de1e71a38..0b8262567809 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -203,7 +203,7 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
203{ 203{
204 struct tomoyo_domain_initializer_entry *entry = NULL; 204 struct tomoyo_domain_initializer_entry *entry = NULL;
205 struct tomoyo_domain_initializer_entry *ptr; 205 struct tomoyo_domain_initializer_entry *ptr;
206 const struct tomoyo_path_info *saved_program; 206 const struct tomoyo_path_info *saved_program = NULL;
207 const struct tomoyo_path_info *saved_domainname = NULL; 207 const struct tomoyo_path_info *saved_domainname = NULL;
208 int error = is_delete ? -ENOENT : -ENOMEM; 208 int error = is_delete ? -ENOENT : -ENOMEM;
209 bool is_last_name = false; 209 bool is_last_name = false;
@@ -216,11 +216,11 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
216 is_last_name = true; 216 is_last_name = true;
217 else if (!tomoyo_is_correct_domain(domainname, __func__)) 217 else if (!tomoyo_is_correct_domain(domainname, __func__))
218 return -EINVAL; 218 return -EINVAL;
219 saved_domainname = tomoyo_save_name(domainname); 219 saved_domainname = tomoyo_get_name(domainname);
220 if (!saved_domainname) 220 if (!saved_domainname)
221 goto out; 221 goto out;
222 } 222 }
223 saved_program = tomoyo_save_name(program); 223 saved_program = tomoyo_get_name(program);
224 if (!saved_program) 224 if (!saved_program)
225 goto out; 225 goto out;
226 if (!is_delete) 226 if (!is_delete)
@@ -237,7 +237,9 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
237 } 237 }
238 if (!is_delete && error && tomoyo_memory_ok(entry)) { 238 if (!is_delete && error && tomoyo_memory_ok(entry)) {
239 entry->domainname = saved_domainname; 239 entry->domainname = saved_domainname;
240 saved_domainname = NULL;
240 entry->program = saved_program; 241 entry->program = saved_program;
242 saved_program = NULL;
241 entry->is_not = is_not; 243 entry->is_not = is_not;
242 entry->is_last_name = is_last_name; 244 entry->is_last_name = is_last_name;
243 list_add_tail_rcu(&entry->list, 245 list_add_tail_rcu(&entry->list,
@@ -247,6 +249,8 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
247 } 249 }
248 mutex_unlock(&tomoyo_policy_lock); 250 mutex_unlock(&tomoyo_policy_lock);
249 out: 251 out:
252 tomoyo_put_name(saved_domainname);
253 tomoyo_put_name(saved_program);
250 kfree(entry); 254 kfree(entry);
251 return error; 255 return error;
252} 256}
@@ -419,7 +423,7 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
419{ 423{
420 struct tomoyo_domain_keeper_entry *entry = NULL; 424 struct tomoyo_domain_keeper_entry *entry = NULL;
421 struct tomoyo_domain_keeper_entry *ptr; 425 struct tomoyo_domain_keeper_entry *ptr;
422 const struct tomoyo_path_info *saved_domainname; 426 const struct tomoyo_path_info *saved_domainname = NULL;
423 const struct tomoyo_path_info *saved_program = NULL; 427 const struct tomoyo_path_info *saved_program = NULL;
424 int error = is_delete ? -ENOENT : -ENOMEM; 428 int error = is_delete ? -ENOENT : -ENOMEM;
425 bool is_last_name = false; 429 bool is_last_name = false;
@@ -432,11 +436,11 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
432 if (program) { 436 if (program) {
433 if (!tomoyo_is_correct_path(program, 1, -1, -1, __func__)) 437 if (!tomoyo_is_correct_path(program, 1, -1, -1, __func__))
434 return -EINVAL; 438 return -EINVAL;
435 saved_program = tomoyo_save_name(program); 439 saved_program = tomoyo_get_name(program);
436 if (!saved_program) 440 if (!saved_program)
437 goto out; 441 goto out;
438 } 442 }
439 saved_domainname = tomoyo_save_name(domainname); 443 saved_domainname = tomoyo_get_name(domainname);
440 if (!saved_domainname) 444 if (!saved_domainname)
441 goto out; 445 goto out;
442 if (!is_delete) 446 if (!is_delete)
@@ -453,7 +457,9 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
453 } 457 }
454 if (!is_delete && error && tomoyo_memory_ok(entry)) { 458 if (!is_delete && error && tomoyo_memory_ok(entry)) {
455 entry->domainname = saved_domainname; 459 entry->domainname = saved_domainname;
460 saved_domainname = NULL;
456 entry->program = saved_program; 461 entry->program = saved_program;
462 saved_program = NULL;
457 entry->is_not = is_not; 463 entry->is_not = is_not;
458 entry->is_last_name = is_last_name; 464 entry->is_last_name = is_last_name;
459 list_add_tail_rcu(&entry->list, &tomoyo_domain_keeper_list); 465 list_add_tail_rcu(&entry->list, &tomoyo_domain_keeper_list);
@@ -462,6 +468,8 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
462 } 468 }
463 mutex_unlock(&tomoyo_policy_lock); 469 mutex_unlock(&tomoyo_policy_lock);
464 out: 470 out:
471 tomoyo_put_name(saved_domainname);
472 tomoyo_put_name(saved_program);
465 kfree(entry); 473 kfree(entry);
466 return error; 474 return error;
467} 475}
@@ -623,8 +631,8 @@ static int tomoyo_update_alias_entry(const char *original_name,
623 if (!tomoyo_is_correct_path(original_name, 1, -1, -1, __func__) || 631 if (!tomoyo_is_correct_path(original_name, 1, -1, -1, __func__) ||
624 !tomoyo_is_correct_path(aliased_name, 1, -1, -1, __func__)) 632 !tomoyo_is_correct_path(aliased_name, 1, -1, -1, __func__))
625 return -EINVAL; /* No patterns allowed. */ 633 return -EINVAL; /* No patterns allowed. */
626 saved_original_name = tomoyo_save_name(original_name); 634 saved_original_name = tomoyo_get_name(original_name);
627 saved_aliased_name = tomoyo_save_name(aliased_name); 635 saved_aliased_name = tomoyo_get_name(aliased_name);
628 if (!saved_original_name || !saved_aliased_name) 636 if (!saved_original_name || !saved_aliased_name)
629 goto out; 637 goto out;
630 if (!is_delete) 638 if (!is_delete)
@@ -640,13 +648,17 @@ static int tomoyo_update_alias_entry(const char *original_name,
640 } 648 }
641 if (!is_delete && error && tomoyo_memory_ok(entry)) { 649 if (!is_delete && error && tomoyo_memory_ok(entry)) {
642 entry->original_name = saved_original_name; 650 entry->original_name = saved_original_name;
651 saved_original_name = NULL;
643 entry->aliased_name = saved_aliased_name; 652 entry->aliased_name = saved_aliased_name;
653 saved_aliased_name = NULL;
644 list_add_tail_rcu(&entry->list, &tomoyo_alias_list); 654 list_add_tail_rcu(&entry->list, &tomoyo_alias_list);
645 entry = NULL; 655 entry = NULL;
646 error = 0; 656 error = 0;
647 } 657 }
648 mutex_unlock(&tomoyo_policy_lock); 658 mutex_unlock(&tomoyo_policy_lock);
649 out: 659 out:
660 tomoyo_put_name(saved_original_name);
661 tomoyo_put_name(saved_aliased_name);
650 kfree(entry); 662 kfree(entry);
651 return error; 663 return error;
652} 664}
@@ -721,7 +733,7 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
721 733
722 if (!tomoyo_is_correct_domain(domainname, __func__)) 734 if (!tomoyo_is_correct_domain(domainname, __func__))
723 return NULL; 735 return NULL;
724 saved_domainname = tomoyo_save_name(domainname); 736 saved_domainname = tomoyo_get_name(domainname);
725 if (!saved_domainname) 737 if (!saved_domainname)
726 return NULL; 738 return NULL;
727 entry = kzalloc(sizeof(*entry), GFP_KERNEL); 739 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
@@ -736,6 +748,7 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
736 if (!found && tomoyo_memory_ok(entry)) { 748 if (!found && tomoyo_memory_ok(entry)) {
737 INIT_LIST_HEAD(&entry->acl_info_list); 749 INIT_LIST_HEAD(&entry->acl_info_list);
738 entry->domainname = saved_domainname; 750 entry->domainname = saved_domainname;
751 saved_domainname = NULL;
739 entry->profile = profile; 752 entry->profile = profile;
740 list_add_tail_rcu(&entry->list, &tomoyo_domain_list); 753 list_add_tail_rcu(&entry->list, &tomoyo_domain_list);
741 domain = entry; 754 domain = entry;
@@ -743,6 +756,7 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
743 found = true; 756 found = true;
744 } 757 }
745 mutex_unlock(&tomoyo_policy_lock); 758 mutex_unlock(&tomoyo_policy_lock);
759 tomoyo_put_name(saved_domainname);
746 kfree(entry); 760 kfree(entry);
747 return found ? domain : NULL; 761 return found ? domain : NULL;
748} 762}
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c
index f4a27714e077..a49e18cc7bc2 100644
--- a/security/tomoyo/file.c
+++ b/security/tomoyo/file.c
@@ -222,7 +222,7 @@ static int tomoyo_update_globally_readable_entry(const char *filename,
222 222
223 if (!tomoyo_is_correct_path(filename, 1, 0, -1, __func__)) 223 if (!tomoyo_is_correct_path(filename, 1, 0, -1, __func__))
224 return -EINVAL; 224 return -EINVAL;
225 saved_filename = tomoyo_save_name(filename); 225 saved_filename = tomoyo_get_name(filename);
226 if (!saved_filename) 226 if (!saved_filename)
227 return -ENOMEM; 227 return -ENOMEM;
228 if (!is_delete) 228 if (!is_delete)
@@ -237,11 +237,13 @@ static int tomoyo_update_globally_readable_entry(const char *filename,
237 } 237 }
238 if (!is_delete && error && tomoyo_memory_ok(entry)) { 238 if (!is_delete && error && tomoyo_memory_ok(entry)) {
239 entry->filename = saved_filename; 239 entry->filename = saved_filename;
240 saved_filename = NULL;
240 list_add_tail_rcu(&entry->list, &tomoyo_globally_readable_list); 241 list_add_tail_rcu(&entry->list, &tomoyo_globally_readable_list);
241 entry = NULL; 242 entry = NULL;
242 error = 0; 243 error = 0;
243 } 244 }
244 mutex_unlock(&tomoyo_policy_lock); 245 mutex_unlock(&tomoyo_policy_lock);
246 tomoyo_put_name(saved_filename);
245 kfree(entry); 247 kfree(entry);
246 return error; 248 return error;
247} 249}
@@ -365,7 +367,7 @@ static int tomoyo_update_file_pattern_entry(const char *pattern,
365 const struct tomoyo_path_info *saved_pattern; 367 const struct tomoyo_path_info *saved_pattern;
366 int error = is_delete ? -ENOENT : -ENOMEM; 368 int error = is_delete ? -ENOENT : -ENOMEM;
367 369
368 saved_pattern = tomoyo_save_name(pattern); 370 saved_pattern = tomoyo_get_name(pattern);
369 if (!saved_pattern) 371 if (!saved_pattern)
370 return error; 372 return error;
371 if (!saved_pattern->is_patterned) 373 if (!saved_pattern->is_patterned)
@@ -382,6 +384,7 @@ static int tomoyo_update_file_pattern_entry(const char *pattern,
382 } 384 }
383 if (!is_delete && error && tomoyo_memory_ok(entry)) { 385 if (!is_delete && error && tomoyo_memory_ok(entry)) {
384 entry->pattern = saved_pattern; 386 entry->pattern = saved_pattern;
387 saved_pattern = NULL;
385 list_add_tail_rcu(&entry->list, &tomoyo_pattern_list); 388 list_add_tail_rcu(&entry->list, &tomoyo_pattern_list);
386 entry = NULL; 389 entry = NULL;
387 error = 0; 390 error = 0;
@@ -389,6 +392,7 @@ static int tomoyo_update_file_pattern_entry(const char *pattern,
389 mutex_unlock(&tomoyo_policy_lock); 392 mutex_unlock(&tomoyo_policy_lock);
390 out: 393 out:
391 kfree(entry); 394 kfree(entry);
395 tomoyo_put_name(saved_pattern);
392 return error; 396 return error;
393} 397}
394 398
@@ -518,7 +522,7 @@ static int tomoyo_update_no_rewrite_entry(const char *pattern,
518 522
519 if (!tomoyo_is_correct_path(pattern, 0, 0, 0, __func__)) 523 if (!tomoyo_is_correct_path(pattern, 0, 0, 0, __func__))
520 return -EINVAL; 524 return -EINVAL;
521 saved_pattern = tomoyo_save_name(pattern); 525 saved_pattern = tomoyo_get_name(pattern);
522 if (!saved_pattern) 526 if (!saved_pattern)
523 return error; 527 return error;
524 if (!is_delete) 528 if (!is_delete)
@@ -533,11 +537,13 @@ static int tomoyo_update_no_rewrite_entry(const char *pattern,
533 } 537 }
534 if (!is_delete && error && tomoyo_memory_ok(entry)) { 538 if (!is_delete && error && tomoyo_memory_ok(entry)) {
535 entry->pattern = saved_pattern; 539 entry->pattern = saved_pattern;
540 saved_pattern = NULL;
536 list_add_tail_rcu(&entry->list, &tomoyo_no_rewrite_list); 541 list_add_tail_rcu(&entry->list, &tomoyo_no_rewrite_list);
537 entry = NULL; 542 entry = NULL;
538 error = 0; 543 error = 0;
539 } 544 }
540 mutex_unlock(&tomoyo_policy_lock); 545 mutex_unlock(&tomoyo_policy_lock);
546 tomoyo_put_name(saved_pattern);
541 kfree(entry); 547 kfree(entry);
542 return error; 548 return error;
543} 549}
@@ -867,7 +873,7 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
867 return -EINVAL; 873 return -EINVAL;
868 if (!tomoyo_is_correct_path(filename, 0, 0, 0, __func__)) 874 if (!tomoyo_is_correct_path(filename, 0, 0, 0, __func__))
869 return -EINVAL; 875 return -EINVAL;
870 saved_filename = tomoyo_save_name(filename); 876 saved_filename = tomoyo_get_name(filename);
871 if (!saved_filename) 877 if (!saved_filename)
872 return -ENOMEM; 878 return -ENOMEM;
873 if (!is_delete) 879 if (!is_delete)
@@ -913,12 +919,14 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
913 if (perm == (1 << TOMOYO_TYPE_READ_WRITE_ACL)) 919 if (perm == (1 << TOMOYO_TYPE_READ_WRITE_ACL))
914 entry->perm |= rw_mask; 920 entry->perm |= rw_mask;
915 entry->filename = saved_filename; 921 entry->filename = saved_filename;
922 saved_filename = NULL;
916 list_add_tail_rcu(&entry->head.list, &domain->acl_info_list); 923 list_add_tail_rcu(&entry->head.list, &domain->acl_info_list);
917 entry = NULL; 924 entry = NULL;
918 error = 0; 925 error = 0;
919 } 926 }
920 mutex_unlock(&tomoyo_policy_lock); 927 mutex_unlock(&tomoyo_policy_lock);
921 kfree(entry); 928 kfree(entry);
929 tomoyo_put_name(saved_filename);
922 return error; 930 return error;
923} 931}
924 932
@@ -952,8 +960,8 @@ static int tomoyo_update_double_path_acl(const u8 type, const char *filename1,
952 if (!tomoyo_is_correct_path(filename1, 0, 0, 0, __func__) || 960 if (!tomoyo_is_correct_path(filename1, 0, 0, 0, __func__) ||
953 !tomoyo_is_correct_path(filename2, 0, 0, 0, __func__)) 961 !tomoyo_is_correct_path(filename2, 0, 0, 0, __func__))
954 return -EINVAL; 962 return -EINVAL;
955 saved_filename1 = tomoyo_save_name(filename1); 963 saved_filename1 = tomoyo_get_name(filename1);
956 saved_filename2 = tomoyo_save_name(filename2); 964 saved_filename2 = tomoyo_get_name(filename2);
957 if (!saved_filename1 || !saved_filename2) 965 if (!saved_filename1 || !saved_filename2)
958 goto out; 966 goto out;
959 if (!is_delete) 967 if (!is_delete)
@@ -979,13 +987,17 @@ static int tomoyo_update_double_path_acl(const u8 type, const char *filename1,
979 entry->head.type = TOMOYO_TYPE_DOUBLE_PATH_ACL; 987 entry->head.type = TOMOYO_TYPE_DOUBLE_PATH_ACL;
980 entry->perm = perm; 988 entry->perm = perm;
981 entry->filename1 = saved_filename1; 989 entry->filename1 = saved_filename1;
990 saved_filename1 = NULL;
982 entry->filename2 = saved_filename2; 991 entry->filename2 = saved_filename2;
992 saved_filename2 = NULL;
983 list_add_tail_rcu(&entry->head.list, &domain->acl_info_list); 993 list_add_tail_rcu(&entry->head.list, &domain->acl_info_list);
984 entry = NULL; 994 entry = NULL;
985 error = 0; 995 error = 0;
986 } 996 }
987 mutex_unlock(&tomoyo_policy_lock); 997 mutex_unlock(&tomoyo_policy_lock);
988 out: 998 out:
999 tomoyo_put_name(saved_filename1);
1000 tomoyo_put_name(saved_filename2);
989 kfree(entry); 1001 kfree(entry);
990 return error; 1002 return error;
991} 1003}
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c
index 92460c7ded67..2f7f54fc6812 100644
--- a/security/tomoyo/realpath.c
+++ b/security/tomoyo/realpath.c
@@ -254,21 +254,6 @@ static unsigned int tomoyo_quota_for_savename;
254#define TOMOYO_MAX_HASH (1u<<TOMOYO_HASH_BITS) 254#define TOMOYO_MAX_HASH (1u<<TOMOYO_HASH_BITS)
255 255
256/* 256/*
257 * tomoyo_name_entry is a structure which is used for linking
258 * "struct tomoyo_path_info" into tomoyo_name_list .
259 *
260 * Since tomoyo_name_list manages a list of strings which are shared by
261 * multiple processes (whereas "struct tomoyo_path_info" inside
262 * "struct tomoyo_path_info_with_data" is not shared), a reference counter will
263 * be added to "struct tomoyo_name_entry" rather than "struct tomoyo_path_info"
264 * when TOMOYO starts supporting garbage collector.
265 */
266struct tomoyo_name_entry {
267 struct list_head list;
268 struct tomoyo_path_info entry;
269};
270
271/*
272 * tomoyo_name_list is used for holding string data used by TOMOYO. 257 * tomoyo_name_list is used for holding string data used by TOMOYO.
273 * Since same string data is likely used for multiple times (e.g. 258 * Since same string data is likely used for multiple times (e.g.
274 * "/lib/libc-2.5.so"), TOMOYO shares string data in the form of 259 * "/lib/libc-2.5.so"), TOMOYO shares string data in the form of
@@ -277,13 +262,13 @@ struct tomoyo_name_entry {
277static struct list_head tomoyo_name_list[TOMOYO_MAX_HASH]; 262static struct list_head tomoyo_name_list[TOMOYO_MAX_HASH];
278 263
279/** 264/**
280 * tomoyo_save_name - Allocate permanent memory for string data. 265 * tomoyo_get_name - Allocate permanent memory for string data.
281 * 266 *
282 * @name: The string to store into the permernent memory. 267 * @name: The string to store into the permernent memory.
283 * 268 *
284 * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise. 269 * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise.
285 */ 270 */
286const struct tomoyo_path_info *tomoyo_save_name(const char *name) 271const struct tomoyo_path_info *tomoyo_get_name(const char *name)
287{ 272{
288 static DEFINE_MUTEX(lock); 273 static DEFINE_MUTEX(lock);
289 struct tomoyo_name_entry *ptr; 274 struct tomoyo_name_entry *ptr;
@@ -299,8 +284,10 @@ const struct tomoyo_path_info *tomoyo_save_name(const char *name)
299 head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)]; 284 head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)];
300 mutex_lock(&lock); 285 mutex_lock(&lock);
301 list_for_each_entry(ptr, head, list) { 286 list_for_each_entry(ptr, head, list) {
302 if (hash == ptr->entry.hash && !strcmp(name, ptr->entry.name)) 287 if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name))
303 goto out; 288 continue;
289 atomic_inc(&ptr->users);
290 goto out;
304 } 291 }
305 ptr = kzalloc(sizeof(*ptr) + len, GFP_KERNEL); 292 ptr = kzalloc(sizeof(*ptr) + len, GFP_KERNEL);
306 allocated_len = ptr ? ksize(ptr) : 0; 293 allocated_len = ptr ? ksize(ptr) : 0;
@@ -309,7 +296,7 @@ const struct tomoyo_path_info *tomoyo_save_name(const char *name)
309 > tomoyo_quota_for_savename)) { 296 > tomoyo_quota_for_savename)) {
310 kfree(ptr); 297 kfree(ptr);
311 printk(KERN_WARNING "ERROR: Out of memory " 298 printk(KERN_WARNING "ERROR: Out of memory "
312 "for tomoyo_save_name().\n"); 299 "for tomoyo_get_name().\n");
313 if (!tomoyo_policy_loaded) 300 if (!tomoyo_policy_loaded)
314 panic("MAC Initialization failed.\n"); 301 panic("MAC Initialization failed.\n");
315 ptr = NULL; 302 ptr = NULL;
@@ -318,6 +305,7 @@ const struct tomoyo_path_info *tomoyo_save_name(const char *name)
318 tomoyo_allocated_memory_for_savename += allocated_len; 305 tomoyo_allocated_memory_for_savename += allocated_len;
319 ptr->entry.name = ((char *) ptr) + sizeof(*ptr); 306 ptr->entry.name = ((char *) ptr) + sizeof(*ptr);
320 memmove((char *) ptr->entry.name, name, len); 307 memmove((char *) ptr->entry.name, name, len);
308 atomic_set(&ptr->users, 1);
321 tomoyo_fill_path_info(&ptr->entry); 309 tomoyo_fill_path_info(&ptr->entry);
322 list_add_tail(&ptr->list, head); 310 list_add_tail(&ptr->list, head);
323 out: 311 out:
@@ -336,7 +324,7 @@ void __init tomoyo_realpath_init(void)
336 for (i = 0; i < TOMOYO_MAX_HASH; i++) 324 for (i = 0; i < TOMOYO_MAX_HASH; i++)
337 INIT_LIST_HEAD(&tomoyo_name_list[i]); 325 INIT_LIST_HEAD(&tomoyo_name_list[i]);
338 INIT_LIST_HEAD(&tomoyo_kernel_domain.acl_info_list); 326 INIT_LIST_HEAD(&tomoyo_kernel_domain.acl_info_list);
339 tomoyo_kernel_domain.domainname = tomoyo_save_name(TOMOYO_ROOT_NAME); 327 tomoyo_kernel_domain.domainname = tomoyo_get_name(TOMOYO_ROOT_NAME);
340 /* 328 /*
341 * tomoyo_read_lock() is not needed because this function is 329 * tomoyo_read_lock() is not needed because this function is
342 * called before the first "delete" request. 330 * called before the first "delete" request.
diff --git a/security/tomoyo/realpath.h b/security/tomoyo/realpath.h
index da4f06ff6f8d..b94cb512adb5 100644
--- a/security/tomoyo/realpath.h
+++ b/security/tomoyo/realpath.h
@@ -43,7 +43,7 @@ bool tomoyo_memory_ok(void *ptr);
43 * Keep the given name on the RAM. 43 * Keep the given name on the RAM.
44 * The RAM is shared, so NEVER try to modify or kfree() the returned name. 44 * The RAM is shared, so NEVER try to modify or kfree() the returned name.
45 */ 45 */
46const struct tomoyo_path_info *tomoyo_save_name(const char *name); 46const struct tomoyo_path_info *tomoyo_get_name(const char *name);
47 47
48/* Check for memory usage. */ 48/* Check for memory usage. */
49int tomoyo_read_memory_counter(struct tomoyo_io_buffer *head); 49int tomoyo_read_memory_counter(struct tomoyo_io_buffer *head);
@@ -54,4 +54,23 @@ int tomoyo_write_memory_quota(struct tomoyo_io_buffer *head);
54/* Initialize realpath related code. */ 54/* Initialize realpath related code. */
55void __init tomoyo_realpath_init(void); 55void __init tomoyo_realpath_init(void);
56 56
57/*
58 * tomoyo_name_entry is a structure which is used for linking
59 * "struct tomoyo_path_info" into tomoyo_name_list .
60 */
61struct tomoyo_name_entry {
62 struct list_head list;
63 atomic_t users;
64 struct tomoyo_path_info entry;
65};
66
67static inline void tomoyo_put_name(const struct tomoyo_path_info *name)
68{
69 if (name) {
70 struct tomoyo_name_entry *ptr =
71 container_of(name, struct tomoyo_name_entry, entry);
72 atomic_dec(&ptr->users);
73 }
74}
75
57#endif /* !defined(_SECURITY_TOMOYO_REALPATH_H) */ 76#endif /* !defined(_SECURITY_TOMOYO_REALPATH_H) */