]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
tomoyo: Allow multiple use_group lines.
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Thu, 24 Jan 2019 09:37:36 +0000 (18:37 +0900)
committerJames Morris <james.morris@microsoft.com>
Thu, 24 Jan 2019 22:50:27 +0000 (14:50 -0800)
Being able to specify multiple "use_group" lines makes it
easier to write whitelisted policies.

Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: James Morris <james.morris@microsoft.com>
security/tomoyo/common.c
security/tomoyo/common.h
security/tomoyo/domain.c

index 0f8079b65e23a791ee933dfbadfa2e4e90d3c2c7..148ad50a1f944cb92ecca47505c6578023b4131e 100644 (file)
@@ -1174,7 +1174,7 @@ static int tomoyo_write_domain(struct tomoyo_io_buffer *head)
        struct tomoyo_domain_info *domain = head->w.domain;
        const bool is_delete = head->w.is_delete;
        bool is_select = !is_delete && tomoyo_str_starts(&data, "select ");
-       unsigned int profile;
+       unsigned int idx;
 
        if (*data == '<') {
                int ret = 0;
@@ -1192,24 +1192,27 @@ static int tomoyo_write_domain(struct tomoyo_io_buffer *head)
        if (!domain)
                return -EINVAL;
        ns = domain->ns;
-       if (sscanf(data, "use_profile %u", &profile) == 1
-           && profile < TOMOYO_MAX_PROFILES) {
-               if (!tomoyo_policy_loaded || ns->profile_ptr[profile])
-                       domain->profile = (u8) profile;
+       if (sscanf(data, "use_profile %u", &idx) == 1
+           && idx < TOMOYO_MAX_PROFILES) {
+               if (!tomoyo_policy_loaded || ns->profile_ptr[idx])
+                       if (!is_delete)
+                               domain->profile = (u8) idx;
                return 0;
        }
-       if (sscanf(data, "use_group %u\n", &profile) == 1
-           && profile < TOMOYO_MAX_ACL_GROUPS) {
+       if (sscanf(data, "use_group %u\n", &idx) == 1
+           && idx < TOMOYO_MAX_ACL_GROUPS) {
                if (!is_delete)
-                       domain->group = (u8) profile;
+                       set_bit(idx, domain->group);
+               else
+                       clear_bit(idx, domain->group);
                return 0;
        }
-       for (profile = 0; profile < TOMOYO_MAX_DOMAIN_INFO_FLAGS; profile++) {
-               const char *cp = tomoyo_dif[profile];
+       for (idx = 0; idx < TOMOYO_MAX_DOMAIN_INFO_FLAGS; idx++) {
+               const char *cp = tomoyo_dif[idx];
 
                if (strncmp(data, cp, strlen(cp) - 1))
                        continue;
-               domain->flags[profile] = !is_delete;
+               domain->flags[idx] = !is_delete;
                return 0;
        }
        return tomoyo_write_domain2(ns, &domain->acl_info_list, data,
@@ -1629,22 +1632,33 @@ static void tomoyo_read_domain(struct tomoyo_io_buffer *head)
                        tomoyo_set_lf(head);
                        tomoyo_io_printf(head, "use_profile %u\n",
                                         domain->profile);
-                       tomoyo_io_printf(head, "use_group %u\n",
-                                        domain->group);
                        for (i = 0; i < TOMOYO_MAX_DOMAIN_INFO_FLAGS; i++)
                                if (domain->flags[i])
                                        tomoyo_set_string(head, tomoyo_dif[i]);
+                       head->r.index = 0;
                        head->r.step++;
-                       tomoyo_set_lf(head);
                        /* fall through */
                case 1:
+                       while (head->r.index < TOMOYO_MAX_ACL_GROUPS) {
+                               i = head->r.index++;
+                               if (!test_bit(i, domain->group))
+                                       continue;
+                               tomoyo_io_printf(head, "use_group %u\n", i);
+                               if (!tomoyo_flush(head))
+                                       return;
+                       }
+                       head->r.index = 0;
+                       head->r.step++;
+                       tomoyo_set_lf(head);
+                       /* fall through */
+               case 2:
                        if (!tomoyo_read_domain2(head, &domain->acl_info_list))
                                return;
                        head->r.step++;
                        if (!tomoyo_set_lf(head))
                                return;
                        /* fall through */
-               case 2:
+               case 3:
                        head->r.step = 0;
                        if (head->r.print_this_domain_only)
                                goto done;
index f2c458ab9942826bd0a584b69333d91cac217a52..74dbd3bdc64ef9f3228b54fea602ce9b2bd0cc2c 100644 (file)
@@ -684,8 +684,9 @@ struct tomoyo_domain_info {
        const struct tomoyo_path_info *domainname;
        /* Namespace for this domain. Never NULL. */
        struct tomoyo_policy_namespace *ns;
+       /* Group numbers to use.   */
+       unsigned long group[TOMOYO_MAX_ACL_GROUPS / BITS_PER_LONG];
        u8 profile;        /* Profile number to use. */
-       u8 group;          /* Group number to use.   */
        bool is_deleted;   /* Delete flag.           */
        bool flags[TOMOYO_MAX_DOMAIN_INFO_FLAGS];
        atomic_t users; /* Number of referring tasks. */
index bf832b3014125f4877fc47ef1528707725a2b49d..8526a0a74023855bbf383e56528e7ebf8107a8a9 100644 (file)
@@ -162,8 +162,8 @@ void tomoyo_check_acl(struct tomoyo_request_info *r,
 {
        const struct tomoyo_domain_info *domain = r->domain;
        struct tomoyo_acl_info *ptr;
-       bool retried = false;
        const struct list_head *list = &domain->acl_info_list;
+       u16 i = 0;
 
 retry:
        list_for_each_entry_rcu(ptr, list, list) {
@@ -177,9 +177,10 @@ void tomoyo_check_acl(struct tomoyo_request_info *r,
                r->granted = true;
                return;
        }
-       if (!retried) {
-               retried = true;
-               list = &domain->ns->acl_group[domain->group];
+       for (; i < TOMOYO_MAX_ACL_GROUPS; i++) {
+               if (!test_bit(i, domain->group))
+                       continue;
+               list = &domain->ns->acl_group[i++];
                goto retry;
        }
        r->granted = false;
@@ -561,7 +562,7 @@ struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname,
                const struct tomoyo_domain_info *domain = tomoyo_domain();
 
                e.profile = domain->profile;
-               e.group = domain->group;
+               memcpy(e.group, domain->group, sizeof(e.group));
        }
        e.domainname = tomoyo_get_name(domainname);
        if (!e.domainname)
@@ -583,13 +584,17 @@ struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname,
        if (entry && transit) {
                if (created) {
                        struct tomoyo_request_info r;
+                       int i;
 
                        tomoyo_init_request_info(&r, entry,
                                                 TOMOYO_MAC_FILE_EXECUTE);
                        r.granted = false;
                        tomoyo_write_log(&r, "use_profile %u\n",
                                         entry->profile);
-                       tomoyo_write_log(&r, "use_group %u\n", entry->group);
+                       for (i = 0; i < TOMOYO_MAX_ACL_GROUPS; i++)
+                               if (test_bit(i, entry->group))
+                                       tomoyo_write_log(&r, "use_group %u\n",
+                                                        i);
                        tomoyo_update_stat(TOMOYO_STAT_POLICY_UPDATES);
                }
        }