summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2011-10-20 06:48:57 +0900
committerJames Morris <jmorris@namei.org>2011-10-29 08:34:41 +1100
commit59df3166ef293288d164ab3362a717743e62d20c (patch)
treeee10bb9ae940bf59beaf05dd5925d03044eb6559
parentc45ed235abf1b0b6666417e3c394f18717976acd (diff)
TOMOYO: Fix interactive judgment functionality.
Commit 17fcfbd9 "TOMOYO: Add interactive enforcing mode." introduced ability to query access decision using userspace programs. It was using global PID for reaching policy configuration of the process. However, use of PID returns stale policy configuration when the process's subjective credentials and objective credentials differ. Fix this problem by allowing reaching policy configuration via query id. Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Signed-off-by: James Morris <jmorris@namei.org>
-rw-r--r--security/tomoyo/common.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index d41900de8a69..610b535108af 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -963,6 +963,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.
*
@@ -996,6 +999,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;
@@ -1891,6 +1896,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;
@@ -2041,6 +2047,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
@@ -2088,6 +2095,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".