From 6c2cfe35083a3fd38b790e33351fdb2ea063b9ea Mon Sep 17 00:00:00 2001 From: John Johansen Date: Sat, 10 Mar 2012 11:19:51 -0800 Subject: [PATCH] --- yaml --- r: 292298 b: refs/heads/master c: ef9a762279c9ce98c592fb144b31898411feb94d h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/security/apparmor/path.c | 2 +- trunk/security/tomoyo/audit.c | 4 +- trunk/security/tomoyo/common.c | 54 ++++++++++++++++++--------- trunk/security/tomoyo/common.h | 6 +-- trunk/security/tomoyo/securityfs_if.c | 5 +-- 6 files changed, 45 insertions(+), 28 deletions(-) diff --git a/[refs] b/[refs] index 02d9bbb146f9..ecef6669fc73 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 6041e8346f2165679c2184cab60db768d6a26a1d +refs/heads/master: ef9a762279c9ce98c592fb144b31898411feb94d diff --git a/trunk/security/apparmor/path.c b/trunk/security/apparmor/path.c index c31ce837fef4..3dd605c69970 100644 --- a/trunk/security/apparmor/path.c +++ b/trunk/security/apparmor/path.c @@ -137,7 +137,7 @@ static int d_namespace_path(struct path *path, char *buf, int buflen, /* disconnected path, don't return pathname starting * with '/' */ - error = -ESTALE; + error = -EACCES; if (*res == '/') *name = res + 1; } diff --git a/trunk/security/tomoyo/audit.c b/trunk/security/tomoyo/audit.c index 7ef9fa3e37e0..5ca47ea3049f 100644 --- a/trunk/security/tomoyo/audit.c +++ b/trunk/security/tomoyo/audit.c @@ -446,11 +446,11 @@ void tomoyo_read_log(struct tomoyo_io_buffer *head) * tomoyo_poll_log - Wait for an audit log. * * @file: Pointer to "struct file". - * @wait: Pointer to "poll_table". Maybe NULL. + * @wait: Pointer to "poll_table". * * Returns POLLIN | POLLRDNORM when ready to read an audit log. */ -unsigned int tomoyo_poll_log(struct file *file, poll_table *wait) +int tomoyo_poll_log(struct file *file, poll_table *wait) { if (tomoyo_log_count) return POLLIN | POLLRDNORM; diff --git a/trunk/security/tomoyo/common.c b/trunk/security/tomoyo/common.c index d8561c30fbf2..c47d3ce6c733 100644 --- a/trunk/security/tomoyo/common.c +++ b/trunk/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) + if (ptr->serial != serial || ptr->answer) continue; domain = ptr->domain; break; @@ -2130,13 +2130,28 @@ static struct tomoyo_domain_info *tomoyo_find_domain_by_qid * * Waits for access requests which violated policy in enforcing mode. */ -static unsigned int tomoyo_poll_query(struct file *file, poll_table *wait) +static int tomoyo_poll_query(struct file *file, poll_table *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; + 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); + } return 0; } @@ -2160,6 +2175,8 @@ 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; @@ -2177,6 +2194,8 @@ 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; /* @@ -2224,10 +2243,8 @@ 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; - ptr->answer = answer; - /* Remove from tomoyo_query_list. */ - if (ptr->answer) - list_del_init(&ptr->list); + if (!ptr->answer) + ptr->answer = answer; break; } spin_unlock(&tomoyo_query_list_lock); @@ -2460,17 +2477,18 @@ 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". Maybe NULL. + * @wait: Pointer to "poll_table". * - * Returns POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM if ready to read/write, - * POLLOUT | POLLWRNORM otherwise. + * 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. */ -unsigned int tomoyo_poll_control(struct file *file, poll_table *wait) +int tomoyo_poll_control(struct file *file, poll_table *wait) { struct tomoyo_io_buffer *head = file->private_data; - if (head->poll) - return head->poll(file, wait) | POLLOUT | POLLWRNORM; - return POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM; + if (!head->poll) + return -ENOSYS; + return head->poll(file, wait); } /** diff --git a/trunk/security/tomoyo/common.h b/trunk/security/tomoyo/common.h index 30fd98369700..9512222d5581 100644 --- a/trunk/security/tomoyo/common.h +++ b/trunk/security/tomoyo/common.h @@ -788,7 +788,7 @@ struct tomoyo_acl_param { struct tomoyo_io_buffer { void (*read) (struct tomoyo_io_buffer *); int (*write) (struct tomoyo_io_buffer *); - unsigned int (*poll) (struct file *file, poll_table *wait); + int (*poll) (struct file *file, poll_table *wait); /* Exclusive lock for this structure. */ struct mutex io_sem; char __user *read_user_buf; @@ -981,8 +981,8 @@ int tomoyo_path_number_perm(const u8 operation, struct path *path, unsigned long number); int tomoyo_path_perm(const u8 operation, struct path *path, const char *target); -unsigned int tomoyo_poll_control(struct file *file, poll_table *wait); -unsigned int tomoyo_poll_log(struct file *file, poll_table *wait); +int tomoyo_poll_control(struct file *file, poll_table *wait); +int tomoyo_poll_log(struct file *file, poll_table *wait); int tomoyo_socket_bind_permission(struct socket *sock, struct sockaddr *addr, int addr_len); int tomoyo_socket_connect_permission(struct socket *sock, diff --git a/trunk/security/tomoyo/securityfs_if.c b/trunk/security/tomoyo/securityfs_if.c index 8592f2fc6ebb..482b2a5f48f0 100644 --- a/trunk/security/tomoyo/securityfs_if.c +++ b/trunk/security/tomoyo/securityfs_if.c @@ -157,10 +157,9 @@ static int tomoyo_release(struct inode *inode, struct file *file) * tomoyo_poll - poll() for /sys/kernel/security/tomoyo/ interface. * * @file: Pointer to "struct file". - * @wait: Pointer to "poll_table". Maybe NULL. + * @wait: Pointer to "poll_table". * - * Returns POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM if ready to read/write, - * POLLOUT | POLLWRNORM otherwise. + * Returns 0 on success, negative value otherwise. */ static unsigned int tomoyo_poll(struct file *file, poll_table *wait) {