Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 43fc4609 authored by Casey Schaufler's avatar Casey Schaufler Committed by Kees Cook
Browse files

TOMOYO: Abstract use of cred security blob



Don't use the cred->security pointer directly.
Provide helper functions that provide the security blob pointer.

Signed-off-by: default avatarCasey Schaufler <casey@schaufler-ca.com>
Reviewed-by: default avatarKees Cook <keescook@chromium.org>
[kees: adjusted for ordered init series]
Signed-off-by: default avatarKees Cook <keescook@chromium.org>
parent 69b5a44a
Loading
Loading
Loading
Loading
+19 −2
Original line number Original line Diff line number Diff line
@@ -29,6 +29,7 @@
#include <linux/in.h>
#include <linux/in.h>
#include <linux/in6.h>
#include <linux/in6.h>
#include <linux/un.h>
#include <linux/un.h>
#include <linux/lsm_hooks.h>
#include <net/sock.h>
#include <net/sock.h>
#include <net/af_unix.h>
#include <net/af_unix.h>
#include <net/ip.h>
#include <net/ip.h>
@@ -1062,6 +1063,7 @@ void tomoyo_write_log2(struct tomoyo_request_info *r, int len, const char *fmt,
/********** External variable definitions. **********/
/********** External variable definitions. **********/


extern bool tomoyo_policy_loaded;
extern bool tomoyo_policy_loaded;
extern int tomoyo_enabled;
extern const char * const tomoyo_condition_keyword
extern const char * const tomoyo_condition_keyword
[TOMOYO_MAX_CONDITION_KEYWORD];
[TOMOYO_MAX_CONDITION_KEYWORD];
extern const char * const tomoyo_dif[TOMOYO_MAX_DOMAIN_INFO_FLAGS];
extern const char * const tomoyo_dif[TOMOYO_MAX_DOMAIN_INFO_FLAGS];
@@ -1196,6 +1198,17 @@ static inline void tomoyo_put_group(struct tomoyo_group *group)
		atomic_dec(&group->head.users);
		atomic_dec(&group->head.users);
}
}


/**
 * tomoyo_cred - Get a pointer to the tomoyo cred security blob
 * @cred - the relevant cred
 *
 * Returns pointer to the tomoyo cred blob.
 */
static inline struct tomoyo_domain_info **tomoyo_cred(const struct cred *cred)
{
	return (struct tomoyo_domain_info **)&cred->security;
}

/**
/**
 * tomoyo_domain - Get "struct tomoyo_domain_info" for current thread.
 * tomoyo_domain - Get "struct tomoyo_domain_info" for current thread.
 *
 *
@@ -1203,7 +1216,9 @@ static inline void tomoyo_put_group(struct tomoyo_group *group)
 */
 */
static inline struct tomoyo_domain_info *tomoyo_domain(void)
static inline struct tomoyo_domain_info *tomoyo_domain(void)
{
{
	return current_cred()->security;
	struct tomoyo_domain_info **blob = tomoyo_cred(current_cred());

	return *blob;
}
}


/**
/**
@@ -1216,7 +1231,9 @@ static inline struct tomoyo_domain_info *tomoyo_domain(void)
static inline struct tomoyo_domain_info *tomoyo_real_domain(struct task_struct
static inline struct tomoyo_domain_info *tomoyo_real_domain(struct task_struct
							    *task)
							    *task)
{
{
	return task_cred_xxx(task, security);
	struct tomoyo_domain_info **blob = tomoyo_cred(get_task_cred(task));

	return *blob;
}
}


/**
/**
+3 −1
Original line number Original line Diff line number Diff line
@@ -678,6 +678,7 @@ static int tomoyo_environ(struct tomoyo_execve *ee)
 */
 */
