aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2010-01-04 16:39:37 -0500
committerJames Morris <jmorris@namei.org>2010-01-10 17:27:40 -0500
commitcd7bec6ad80188394a8ea857ff1aa3512fc2282a (patch)
tree598e7d59c29966e0d8fa8abf24eb51bbb2f567a6
parente41035a996356c257183e53a70abfb46fa84908b (diff)
TOMOYO: Remove memory pool for list elements.
Currently, TOMOYO allocates memory for list elements from memory pool allocated by kmalloc(PAGE_SIZE). But that makes it difficult to kfree() when garbage collector is added. Thus, remove memory pool and use kmalloc(sizeof()). 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.c41
-rw-r--r--security/tomoyo/common.h2
-rw-r--r--security/tomoyo/domain.c58
-rw-r--r--security/tomoyo/file.c34
-rw-r--r--security/tomoyo/realpath.c65
-rw-r--r--security/tomoyo/realpath.h7
6 files changed, 73 insertions, 134 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index 642e0e565df..e331e699cf5 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -900,9 +900,11 @@ static struct tomoyo_profile *tomoyo_find_or_assign_new_profile(const unsigned
900 ptr = tomoyo_profile_ptr[profile]; 900 ptr = tomoyo_profile_ptr[profile];
901 if (ptr) 901 if (ptr)
902 goto ok; 902 goto ok;
903 ptr = tomoyo_alloc_element(sizeof(*ptr)); 903 ptr = kmalloc(sizeof(*ptr), GFP_KERNEL);
904 if (!ptr) 904 if (!tomoyo_memory_ok(ptr)) {
905 kfree(ptr);
905 goto ok; 906 goto ok;
907 }
906 for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++) 908 for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++)
907 ptr->value[i] = tomoyo_control_array[i].current_value; 909 ptr->value[i] = tomoyo_control_array[i].current_value;
908 mb(); /* Avoid out-of-order execution. */ 910 mb(); /* Avoid out-of-order execution. */
@@ -1120,6 +1122,7 @@ static int tomoyo_update_manager_entry(const char *manager,
1120 saved_manager = tomoyo_save_name(manager); 1122 saved_manager = tomoyo_save_name(manager);
1121 if (!saved_manager) 1123 if (!saved_manager)
1122 return -ENOMEM; 1124 return -ENOMEM;
1125 new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL);
1123 mutex_lock(&tomoyo_policy_lock); 1126 mutex_lock(&tomoyo_policy_lock);
1124 list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) { 1127 list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) {
1125 if (ptr->manager != saved_manager) 1128 if (ptr->manager != saved_manager)
@@ -1132,15 +1135,16 @@ static int tomoyo_update_manager_entry(const char *manager,
1132 error = -ENOENT; 1135 error = -ENOENT;
1133 goto out; 1136 goto out;
1134 } 1137 }
1135 new_entry = tomoyo_alloc_element(sizeof(*new_entry)); 1138 if (!tomoyo_memory_ok(new_entry))
1136 if (!new_entry)
1137 goto out; 1139 goto out;
1138 new_entry->manager = saved_manager; 1140 new_entry->manager = saved_manager;
1139 new_entry->is_domain = is_domain; 1141 new_entry->is_domain = is_domain;
1140 list_add_tail_rcu(&new_entry->list, &tomoyo_policy_manager_list); 1142 list_add_tail_rcu(&new_entry->list, &tomoyo_policy_manager_list);
1143 new_entry = NULL;
1141 error = 0; 1144 error = 0;
1142 out: 1145 out:
1143 mutex_unlock(&tomoyo_policy_lock); 1146 mutex_unlock(&tomoyo_policy_lock);
1147 kfree(new_entry);
1144 return error; 1148 return error;
1145} 1149}
1146 1150
@@ -2148,35 +2152,6 @@ static int tomoyo_close_control(struct file *file)
2148} 2152}
2149 2153
2150/** 2154/**
2151 * tomoyo_alloc_acl_element - Allocate permanent memory for ACL entry.
2152 *
2153 * @acl_type: Type of ACL entry.
2154 *
2155 * Returns pointer to the ACL entry on success, NULL otherwise.
2156 */
2157void *tomoyo_alloc_acl_element(const u8 acl_type)
2158{
2159 int len;
2160 struct tomoyo_acl_info *ptr;
2161
2162 switch (acl_type) {
2163 case TOMOYO_TYPE_SINGLE_PATH_ACL:
2164 len = sizeof(struct tomoyo_single_path_acl_record);
2165 break;
2166 case TOMOYO_TYPE_DOUBLE_PATH_ACL:
2167 len = sizeof(struct tomoyo_double_path_acl_record);
2168 break;
2169 default:
2170 return NULL;
2171 }
2172 ptr = tomoyo_alloc_element(len);
2173 if (!ptr)
2174 return NULL;
2175 ptr->type = acl_type;
2176 return ptr;
2177}
2178
2179/**
2180 * tomoyo_open - open() for /sys/kernel/security/tomoyo/ interface. 2155 * tomoyo_open - open() for /sys/kernel/security/tomoyo/ interface.
2181 * 2156 *
2182 * @inode: Pointer to "struct inode". 2157 * @inode: Pointer to "struct inode".
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index 874abf8df43..610a6a05682 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -376,8 +376,6 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
376/* Check mode for specified functionality. */ 376/* Check mode for specified functionality. */
377unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain, 377unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain,
378 const u8 index); 378 const u8 index);
379/* Allocate memory for structures. */
380void *tomoyo_alloc_acl_element(const u8 acl_type);
381/* Fill in "struct tomoyo_path_info" members. */ 379/* Fill in "struct tomoyo_path_info" members. */
382void tomoyo_fill_path_info(struct tomoyo_path_info *ptr); 380void tomoyo_fill_path_info(struct tomoyo_path_info *ptr);
383/* Run policy loader when /sbin/init starts. */ 381/* Run policy loader when /sbin/init starts. */
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index 7d0b0bc4820..a55a1cced58 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -245,6 +245,7 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
245 saved_program = tomoyo_save_name(program); 245 saved_program = tomoyo_save_name(program);
246 if (!saved_program) 246 if (!saved_program)
247 return -ENOMEM; 247 return -ENOMEM;
248 new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL);
248 mutex_lock(&tomoyo_policy_lock); 249 mutex_lock(&tomoyo_policy_lock);
249 list_for_each_entry_rcu(ptr, &tomoyo_domain_initializer_list, list) { 250 list_for_each_entry_rcu(ptr, &tomoyo_domain_initializer_list, list) {
250 if (ptr->is_not != is_not || 251 if (ptr->is_not != is_not ||
@@ -259,17 +260,18 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
259 error = -ENOENT; 260 error = -ENOENT;
260 goto out; 261 goto out;
261 } 262 }
262 new_entry = tomoyo_alloc_element(sizeof(*new_entry)); 263 if (!tomoyo_memory_ok(new_entry))
263 if (!new_entry)
264 goto out; 264 goto out;
265 new_entry->domainname = saved_domainname; 265 new_entry->domainname = saved_domainname;
266 new_entry->program = saved_program; 266 new_entry->program = saved_program;
267 new_entry->is_not = is_not; 267 new_entry->is_not = is_not;
268 new_entry->is_last_name = is_last_name; 268 new_entry->is_last_name = is_last_name;
269 list_add_tail_rcu(&new_entry->list, &tomoyo_domain_initializer_list); 269 list_add_tail_rcu(&new_entry->list, &tomoyo_domain_initializer_list);
270 new_entry = NULL;
270 error = 0; 271 error = 0;
271 out: 272 out:
272 mutex_unlock(&tomoyo_policy_lock); 273 mutex_unlock(&tomoyo_policy_lock);
274 kfree(new_entry);
273 return error; 275 return error;
274} 276}
275 277
@@ -461,6 +463,7 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
461 saved_domainname = tomoyo_save_name(domainname); 463 saved_domainname = tomoyo_save_name(domainname);
462 if (!saved_domainname) 464 if (!saved_domainname)
463 return -ENOMEM; 465 return -ENOMEM;
466 new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL);
464 mutex_lock(&tomoyo_policy_lock); 467 mutex_lock(&tomoyo_policy_lock);
465 list_for_each_entry_rcu(ptr, &tomoyo_domain_keeper_list, list) { 468 list_for_each_entry_rcu(ptr, &tomoyo_domain_keeper_list, list) {
466 if (ptr->is_not != is_not || 469 if (ptr->is_not != is_not ||
@@ -475,17 +478,18 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
475 error = -ENOENT; 478 error = -ENOENT;
476 goto out; 479 goto out;
477 } 480 }
478 new_entry = tomoyo_alloc_element(sizeof(*new_entry)); 481 if (!tomoyo_memory_ok(new_entry))
479 if (!new_entry)
480 goto out; 482 goto out;
481 new_entry->domainname = saved_domainname; 483 new_entry->domainname = saved_domainname;
482 new_entry->program = saved_program; 484 new_entry->program = saved_program;
483 new_entry->is_not = is_not; 485 new_entry->is_not = is_not;
484 new_entry->is_last_name = is_last_name; 486 new_entry->is_last_name = is_last_name;
485 list_add_tail_rcu(&new_entry->list, &tomoyo_domain_keeper_list); 487 list_add_tail_rcu(&new_entry->list, &tomoyo_domain_keeper_list);
488 new_entry = NULL;
486 error = 0; 489 error = 0;
487 out: 490 out:
488 mutex_unlock(&tomoyo_policy_lock); 491 mutex_unlock(&tomoyo_policy_lock);
492 kfree(new_entry);
489 return error; 493 return error;
490} 494}
491 495
@@ -650,6 +654,7 @@ static int tomoyo_update_alias_entry(const char *original_name,
650 saved_aliased_name = tomoyo_save_name(aliased_name); 654 saved_aliased_name = tomoyo_save_name(aliased_name);
651 if (!saved_original_name || !saved_aliased_name) 655 if (!saved_original_name || !saved_aliased_name)
652 return -ENOMEM; 656 return -ENOMEM;
657 new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL);
653 mutex_lock(&tomoyo_policy_lock); 658 mutex_lock(&tomoyo_policy_lock);
654 list_for_each_entry_rcu(ptr, &tomoyo_alias_list, list) { 659 list_for_each_entry_rcu(ptr, &tomoyo_alias_list, list) {
655 if (ptr->original_name != saved_original_name || 660 if (ptr->original_name != saved_original_name ||
@@ -663,15 +668,16 @@ static int tomoyo_update_alias_entry(const char *original_name,
663 error = -ENOENT; 668 error = -ENOENT;
664 goto out; 669 goto out;
665 } 670 }
666 new_entry = tomoyo_alloc_element(sizeof(*new_entry)); 671 if (!tomoyo_memory_ok(new_entry))
667 if (!new_entry)
668 goto out; 672 goto out;
669 new_entry->original_name = saved_original_name; 673 new_entry->original_name = saved_original_name;
670 new_entry->aliased_name = saved_aliased_name; 674 new_entry->aliased_name = saved_aliased_name;
671 list_add_tail_rcu(&new_entry->list, &tomoyo_alias_list); 675 list_add_tail_rcu(&new_entry->list, &tomoyo_alias_list);
676 new_entry = NULL;
672 error = 0; 677 error = 0;
673 out: 678 out:
674 mutex_unlock(&tomoyo_policy_lock); 679 mutex_unlock(&tomoyo_policy_lock);
680 kfree(new_entry);
675 return error; 681 return error;
676} 682}
677 683
@@ -738,7 +744,7 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
738 domainname, 744 domainname,
739 const u8 profile) 745 const u8 profile)
740{ 746{
741 struct tomoyo_domain_info *domain = NULL; 747 struct tomoyo_domain_info *domain;
742 const struct tomoyo_path_info *saved_domainname; 748 const struct tomoyo_path_info *saved_domainname;
743 749
744 mutex_lock(&tomoyo_policy_lock); 750 mutex_lock(&tomoyo_policy_lock);
@@ -750,43 +756,17 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
750 saved_domainname = tomoyo_save_name(domainname); 756 saved_domainname = tomoyo_save_name(domainname);
751 if (!saved_domainname) 757 if (!saved_domainname)
752 goto out; 758 goto out;
753 /* Can I reuse memory of deleted domain? */ 759 domain = kmalloc(sizeof(*domain), GFP_KERNEL);
754 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { 760 if (tomoyo_memory_ok(domain)) {
755 struct task_struct *p;
756 struct tomoyo_acl_info *ptr;
757 bool flag;
758 if (!domain->is_deleted ||
759 domain->domainname != saved_domainname)
760 continue;
761 flag = false;
762 read_lock(&tasklist_lock);
763 for_each_process(p) {
764 if (tomoyo_real_domain(p) != domain)
765 continue;
766 flag = true;
767 break;
768 }
769 read_unlock(&tasklist_lock);
770 if (flag)
771 continue;
772 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
773 ptr->type |= TOMOYO_ACL_DELETED;
774 }
775 tomoyo_set_domain_flag(domain, true, domain->flags);
776 domain->profile = profile;
777 domain->quota_warned = false;
778 mb(); /* Avoid out-of-order execution. */
779 domain->is_deleted = false;
780 goto out;
781 }
782 /* No memory reusable. Create using new memory. */
783 domain = tomoyo_alloc_element(sizeof(*domain));
784 if (domain) {
785 INIT_LIST_HEAD(&domain->acl_info_list); 761 INIT_LIST_HEAD(&domain->acl_info_list);
786 domain->domainname = saved_domainname; 762 domain->domainname = saved_domainname;
787 domain->profile = profile; 763 domain->profile = profile;
788 list_add_tail_rcu(&domain->list, &tomoyo_domain_list); 764 list_add_tail_rcu(&domain->list, &tomoyo_domain_list);
765 } else {
766 kfree(domain);
767 domain = NULL;
789 } 768 }
769
790 out: 770 out:
791 mutex_unlock(&tomoyo_policy_lock); 771 mutex_unlock(&tomoyo_policy_lock);
792 return domain; 772 return domain;
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c
index 5d1689d6e16..075392c052b 100644
--- a/security/tomoyo/file.c
+++ b/security/tomoyo/file.c
@@ -225,6 +225,7 @@ static int tomoyo_update_globally_readable_entry(const char *filename,
225 saved_filename = tomoyo_save_name(filename); 225 saved_filename = tomoyo_save_name(filename);
226 if (!saved_filename) 226 if (!saved_filename)
227 return -ENOMEM; 227 return -ENOMEM;
228 new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL);
228 mutex_lock(&tomoyo_policy_lock); 229 mutex_lock(&tomoyo_policy_lock);
229 list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) { 230 list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) {
230 if (ptr->filename != saved_filename) 231 if (ptr->filename != saved_filename)
@@ -237,14 +238,15 @@ static int tomoyo_update_globally_readable_entry(const char *filename,
237 error = -ENOENT; 238 error = -ENOENT;
238 goto out; 239 goto out;
239 } 240 }
240 new_entry = tomoyo_alloc_element(sizeof(*new_entry)); 241 if (!tomoyo_memory_ok(new_entry))
241 if (!new_entry)
242 goto out; 242 goto out;
243 new_entry->filename = saved_filename; 243 new_entry->filename = saved_filename;
244 list_add_tail_rcu(&new_entry->list, &tomoyo_globally_readable_list); 244 list_add_tail_rcu(&new_entry->list, &tomoyo_globally_readable_list);
245 new_entry = NULL;
245 error = 0; 246 error = 0;
246 out: 247 out:
247 mutex_unlock(&tomoyo_policy_lock); 248 mutex_unlock(&tomoyo_policy_lock);
249 kfree(new_entry);
248 return error; 250 return error;
249} 251}
250 252
@@ -372,6 +374,7 @@ static int tomoyo_update_file_pattern_entry(const char *pattern,
372 saved_pattern = tomoyo_save_name(pattern); 374 saved_pattern = tomoyo_save_name(pattern);
373 if (!saved_pattern) 375 if (!saved_pattern)
374 return -ENOMEM; 376 return -ENOMEM;
377 new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL);
375 mutex_lock(&tomoyo_policy_lock); 378 mutex_lock(&tomoyo_policy_lock);
376 list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) { 379 list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) {
377 if (saved_pattern != ptr->pattern) 380 if (saved_pattern != ptr->pattern)
@@ -384,14 +387,15 @@ static int tomoyo_update_file_pattern_entry(const char *pattern,
384 error = -ENOENT; 387 error = -ENOENT;
385 goto out; 388 goto out;
386 } 389 }
387 new_entry = tomoyo_alloc_element(sizeof(*new_entry)); 390 if (!tomoyo_memory_ok(new_entry))
388 if (!new_entry)
389 goto out; 391 goto out;
390 new_entry->pattern = saved_pattern; 392 new_entry->pattern = saved_pattern;
391 list_add_tail_rcu(&new_entry->list, &tomoyo_pattern_list); 393 list_add_tail_rcu(&new_entry->list, &tomoyo_pattern_list);
394 new_entry = NULL;
392 error = 0; 395 error = 0;
393 out: 396 out:
394 mutex_unlock(&tomoyo_policy_lock); 397 mutex_unlock(&tomoyo_policy_lock);
398 kfree(new_entry);
395 return error; 399 return error;
396} 400}
397 401
@@ -523,6 +527,7 @@ static int tomoyo_update_no_rewrite_entry(const char *pattern,
523 saved_pattern = tomoyo_save_name(pattern); 527 saved_pattern = tomoyo_save_name(pattern);
524 if (!saved_pattern) 528 if (!saved_pattern)
525 return -ENOMEM; 529 return -ENOMEM;
530 new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL);
526 mutex_lock(&tomoyo_policy_lock); 531 mutex_lock(&tomoyo_policy_lock);
527 list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) { 532 list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) {
528 if (ptr->pattern != saved_pattern) 533 if (ptr->pattern != saved_pattern)
@@ -535,14 +540,15 @@ static int tomoyo_update_no_rewrite_entry(const char *pattern,
535 error = -ENOENT; 540 error = -ENOENT;
536 goto out; 541 goto out;
537 } 542 }
538 new_entry = tomoyo_alloc_element(sizeof(*new_entry)); 543 if (!tomoyo_memory_ok(new_entry))
539 if (!new_entry)
540 goto out; 544 goto out;
541 new_entry->pattern = saved_pattern; 545 new_entry->pattern = saved_pattern;
542 list_add_tail_rcu(&new_entry->list, &tomoyo_no_rewrite_list); 546 list_add_tail_rcu(&new_entry->list, &tomoyo_no_rewrite_list);
547 new_entry = NULL;
543 error = 0; 548 error = 0;
544 out: 549 out:
545 mutex_unlock(&tomoyo_policy_lock); 550 mutex_unlock(&tomoyo_policy_lock);
551 kfree(new_entry);
546 return error; 552 return error;
547} 553}
548 554
@@ -901,9 +907,13 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
901 goto out; 907 goto out;
902 } 908 }
903 /* Not found. Append it to the tail. */ 909 /* Not found. Append it to the tail. */
904 acl = tomoyo_alloc_acl_element(TOMOYO_TYPE_SINGLE_PATH_ACL); 910 acl = kmalloc(sizeof(*acl), GFP_KERNEL);
905 if (!acl) 911 if (!tomoyo_memory_ok(acl)) {
912 kfree(acl);
913 acl = NULL;
906 goto out; 914 goto out;
915 }
916 acl->head.type = TOMOYO_TYPE_SINGLE_PATH_ACL;
907 if (perm <= 0xFFFF) 917 if (perm <= 0xFFFF)
908 acl->perm = perm; 918 acl->perm = perm;
909 else 919 else
@@ -995,9 +1005,13 @@ static int tomoyo_update_double_path_acl(const u8 type, const char *filename1,
995 goto out; 1005 goto out;
996 } 1006 }
997 /* Not found. Append it to the tail. */ 1007 /* Not found. Append it to the tail. */
998 acl = tomoyo_alloc_acl_element(TOMOYO_TYPE_DOUBLE_PATH_ACL); 1008 acl = kmalloc(sizeof(*acl), GFP_KERNEL);
999 if (!acl) 1009 if (!tomoyo_memory_ok(acl)) {
1010 kfree(acl);
1011 acl = NULL;
1000 goto out; 1012 goto out;
1013 }
1014 acl->head.type = TOMOYO_TYPE_DOUBLE_PATH_ACL;
1001 acl->perm = perm; 1015 acl->perm = perm;
1002 acl->filename1 = saved_filename1; 1016 acl->filename1 = saved_filename1;
1003 acl->filename2 = saved_filename2; 1017 acl->filename2 = saved_filename2;
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c
index 9105e5e29da..54226d5be49 100644
--- a/security/tomoyo/realpath.c
+++ b/security/tomoyo/realpath.c
@@ -212,57 +212,32 @@ static unsigned int tomoyo_allocated_memory_for_elements;
212static unsigned int tomoyo_quota_for_elements; 212static unsigned int tomoyo_quota_for_elements;
213 213
214/** 214/**
215 * tomoyo_alloc_element - Allocate permanent memory for structures. 215 * tomoyo_memory_ok - Check memory quota.
216 * 216 *
217 * @size: Size in bytes. 217 * @ptr: Pointer to allocated memory.
218 * 218 *
219 * Returns pointer to allocated memory on success, NULL otherwise. 219 * Returns true on success, false otherwise.
220 * 220 *
221 * Memory has to be zeroed. 221 * Caller holds tomoyo_policy_lock.
222 * The RAM is chunked, so NEVER try to kfree() the returned pointer. 222 * Memory pointed by @ptr will be zeroed on success.
223 */ 223 */
224void *tomoyo_alloc_element(const unsigned int size) 224bool tomoyo_memory_ok(void *ptr)
225{ 225{
226 static char *buf; 226 int allocated_len = ptr ? ksize(ptr) : 0;
227 static DEFINE_MUTEX(lock); 227 bool result = false;
228 static unsigned int buf_used_len = PATH_MAX; 228 if (!ptr || (tomoyo_quota_for_elements &&
229 char *ptr = NULL; 229 tomoyo_allocated_memory_for_elements
230 /*Assumes sizeof(void *) >= sizeof(long) is true. */ 230 + allocated_len > tomoyo_quota_for_elements)) {
231 const unsigned int word_aligned_size 231 printk(KERN_WARNING "ERROR: Out of memory "
232 = roundup(size, max(sizeof(void *), sizeof(long))); 232 "for tomoyo_alloc_element().\n");
233 if (word_aligned_size > PATH_MAX) 233 if (!tomoyo_policy_loaded)
234 return NULL; 234 panic("MAC Initialization failed.\n");
235 mutex_lock(&lock); 235 } else {
236 if (buf_used_len + word_aligned_size > PATH_MAX) { 236 result = true;
237 if (!tomoyo_quota_for_elements || 237 tomoyo_allocated_memory_for_elements += allocated_len;
238 tomoyo_allocated_memory_for_elements 238 memset(ptr, 0, allocated_len);
239 + PATH_MAX <= tomoyo_quota_for_elements)
240 ptr = kzalloc(PATH_MAX, GFP_KERNEL);
241 if (!ptr) {
242 printk(KERN_WARNING "ERROR: Out of memory "
243 "for tomoyo_alloc_element().\n");
244 if (!tomoyo_policy_loaded)
245 panic("MAC Initialization failed.\n");
246 } else {
247 buf = ptr;
248 tomoyo_allocated_memory_for_elements += PATH_MAX;
249 buf_used_len = word_aligned_size;
250 ptr = buf;
251 }
252 } else if (word_aligned_size) {
253 int i;
254 ptr = buf + buf_used_len;
255 buf_used_len += word_aligned_size;
256 for (i = 0; i < word_aligned_size; i++) {
257 if (!ptr[i])
258 continue;
259 printk(KERN_ERR "WARNING: Reserved memory was tainted! "
260 "The system might go wrong.\n");
261 ptr[i] = '\0';
262 }
263 } 239 }
264 mutex_unlock(&lock); 240 return result;
265 return ptr;
266} 241}
267 242
268/* Memory allocated for string data in bytes. */ 243/* Memory allocated for string data in bytes. */
diff --git a/security/tomoyo/realpath.h b/security/tomoyo/realpath.h
index 78217a37960..47b4f59dad6 100644
--- a/security/tomoyo/realpath.h
+++ b/security/tomoyo/realpath.h
@@ -36,11 +36,8 @@ char *tomoyo_realpath_nofollow(const char *pathname);
36/* Same with tomoyo_realpath() except that the pathname is already solved. */ 36/* Same with tomoyo_realpath() except that the pathname is already solved. */
37char *tomoyo_realpath_from_path(struct path *path); 37char *tomoyo_realpath_from_path(struct path *path);
38 38
39/* 39/* Check memory quota. */
40 * Allocate memory for ACL entry. 40bool tomoyo_memory_ok(void *ptr);
41 * The RAM is chunked, so NEVER try to kfree() the returned pointer.
42 */
43void *tomoyo_alloc_element(const unsigned int size);
44 41
45/* 42/*
46 * Keep the given name on the RAM. 43 * Keep the given name on the RAM.