TOMOYO: Fix interactive judgment functionality.
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Wed, 19 Oct 2011 21:48:57 +0000 (06:48 +0900)
committerJames Morris <jmorris@namei.org>
Fri, 28 Oct 2011 21:34:41 +0000 (08:34 +1100)
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>
security/tomoyo/common.c

index d41900de8a69d267dce90c66b7ef0fc21229bb48..610b535108af8e9465cbec284f448214a2e39f66 100644 (file)
@@ -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
@@ -2087,6 +2094,29 @@ out:
        return error;
 }
 
+/**
+ * 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.
  *