diff options
author | Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> | 2019-01-24 04:37:36 -0500 |
---|---|---|
committer | James Morris <james.morris@microsoft.com> | 2019-01-24 17:50:27 -0500 |
commit | 4b42564181d683d767b495d7041b1f229468042f (patch) | |
tree | 8f100d312c522aa2a0d3cfbb118293919826702d | |
parent | cdcf6723add57a0ffb37cfde1ca54a00f5715b71 (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.c | 44 | ||||
-rw-r--r-- | security/tomoyo/common.h | 3 | ||||
-rw-r--r-- | security/tomoyo/domain.c | 17 |
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 | ||
168 | retry: | 168 | retry: |
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 | } |