Commit 4b425641 authored by Tetsuo Handa's avatar Tetsuo Handa Committed by James Morris

tomoyo: Allow multiple use_group lines.

Being able to specify multiple "use_group" lines makes it
easier to write whitelisted policies.
Signed-off-by: default avatarTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: default avatarJames Morris <james.morris@microsoft.com>
parent cdcf6723
...@@ -1174,7 +1174,7 @@ static int tomoyo_write_domain(struct tomoyo_io_buffer *head) ...@@ -1174,7 +1174,7 @@ static int tomoyo_write_domain(struct tomoyo_io_buffer *head)
struct tomoyo_domain_info *domain = head->w.domain; struct tomoyo_domain_info *domain = head->w.domain;
const bool is_delete = head->w.is_delete; const bool is_delete = head->w.is_delete;
bool is_select = !is_delete && tomoyo_str_starts(&data, "select "); bool is_select = !is_delete && tomoyo_str_starts(&data, "select ");
unsigned int profile; unsigned int idx;
if (*data == '<') { if (*data == '<') {
int ret = 0; int ret = 0;
...@@ -1192,24 +1192,27 @@ static int tomoyo_write_domain(struct tomoyo_io_buffer *head) ...@@ -1192,24 +1192,27 @@ static int tomoyo_write_domain(struct tomoyo_io_buffer *head)
if (!domain) if (!domain)
return -EINVAL; return -EINVAL;
ns = domain->ns; ns = domain->ns;
if (sscanf(data, "use_profile %u", &profile) == 1 if (sscanf(data, "use_profile %u", &idx) == 1
&& profile < TOMOYO_MAX_PROFILES) { && idx < TOMOYO_MAX_PROFILES) {
if (!tomoyo_policy_loaded || ns->profile_ptr[profile]) if (!tomoyo_policy_loaded || ns->profile_ptr[idx])
domain->profile = (u8) profile; if (!is_delete)
domain->profile = (u8) idx;
return 0; return 0;
} }
if (sscanf(data, "use_group %u\n", &profile) == 1 if (sscanf(data, "use_group %u\n", &idx) == 1
&& profile < TOMOYO_MAX_ACL_GROUPS) { && idx < TOMOYO_MAX_ACL_GROUPS) {
if (!is_delete) if (!is_delete)
domain->group = (u8) profile; set_bit(idx, domain->group);
else
clear_bit(idx, domain->group);
return 0; return 0;
} }
for (profile = 0; profile < TOMOYO_MAX_DOMAIN_INFO_FLAGS; profile++) { for (idx = 0; idx < TOMOYO_MAX_DOMAIN_INFO_FLAGS; idx++) {
const char *cp = tomoyo_dif[profile]; const char *cp = tomoyo_dif[idx];
if (strncmp(data, cp, strlen(cp) - 1)) if (strncmp(data, cp, strlen(cp) - 1))
continue; continue;
domain->flags[profile] = !is_delete; domain->flags[idx] = !is_delete;
return 0; return 0;
} }
return tomoyo_write_domain2(ns, &domain->acl_info_list, data, 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,22 +1632,33 @@ static void tomoyo_read_domain(struct tomoyo_io_buffer *head)
tomoyo_set_lf(head); tomoyo_set_lf(head);
tomoyo_io_printf(head, "use_profile %u\n", tomoyo_io_printf(head, "use_profile %u\n",
domain->profile); domain->profile);
tomoyo_io_printf(head, "use_group %u\n",
domain->group);
for (i = 0; i < TOMOYO_MAX_DOMAIN_INFO_FLAGS; i++) for (i = 0; i < TOMOYO_MAX_DOMAIN_INFO_FLAGS; i++)
if (domain->flags[i]) if (domain->flags[i])
tomoyo_set_string(head, tomoyo_dif[i]); tomoyo_set_string(head, tomoyo_dif[i]);
head->r.index = 0;
head->r.step++; head->r.step++;
tomoyo_set_lf(head);
/* fall through */ /* fall through */
case 1: 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)) if (!tomoyo_read_domain2(head, &domain->acl_info_list))
return; return;
head->r.step++; head->r.step++;
if (!tomoyo_set_lf(head)) if (!tomoyo_set_lf(head))
return; return;
/* fall through */ /* fall through */
case 2: case 3:
head->r.step = 0; head->r.step = 0;
if (head->r.print_this_domain_only) if (head->r.print_this_domain_only)
goto done; goto done;
......
...@@ -684,8 +684,9 @@ struct tomoyo_domain_info { ...@@ -684,8 +684,9 @@ struct tomoyo_domain_info {
const struct tomoyo_path_info *domainname; const struct tomoyo_path_info *domainname;
/* Namespace for this domain. Never NULL. */ /* Namespace for this domain. Never NULL. */
struct tomoyo_policy_namespace *ns; 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 profile; /* Profile number to use. */
u8 group; /* Group number to use. */
bool is_deleted; /* Delete flag. */ bool is_deleted; /* Delete flag. */
bool flags[TOMOYO_MAX_DOMAIN_INFO_FLAGS]; bool flags[TOMOYO_MAX_DOMAIN_INFO_FLAGS];
atomic_t users; /* Number of referring tasks. */ atomic_t users; /* Number of referring tasks. */
......
...@@ -162,8 +162,8 @@ void tomoyo_check_acl(struct tomoyo_request_info *r, ...@@ -162,8 +162,8 @@ void tomoyo_check_acl(struct tomoyo_request_info *r,
{ {
const struct tomoyo_domain_info *domain = r->domain; const struct tomoyo_domain_info *domain = r->domain;
struct tomoyo_acl_info *ptr; struct tomoyo_acl_info *ptr;
bool retried = false;
const struct list_head *list = &domain->acl_info_list; const struct list_head *list = &domain->acl_info_list;
u16 i = 0;
retry: retry:
list_for_each_entry_rcu(ptr, list, list) { list_for_each_entry_rcu(ptr, list, list) {
...@@ -177,9 +177,10 @@ void tomoyo_check_acl(struct tomoyo_request_info *r, ...@@ -177,9 +177,10 @@ void tomoyo_check_acl(struct tomoyo_request_info *r,
r->granted = true; r->granted = true;
return; return;
} }
if (!retried) { for (; i < TOMOYO_MAX_ACL_GROUPS; i++) {
retried = true; if (!test_bit(i, domain->group))
list = &domain->ns->acl_group[domain->group]; continue;
list = &domain->ns->acl_group[i++];
goto retry; goto retry;
} }
r->granted = false; r->granted = false;
...@@ -561,7 +562,7 @@ struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname, ...@@ -561,7 +562,7 @@ struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname,
const struct tomoyo_domain_info *domain = tomoyo_domain(); const struct tomoyo_domain_info *domain = tomoyo_domain();
e.profile = domain->profile; e.profile = domain->profile;
e.group = domain->group; memcpy(e.group, domain->group, sizeof(e.group));
} }
e.domainname = tomoyo_get_name(domainname); e.domainname = tomoyo_get_name(domainname);
if (!e.domainname) if (!e.domainname)
...@@ -583,13 +584,17 @@ struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname, ...@@ -583,13 +584,17 @@ struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname,
if (entry && transit) { if (entry && transit) {
if (created) { if (created) {
struct tomoyo_request_info r; struct tomoyo_request_info r;
int i;
tomoyo_init_request_info(&r, entry, tomoyo_init_request_info(&r, entry,
TOMOYO_MAC_FILE_EXECUTE); TOMOYO_MAC_FILE_EXECUTE);
r.granted = false; r.granted = false;
tomoyo_write_log(&r, "use_profile %u\n", tomoyo_write_log(&r, "use_profile %u\n",
entry->profile); 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); tomoyo_update_stat(TOMOYO_STAT_POLICY_UPDATES);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment