Commit 6041e8346f2165679c2184cab60db768d6a26a1d
Committed by
James Morris
1 parent
f67dabbdde
TOMOYO: Return appropriate value to poll().
"struct file_operations"->poll() expects "unsigned int" return value. All files in /sys/kernel/security/tomoyo/ directory other than /sys/kernel/security/tomoyo/query and /sys/kernel/security/tomoyo/audit should return POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM rather than -ENOSYS. Also, /sys/kernel/security/tomoyo/query and /sys/kernel/security/tomoyo/audit should return POLLOUT | POLLWRNORM rather than 0 when there is no data to read. Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Signed-off-by: James Morris <james.l.morris@oracle.com>
Showing 4 changed files with 26 additions and 43 deletions Side-by-side Diff
security/tomoyo/audit.c
... | ... | @@ -446,11 +446,11 @@ |
446 | 446 | * tomoyo_poll_log - Wait for an audit log. |
447 | 447 | * |
448 | 448 | * @file: Pointer to "struct file". |
449 | - * @wait: Pointer to "poll_table". | |
449 | + * @wait: Pointer to "poll_table". Maybe NULL. | |
450 | 450 | * |
451 | 451 | * Returns POLLIN | POLLRDNORM when ready to read an audit log. |
452 | 452 | */ |
453 | -int tomoyo_poll_log(struct file *file, poll_table *wait) | |
453 | +unsigned int tomoyo_poll_log(struct file *file, poll_table *wait) | |
454 | 454 | { |
455 | 455 | if (tomoyo_log_count) |
456 | 456 | return POLLIN | POLLRDNORM; |
security/tomoyo/common.c
... | ... | @@ -2111,7 +2111,7 @@ |
2111 | 2111 | struct tomoyo_domain_info *domain = NULL; |
2112 | 2112 | spin_lock(&tomoyo_query_list_lock); |
2113 | 2113 | list_for_each_entry(ptr, &tomoyo_query_list, list) { |
2114 | - if (ptr->serial != serial || ptr->answer) | |
2114 | + if (ptr->serial != serial) | |
2115 | 2115 | continue; |
2116 | 2116 | domain = ptr->domain; |
2117 | 2117 | break; |
2118 | 2118 | |
... | ... | @@ -2130,28 +2130,13 @@ |
2130 | 2130 | * |
2131 | 2131 | * Waits for access requests which violated policy in enforcing mode. |
2132 | 2132 | */ |
2133 | -static int tomoyo_poll_query(struct file *file, poll_table *wait) | |
2133 | +static unsigned int tomoyo_poll_query(struct file *file, poll_table *wait) | |
2134 | 2134 | { |
2135 | - struct list_head *tmp; | |
2136 | - bool found = false; | |
2137 | - u8 i; | |
2138 | - for (i = 0; i < 2; i++) { | |
2139 | - spin_lock(&tomoyo_query_list_lock); | |
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 | - } | |
2135 | + if (!list_empty(&tomoyo_query_list)) | |
2136 | + return POLLIN | POLLRDNORM; | |
2137 | + poll_wait(file, &tomoyo_query_wait, wait); | |
2138 | + if (!list_empty(&tomoyo_query_list)) | |
2139 | + return POLLIN | POLLRDNORM; | |
2155 | 2140 | return 0; |
2156 | 2141 | } |
2157 | 2142 | |
... | ... | @@ -2175,8 +2160,6 @@ |
2175 | 2160 | spin_lock(&tomoyo_query_list_lock); |
2176 | 2161 | list_for_each(tmp, &tomoyo_query_list) { |
2177 | 2162 | struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); |
2178 | - if (ptr->answer) | |
2179 | - continue; | |
2180 | 2163 | if (pos++ != head->r.query_index) |
2181 | 2164 | continue; |
2182 | 2165 | len = ptr->query_len; |
... | ... | @@ -2194,8 +2177,6 @@ |
2194 | 2177 | spin_lock(&tomoyo_query_list_lock); |
2195 | 2178 | list_for_each(tmp, &tomoyo_query_list) { |
2196 | 2179 | struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); |
2197 | - if (ptr->answer) | |
2198 | - continue; | |
2199 | 2180 | if (pos++ != head->r.query_index) |
2200 | 2181 | continue; |
2201 | 2182 | /* |
... | ... | @@ -2243,8 +2224,10 @@ |
2243 | 2224 | struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); |
2244 | 2225 | if (ptr->serial != serial) |
2245 | 2226 | continue; |
2246 | - if (!ptr->answer) | |
2247 | - ptr->answer = answer; | |
2227 | + ptr->answer = answer; | |
2228 | + /* Remove from tomoyo_query_list. */ | |
2229 | + if (ptr->answer) | |
2230 | + list_del_init(&ptr->list); | |
2248 | 2231 | break; |
2249 | 2232 | } |
2250 | 2233 | spin_unlock(&tomoyo_query_list_lock); |
2251 | 2234 | |
2252 | 2235 | |
2253 | 2236 | |
... | ... | @@ -2477,18 +2460,17 @@ |
2477 | 2460 | * tomoyo_poll_control - poll() for /sys/kernel/security/tomoyo/ interface. |
2478 | 2461 | * |
2479 | 2462 | * @file: Pointer to "struct file". |
2480 | - * @wait: Pointer to "poll_table". | |
2463 | + * @wait: Pointer to "poll_table". Maybe NULL. | |
2481 | 2464 | * |
2482 | - * Waits for read readiness. | |
2483 | - * /sys/kernel/security/tomoyo/query is handled by /usr/sbin/tomoyo-queryd and | |
2484 | - * /sys/kernel/security/tomoyo/audit is handled by /usr/sbin/tomoyo-auditd. | |
2465 | + * Returns POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM if ready to read/write, | |
2466 | + * POLLOUT | POLLWRNORM otherwise. | |
2485 | 2467 | */ |
2486 | -int tomoyo_poll_control(struct file *file, poll_table *wait) | |
2468 | +unsigned int tomoyo_poll_control(struct file *file, poll_table *wait) | |
2487 | 2469 | { |
2488 | 2470 | struct tomoyo_io_buffer *head = file->private_data; |
2489 | - if (!head->poll) | |
2490 | - return -ENOSYS; | |
2491 | - return head->poll(file, wait); | |
2471 | + if (head->poll) | |
2472 | + return head->poll(file, wait) | POLLOUT | POLLWRNORM; | |
2473 | + return POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM; | |
2492 | 2474 | } |
2493 | 2475 | |
2494 | 2476 | /** |
security/tomoyo/common.h
... | ... | @@ -788,7 +788,7 @@ |
788 | 788 | struct tomoyo_io_buffer { |
789 | 789 | void (*read) (struct tomoyo_io_buffer *); |
790 | 790 | int (*write) (struct tomoyo_io_buffer *); |
791 | - int (*poll) (struct file *file, poll_table *wait); | |
791 | + unsigned int (*poll) (struct file *file, poll_table *wait); | |
792 | 792 | /* Exclusive lock for this structure. */ |
793 | 793 | struct mutex io_sem; |
794 | 794 | char __user *read_user_buf; |
... | ... | @@ -981,8 +981,8 @@ |
981 | 981 | unsigned long number); |
982 | 982 | int tomoyo_path_perm(const u8 operation, struct path *path, |
983 | 983 | const char *target); |
984 | -int tomoyo_poll_control(struct file *file, poll_table *wait); | |
985 | -int tomoyo_poll_log(struct file *file, poll_table *wait); | |
984 | +unsigned int tomoyo_poll_control(struct file *file, poll_table *wait); | |
985 | +unsigned int tomoyo_poll_log(struct file *file, poll_table *wait); | |
986 | 986 | int tomoyo_socket_bind_permission(struct socket *sock, struct sockaddr *addr, |
987 | 987 | int addr_len); |
988 | 988 | int tomoyo_socket_connect_permission(struct socket *sock, |
security/tomoyo/securityfs_if.c
... | ... | @@ -157,9 +157,10 @@ |
157 | 157 | * tomoyo_poll - poll() for /sys/kernel/security/tomoyo/ interface. |
158 | 158 | * |
159 | 159 | * @file: Pointer to "struct file". |
160 | - * @wait: Pointer to "poll_table". | |
160 | + * @wait: Pointer to "poll_table". Maybe NULL. | |
161 | 161 | * |
162 | - * Returns 0 on success, negative value otherwise. | |
162 | + * Returns POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM if ready to read/write, | |
163 | + * POLLOUT | POLLWRNORM otherwise. | |
163 | 164 | */ |
164 | 165 | static unsigned int tomoyo_poll(struct file *file, poll_table *wait) |
165 | 166 | { |