diff options
author | Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> | 2010-06-03 07:36:43 -0400 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2010-08-02 01:33:41 -0400 |
commit | c8c57e842720d8cc92ac8607f2d1c16d92314573 (patch) | |
tree | dc921366b931ba5817ad530433f3b1ee178bc56a /security/tomoyo/domain.c | |
parent | 9b244373da3eab671da6c5125482121528a9ebf3 (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.c | 72 |
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 * | |||
676 | int tomoyo_find_next_domain(struct linux_binprm *bprm) | 676 | int 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 | } |