diff options
Diffstat (limited to 'security/tomoyo')
-rw-r--r-- | security/tomoyo/common.c | 30 | ||||
-rw-r--r-- | security/tomoyo/realpath.c | 13 |
2 files changed, 40 insertions, 3 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index 150911c7ff08..c47d3ce6c733 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c @@ -966,6 +966,9 @@ static bool tomoyo_manager(void) return found; } +static struct tomoyo_domain_info *tomoyo_find_domain_by_qid +(unsigned int serial); + /** * tomoyo_select_domain - Parse select command. * @@ -999,6 +1002,8 @@ static bool tomoyo_select_domain(struct tomoyo_io_buffer *head, } else if (!strncmp(data, "domain=", 7)) { if (tomoyo_domain_def(data + 7)) domain = tomoyo_find_domain(data + 7); + } else if (sscanf(data, "Q=%u", &pid) == 1) { + domain = tomoyo_find_domain_by_qid(pid); } else return false; head->w.domain = domain; @@ -1894,6 +1899,7 @@ static DECLARE_WAIT_QUEUE_HEAD(tomoyo_answer_wait); /* Structure for query. */ struct tomoyo_query { struct list_head list; + struct tomoyo_domain_info *domain; char *query; size_t query_len; unsigned int serial; @@ -2044,6 +2050,7 @@ int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...) goto out; } len = tomoyo_round2(entry.query_len); + entry.domain = r->domain; spin_lock(&tomoyo_query_list_lock); if (tomoyo_memory_quota[TOMOYO_MEMORY_QUERY] && tomoyo_memory_used[TOMOYO_MEMORY_QUERY] + len @@ -2091,6 +2098,29 @@ out: } /** + * tomoyo_find_domain_by_qid - Get domain by query id. + * + * @serial: Query ID assigned by tomoyo_supervisor(). + * + * Returns pointer to "struct tomoyo_domain_info" if found, NULL otherwise. + */ +static struct tomoyo_domain_info *tomoyo_find_domain_by_qid +(unsigned int serial) +{ + struct tomoyo_query *ptr; + 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) + continue; + domain = ptr->domain; + break; + } + spin_unlock(&tomoyo_query_list_lock); + return domain; +} + +/** * tomoyo_poll_query - poll() for /sys/kernel/security/tomoyo/query. * * @file: Pointer to "struct file". diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c index 738bbdf8d4c7..d9f3ced8756e 100644 --- a/security/tomoyo/realpath.c +++ b/security/tomoyo/realpath.c @@ -101,9 +101,8 @@ static char *tomoyo_get_absolute_path(struct path *path, char * const buffer, { char *pos = ERR_PTR(-ENOMEM); if (buflen >= 256) { - struct path ns_root = { }; /* go to whatever namespace root we are under */ - pos = __d_path(path, &ns_root, buffer, buflen - 1); + pos = d_absolute_path(path, buffer, buflen - 1); if (!IS_ERR(pos) && *pos == '/' && pos[1]) { struct inode *inode = path->dentry->d_inode; if (inode && S_ISDIR(inode->i_mode)) { @@ -294,8 +293,16 @@ char *tomoyo_realpath_from_path(struct path *path) pos = tomoyo_get_local_path(path->dentry, buf, buf_len - 1); /* Get absolute name for the rest. */ - else + else { pos = tomoyo_get_absolute_path(path, buf, buf_len - 1); + /* + * Fall back to local name if absolute name is not + * available. + */ + if (pos == ERR_PTR(-EINVAL)) + pos = tomoyo_get_local_path(path->dentry, buf, + buf_len - 1); + } encode: if (IS_ERR(pos)) continue; |