aboutsummaryrefslogtreecommitdiffstats
path: root/security/tomoyo/domain.c
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2010-05-16 21:11:36 -0400
committerJames Morris <jmorris@namei.org>2010-08-02 01:33:38 -0400
commit17fcfbd9d45b57f38d40e31f9d28db53f4af5c88 (patch)
treee221937affe4d886706e880f39e1424333490cc0 /security/tomoyo/domain.c
parent2106ccd972dcd9fda7df9b181505fac1741b3508 (diff)
TOMOYO: Add interactive enforcing mode.
Since the behavior of the system is restricted by policy, we may need to update policy when you update packages. We need to update policy in the following cases. * The pathname of files has changed. * The dependency of files has changed. * The access permissions required has increased. The ideal way to update policy is to rebuild from the scratch using learning mode. But it is not desirable to change from enforcing mode to other mode if the system has once entered in production state. Suppose MAC could support per-application enforcing mode, the MAC becomes useless if an application that is not running in enforcing mode was cracked. For example, the whole system becomes vulnerable if only HTTP server application is running in learning mode to rebuild policy for the application. So, in TOMOYO Linux, updating policy is done while the system is running in enforcing mode. This patch implements "interactive enforcing mode" which allows administrators to judge whether to accept policy violation in enforcing mode or not. A demo movie is available at http://www.youtube.com/watch?v=b9q1Jo25LPA . 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.c47
1 files changed, 29 insertions, 18 deletions
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index afdf26128bfe..7e242d27da5a 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -678,6 +678,7 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
678 */ 678 */
679int tomoyo_find_next_domain(struct linux_binprm *bprm) 679int tomoyo_find_next_domain(struct linux_binprm *bprm)
680{ 680{
681 struct tomoyo_request_info r;
681 /* 682 /*
682 * This function assumes that the size of buffer returned by 683 * This function assumes that the size of buffer returned by
683 * tomoyo_realpath() = TOMOYO_MAX_PATHNAME_LEN. 684 * tomoyo_realpath() = TOMOYO_MAX_PATHNAME_LEN.
@@ -693,11 +694,12 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
693 const u8 mode = tomoyo_check_flags(old_domain, TOMOYO_MAC_FOR_FILE); 694 const u8 mode = tomoyo_check_flags(old_domain, TOMOYO_MAC_FOR_FILE);
694 const bool is_enforce = (mode == TOMOYO_CONFIG_ENFORCING); 695 const bool is_enforce = (mode == TOMOYO_CONFIG_ENFORCING);
695 int retval = -ENOMEM; 696 int retval = -ENOMEM;
696 struct tomoyo_path_info r; /* real name */ 697 struct tomoyo_path_info rn; /* real name */
697 struct tomoyo_path_info s; /* symlink name */ 698 struct tomoyo_path_info sn; /* symlink name */
698 struct tomoyo_path_info l; /* last name */ 699 struct tomoyo_path_info ln; /* last name */
699 static bool initialized; 700 static bool initialized;
700 701
702 tomoyo_init_request_info(&r, NULL);
701 if (!tmp) 703 if (!tmp)
702 goto out; 704 goto out;
703 705
@@ -713,6 +715,7 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
713 initialized = true; 715 initialized = true;
714 } 716 }
715 717
718 retry:
716 /* Get tomoyo_realpath of program. */ 719 /* Get tomoyo_realpath of program. */
717 retval = -ENOENT; 720 retval = -ENOENT;
718 /* I hope tomoyo_realpath() won't fail with -ENOMEM. */ 721 /* I hope tomoyo_realpath() won't fail with -ENOMEM. */
@@ -724,37 +727,39 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
724 if (!symlink_program_name) 727 if (!symlink_program_name)
725 goto out; 728 goto out;
726 729
727 r.name = real_program_name; 730 rn.name = real_program_name;
728 tomoyo_fill_path_info(&r); 731 tomoyo_fill_path_info(&rn);
729 s.name = symlink_program_name; 732 sn.name = symlink_program_name;
730 tomoyo_fill_path_info(&s); 733 tomoyo_fill_path_info(&sn);
731 l.name = tomoyo_get_last_name(old_domain); 734 ln.name = tomoyo_get_last_name(old_domain);
732 tomoyo_fill_path_info(&l); 735 tomoyo_fill_path_info(&ln);
733 736
734 /* Check 'alias' directive. */ 737 /* Check 'alias' directive. */
735 if (tomoyo_pathcmp(&r, &s)) { 738 if (tomoyo_pathcmp(&rn, &sn)) {
736 struct tomoyo_alias_entry *ptr; 739 struct tomoyo_alias_entry *ptr;
737 /* Is this program allowed to be called via symbolic links? */ 740 /* Is this program allowed to be called via symbolic links? */
738 list_for_each_entry_rcu(ptr, &tomoyo_alias_list, list) { 741 list_for_each_entry_rcu(ptr, &tomoyo_alias_list, list) {
739 if (ptr->is_deleted || 742 if (ptr->is_deleted ||
740 tomoyo_pathcmp(&r, ptr->original_name) || 743 tomoyo_pathcmp(&rn, ptr->original_name) ||
741 tomoyo_pathcmp(&s, ptr->aliased_name)) 744 tomoyo_pathcmp(&sn, ptr->aliased_name))
742 continue; 745 continue;
743 memset(real_program_name, 0, TOMOYO_MAX_PATHNAME_LEN); 746 memset(real_program_name, 0, TOMOYO_MAX_PATHNAME_LEN);
744 strncpy(real_program_name, ptr->aliased_name->name, 747 strncpy(real_program_name, ptr->aliased_name->name,
745 TOMOYO_MAX_PATHNAME_LEN - 1); 748 TOMOYO_MAX_PATHNAME_LEN - 1);
746 tomoyo_fill_path_info(&r); 749 tomoyo_fill_path_info(&rn);
747 break; 750 break;
748 } 751 }
749 } 752 }
750 753
751 /* Check execute permission. */ 754 /* Check execute permission. */
752 retval = tomoyo_check_exec_perm(old_domain, &r); 755 retval = tomoyo_check_exec_perm(old_domain, &rn);
756 if (retval == TOMOYO_RETRY_REQUEST)
757 goto retry;
753 if (retval < 0) 758 if (retval < 0)
754 goto out; 759 goto out;
755 760
756 new_domain_name = tmp->buffer; 761 new_domain_name = tmp->buffer;
757 if (tomoyo_is_domain_initializer(old_domain->domainname, &r, &l)) { 762 if (tomoyo_is_domain_initializer(old_domain->domainname, &rn, &ln)) {
758 /* Transit to the child of tomoyo_kernel_domain domain. */ 763 /* Transit to the child of tomoyo_kernel_domain domain. */
759 snprintf(new_domain_name, TOMOYO_MAX_PATHNAME_LEN + 1, 764 snprintf(new_domain_name, TOMOYO_MAX_PATHNAME_LEN + 1,
760 TOMOYO_ROOT_NAME " " "%s", real_program_name); 765 TOMOYO_ROOT_NAME " " "%s", real_program_name);
@@ -766,7 +771,7 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
766 * initializers because they might start before /sbin/init. 771 * initializers because they might start before /sbin/init.
767 */ 772 */
768 domain = old_domain; 773 domain = old_domain;
769 } else if (tomoyo_is_domain_keeper(old_domain->domainname, &r, &l)) { 774 } else if (tomoyo_is_domain_keeper(old_domain->domainname, &rn, &ln)) {
770 /* Keep current domain. */ 775 /* Keep current domain. */
771 domain = old_domain; 776 domain = old_domain;
772 } else { 777 } else {
@@ -779,8 +784,14 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
779 domain = tomoyo_find_domain(new_domain_name); 784 domain = tomoyo_find_domain(new_domain_name);
780 if (domain) 785 if (domain)
781 goto done; 786 goto done;
782 if (is_enforce) 787 if (is_enforce) {
783 goto done; 788 int error = tomoyo_supervisor(&r, "# wants to create domain\n"
789 "%s\n", new_domain_name);
790 if (error == TOMOYO_RETRY_REQUEST)
791 goto retry;
792 if (error < 0)
793 goto done;
794 }
784 domain = tomoyo_find_or_assign_new_domain(new_domain_name, 795 domain = tomoyo_find_or_assign_new_domain(new_domain_name,
785 old_domain->profile); 796 old_domain->profile);
786 done: 797 done: