summaryrefslogtreecommitdiffstats
path: root/security/tomoyo
diff options
context:
space:
mode:
Diffstat (limited to 'security/tomoyo')
-rw-r--r--security/tomoyo/common.c30
-rw-r--r--security/tomoyo/realpath.c13
2 files changed, 40 insertions, 3 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index 150911c7ff0..c47d3ce6c73 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 738bbdf8d4c..d9f3ced8756 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;