aboutsummaryrefslogtreecommitdiffstats
path: root/security/tomoyo/domain.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/tomoyo/domain.c')
-rw-r--r--security/tomoyo/domain.c147
1 files changed, 72 insertions, 75 deletions
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index ec612ae87b51..229de1e71a38 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -201,11 +201,11 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
201 const bool is_not, 201 const bool is_not,
202 const bool is_delete) 202 const bool is_delete)
203{ 203{
204 struct tomoyo_domain_initializer_entry *new_entry; 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;
207 const struct tomoyo_path_info *saved_domainname = NULL; 207 const struct tomoyo_path_info *saved_domainname = NULL;
208 int error = -ENOMEM; 208 int error = is_delete ? -ENOENT : -ENOMEM;
209 bool is_last_name = false; 209 bool is_last_name = false;
210 210
211 if (!tomoyo_is_correct_path(program, 1, -1, -1, __func__)) 211 if (!tomoyo_is_correct_path(program, 1, -1, -1, __func__))
@@ -218,12 +218,13 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
218 return -EINVAL; 218 return -EINVAL;
219 saved_domainname = tomoyo_save_name(domainname); 219 saved_domainname = tomoyo_save_name(domainname);
220 if (!saved_domainname) 220 if (!saved_domainname)
221 return -ENOMEM; 221 goto out;
222 } 222 }
223 saved_program = tomoyo_save_name(program); 223 saved_program = tomoyo_save_name(program);
224 if (!saved_program) 224 if (!saved_program)
225 return -ENOMEM; 225 goto out;
226 new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL); 226 if (!is_delete)
227 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
227 mutex_lock(&tomoyo_policy_lock); 228 mutex_lock(&tomoyo_policy_lock);
228 list_for_each_entry_rcu(ptr, &tomoyo_domain_initializer_list, list) { 229 list_for_each_entry_rcu(ptr, &tomoyo_domain_initializer_list, list) {
229 if (ptr->is_not != is_not || 230 if (ptr->is_not != is_not ||
@@ -232,24 +233,21 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
232 continue; 233 continue;
233 ptr->is_deleted = is_delete; 234 ptr->is_deleted = is_delete;
234 error = 0; 235 error = 0;
235 goto out; 236 break;
236 } 237 }
237 if (is_delete) { 238 if (!is_delete && error && tomoyo_memory_ok(entry)) {
238 error = -ENOENT; 239 entry->domainname = saved_domainname;
239 goto out; 240 entry->program = saved_program;
241 entry->is_not = is_not;
242 entry->is_last_name = is_last_name;
243 list_add_tail_rcu(&entry->list,
244 &tomoyo_domain_initializer_list);
245 entry = NULL;
246 error = 0;
240 } 247 }
241 if (!tomoyo_memory_ok(new_entry))
242 goto out;
243 new_entry->domainname = saved_domainname;
244 new_entry->program = saved_program;
245 new_entry->is_not = is_not;
246 new_entry->is_last_name = is_last_name;
247 list_add_tail_rcu(&new_entry->list, &tomoyo_domain_initializer_list);
248 new_entry = NULL;
249 error = 0;
250 out:
251 mutex_unlock(&tomoyo_policy_lock); 248 mutex_unlock(&tomoyo_policy_lock);
252 kfree(new_entry); 249 out:
250 kfree(entry);
253 return error; 251 return error;
254} 252}
255 253
@@ -419,11 +417,11 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
419 const bool is_not, 417 const bool is_not,
420 const bool is_delete) 418 const bool is_delete)
421{ 419{
422 struct tomoyo_domain_keeper_entry *new_entry; 420 struct tomoyo_domain_keeper_entry *entry = NULL;
423 struct tomoyo_domain_keeper_entry *ptr; 421 struct tomoyo_domain_keeper_entry *ptr;
424 const struct tomoyo_path_info *saved_domainname; 422 const struct tomoyo_path_info *saved_domainname;
425 const struct tomoyo_path_info *saved_program = NULL; 423 const struct tomoyo_path_info *saved_program = NULL;
426 int error = -ENOMEM; 424 int error = is_delete ? -ENOENT : -ENOMEM;
427 bool is_last_name = false; 425 bool is_last_name = false;
428 426
429 if (!tomoyo_is_domain_def(domainname) && 427 if (!tomoyo_is_domain_def(domainname) &&
@@ -436,12 +434,13 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
436 return -EINVAL; 434 return -EINVAL;
437 saved_program = tomoyo_save_name(program); 435 saved_program = tomoyo_save_name(program);
438 if (!saved_program) 436 if (!saved_program)
439 return -ENOMEM; 437 goto out;
440 } 438 }
441 saved_domainname = tomoyo_save_name(domainname); 439 saved_domainname = tomoyo_save_name(domainname);
442 if (!saved_domainname) 440 if (!saved_domainname)
443 return -ENOMEM; 441 goto out;
444 new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL); 442 if (!is_delete)
443 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
445 mutex_lock(&tomoyo_policy_lock); 444 mutex_lock(&tomoyo_policy_lock);
446 list_for_each_entry_rcu(ptr, &tomoyo_domain_keeper_list, list) { 445 list_for_each_entry_rcu(ptr, &tomoyo_domain_keeper_list, list) {
447 if (ptr->is_not != is_not || 446 if (ptr->is_not != is_not ||
@@ -450,24 +449,20 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
450 continue; 449 continue;
451 ptr->is_deleted = is_delete; 450 ptr->is_deleted = is_delete;
452 error = 0; 451 error = 0;
453 goto out; 452 break;
454 } 453 }
455 if (is_delete) { 454 if (!is_delete && error && tomoyo_memory_ok(entry)) {
456 error = -ENOENT; 455 entry->domainname = saved_domainname;
457 goto out; 456 entry->program = saved_program;
457 entry->is_not = is_not;
458 entry->is_last_name = is_last_name;
459 list_add_tail_rcu(&entry->list, &tomoyo_domain_keeper_list);
460 entry = NULL;
461 error = 0;
458 } 462 }
459 if (!tomoyo_memory_ok(new_entry))
460 goto out;
461 new_entry->domainname = saved_domainname;
462 new_entry->program = saved_program;
463 new_entry->is_not = is_not;
464 new_entry->is_last_name = is_last_name;
465 list_add_tail_rcu(&new_entry->list, &tomoyo_domain_keeper_list);
466 new_entry = NULL;
467 error = 0;
468 out:
469 mutex_unlock(&tomoyo_policy_lock); 463 mutex_unlock(&tomoyo_policy_lock);
470 kfree(new_entry); 464 out:
465 kfree(entry);
471 return error; 466 return error;
472} 467}
473 468
@@ -619,11 +614,11 @@ static int tomoyo_update_alias_entry(const char *original_name,
619 const char *aliased_name, 614 const char *aliased_name,
620 const bool is_delete) 615 const bool is_delete)
621{ 616{
622 struct tomoyo_alias_entry *new_entry; 617 struct tomoyo_alias_entry *entry = NULL;
623 struct tomoyo_alias_entry *ptr; 618 struct tomoyo_alias_entry *ptr;
624 const struct tomoyo_path_info *saved_original_name; 619 const struct tomoyo_path_info *saved_original_name;
625 const struct tomoyo_path_info *saved_aliased_name; 620 const struct tomoyo_path_info *saved_aliased_name;
626 int error = -ENOMEM; 621 int error = is_delete ? -ENOENT : -ENOMEM;
627 622
628 if (!tomoyo_is_correct_path(original_name, 1, -1, -1, __func__) || 623 if (!tomoyo_is_correct_path(original_name, 1, -1, -1, __func__) ||
629 !tomoyo_is_correct_path(aliased_name, 1, -1, -1, __func__)) 624 !tomoyo_is_correct_path(aliased_name, 1, -1, -1, __func__))
@@ -631,8 +626,9 @@ static int tomoyo_update_alias_entry(const char *original_name,
631 saved_original_name = tomoyo_save_name(original_name); 626 saved_original_name = tomoyo_save_name(original_name);
632 saved_aliased_name = tomoyo_save_name(aliased_name); 627 saved_aliased_name = tomoyo_save_name(aliased_name);
633 if (!saved_original_name || !saved_aliased_name) 628 if (!saved_original_name || !saved_aliased_name)
634 return -ENOMEM; 629 goto out;
635 new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL); 630 if (!is_delete)
631 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
636 mutex_lock(&tomoyo_policy_lock); 632 mutex_lock(&tomoyo_policy_lock);
637 list_for_each_entry_rcu(ptr, &tomoyo_alias_list, list) { 633 list_for_each_entry_rcu(ptr, &tomoyo_alias_list, list) {
638 if (ptr->original_name != saved_original_name || 634 if (ptr->original_name != saved_original_name ||
@@ -640,22 +636,18 @@ static int tomoyo_update_alias_entry(const char *original_name,
640 continue; 636 continue;
641 ptr->is_deleted = is_delete; 637 ptr->is_deleted = is_delete;
642 error = 0; 638 error = 0;
643 goto out; 639 break;
644 } 640 }
645 if (is_delete) { 641 if (!is_delete && error && tomoyo_memory_ok(entry)) {
646 error = -ENOENT; 642 entry->original_name = saved_original_name;
647 goto out; 643 entry->aliased_name = saved_aliased_name;
644 list_add_tail_rcu(&entry->list, &tomoyo_alias_list);
645 entry = NULL;
646 error = 0;
648 } 647 }
649 if (!tomoyo_memory_ok(new_entry))
650 goto out;
651 new_entry->original_name = saved_original_name;
652 new_entry->aliased_name = saved_aliased_name;
653 list_add_tail_rcu(&new_entry->list, &tomoyo_alias_list);
654 new_entry = NULL;
655 error = 0;
656 out:
657 mutex_unlock(&tomoyo_policy_lock); 648 mutex_unlock(&tomoyo_policy_lock);
658 kfree(new_entry); 649 out:
650 kfree(entry);
659 return error; 651 return error;
660} 652}
661 653
@@ -722,32 +714,37 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
722 domainname, 714 domainname,
723 const u8 profile) 715 const u8 profile)
724{ 716{
717 struct tomoyo_domain_info *entry;
725 struct tomoyo_domain_info *domain; 718 struct tomoyo_domain_info *domain;
726 const struct tomoyo_path_info *saved_domainname; 719 const struct tomoyo_path_info *saved_domainname;
720 bool found = false;
727 721
728 mutex_lock(&tomoyo_policy_lock);
729 domain = tomoyo_find_domain(domainname);
730 if (domain)
731 goto out;
732 if (!tomoyo_is_correct_domain(domainname, __func__)) 722 if (!tomoyo_is_correct_domain(domainname, __func__))
733 goto out; 723 return NULL;
734 saved_domainname = tomoyo_save_name(domainname); 724 saved_domainname = tomoyo_save_name(domainname);
735 if (!saved_domainname) 725 if (!saved_domainname)
736 goto out; 726 return NULL;
737 domain = kmalloc(sizeof(*domain), GFP_KERNEL); 727 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
738 if (tomoyo_memory_ok(domain)) { 728 mutex_lock(&tomoyo_policy_lock);
739 INIT_LIST_HEAD(&domain->acl_info_list); 729 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
740 domain->domainname = saved_domainname; 730 if (domain->is_deleted ||
741 domain->profile = profile; 731 tomoyo_pathcmp(saved_domainname, domain->domainname))
742 list_add_tail_rcu(&domain->list, &tomoyo_domain_list); 732 continue;
743 } else { 733 found = true;
744 kfree(domain); 734 break;
745 domain = NULL; 735 }
736 if (!found && tomoyo_memory_ok(entry)) {
737 INIT_LIST_HEAD(&entry->acl_info_list);
738 entry->domainname = saved_domainname;
739 entry->profile = profile;
740 list_add_tail_rcu(&entry->list, &tomoyo_domain_list);
741 domain = entry;
742 entry = NULL;
743 found = true;
746 } 744 }
747
748 out:
749 mutex_unlock(&tomoyo_policy_lock); 745 mutex_unlock(&tomoyo_policy_lock);
750 return domain; 746 kfree(entry);
747 return found ? domain : NULL;
751} 748}
752 749
753/** 750/**