|
@@ -2111,7 +2111,7 @@ static struct tomoyo_domain_info *tomoyo_find_domain_by_qid
|
|
|
struct tomoyo_domain_info *domain = NULL;
|
|
|
spin_lock(&tomoyo_query_list_lock);
|
|
|
list_for_each_entry(ptr, &tomoyo_query_list, list) {
|
|
|
- if (ptr->serial != serial || ptr->answer)
|
|
|
+ if (ptr->serial != serial)
|
|
|
continue;
|
|
|
domain = ptr->domain;
|
|
|
break;
|
|
@@ -2130,28 +2130,13 @@ static struct tomoyo_domain_info *tomoyo_find_domain_by_qid
|
|
|
*
|
|
|
* Waits for access requests which violated policy in enforcing mode.
|
|
|
*/
|
|
|
-static int tomoyo_poll_query(struct file *file, poll_table *wait)
|
|
|
+static unsigned int tomoyo_poll_query(struct file *file, poll_table *wait)
|
|
|
{
|
|
|
- struct list_head *tmp;
|
|
|
- bool found = false;
|
|
|
- u8 i;
|
|
|
- for (i = 0; i < 2; i++) {
|
|
|
- spin_lock(&tomoyo_query_list_lock);
|
|
|
- list_for_each(tmp, &tomoyo_query_list) {
|
|
|
- struct tomoyo_query *ptr =
|
|
|
- list_entry(tmp, typeof(*ptr), list);
|
|
|
- if (ptr->answer)
|
|
|
- continue;
|
|
|
- found = true;
|
|
|
- break;
|
|
|
- }
|
|
|
- spin_unlock(&tomoyo_query_list_lock);
|
|
|
- if (found)
|
|
|
- return POLLIN | POLLRDNORM;
|
|
|
- if (i)
|
|
|
- break;
|
|
|
- poll_wait(file, &tomoyo_query_wait, wait);
|
|
|
- }
|
|
|
+ if (!list_empty(&tomoyo_query_list))
|
|
|
+ return POLLIN | POLLRDNORM;
|
|
|
+ poll_wait(file, &tomoyo_query_wait, wait);
|
|
|
+ if (!list_empty(&tomoyo_query_list))
|
|
|
+ return POLLIN | POLLRDNORM;
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -2175,8 +2160,6 @@ static void tomoyo_read_query(struct tomoyo_io_buffer *head)
|
|
|
spin_lock(&tomoyo_query_list_lock);
|
|
|
list_for_each(tmp, &tomoyo_query_list) {
|
|
|
struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list);
|
|
|
- if (ptr->answer)
|
|
|
- continue;
|
|
|
if (pos++ != head->r.query_index)
|
|
|
continue;
|
|
|
len = ptr->query_len;
|
|
@@ -2194,8 +2177,6 @@ static void tomoyo_read_query(struct tomoyo_io_buffer *head)
|
|
|
spin_lock(&tomoyo_query_list_lock);
|
|
|
list_for_each(tmp, &tomoyo_query_list) {
|
|
|
struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list);
|
|
|
- if (ptr->answer)
|
|
|
- continue;
|
|
|
if (pos++ != head->r.query_index)
|
|
|
continue;
|
|
|
/*
|
|
@@ -2243,8 +2224,10 @@ static int tomoyo_write_answer(struct tomoyo_io_buffer *head)
|
|
|
struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list);
|
|
|
if (ptr->serial != serial)
|
|
|
continue;
|
|
|
- if (!ptr->answer)
|
|
|
- ptr->answer = answer;
|
|
|
+ ptr->answer = answer;
|
|
|
+ /* Remove from tomoyo_query_list. */
|
|
|
+ if (ptr->answer)
|
|
|
+ list_del_init(&ptr->list);
|
|
|
break;
|
|
|
}
|
|
|
spin_unlock(&tomoyo_query_list_lock);
|
|
@@ -2477,18 +2460,17 @@ int tomoyo_open_control(const u8 type, struct file *file)
|
|
|
* tomoyo_poll_control - poll() for /sys/kernel/security/tomoyo/ interface.
|
|
|
*
|
|
|
* @file: Pointer to "struct file".
|
|
|
- * @wait: Pointer to "poll_table".
|
|
|
+ * @wait: Pointer to "poll_table". Maybe NULL.
|
|
|
*
|
|
|
- * Waits for read readiness.
|
|
|
- * /sys/kernel/security/tomoyo/query is handled by /usr/sbin/tomoyo-queryd and
|
|
|
- * /sys/kernel/security/tomoyo/audit is handled by /usr/sbin/tomoyo-auditd.
|
|
|
+ * Returns POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM if ready to read/write,
|
|
|
+ * POLLOUT | POLLWRNORM otherwise.
|
|
|
*/
|
|
|
-int tomoyo_poll_control(struct file *file, poll_table *wait)
|
|
|
+unsigned int tomoyo_poll_control(struct file *file, poll_table *wait)
|
|
|
{
|
|
|
struct tomoyo_io_buffer *head = file->private_data;
|
|
|
- if (!head->poll)
|
|
|
- return -ENOSYS;
|
|
|
- return head->poll(file, wait);
|
|
|
+ if (head->poll)
|
|
|
+ return head->poll(file, wait) | POLLOUT | POLLWRNORM;
|
|
|
+ return POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM;
|
|
|
}
|
|
|
|
|
|
/**
|