Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Tetsuo Handa and committed by
James Morris
4b425641 cdcf6723

+42 -22
+29 -15
security/tomoyo/common.c
··· 1174 1174 struct tomoyo_domain_info *domain = head->w.domain; 1175 1175 const bool is_delete = head->w.is_delete; 1176 1176 bool is_select = !is_delete && tomoyo_str_starts(&data, "select "); 1177 - unsigned int profile; 1177 + unsigned int idx; 1178 1178 1179 1179 if (*data == '<') { 1180 1180 int ret = 0; ··· 1192 1192 if (!domain) 1193 1193 return -EINVAL; 1194 1194 ns = domain->ns; 1195 - if (sscanf(data, "use_profile %u", &profile) == 1 1196 - && profile < TOMOYO_MAX_PROFILES) { 1197 - if (!tomoyo_policy_loaded || ns->profile_ptr[profile]) 1198 - domain->profile = (u8) profile; 1195 + if (sscanf(data, "use_profile %u", &idx) == 1 1196 + && idx < TOMOYO_MAX_PROFILES) { 1197 + if (!tomoyo_policy_loaded || ns->profile_ptr[idx]) 1198 + if (!is_delete) 1199 + domain->profile = (u8) idx; 1199 1200 return 0; 1200 1201 } 1201 - if (sscanf(data, "use_group %u\n", &profile) == 1 1202 - && profile < TOMOYO_MAX_ACL_GROUPS) { 1202 + if (sscanf(data, "use_group %u\n", &idx) == 1 1203 + && idx < TOMOYO_MAX_ACL_GROUPS) { 1203 1204 if (!is_delete) 1204 - domain->group = (u8) profile; 1205 + set_bit(idx, domain->group); 1206 + else 1207 + clear_bit(idx, domain->group); 1205 1208 return 0; 1206 1209 } 1207 - for (profile = 0; profile < TOMOYO_MAX_DOMAIN_INFO_FLAGS; profile++) { 1208 - const char *cp = tomoyo_dif[profile]; 1210 + for (idx = 0; idx < TOMOYO_MAX_DOMAIN_INFO_FLAGS; idx++) { 1211 + const char *cp = tomoyo_dif[idx]; 1209 1212 1210 1213 if (strncmp(data, cp, strlen(cp) - 1)) 1211 1214 continue; 1212 - domain->flags[profile] = !is_delete; 1215 + domain->flags[idx] = !is_delete; 1213 1216 return 0; 1214 1217 } 1215 1218 return tomoyo_write_domain2(ns, &domain->acl_info_list, data, ··· 1632 1629 tomoyo_set_lf(head); 1633 1630 tomoyo_io_printf(head, "use_profile %u\n", 1634 1631 domain->profile); 1635 - tomoyo_io_printf(head, "use_group %u\n", 1636 - domain->group); 1637 1632 for (i = 0; i < TOMOYO_MAX_DOMAIN_INFO_FLAGS; i++) 1638 1633 if (domain->flags[i]) 1639 1634 tomoyo_set_string(head, tomoyo_dif[i]); 1635 + head->r.index = 0; 1636 + head->r.step++; 1637 + /* fall through */ 1638 + case 1: 1639 + while (head->r.index < TOMOYO_MAX_ACL_GROUPS) { 1640 + i = head->r.index++; 1641 + if (!test_bit(i, domain->group)) 1642 + continue; 1643 + tomoyo_io_printf(head, "use_group %u\n", i); 1644 + if (!tomoyo_flush(head)) 1645 + return; 1646 + } 1647 + head->r.index = 0; 1640 1648 head->r.step++; 1641 1649 tomoyo_set_lf(head); 1642 1650 /* fall through */ 1643 - case 1: 1651 + case 2: 1644 1652 if (!tomoyo_read_domain2(head, &domain->acl_info_list)) 1645 1653 return; 1646 1654 head->r.step++; 1647 1655 if (!tomoyo_set_lf(head)) 1648 1656 return; 1649 1657 /* fall through */ 1650 - case 2: 1658 + case 3: 1651 1659 head->r.step = 0; 1652 1660 if (head->r.print_this_domain_only) 1653 1661 goto done;
+2 -1
security/tomoyo/common.h
··· 684 684 const struct tomoyo_path_info *domainname; 685 685 /* Namespace for this domain. Never NULL. */ 686 686 struct tomoyo_policy_namespace *ns; 687 + /* Group numbers to use. */ 688 + unsigned long group[TOMOYO_MAX_ACL_GROUPS / BITS_PER_LONG]; 687 689 u8 profile; /* Profile number to use. */ 688 - u8 group; /* Group number to use. */ 689 690 bool is_deleted; /* Delete flag. */ 690 691 bool flags[TOMOYO_MAX_DOMAIN_INFO_FLAGS]; 691 692 atomic_t users; /* Number of referring tasks. */
+11 -6
security/tomoyo/domain.c
··· 162 162 { 163 163 const struct tomoyo_domain_info *domain = r->domain; 164 164 struct tomoyo_acl_info *ptr; 165 - bool retried = false; 166 165 const struct list_head *list = &domain->acl_info_list; 166 + u16 i = 0; 167 167 168 168 retry: 169 169 list_for_each_entry_rcu(ptr, list, list) { ··· 177 177 r->granted = true; 178 178 return; 179 179 } 180 - if (!retried) { 181 - retried = true; 182 - list = &domain->ns->acl_group[domain->group]; 180 + for (; i < TOMOYO_MAX_ACL_GROUPS; i++) { 181 + if (!test_bit(i, domain->group)) 182 + continue; 183 + list = &domain->ns->acl_group[i++]; 183 184 goto retry; 184 185 } 185 186 r->granted = false; ··· 562 561 const struct tomoyo_domain_info *domain = tomoyo_domain(); 563 562 564 563 e.profile = domain->profile; 565 - e.group = domain->group; 564 + memcpy(e.group, domain->group, sizeof(e.group)); 566 565 } 567 566 e.domainname = tomoyo_get_name(domainname); 568 567 if (!e.domainname) ··· 584 583 if (entry && transit) { 585 584 if (created) { 586 585 struct tomoyo_request_info r; 586 + int i; 587 587 588 588 tomoyo_init_request_info(&r, entry, 589 589 TOMOYO_MAC_FILE_EXECUTE); 590 590 r.granted = false; 591 591 tomoyo_write_log(&r, "use_profile %u\n", 592 592 entry->profile); 593 - tomoyo_write_log(&r, "use_group %u\n", entry->group); 593 + for (i = 0; i < TOMOYO_MAX_ACL_GROUPS; i++) 594 + if (test_bit(i, entry->group)) 595 + tomoyo_write_log(&r, "use_group %u\n", 596 + i); 594 597 tomoyo_update_stat(TOMOYO_STAT_POLICY_UPDATES); 595 598 } 596 599 }