[08/38] TOMOYO: Use external hashtable for maintaining per task_struct variables.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Subject: [08/38] TOMOYO: Use external hashtable for maintaining per task_struct variables.

Currently, TOMOYO cannot check binary loader's permissions using
"struct linux_binprm"->"struct cred"->security . As explained in the previous
patch, as long as TOMOYO depends on "struct cred", TOMOYO cannot work as
expected.

This patch changes TOMOYO to use external hashtable for maintaining security
context in order to make TOMOYO work as expected.

By applying this patch, TOMOYO no longer requires "void *security" of various
kernel objects, making it easier to run multiple LSM modules in parallel.

Signed-off-by: Tetsuo Handa <penguin-kernel@xxxxxxxxxxxxxxxxxxx>
---
 security/tomoyo/common.h        |   80 +++++++++--
 security/tomoyo/domain.c        |   19 ++
 security/tomoyo/file.c          |   14 +
 security/tomoyo/gc.c            |   54 ++++++-
 security/tomoyo/memory.c        |    2 
 security/tomoyo/securityfs_if.c |    2 
 security/tomoyo/tomoyo.c        |  287 ++++++++++++++++++++++++++--------------
 7 files changed, 335 insertions(+), 123 deletions(-)

--- security-testing-2.6.orig/security/tomoyo/common.h
+++ security-testing-2.6/security/tomoyo/common.h
@@ -394,10 +394,6 @@ struct tomoyo_acl_info {
  *      name of the domain to be created was too long or it could not allocate
  *      memory. If set to true, more than one process continued execve()
  *      without domain transition.
- *  (9) "users" is an atomic_t that holds how many "struct cred"->security
- *      are referring this "struct tomoyo_domain_info". If is_deleted == true
- *      and users == 0, this struct will be kfree()d upon next garbage
- *      collection.
  *
  * A domain's lifecycle is an analogy of files on / directory.
  * Multiple domains with the same domainname cannot be created (as with
@@ -416,7 +412,6 @@ struct tomoyo_domain_info {
 	bool quota_warned; /* Quota warnning flag.   */
 	bool ignore_global_allow_read; /* Ignore "allow_read" flag. */
 	bool transition_failed; /* Domain transition failed flag. */
-	atomic_t users; /* Number of referring credentials. */
 };
 
 /*
@@ -657,6 +652,72 @@ struct tomoyo_time {
 	u8 sec;
 };
 
+/*
+ * Structure for holding "struct tomoyo_domain_info *" for each
+ * "struct task_struct".
+ */
+struct tomoyo_security {
+	struct list_head list;
+	const struct task_struct *task; /* == current */
+	/*
+	 * Holds current thread's domain. Only current thread can modify this
+	 * member but any threads can read this member under RCU.
+	 */
+	struct tomoyo_domain_info *tomoyo_domain_info;
+	/*
+	 * Holds previous tomoyo_domain_info during do_execve() in case
+	 * do_execve() failed, NULL otherwise. Only current thread can access
+	 * this member.
+	 */
+	struct tomoyo_domain_info *previous_domain_info;
+	struct rcu_head rcu;
+};
+
+#define TOMOYO_TASK_SECURITY_HASH_BITS 12
+#define TOMOYO_MAX_TASK_SECURITY_HASH (1u << TOMOYO_TASK_SECURITY_HASH_BITS)
+extern struct list_head
+tomoyo_task_security_list[TOMOYO_MAX_TASK_SECURITY_HASH];
+
+struct tomoyo_security *tomoyo_find_task_security
+(const struct task_struct *task);
+
+/**
+ * tomoyo_current_security - Get "struct tomoyo_security" for current thread.
+ *
+ * Returns pointer to "struct tomoyo_security" for current thread.
+ */
+static inline struct tomoyo_security *tomoyo_current_security(void)
+{
+	return tomoyo_find_task_security(current);
+}
+
+/**
+ * tomoyo_task_domain - Get "struct tomoyo_domain_info" for specified thread.
+ *
+ * @task: Pointer to "struct task_struct".
+ *
+ * Returns pointer to "struct tomoyo_security" for specified thread.
+ */
+static inline struct tomoyo_domain_info *tomoyo_task_domain
+(struct task_struct *task)
+{
+	struct tomoyo_domain_info *domain;
+	rcu_read_lock();
+	domain = tomoyo_find_task_security(task)->tomoyo_domain_info;
+	rcu_read_unlock();
+	return domain;
+}
+
+/**
+ * tomoyo_current_domain - Get "struct tomoyo_domain_info" for current thread.
+ *
+ * Returns pointer to "struct tomoyo_domain_info" for current thread.
+ */
+static inline struct tomoyo_domain_info *tomoyo_current_domain(void)
+{
+	return tomoyo_find_task_security(current)->tomoyo_domain_info;
+}
+
 /********** Function prototypes. **********/
 
 /* Check whether the given string starts with the given keyword. */
@@ -803,8 +864,7 @@ int tomoyo_write_memory_quota(struct tom
 void __init tomoyo_mm_init(void);
 int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
 			   const struct tomoyo_path_info *filename);
-int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
-				 struct path *path, const int flag);
+int tomoyo_check_open_permission(struct path *path, const int flag);
 int tomoyo_path_number_perm(const u8 operation, struct path *path,
 			    unsigned long number);
 int tomoyo_mkdev_perm(const u8 operation, struct path *path,
@@ -883,6 +943,8 @@ extern unsigned int tomoyo_memory_quota[
 extern unsigned int tomoyo_memory_used[TOMOYO_MAX_MEMORY_STAT];
 
 
+extern bool tomoyo_registered;
+
 /********** Inlined functions. **********/
 
 static inline int tomoyo_read_lock(void)
@@ -943,13 +1005,13 @@ static inline void tomoyo_put_group(stru
 
 static inline struct tomoyo_domain_info *tomoyo_domain(void)
 {
-	return current_cred()->security;
+	return tomoyo_current_domain();
 }
 
 static inline struct tomoyo_domain_info *tomoyo_real_domain(struct task_struct
 							    *task)
 {
-	return task_cred_xxx(task, security);
+	return tomoyo_task_domain(task);
 }
 
 static inline bool tomoyo_same_acl_head(const struct tomoyo_acl_info *p1,
--- security-testing-2.6.orig/security/tomoyo/domain.c
+++ security-testing-2.6/security/tomoyo/domain.c
@@ -415,6 +415,7 @@ int tomoyo_find_next_domain(struct linux
 {
 	struct tomoyo_request_info r;
 	char *tmp = kzalloc(TOMOYO_EXEC_TMPSIZE, GFP_NOFS);
+	struct tomoyo_security *security = tomoyo_current_security();
 	struct tomoyo_domain_info *old_domain = tomoyo_domain();
 	struct tomoyo_domain_info *domain = NULL;
 	const char *original_name = bprm->filename;
@@ -532,9 +533,21 @@ int tomoyo_find_next_domain(struct linux
  out:
 	if (!domain)
 		domain = old_domain;
-	/* Update reference count on "struct tomoyo_domain_info". */
-	atomic_inc(&domain->users);
-	bprm->cred->security = domain;
+	if (retval)
+		goto out2;
+	security->previous_domain_info = old_domain;
+	/*
+	 * Make security->previous_domain_info visible to GC before changing
+	 * security->tomoyo_domain_info.
+	 */
+	smp_wmb();
+	/*
+	 * Proceed to the next domain in order to allow checking permissions
+	 * for binary loader programs. Current thread will go back to the
+	 * previous domain if do_execve() failed.
+	 */
+	security->tomoyo_domain_info = domain;
+out2:
 	if (need_kfree)
 		kfree(rn.name);
 	kfree(tmp);
--- security-testing-2.6.orig/security/tomoyo/file.c
+++ security-testing-2.6/security/tomoyo/file.c
@@ -703,14 +703,12 @@ int tomoyo_path_number_perm(const u8 typ
 /**
  * tomoyo_check_open_permission - Check permission for "read" and "write".
  *
- * @domain: Pointer to "struct tomoyo_domain_info".
  * @path:   Pointer to "struct path".
  * @flag:   Flags for open().
  *
  * Returns 0 on success, negative value otherwise.
  */
-int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
-				 struct path *path, const int flag)
+int tomoyo_check_open_permission(struct path *path, const int flag)
 {
 	const u8 acc_mode = ACC_MODE(flag);
 	int error = 0;
@@ -721,11 +719,19 @@ int tomoyo_check_open_permission(struct 
 	if (!path->mnt ||
 	    (path->dentry->d_inode && S_ISDIR(path->dentry->d_inode->i_mode)))
 		return 0;
+	/*
+	 * Don't check read permission here if called from do_execve().
+	 * But check read permission here if called from binary loader
+	 * functions.
+	 */
+	if (current->in_execve &&
+	    !tomoyo_current_security()->previous_domain_info)
+		return 0;
 	buf.name = NULL;
 	r.mode = TOMOYO_CONFIG_DISABLED;
 	idx = tomoyo_read_lock();
 	if (acc_mode &&
-	    tomoyo_init_request_info(&r, domain, TOMOYO_MAC_FILE_OPEN)
+	    tomoyo_init_request_info(&r, NULL, TOMOYO_MAC_FILE_OPEN)
 	    != TOMOYO_CONFIG_DISABLED) {
 		if (!tomoyo_get_realpath(&buf, path)) {
 			error = -ENOMEM;
--- security-testing-2.6.orig/security/tomoyo/gc.c
+++ security-testing-2.6/security/tomoyo/gc.c
@@ -113,6 +113,44 @@ static void tomoyo_del_acl(struct list_h
 	}
 }
 
+/**
+ * tomoyo_used_by_task - Check whether the given pointer is referenced by a task.
+ *
+ * @domain: Pointer to "struct tomoyo_domain_info".
+ *
+ * Returns true if @domain is in use, false otherwise.
+ */
+static bool tomoyo_used_by_task(struct tomoyo_domain_info *domain)
+{
+	bool in_use = false;
+	/*
+	 * Don't delete this domain if somebody is doing execve().
+	 *
+	 * Since tomoyo_find_task_security() first reverts tomoyo_domain_info
+	 * and then clears previous_domain_info, we need smp_rmb() to make sure
+	 * that GC first checks previous_domain_info and then checks
+	 * tomoyo_domain_info.
+	 */
+	int idx;
+	rcu_read_lock();
+	for (idx = 0; idx < TOMOYO_MAX_TASK_SECURITY_HASH; idx++) {
+		struct tomoyo_security *ptr;
+		struct list_head *list = &tomoyo_task_security_list[idx];
+		list_for_each_entry_rcu(ptr, list, list) {
+			if (ptr->previous_domain_info != domain) {
+				smp_rmb(); /* Avoid out of order execution. */
+				if (ptr->tomoyo_domain_info != domain)
+					continue;
+			}
+			in_use = true;
+			goto out;
+		}
+	}
+out:
+	rcu_read_unlock();
+	return in_use;
+}
+
 static bool tomoyo_del_domain(struct list_head *element)
 {
 	struct tomoyo_domain_info *domain =
@@ -121,7 +159,7 @@ static bool tomoyo_del_domain(struct lis
 	struct tomoyo_acl_info *tmp;
 	/*
 	 * Since we don't protect whole execve() operation using SRCU,
-	 * we need to recheck domain->users at this point.
+	 * we need to recheck domain at this point.
 	 *
 	 * (1) Reader starts SRCU section upon execve().
 	 * (2) Reader traverses tomoyo_domain_list and finds this domain.
@@ -129,19 +167,19 @@ static bool tomoyo_del_domain(struct lis
 	 * (4) Garbage collector removes this domain from tomoyo_domain_list
 	 *     because this domain is marked as deleted and used by nobody.
 	 * (5) Reader saves reference to this domain into
-	 *     "struct linux_binprm"->cred->security .
+	 *     "struct tomoyo_security"->previous_domain_info .
 	 * (6) Reader finishes SRCU section, although execve() operation has
 	 *     not finished yet.
 	 * (7) Garbage collector waits for SRCU synchronization.
 	 * (8) Garbage collector kfree() this domain because this domain is
 	 *     used by nobody.
 	 * (9) Reader finishes execve() operation and restores this domain from
-	 *     "struct linux_binprm"->cred->security.
+	 *     "struct tomoyo_security"->previous_domain_info.
 	 *
-	 * By updating domain->users at (5), we can solve this race problem
-	 * by rechecking domain->users at (8).
+	 * By rechecking whether this domain is used by somebody or not at (8),
+	 * we can solve this race problem.
 	 */
-	if (atomic_read(&domain->users))
+	if (tomoyo_used_by_task(domain))
 		return false;
 	list_for_each_entry_safe(acl, tmp, &domain->acl_info_list, list) {
 		tomoyo_del_acl(&acl->list);
@@ -216,12 +254,12 @@ static void tomoyo_collect_entry(void)
 		list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
 			if (!tomoyo_collect_acl(domain))
 				goto unlock;
-			if (!domain->is_deleted || atomic_read(&domain->users))
+			if (!domain->is_deleted || tomoyo_used_by_task(domain))
 				continue;
 			/*
 			 * Nobody is referring this domain. But somebody may
 			 * refer this domain after successful execve().
-			 * We recheck domain->users after SRCU synchronization.
+			 * We recheck after SRCU synchronization.
 			 */
 			if (!tomoyo_add_to_gc(TOMOYO_ID_DOMAIN, &domain->list))
 				goto unlock;
--- security-testing-2.6.orig/security/tomoyo/memory.c
+++ security-testing-2.6/security/tomoyo/memory.c
@@ -210,6 +210,8 @@ void __init tomoyo_mm_init(void)
 	for (idx = 0; idx < TOMOYO_MAX_HASH; idx++)
 		INIT_LIST_HEAD(&tomoyo_name_list[idx]);
 	INIT_LIST_HEAD(&tomoyo_kernel_domain.acl_info_list);
+	for (idx = 0; idx < TOMOYO_MAX_TASK_SECURITY_HASH; idx++)
+		INIT_LIST_HEAD(&tomoyo_task_security_list[idx]);
 	tomoyo_kernel_domain.domainname = tomoyo_get_name(TOMOYO_ROOT_NAME);
 	list_add_tail_rcu(&tomoyo_kernel_domain.list, &tomoyo_domain_list);
 	idx = tomoyo_read_lock();
--- security-testing-2.6.orig/security/tomoyo/securityfs_if.c
+++ security-testing-2.6/security/tomoyo/securityfs_if.c
@@ -125,7 +125,7 @@ static int __init tomoyo_initerface_init
 	struct dentry *tomoyo_dir;
 
 	/* Don't create securityfs entries unless registered. */
-	if (current_cred()->security != &tomoyo_kernel_domain)
+	if (!tomoyo_registered)
 		return 0;
 
 	tomoyo_dir = securityfs_create_dir("tomoyo", NULL);
--- security-testing-2.6.orig/security/tomoyo/tomoyo.c
+++ security-testing-2.6/security/tomoyo/tomoyo.c
@@ -8,90 +8,7 @@
 
 #include <linux/security.h>
 #include "common.h"
-
-static int tomoyo_cred_alloc_blank(struct cred *new, gfp_t gfp)
-{
-	new->security = NULL;
-	return 0;
-}
-
-static int tomoyo_cred_prepare(struct cred *new, const struct cred *old,
-			       gfp_t gfp)
-{
-	struct tomoyo_domain_info *domain = old->security;
-	new->security = domain;
-	if (domain)
-		atomic_inc(&domain->users);
-	return 0;
-}
-
-static void tomoyo_cred_transfer(struct cred *new, const struct cred *old)
-{
-	tomoyo_cred_prepare(new, old, 0);
-}
-
-static void tomoyo_cred_free(struct cred *cred)
-{
-	struct tomoyo_domain_info *domain = cred->security;
-	if (domain)
-		atomic_dec(&domain->users);
-}
-
-static int tomoyo_bprm_set_creds(struct linux_binprm *bprm)
-{
-	int rc;
-
-	rc = cap_bprm_set_creds(bprm);
-	if (rc)
-		return rc;
-
-	/*
-	 * Do only if this function is called for the first time of an execve
-	 * operation.
-	 */
-	if (bprm->cred_prepared)
-		return 0;
-	/*
-	 * Load policy if /sbin/tomoyo-init exists and /sbin/init is requested
-	 * for the first time.
-	 */
-	if (!tomoyo_policy_loaded)
-		tomoyo_load_policy(bprm->filename);
-	/*
-	 * Release reference to "struct tomoyo_domain_info" stored inside
-	 * "bprm->cred->security". New reference to "struct tomoyo_domain_info"
-	 * stored inside "bprm->cred->security" will be acquired later inside
-	 * tomoyo_find_next_domain().
-	 */
-	atomic_dec(&((struct tomoyo_domain_info *)
-		     bprm->cred->security)->users);
-	/*
-	 * Tell tomoyo_bprm_check_security() is called for the first time of an
-	 * execve operation.
-	 */
-	bprm->cred->security = NULL;
-	return 0;
-}
-
-static int tomoyo_bprm_check_security(struct linux_binprm *bprm)
-{
-	struct tomoyo_domain_info *domain = bprm->cred->security;
-
-	/*
-	 * Execute permission is checked against pathname passed to do_execve()
-	 * using current domain.
-	 */
-	if (!domain) {
-		const int idx = tomoyo_read_lock();
-		const int err = tomoyo_find_next_domain(bprm);
-		tomoyo_read_unlock(idx);
-		return err;
-	}
-	/*
-	 * Read permission is checked against interpreters using next domain.
-	 */
-	return tomoyo_check_open_permission(domain, &bprm->file->f_path, O_RDONLY);
-}
+#include <linux/hash.h>
 
 static int tomoyo_path_truncate(struct path *path)
 {
@@ -178,17 +95,13 @@ static int tomoyo_file_fcntl(struct file
 {
 	if (!(cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND)))
 		return 0;
-	return tomoyo_check_open_permission(tomoyo_domain(), &file->f_path,
+	return tomoyo_check_open_permission(&file->f_path,
 					    O_WRONLY | (arg & O_APPEND));
 }
 
 static int tomoyo_dentry_open(struct file *f, const struct cred *cred)
 {
-	int flags = f->f_flags;
-	/* Don't check read permission here if called from do_execve(). */
-	if (current->in_execve)
-		return 0;
-	return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path, flags);
+	return tomoyo_check_open_permission(&f->f_path, f->f_flags);
 }
 
 static int tomoyo_file_ioctl(struct file *file, unsigned int cmd,
@@ -237,17 +150,190 @@ static int tomoyo_sb_pivotroot(struct pa
 	return tomoyo_path2_perm(TOMOYO_TYPE_PIVOT_ROOT, new_path, old_path);
 }
 
+/* Dummy security context for avoiding NULL pointer dereference. */
+static struct tomoyo_security tomoyo_null_security = {
+	.tomoyo_domain_info = &tomoyo_kernel_domain,
+};
+
+/* Security context for init_task task. */
+static struct tomoyo_security tomoyo_init_security = {
+	.task = &init_task,
+	.tomoyo_domain_info = &tomoyo_kernel_domain,
+};
+
+/* List of "struct tomoyo_security". */
+struct list_head tomoyo_task_security_list[TOMOYO_MAX_TASK_SECURITY_HASH];
+/* Lock for protecting tomoyo_task_security_list[]. */
+static DEFINE_SPINLOCK(tomoyo_task_security_list_lock);
+
+/**
+ * tomoyo_add_task_security - Add "struct tomoyo_security" to list.
+ *
+ * @ptr:  Pointer to "struct tomoyo_security".
+ * @list: Pointer to "struct list_head".
+ *
+ * Returns nothing.
+ */
+static void tomoyo_add_task_security(struct tomoyo_security *ptr,
+				     struct list_head *list)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&tomoyo_task_security_list_lock, flags);
+	list_add_rcu(&ptr->list, list);
+	spin_unlock_irqrestore(&tomoyo_task_security_list_lock, flags);
+}
+
+/**
+ * tomoyo_alloc_task_security - Allocate memory for new tasks.
+ *
+ * @task: Pointer to "struct task_struct".
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int tomoyo_alloc_task_security(struct task_struct *task)
+{
+	struct tomoyo_security *old_security = tomoyo_current_security();
+	struct tomoyo_security *new_security = kzalloc(sizeof(*new_security),
+						       GFP_KERNEL);
+	struct list_head *list = &tomoyo_task_security_list
+		[hash_ptr((void *) task, TOMOYO_TASK_SECURITY_HASH_BITS)];
+	if (!new_security)
+		return -ENOMEM;
+	*new_security = *old_security;
+	new_security->task = task;
+	tomoyo_add_task_security(new_security, list);
+	return 0;
+}
+
+/**
+ * tomoyo_find_task_security - Find "struct tomoyo_security" for given task.
+ *
+ * @task: Pointer to "struct task_struct".
+ *
+ * Returns pointer to "struct tomoyo_security".
+ */
+struct tomoyo_security *tomoyo_find_task_security
+(const struct task_struct *task)
+{
+	struct tomoyo_security *ptr;
+	struct list_head *list = &tomoyo_task_security_list
+		[hash_ptr((void *) task, TOMOYO_TASK_SECURITY_HASH_BITS)];
+	rcu_read_lock();
+	list_for_each_entry_rcu(ptr, list, list) {
+		if (ptr->task != task)
+			continue;
+		rcu_read_unlock();
+		return ptr;
+	}
+	rcu_read_unlock();
+	return &tomoyo_null_security;
+}
+
+/**
+ * tomoyo_rcu_free - RCU callback for releasing "struct tomoyo_security".
+ *
+ * @rcu: Pointer to "struct rcu_head".
+ *
+ * Returns nothing.
+ */
+static void tomoyo_rcu_free(struct rcu_head *rcu)
+{
+	struct tomoyo_security *ptr = container_of(rcu, typeof(*ptr), rcu);
+	kfree(ptr);
+}
+
+/**
+ * tomoyo_free_task_security - Release memory associated with "struct task_struct".
+ *
+ * @task: Pointer to "struct task_struct".
+ *
+ * Returns nothing.
+ */
+static void tomoyo_free_task_security(struct task_struct *task)
+{
+	unsigned long flags;
+	struct tomoyo_security *ptr = tomoyo_find_task_security(task);
+	if (ptr == &tomoyo_init_security || ptr == &tomoyo_null_security)
+		return;
+	spin_lock_irqsave(&tomoyo_task_security_list_lock, flags);
+	list_del_rcu(&ptr->list);
+	spin_unlock_irqrestore(&tomoyo_task_security_list_lock, flags);
+	call_rcu(&ptr->rcu, tomoyo_rcu_free);
+}
+
+/**
+ * tomoyo_bprm_committing_creds - A hook which is called when do_execve() succeeded.
+ *
+ * @bprm: Pointer to "struct linux_binprm".
+ *
+ * Returns nothing.
+ */
+static void tomoyo_bprm_committing_creds(struct linux_binprm *bprm)
+{
+	struct tomoyo_security *security = tomoyo_current_security();
+	/* do_execve() succeeded. Forget previous domain. */
+	security->previous_domain_info = NULL;
+}
+
+/**
+ * tomoyo_bprm_free_security - A hook which is called when do_execve() finished.
+ *
+ * @bprm: Pointer to "struct linux_binprm".
+ *
+ * Returns nothing.
+ */
+static void tomoyo_bprm_free_security(struct linux_binprm *bprm)
+{
+	struct tomoyo_security *security = tomoyo_current_security();
+	/*
+	 * tomoyo_bprm_committing_creds() already cleared it if do_execve()
+	 * succeeded.
+	 */
+	if (!security->previous_domain_info)
+		return;
+	/* do_execve() failed. Revert to previous domain. */
+	security->tomoyo_domain_info = security->previous_domain_info;
+	/* Make sure that GC sees valid domain. */
+	smp_wmb();
+	security->previous_domain_info = NULL;
+}
+
+/**
+ * tomoyo_bprm_check_security - Check permission for execve().
+ *
+ * @bprm: Pointer to "struct linux_binprm".
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int tomoyo_bprm_check_security(struct linux_binprm *bprm)
+{
+	struct tomoyo_security *security;
+	/*
+	 * Load policy if /sbin/tomoyo-init exists and /sbin/init is requested
+	 * for the first time.
+	 */
+	if (!tomoyo_policy_loaded)
+		tomoyo_load_policy(bprm->filename);
+	security = tomoyo_current_security();
+	if (!security->previous_domain_info) {
+		const int idx = tomoyo_read_lock();
+		const int rc = tomoyo_find_next_domain(bprm);
+		tomoyo_read_unlock(idx);
+		return rc;
+	}
+	return 0;
+}
+
 /*
  * tomoyo_security_ops is a "struct security_operations" which is used for
  * registering TOMOYO.
  */
 static struct security_operations tomoyo_security_ops = {
 	.name                = "tomoyo",
-	.cred_alloc_blank    = tomoyo_cred_alloc_blank,
-	.cred_prepare        = tomoyo_cred_prepare,
-	.cred_transfer	     = tomoyo_cred_transfer,
-	.cred_free           = tomoyo_cred_free,
-	.bprm_set_creds      = tomoyo_bprm_set_creds,
+	.task_alloc_security = tomoyo_alloc_task_security,
+	.task_free_security  = tomoyo_free_task_security,
+	.bprm_committing_creds = tomoyo_bprm_committing_creds,
+	.bprm_free_security  = tomoyo_bprm_free_security,
 	.bprm_check_security = tomoyo_bprm_check_security,
 	.file_fcntl          = tomoyo_file_fcntl,
 	.dentry_open         = tomoyo_dentry_open,
@@ -271,10 +357,11 @@ static struct security_operations tomoyo
 /* Lock for GC. */
 struct srcu_struct tomoyo_ss;
 
+/* TOMOYO registered by register_security()? */
+bool tomoyo_registered;
+
 static int __init tomoyo_init(void)
 {
-	struct cred *cred = (struct cred *) current_cred();
-
 	if (!security_module_enable(&tomoyo_security_ops))
 		return 0;
 	printk(KERN_INFO "TOMOYO Linux is temporarily disabled due to large "
@@ -285,8 +372,12 @@ static int __init tomoyo_init(void)
 	    init_srcu_struct(&tomoyo_ss))
 		panic("Failure registering TOMOYO Linux");
 	printk(KERN_INFO "TOMOYO Linux initialized\n");
-	cred->security = &tomoyo_kernel_domain;
+	tomoyo_registered = true;
 	tomoyo_mm_init();
+	tomoyo_add_task_security(&tomoyo_init_security,
+				 &tomoyo_task_security_list
+				 [hash_ptr((void *) &init_task,
+					   TOMOYO_TASK_SECURITY_HASH_BITS)]);
 	return 0;
 }
 
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux