aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2019-01-24 04:37:36 -0500
committerJames Morris <james.morris@microsoft.com>2019-01-24 17:50:27 -0500
commit4b42564181d683d767b495d7041b1f229468042f (patch)
tree8f100d312c522aa2a0d3cfbb118293919826702d
parentcdcf6723add57a0ffb37cfde1ca54a00f5715b71 (diff)
tomoyo: Allow multiple use_group lines.
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>
-rw-r--r--security/tomoyo/common.c44
-rw-r--r--security/tomoyo/common.h3
-rw-r--r--security/tomoyo/domain.c17
3 files changed, 42 insertions, 22 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index 0f8079b65e23..148ad50a1f94 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -1174,7 +1174,7 @@ static int tomoyo_write_domain(struct tomoyo_io_buffer *head)
1174 struct tomoyo_domain_info *domain = head->w.domain; 1174 struct tomoyo_domain_info *domain = head->w.domain;
1175 const bool is_delete = head->w.is_delete; 1175 const bool is_delete = head->w.is_delete;
1176 bool is_select = !is_delete && tomoyo_str_starts(&data, "select "); 1176 bool is_select = !is_delete && tomoyo_str_starts(&data, "select ");
1177 unsigned int profile; 1177 unsigned int idx;
1178 1178
1179 if (*data == '<') { 1179 if (*data == '<') {
1180 int ret = 0; 1180 int ret = 0;
@@ -1192,24 +1192,27 @@ static int tomoyo_write_domain(struct tomoyo_io_buffer *head)
1192 if (!domain) 1192 if (!domain)
1193 return -EINVAL; 1193 return -EINVAL;
1194 ns = domain->ns; 1194 ns = domain->ns;
1195 if (sscanf(data, "use_profile %u", &profile) == 1 1195 if (sscanf(data, "use_profile %u", &idx) == 1
1196 && profile < TOMOYO_MAX_PROFILES) { 1196 && idx < TOMOYO_MAX_PROFILES) {
1197 if (!tomoyo_policy_loaded || ns->profile_ptr[profile]) 1197 if (!tomoyo_policy_loaded || ns->profile_ptr[idx])
1198 domain->profile = (u8) profile; 1198 if (!is_delete)
1199 domain->profile = (u8) idx;
1199 return 0; 1200 return 0;
1200 } 1201 }
1201 if (sscanf(data, "use_group %u\n", &profile) == 1 1202 if (sscanf(data, "use_group %u\n", &idx) == 1
1202 && profile < TOMOYO_MAX_ACL_GROUPS) { 1203 && idx < TOMOYO_MAX_ACL_GROUPS) {
1203 if (!is_delete) 1204 if (!is_delete)
1204 domain->group = (u8) profile; 1205 set_bit(idx, domain->group);
1206 else
1207 clear_bit(idx, domain->group);
1205 return 0; 1208 return 0;
1206 } 1209 }
1207 for (profile = 0; profile < TOMOYO_MAX_DOMAIN_INFO_FLAGS; profile++) { 1210 for (idx = 0; idx < TOMOYO_MAX_DOMAIN_INFO_FLAGS; idx++) {
1208 const char *cp = tomoyo_dif[profile]; 1211 const char *cp = tomoyo_dif[idx];
1209 1212
1210 if (strncmp(data, cp, strlen(cp) - 1)) 1213 if (strncmp(data, cp, strlen(cp) - 1))
1211 continue; 1214 continue;
1212 domain->flags[profile] = !is_delete; 1215 domain->flags[idx] = !is_delete;
1213 return 0; 1216 return 0;
1214 } 1217 }
1215 return tomoyo_write_domain2(ns, &domain->acl_info_list, data, 1218 return tomoyo_write_domain2(ns, &domain->acl_info_list, data,
@@ -1629,22 +1632,33 @@ static void tomoyo_read_domain(struct tomoyo_io_buffer *head)
1629 tomoyo_set_lf(head); 1632 tomoyo_set_lf(head);
1630 tomoyo_io_printf(head, "use_profile %u\n", 1633 tomoyo_io_printf(head, "use_profile %u\n",
1631 domain->profile); 1634 domain->profile);
1632 tomoyo_io_printf(head, "use_group %u\n",
1633 domain->group);
1634 for (i = 0; i < TOMOYO_MAX_DOMAIN_INFO_FLAGS; i++) 1635 for (i = 0; i < TOMOYO_MAX_DOMAIN_INFO_FLAGS; i++)
1635 if (domain->flags[i]) 1636 if (domain->flags[i])
1636 tomoyo_set_string(head, tomoyo_dif[i]); 1637 tomoyo_set_string(head, tomoyo_dif[i]);
1638 head->r.index = 0;
1637 head->r.step++; 1639 head->r.step++;
1638 tomoyo_set_lf(head);
1639 /* fall through */ 1640 /* fall through */
1640 case 1: 1641 case 1:
1642 while (head->r.index < TOMOYO_MAX_ACL_GROUPS) {
1643 i = head->r.index++;
1644 if (!test_bit(i, domain->group))
1645 continue;
1646 tomoyo_io_printf(head, "use_group %u\n", i);
1647 if (!tomoyo_flush(head))
1648 return;
1649 }
1650 head->r.index = 0;
1651 head->r.step++;
1652 tomoyo_set_lf(head);
1653 /* fall through */
1654 case 2:
1641 if (!tomoyo_read_domain2(head, &domain->acl_info_list)) 1655 if (!tomoyo_read_domain2(head, &domain->acl_info_list))
1642 return; 1656 return;
1643 head->r.step++; 1657 head->r.step++;
1644 if (!tomoyo_set_lf(head)) 1658 if (!tomoyo_set_lf(head))
1645 return; 1659 return;
1646 /* fall through */ 1660 /* fall through */
1647 case 2: 1661 case 3:
1648 head->r.step = 0; 1662 head->r.step = 0;
1649 if (head->r.print_this_domain_only) 1663 if (head->r.print_this_domain_only)
1650 goto done; 1664 goto done;
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index f2c458ab9942..74dbd3bdc64e 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -684,8 +684,9 @@ struct tomoyo_domain_info {
684 const struct tomoyo_path_info *domainname; 684 const struct tomoyo_path_info *domainname;
685 /* Namespace for this domain. Never NULL. */ 685 /* Namespace for this domain. Never NULL. */
686 struct tomoyo_policy_namespace *ns; 686 struct tomoyo_policy_namespace *ns;
687 /* Group numbers to use. */
688 unsigned long group[TOMOYO_MAX_ACL_GROUPS / BITS_PER_LONG];
687 u8 profile; /* Profile number to use. */ 689 u8 profile; /* Profile number to use. */
688 u8 group; /* Group number to use. */
689 bool is_deleted; /* Delete flag. */ 690 bool is_deleted; /* Delete flag. */
690 bool flags[TOMOYO_MAX_DOMAIN_INFO_FLAGS]; 691 bool flags[TOMOYO_MAX_DOMAIN_INFO_FLAGS];
691 atomic_t users; /* Number of referring tasks. */ 692 atomic_t users; /* Number of referring tasks. */
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index bf832b301412..8526a0a74023 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -162,8 +162,8 @@ void tomoyo_check_acl(struct tomoyo_request_info *r,
162{ 162{
163 const struct tomoyo_domain_info *domain = r->domain; 163 const struct tomoyo_domain_info *domain = r->domain;
164 struct tomoyo_acl_info *ptr; 164 struct tomoyo_acl_info *ptr;
165 bool retried = false;
166 const struct list_head *list = &domain->acl_info_list; 165 const struct list_head *list = &domain->acl_info_list;
166 u16 i = 0;
167 167
168retry: 168retry:
169 list_for_each_entry_rcu(ptr, list, list) { 169 list_for_each_entry_rcu(ptr, list, list) {
@@ -177,9 +177,10 @@ retry:
177 r->granted = true; 177 r->granted = true;
178 return; 178 return;
179 } 179 }
180 if (!retried) { 180 for (; i < TOMOYO_MAX_ACL_GROUPS; i++) {
181 retried = true; 181 if (!test_bit(i, domain->group))
182 list = &domain->ns->acl_group[domain->group]; 182 continue;
183 list = &domain->ns->acl_group[i++];
183 goto retry; 184 goto retry;
184 } 185 }
185 r->granted = false; 186 r->granted = false;
@@ -561,7 +562,7 @@ struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname,
561 const struct tomoyo_domain_info *domain = tomoyo_domain(); 562 const struct tomoyo_domain_info *domain = tomoyo_domain();
562 563
563 e.profile = domain->profile; 564 e.profile = domain->profile;
564 e.group = domain->group; 565 memcpy(e.group, domain->group, sizeof(e.group));
565 } 566 }
566 e.domainname = tomoyo_get_name(domainname); 567 e.domainname = tomoyo_get_name(domainname);
567 if (!e.domainname) 568 if (!e.domainname)
@@ -583,13 +584,17 @@ out:
583 if (entry && transit) { 584 if (entry && transit) {
584 if (created) { 585 if (created) {
585 struct tomoyo_request_info r; 586 struct tomoyo_request_info r;
587 int i;
586 588
587 tomoyo_init_request_info(&r, entry, 589 tomoyo_init_request_info(&r, entry,
588 TOMOYO_MAC_FILE_EXECUTE); 590 TOMOYO_MAC_FILE_EXECUTE);
589 r.granted = false; 591 r.granted = false;
590 tomoyo_write_log(&r, "use_profile %u\n", 592 tomoyo_write_log(&r, "use_profile %u\n",
591 entry->profile); 593 entry->profile);
592 tomoyo_write_log(&r, "use_group %u\n", entry->group); 594 for (i = 0; i < TOMOYO_MAX_ACL_GROUPS; i++)
595 if (test_bit(i, entry->group))
596 tomoyo_write_log(&r, "use_group %u\n",
597 i);
593 tomoyo_update_stat(TOMOYO_STAT_POLICY_UPDATES); 598 tomoyo_update_stat(TOMOYO_STAT_POLICY_UPDATES);
594 } 599 }
595 } 600 }