summary refs log tree commit diff
path: root/security/tomoyo/common.c
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>2012-03-14 18:27:49 +0900
committerJames Morris <james.l.morris@oracle.com>2012-03-15 12:29:18 +1100
commit6041e8346f2165679c2184cab60db768d6a26a1d (patch)
tree2c4eb032eb851f240c1b70d1afb214a2c661b886 /security/tomoyo/common.c
parentf67dabbdde1fe112dfff05d02890f1e0d54117a8 (diff)
downloadlinux-6041e8346f2165679c2184cab60db768d6a26a1d.tar.gz
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>
Diffstat (limited to 'security/tomoyo/common.c')
-rw-r--r--security/tomoyo/common.c54
1 files changed, 18 insertions, 36 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index c47d3ce6c733..d8561c30fbf2 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -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;
 }
 
 /**