int tomoyo_find_next_domain(struct linux_binprm *bprm)
int tomoyo_find_next_domain(struct linux_binprm *bprm)
{
{
	struct tomoyo_domain_info **blob;
	struct tomoyo_domain_info *old_domain = tomoyo_domain();
	struct tomoyo_domain_info *old_domain = tomoyo_domain();
	struct tomoyo_domain_info *domain = NULL;
	struct tomoyo_domain_info *domain = NULL;
	const char *original_name = bprm->filename;
	const char *original_name = bprm->filename;
@@ -843,7 +844,8 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
		domain = old_domain;
		domain = old_domain;
	/* Update reference count on "struct tomoyo_domain_info". */
	/* Update reference count on "struct tomoyo_domain_info". */
	atomic_inc(&domain->users);
	atomic_inc(&domain->users);
	bprm->cred->security = domain;
	blob = tomoyo_cred(bprm->cred);
	*blob = domain;
	kfree(exename.name);
	kfree(exename.name);
	if (!retval) {
	if (!retval) {
		ee->r.domain = domain;
		ee->r.domain = domain;
+11 −4
Original line number Original line Diff line number Diff line
@@ -71,9 +71,12 @@ static ssize_t tomoyo_write_self(struct file *file, const char __user *buf,
				if (!cred) {
				if (!cred) {
					error = -ENOMEM;
					error = -ENOMEM;
				} else {
				} else {
					struct tomoyo_domain_info *old_domain =
					struct tomoyo_domain_info **blob;
						cred->security;
					struct tomoyo_domain_info *old_domain;
					cred->security = new_domain;

					blob = tomoyo_cred(cred);
					old_domain = *blob;
					*blob = new_domain;
					atomic_inc(&new_domain->users);
					atomic_inc(&new_domain->users);
					atomic_dec(&old_domain->users);
					atomic_dec(&old_domain->users);
					commit_creds(cred);
					commit_creds(cred);
@@ -234,10 +237,14 @@ static void __init tomoyo_create_entry(const char *name, const umode_t mode,
 */
 */
static int __init tomoyo_initerface_init(void)
static int __init tomoyo_initerface_init(void)
{
{
	struct tomoyo_domain_info *domain;
	struct dentry *tomoyo_dir;
	struct dentry *tomoyo_dir;


	if (!tomoyo_enabled)
		return 0;
	domain = tomoyo_domain();
	/* Don't create securityfs entries unless registered. */
	/* Don't create securityfs entries unless registered. */
	if (current_cred()->security != &tomoyo_kernel_domain)
	if (domain != &tomoyo_kernel_domain)
		return 0;
		return 0;


	tomoyo_dir = securityfs_create_dir("tomoyo", NULL);
	tomoyo_dir = securityfs_create_dir("tomoyo", NULL);
+31 −9
Original line number Original line Diff line number Diff line
@@ -18,7 +18,9 @@
 */
 */
static int tomoyo_cred_alloc_blank(struct cred *new, gfp_t gfp)
static int tomoyo_cred_alloc_blank(struct cred *new, gfp_t gfp)
{
{
	new->security = NULL;
	struct tomoyo_domain_info **blob = tomoyo_cred(new);

	*blob = NULL;
	return 0;
	return 0;
}
}


@@ -34,8 +36,13 @@ static int tomoyo_cred_alloc_blank(struct cred *new, gfp_t gfp)
static int tomoyo_cred_prepare(struct cred *new, const struct cred *old,
static int tomoyo_cred_prepare(struct cred *new, const struct cred *old,
			       gfp_t gfp)
			       gfp_t gfp)
{
{
	struct tomoyo_domain_info *domain = old->security;
	struct tomoyo_domain_info **old_blob = tomoyo_cred(old);
	new->security = domain;
	struct tomoyo_domain_info **new_blob = tomoyo_cred(new);
	struct tomoyo_domain_info *domain;

	domain = *old_blob;
	*new_blob = domain;

	if (domain)
	if (domain)
		atomic_inc(&domain->users);
		atomic_inc(&domain->users);
	return 0;
	return 0;
@@ -59,7 +66,9 @@ static void tomoyo_cred_transfer(struct cred *new, const struct cred *old)
 */
 */
static void tomoyo_cred_free(struct cred *cred)
static void tomoyo_cred_free(struct cred *cred)
{
{
	struct tomoyo_domain_info *domain = cred->security;
	struct tomoyo_domain_info **blob = tomoyo_cred(cred);
	struct tomoyo_domain_info *domain = *blob;

	if (domain)
	if (domain)
		atomic_dec(&domain->users);
		atomic_dec(&domain->users);
}
}
@@ -73,6 +82,9 @@ static void tomoyo_cred_free(struct cred *cred)
 */
 */
static int tomoyo_bprm_set_creds(struct linux_binprm *bprm)
static int tomoyo_bprm_set_creds(struct linux_binprm *bprm)
{
{
	struct tomoyo_domain_info **blob;
	struct tomoyo_domain_info *domain;

	/*
	/*
	 * Do only if this function is called for the first time of an execve
	 * Do only if this function is called for the first time of an execve
	 * operation.
	 * operation.
@@ -93,13 +105,14 @@ static int tomoyo_bprm_set_creds(struct linux_binprm *bprm)
	 * stored inside "bprm->cred->security" will be acquired later inside
	 * stored inside "bprm->cred->security" will be acquired later inside
	 * tomoyo_find_next_domain().
	 * tomoyo_find_next_domain().
	 */
	 */
	atomic_dec(&((struct tomoyo_domain_info *)
	blob = tomoyo_cred(bprm->cred);
		     bprm->cred->security)->users);
	domain = *blob;
	atomic_dec(&domain->users);
	/*
	/*
	 * Tell tomoyo_bprm_check_security() is called for the first time of an
	 * Tell tomoyo_bprm_check_security() is called for the first time of an
	 * execve operation.
	 * execve operation.
	 */
	 */
	bprm->cred->security = NULL;
	*blob = NULL;
	return 0;
	return 0;
}
}


@@ -112,8 +125,11 @@ static int tomoyo_bprm_set_creds(struct linux_binprm *bprm)
 */
 */
static int tomoyo_bprm_check_security(struct linux_binprm *bprm)
static int tomoyo_bprm_check_security(struct linux_binprm *bprm)
{
{
	struct tomoyo_domain_info *domain = bprm->cred->security;
	struct tomoyo_domain_info **blob;
	struct tomoyo_domain_info *domain;


	blob = tomoyo_cred(bprm->cred);
	domain = *blob;
	/*
	/*
	 * Execute permission is checked against pathname passed to do_execve()
	 * Execute permission is checked against pathname passed to do_execve()
	 * using current domain.
	 * using current domain.
@@ -531,6 +547,8 @@ static struct security_hook_list tomoyo_hooks[] __lsm_ro_after_init = {
/* Lock for GC. */
/* Lock for GC. */
DEFINE_SRCU(tomoyo_ss);
DEFINE_SRCU(tomoyo_ss);


int tomoyo_enabled __lsm_ro_after_init = 1;

/**
/**
 * tomoyo_init - Register TOMOYO Linux as a LSM module.
 * tomoyo_init - Register TOMOYO Linux as a LSM module.
 *
 *
@@ -539,17 +557,21 @@ DEFINE_SRCU(tomoyo_ss);
static int __init tomoyo_init(void)
static int __init tomoyo_init(void)
{
{
	struct cred *cred = (struct cred *) current_cred();
	struct cred *cred = (struct cred *) current_cred();
	struct tomoyo_domain_info **blob;


	/* register ourselves with the security framework */
	/* register ourselves with the security framework */
	security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks), "tomoyo");
	security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks), "tomoyo");
	printk(KERN_INFO "TOMOYO Linux initialized\n");
	printk(KERN_INFO "TOMOYO Linux initialized\n");
	cred->security = &tomoyo_kernel_domain;
	blob = tomoyo_cred(cred);
	*blob = &tomoyo_kernel_domain;
	tomoyo_mm_init();
	tomoyo_mm_init();

	return 0;
	return 0;
}
}


DEFINE_LSM(tomoyo) = {
DEFINE_LSM(tomoyo) = {
	.name = "tomoyo",
	.name = "tomoyo",
	.enabled = &tomoyo_enabled,
	.flags = LSM_FLAG_LEGACY_MAJOR | LSM_FLAG_EXCLUSIVE,
	.flags = LSM_FLAG_LEGACY_MAJOR | LSM_FLAG_EXCLUSIVE,
	.init = tomoyo_init,
	.init = tomoyo_init,
};
};