diff options
Diffstat (limited to 'security/tomoyo/common.c')
-rw-r--r-- | security/tomoyo/common.c | 63 |
1 files changed, 23 insertions, 40 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index c47d3ce6c733..8656b16eef7b 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c | |||
@@ -1069,7 +1069,7 @@ static int tomoyo_write_task(struct tomoyo_acl_param *param) | |||
1069 | * | 1069 | * |
1070 | * @domainname: The name of domain. | 1070 | * @domainname: The name of domain. |
1071 | * | 1071 | * |
1072 | * Returns 0. | 1072 | * Returns 0 on success, negative value otherwise. |
1073 | * | 1073 | * |
1074 | * Caller holds tomoyo_read_lock(). | 1074 | * Caller holds tomoyo_read_lock(). |
1075 | */ | 1075 | */ |
@@ -1081,7 +1081,7 @@ static int tomoyo_delete_domain(char *domainname) | |||
1081 | name.name = domainname; | 1081 | name.name = domainname; |
1082 | tomoyo_fill_path_info(&name); | 1082 | tomoyo_fill_path_info(&name); |
1083 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) | 1083 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) |
1084 | return 0; | 1084 | return -EINTR; |
1085 | /* Is there an active domain? */ | 1085 | /* Is there an active domain? */ |
1086 | list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { | 1086 | list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { |
1087 | /* Never delete tomoyo_kernel_domain */ | 1087 | /* Never delete tomoyo_kernel_domain */ |
@@ -1164,15 +1164,16 @@ static int tomoyo_write_domain(struct tomoyo_io_buffer *head) | |||
1164 | bool is_select = !is_delete && tomoyo_str_starts(&data, "select "); | 1164 | bool is_select = !is_delete && tomoyo_str_starts(&data, "select "); |
1165 | unsigned int profile; | 1165 | unsigned int profile; |
1166 | if (*data == '<') { | 1166 | if (*data == '<') { |
1167 | int ret = 0; | ||
1167 | domain = NULL; | 1168 | domain = NULL; |
1168 | if (is_delete) | 1169 | if (is_delete) |
1169 | tomoyo_delete_domain(data); | 1170 | ret = tomoyo_delete_domain(data); |
1170 | else if (is_select) | 1171 | else if (is_select) |
1171 | domain = tomoyo_find_domain(data); | 1172 | domain = tomoyo_find_domain(data); |
1172 | else | 1173 | else |
1173 | domain = tomoyo_assign_domain(data, false); | 1174 | domain = tomoyo_assign_domain(data, false); |
1174 | head->w.domain = domain; | 1175 | head->w.domain = domain; |
1175 | return 0; | 1176 | return ret; |
1176 | } | 1177 | } |
1177 | if (!domain) | 1178 | if (!domain) |
1178 | return -EINVAL; | 1179 | return -EINVAL; |
@@ -2111,7 +2112,7 @@ static struct tomoyo_domain_info *tomoyo_find_domain_by_qid | |||
2111 | struct tomoyo_domain_info *domain = NULL; | 2112 | struct tomoyo_domain_info *domain = NULL; |
2112 | spin_lock(&tomoyo_query_list_lock); | 2113 | spin_lock(&tomoyo_query_list_lock); |
2113 | list_for_each_entry(ptr, &tomoyo_query_list, list) { | 2114 | list_for_each_entry(ptr, &tomoyo_query_list, list) { |
2114 | if (ptr->serial != serial || ptr->answer) | 2115 | if (ptr->serial != serial) |
2115 | continue; | 2116 | continue; |
2116 | domain = ptr->domain; | 2117 | domain = ptr->domain; |
2117 | break; | 2118 | break; |
@@ -2130,28 +2131,13 @@ static struct tomoyo_domain_info *tomoyo_find_domain_by_qid | |||
2130 | * | 2131 | * |
2131 | * Waits for access requests which violated policy in enforcing mode. | 2132 | * Waits for access requests which violated policy in enforcing mode. |
2132 | */ | 2133 | */ |
2133 | static int tomoyo_poll_query(struct file *file, poll_table *wait) | 2134 | static unsigned int tomoyo_poll_query(struct file *file, poll_table *wait) |
2134 | { | 2135 | { |
2135 | struct list_head *tmp; | 2136 | if (!list_empty(&tomoyo_query_list)) |
2136 | bool found = false; | 2137 | return POLLIN | POLLRDNORM; |
2137 | u8 i; | 2138 | poll_wait(file, &tomoyo_query_wait, wait); |
2138 | for (i = 0; i < 2; i++) { | 2139 | if (!list_empty(&tomoyo_query_list)) |
2139 | spin_lock(&tomoyo_query_list_lock); | 2140 | return POLLIN | POLLRDNORM; |
2140 | list_for_each(tmp, &tomoyo_query_list) { | ||
2141 | struct tomoyo_query *ptr = | ||
2142 | list_entry(tmp, typeof(*ptr), list); | ||
2143 | if (ptr->answer) | ||
2144 | continue; | ||
2145 | found = true; | ||
2146 | break; | ||
2147 | } | ||
2148 | spin_unlock(&tomoyo_query_list_lock); | ||
2149 | if (found) | ||
2150 | return POLLIN | POLLRDNORM; | ||
2151 | if (i) | ||
2152 | break; | ||
2153 | poll_wait(file, &tomoyo_query_wait, wait); | ||
2154 | } | ||
2155 | return 0; | 2141 | return 0; |
2156 | } | 2142 | } |
2157 | 2143 | ||
@@ -2175,8 +2161,6 @@ static void tomoyo_read_query(struct tomoyo_io_buffer *head) | |||
2175 | spin_lock(&tomoyo_query_list_lock); | 2161 | spin_lock(&tomoyo_query_list_lock); |
2176 | list_for_each(tmp, &tomoyo_query_list) { | 2162 | list_for_each(tmp, &tomoyo_query_list) { |
2177 | struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); | 2163 | struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); |
2178 | if (ptr->answer) | ||
2179 | continue; | ||
2180 | if (pos++ != head->r.query_index) | 2164 | if (pos++ != head->r.query_index) |
2181 | continue; | 2165 | continue; |
2182 | len = ptr->query_len; | 2166 | len = ptr->query_len; |
@@ -2194,8 +2178,6 @@ static void tomoyo_read_query(struct tomoyo_io_buffer *head) | |||
2194 | spin_lock(&tomoyo_query_list_lock); | 2178 | spin_lock(&tomoyo_query_list_lock); |
2195 | list_for_each(tmp, &tomoyo_query_list) { | 2179 | list_for_each(tmp, &tomoyo_query_list) { |
2196 | struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); | 2180 | struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); |
2197 | if (ptr->answer) | ||
2198 | continue; | ||
2199 | if (pos++ != head->r.query_index) | 2181 | if (pos++ != head->r.query_index) |
2200 | continue; | 2182 | continue; |
2201 | /* | 2183 | /* |
@@ -2243,8 +2225,10 @@ static int tomoyo_write_answer(struct tomoyo_io_buffer *head) | |||
2243 | struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); | 2225 | struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); |
2244 | if (ptr->serial != serial) | 2226 | if (ptr->serial != serial) |
2245 | continue; | 2227 | continue; |
2246 | if (!ptr->answer) | 2228 | ptr->answer = answer; |
2247 | ptr->answer = answer; | 2229 | /* Remove from tomoyo_query_list. */ |
2230 | if (ptr->answer) | ||
2231 | list_del_init(&ptr->list); | ||
2248 | break; | 2232 | break; |
2249 | } | 2233 | } |
2250 | spin_unlock(&tomoyo_query_list_lock); | 2234 | spin_unlock(&tomoyo_query_list_lock); |
@@ -2477,18 +2461,17 @@ int tomoyo_open_control(const u8 type, struct file *file) | |||
2477 | * tomoyo_poll_control - poll() for /sys/kernel/security/tomoyo/ interface. | 2461 | * tomoyo_poll_control - poll() for /sys/kernel/security/tomoyo/ interface. |
2478 | * | 2462 | * |
2479 | * @file: Pointer to "struct file". | 2463 | * @file: Pointer to "struct file". |
2480 | * @wait: Pointer to "poll_table". | 2464 | * @wait: Pointer to "poll_table". Maybe NULL. |
2481 | * | 2465 | * |
2482 | * Waits for read readiness. | 2466 | * Returns POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM if ready to read/write, |
2483 | * /sys/kernel/security/tomoyo/query is handled by /usr/sbin/tomoyo-queryd and | 2467 | * POLLOUT | POLLWRNORM otherwise. |
2484 | * /sys/kernel/security/tomoyo/audit is handled by /usr/sbin/tomoyo-auditd. | ||
2485 | */ | 2468 | */ |
2486 | int tomoyo_poll_control(struct file *file, poll_table *wait) | 2469 | unsigned int tomoyo_poll_control(struct file *file, poll_table *wait) |
2487 | { | 2470 | { |
2488 | struct tomoyo_io_buffer *head = file->private_data; | 2471 | struct tomoyo_io_buffer *head = file->private_data; |
2489 | if (!head->poll) | 2472 | if (head->poll) |
2490 | return -ENOSYS; | 2473 | return head->poll(file, wait) | POLLOUT | POLLWRNORM; |
2491 | return head->poll(file, wait); | 2474 | return POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM; |
2492 | } | 2475 | } |
2493 | 2476 | ||
2494 | /** | 2477 | /** |