aboutsummaryrefslogtreecommitdiffstats
path: root/security/tomoyo/domain.c
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2010-06-03 07:36:43 -0400
committerJames Morris <jmorris@namei.org>2010-08-02 01:33:41 -0400
commitc8c57e842720d8cc92ac8607f2d1c16d92314573 (patch)
treedc921366b931ba5817ad530433f3b1ee178bc56a /security/tomoyo/domain.c
parent9b244373da3eab671da6c5125482121528a9ebf3 (diff)
TOMOYO: Support longer pathname.
Allow pathnames longer than 4000 bytes. Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/tomoyo/domain.c')
-rw-r--r--security/tomoyo/domain.c72
1 files changed, 33 insertions, 39 deletions
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index 08428bc082df..7b8693e29a13 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -676,47 +676,43 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
676int tomoyo_find_next_domain(struct linux_binprm *bprm) 676int tomoyo_find_next_domain(struct linux_binprm *bprm)
677{ 677{
678 struct tomoyo_request_info r; 678 struct tomoyo_request_info r;
679 /* 679 char *tmp = kzalloc(TOMOYO_EXEC_TMPSIZE, GFP_NOFS);
680 * This function assumes that the size of buffer returned by
681 * tomoyo_realpath() = TOMOYO_MAX_PATHNAME_LEN.
682 */
683 struct tomoyo_page_buffer *tmp = kzalloc(sizeof(*tmp), GFP_NOFS);
684 struct tomoyo_domain_info *old_domain = tomoyo_domain(); 680 struct tomoyo_domain_info *old_domain = tomoyo_domain();
685 struct tomoyo_domain_info *domain = NULL; 681 struct tomoyo_domain_info *domain = NULL;
686 const char *old_domain_name = old_domain->domainname->name; 682 const char *old_domain_name = old_domain->domainname->name;
687 const char *original_name = bprm->filename; 683 const char *original_name = bprm->filename;
688 char *new_domain_name = NULL;
689 char *real_program_name = NULL;
690 char *symlink_program_name = NULL;
691 const u8 mode = tomoyo_check_flags(old_domain, TOMOYO_MAC_FOR_FILE); 684 const u8 mode = tomoyo_check_flags(old_domain, TOMOYO_MAC_FOR_FILE);
692 const bool is_enforce = (mode == TOMOYO_CONFIG_ENFORCING); 685 const bool is_enforce = (mode == TOMOYO_CONFIG_ENFORCING);
693 int retval = -ENOMEM; 686 int retval = -ENOMEM;
694 struct tomoyo_path_info rn; /* real name */ 687 bool need_kfree = false;
695 struct tomoyo_path_info sn; /* symlink name */ 688 struct tomoyo_path_info rn = { }; /* real name */
689 struct tomoyo_path_info sn = { }; /* symlink name */
696 struct tomoyo_path_info ln; /* last name */ 690 struct tomoyo_path_info ln; /* last name */
697 691
692 ln.name = tomoyo_get_last_name(old_domain);
693 tomoyo_fill_path_info(&ln);
698 tomoyo_init_request_info(&r, NULL); 694 tomoyo_init_request_info(&r, NULL);
699 if (!tmp) 695 if (!tmp)
700 goto out; 696 goto out;
701 697
702 retry: 698 retry:
699 if (need_kfree) {
700 kfree(rn.name);
701 need_kfree = false;
702 }
703 /* Get tomoyo_realpath of program. */ 703 /* Get tomoyo_realpath of program. */
704 retval = -ENOENT; 704 retval = -ENOENT;
705 /* I hope tomoyo_realpath() won't fail with -ENOMEM. */ 705 rn.name = tomoyo_realpath(original_name);
706 real_program_name = tomoyo_realpath(original_name); 706 if (!rn.name)
707 if (!real_program_name)
708 goto out; 707 goto out;
708 tomoyo_fill_path_info(&rn);
709 need_kfree = true;
710
709 /* Get tomoyo_realpath of symbolic link. */ 711 /* Get tomoyo_realpath of symbolic link. */
710 symlink_program_name = tomoyo_realpath_nofollow(original_name); 712 sn.name = tomoyo_realpath_nofollow(original_name);
711 if (!symlink_program_name) 713 if (!sn.name)
712 goto out; 714 goto out;
713
714 rn.name = real_program_name;
715 tomoyo_fill_path_info(&rn);
716 sn.name = symlink_program_name;
717 tomoyo_fill_path_info(&sn); 715 tomoyo_fill_path_info(&sn);
718 ln.name = tomoyo_get_last_name(old_domain);
719 tomoyo_fill_path_info(&ln);
720 716
721 /* Check 'alias' directive. */ 717 /* Check 'alias' directive. */
722 if (tomoyo_pathcmp(&rn, &sn)) { 718 if (tomoyo_pathcmp(&rn, &sn)) {
@@ -727,10 +723,10 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
727 tomoyo_pathcmp(&rn, ptr->original_name) || 723 tomoyo_pathcmp(&rn, ptr->original_name) ||
728 tomoyo_pathcmp(&sn, ptr->aliased_name)) 724 tomoyo_pathcmp(&sn, ptr->aliased_name))
729 continue; 725 continue;
730 memset(real_program_name, 0, TOMOYO_MAX_PATHNAME_LEN); 726 kfree(rn.name);
731 strncpy(real_program_name, ptr->aliased_name->name, 727 need_kfree = false;
732 TOMOYO_MAX_PATHNAME_LEN - 1); 728 /* This is OK because it is read only. */
733 tomoyo_fill_path_info(&rn); 729 rn = *ptr->aliased_name;
734 break; 730 break;
735 } 731 }
736 } 732 }
@@ -742,11 +738,10 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
742 if (retval < 0) 738 if (retval < 0)
743 goto out; 739 goto out;
744 740
745 new_domain_name = tmp->buffer;
746 if (tomoyo_is_domain_initializer(old_domain->domainname, &rn, &ln)) { 741 if (tomoyo_is_domain_initializer(old_domain->domainname, &rn, &ln)) {
747 /* Transit to the child of tomoyo_kernel_domain domain. */ 742 /* Transit to the child of tomoyo_kernel_domain domain. */
748 snprintf(new_domain_name, TOMOYO_MAX_PATHNAME_LEN + 1, 743 snprintf(tmp, TOMOYO_EXEC_TMPSIZE - 1,
749 TOMOYO_ROOT_NAME " " "%s", real_program_name); 744 TOMOYO_ROOT_NAME " " "%s", rn.name);
750 } else if (old_domain == &tomoyo_kernel_domain && 745 } else if (old_domain == &tomoyo_kernel_domain &&
751 !tomoyo_policy_loaded) { 746 !tomoyo_policy_loaded) {
752 /* 747 /*
@@ -760,29 +755,27 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
760 domain = old_domain; 755 domain = old_domain;
761 } else { 756 } else {
762 /* Normal domain transition. */ 757 /* Normal domain transition. */
763 snprintf(new_domain_name, TOMOYO_MAX_PATHNAME_LEN + 1, 758 snprintf(tmp, TOMOYO_EXEC_TMPSIZE - 1,
764 "%s %s", old_domain_name, real_program_name); 759 "%s %s", old_domain_name, rn.name);
765 } 760 }
766 if (domain || strlen(new_domain_name) >= TOMOYO_MAX_PATHNAME_LEN) 761 if (domain || strlen(tmp) >= TOMOYO_EXEC_TMPSIZE - 10)
767 goto done; 762 goto done;
768 domain = tomoyo_find_domain(new_domain_name); 763 domain = tomoyo_find_domain(tmp);
769 if (domain) 764 if (domain)
770 goto done; 765 goto done;
771 if (is_enforce) { 766 if (is_enforce) {
772 int error = tomoyo_supervisor(&r, "# wants to create domain\n" 767 int error = tomoyo_supervisor(&r, "# wants to create domain\n"
773 "%s\n", new_domain_name); 768 "%s\n", tmp);
774 if (error == TOMOYO_RETRY_REQUEST) 769 if (error == TOMOYO_RETRY_REQUEST)
775 goto retry; 770 goto retry;
776 if (error < 0) 771 if (error < 0)
777 goto done; 772 goto done;
778 } 773 }
779 domain = tomoyo_find_or_assign_new_domain(new_domain_name, 774 domain = tomoyo_find_or_assign_new_domain(tmp, old_domain->profile);
780 old_domain->profile);
781 done: 775 done:
782 if (domain) 776 if (domain)
783 goto out; 777 goto out;
784 printk(KERN_WARNING "TOMOYO-ERROR: Domain '%s' not defined.\n", 778 printk(KERN_WARNING "TOMOYO-ERROR: Domain '%s' not defined.\n", tmp);
785 new_domain_name);
786 if (is_enforce) 779 if (is_enforce)
787 retval = -EPERM; 780 retval = -EPERM;
788 else 781 else
@@ -793,8 +786,9 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
793 /* Update reference count on "struct tomoyo_domain_info". */ 786 /* Update reference count on "struct tomoyo_domain_info". */
794 atomic_inc(&domain->users); 787 atomic_inc(&domain->users);
795 bprm->cred->security = domain; 788 bprm->cred->security = domain;
796 kfree(real_program_name); 789 if (need_kfree)
797 kfree(symlink_program_name); 790 kfree(rn.name);
791 kfree(sn.name);
798 kfree(tmp); 792 kfree(tmp);
799 return retval; 793 return retval;
800} 794}