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

Commit bd71164a authored by James Morris's avatar James Morris
Browse files
parents f722406f 2654bfbc
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -88,7 +88,7 @@ static const char *const aa_audit_type[] = {
	"HINT",
	"HINT",
	"STATUS",
	"STATUS",
	"ERROR",
	"ERROR",
	"KILLED"
	"KILLED",
	"AUTO"
	"AUTO"
};
};


+28 −16
Original line number Original line Diff line number Diff line
@@ -68,6 +68,23 @@ void aa_dup_task_context(struct aa_task_cxt *new, const struct aa_task_cxt *old)
	aa_get_profile(new->onexec);
	aa_get_profile(new->onexec);
}
}


/**
 * aa_get_task_profile - Get another task's profile
 * @task: task to query  (NOT NULL)
 *
 * Returns: counted reference to @task's profile
 */
struct aa_profile *aa_get_task_profile(struct task_struct *task)
{
	struct aa_profile *p;

	rcu_read_lock();
	p = aa_get_profile(__aa_task_profile(task));
	rcu_read_unlock();

	return p;
}

/**
/**
 * aa_replace_current_profile - replace the current tasks profiles
 * aa_replace_current_profile - replace the current tasks profiles
 * @profile: new profile  (NOT NULL)
 * @profile: new profile  (NOT NULL)
@@ -76,7 +93,7 @@ void aa_dup_task_context(struct aa_task_cxt *new, const struct aa_task_cxt *old)
 */
 */
int aa_replace_current_profile(struct aa_profile *profile)
int aa_replace_current_profile(struct aa_profile *profile)
{
{
	struct aa_task_cxt *cxt = current_cred()->security;
	struct aa_task_cxt *cxt = current_cxt();
	struct cred *new;
	struct cred *new;
	BUG_ON(!profile);
	BUG_ON(!profile);


@@ -87,17 +104,13 @@ int aa_replace_current_profile(struct aa_profile *profile)
	if (!new)
	if (!new)
		return -ENOMEM;
		return -ENOMEM;


	cxt = new->security;
	cxt = cred_cxt(new);
	if (unconfined(profile) || (cxt->profile->ns != profile->ns)) {
	if (unconfined(profile) || (cxt->profile->ns != profile->ns))
		/* if switching to unconfined or a different profile namespace
		/* if switching to unconfined or a different profile namespace
		 * clear out context state
		 * clear out context state
		 */
		 */
		aa_put_profile(cxt->previous);
		aa_clear_task_cxt_trans(cxt);
		aa_put_profile(cxt->onexec);

		cxt->previous = NULL;
		cxt->onexec = NULL;
		cxt->token = 0;
	}
	/* be careful switching cxt->profile, when racing replacement it
	/* be careful switching cxt->profile, when racing replacement it
	 * is possible that cxt->profile->replacedby is the reference keeping
	 * is possible that cxt->profile->replacedby is the reference keeping
	 * @profile valid, so make sure to get its reference before dropping
	 * @profile valid, so make sure to get its reference before dropping
@@ -123,7 +136,7 @@ int aa_set_current_onexec(struct aa_profile *profile)
	if (!new)
	if (!new)
		return -ENOMEM;
		return -ENOMEM;


	cxt = new->security;
	cxt = cred_cxt(new);
	aa_get_profile(profile);
	aa_get_profile(profile);
	aa_put_profile(cxt->onexec);
	aa_put_profile(cxt->onexec);
	cxt->onexec = profile;
	cxt->onexec = profile;
@@ -150,7 +163,7 @@ int aa_set_current_hat(struct aa_profile *profile, u64 token)
		return -ENOMEM;
		return -ENOMEM;
	BUG_ON(!profile);
	BUG_ON(!profile);


	cxt = new->security;
	cxt = cred_cxt(new);
	if (!cxt->previous) {
	if (!cxt->previous) {
		/* transfer refcount */
		/* transfer refcount */
		cxt->previous = cxt->profile;
		cxt->previous = cxt->profile;
@@ -187,7 +200,7 @@ int aa_restore_previous_profile(u64 token)
	if (!new)
	if (!new)
		return -ENOMEM;
		return -ENOMEM;


	cxt = new->security;
	cxt = cred_cxt(new);
	if (cxt->token != token) {
	if (cxt->token != token) {
		abort_creds(new);
		abort_creds(new);
		return -EACCES;
		return -EACCES;
@@ -205,11 +218,10 @@ int aa_restore_previous_profile(u64 token)
		aa_get_profile(cxt->profile);
		aa_get_profile(cxt->profile);
		aa_put_profile(cxt->previous);
		aa_put_profile(cxt->previous);
	}
	}
	/* clear exec && prev information when restoring to previous context */
	/* ref has been transfered so avoid putting ref in clear_task_cxt */
	cxt->previous = NULL;
	cxt->previous = NULL;
	cxt->token = 0;
	/* clear exec && prev information when restoring to previous context */
	aa_put_profile(cxt->onexec);
	aa_clear_task_cxt_trans(cxt);
	cxt->onexec = NULL;


	commit_creds(new);
	commit_creds(new);
	return 0;
	return 0;
+9 −17
Original line number Original line Diff line number Diff line
@@ -62,17 +62,14 @@ static int may_change_ptraced_domain(struct task_struct *task,
				     struct aa_profile *to_profile)
				     struct aa_profile *to_profile)
{
{
	struct task_struct *tracer;
	struct task_struct *tracer;
	const struct cred *cred = NULL;
	struct aa_profile *tracerp = NULL;
	struct aa_profile *tracerp = NULL;
	int error = 0;
	int error = 0;


	rcu_read_lock();
	rcu_read_lock();
	tracer = ptrace_parent(task);
	tracer = ptrace_parent(task);
	if (tracer) {
	if (tracer)
		/* released below */
		/* released below */
		cred = get_task_cred(tracer);
		tracerp = aa_get_task_profile(tracer);
		tracerp = aa_cred_profile(cred);
	}


	/* not ptraced */
	/* not ptraced */
	if (!tracer || unconfined(tracerp))
	if (!tracer || unconfined(tracerp))
@@ -82,8 +79,7 @@ static int may_change_ptraced_domain(struct task_struct *task,


out:
out:
	rcu_read_unlock();
	rcu_read_unlock();
	if (cred)
	aa_put_profile(tracerp);
		put_cred(cred);


	return error;
	return error;
}
}
@@ -360,7 +356,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
	if (bprm->cred_prepared)
	if (bprm->cred_prepared)
		return 0;
		return 0;


	cxt = bprm->cred->security;
	cxt = cred_cxt(bprm->cred);
	BUG_ON(!cxt);
	BUG_ON(!cxt);


	profile = aa_get_profile(aa_newest_version(cxt->profile));
	profile = aa_get_profile(aa_newest_version(cxt->profile));
@@ -443,6 +439,8 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
			} else {
			} else {
				error = -ENOENT;
				error = -ENOENT;
				info = "profile not found";
				info = "profile not found";
				/* remove MAY_EXEC to audit as failure */
				perms.allow &= ~MAY_EXEC;
			}
			}
		}
		}
	} else if (COMPLAIN_MODE(profile)) {
	} else if (COMPLAIN_MODE(profile)) {
@@ -514,11 +512,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
	cxt->profile = new_profile;
	cxt->profile = new_profile;


	/* clear out all temporary/transitional state from the context */
	/* clear out all temporary/transitional state from the context */
	aa_put_profile(cxt->previous);
	aa_clear_task_cxt_trans(cxt);
	aa_put_profile(cxt->onexec);
	cxt->previous = NULL;
	cxt->onexec = NULL;
	cxt->token = 0;


audit:
audit:
	error = aa_audit_file(profile, &perms, GFP_KERNEL, OP_EXEC, MAY_EXEC,
	error = aa_audit_file(profile, &perms, GFP_KERNEL, OP_EXEC, MAY_EXEC,
@@ -557,7 +551,7 @@ int apparmor_bprm_secureexec(struct linux_binprm *bprm)
void apparmor_bprm_committing_creds(struct linux_binprm *bprm)
void apparmor_bprm_committing_creds(struct linux_binprm *bprm)
{
{
	struct aa_profile *profile = __aa_current_profile();
	struct aa_profile *profile = __aa_current_profile();
	struct aa_task_cxt *new_cxt = bprm->cred->security;
	struct aa_task_cxt *new_cxt = cred_cxt(bprm->cred);


	/* bail out if unconfined or not changing profile */
	/* bail out if unconfined or not changing profile */
	if ((new_cxt->profile == profile) ||
	if ((new_cxt->profile == profile) ||
@@ -634,7 +628,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest)


	/* released below */
	/* released below */
	cred = get_current_cred();
	cred = get_current_cred();
	cxt = cred->security;
	cxt = cred_cxt(cred);
	profile = aa_cred_profile(cred);
	profile = aa_cred_profile(cred);
	previous_profile = cxt->previous;
	previous_profile = cxt->previous;


@@ -750,7 +744,6 @@ int aa_change_profile(const char *ns_name, const char *hname, bool onexec,
		      bool permtest)
		      bool permtest)
{
{
	const struct cred *cred;
	const struct cred *cred;
	struct aa_task_cxt *cxt;
	struct aa_profile *profile, *target = NULL;
	struct aa_profile *profile, *target = NULL;
	struct aa_namespace *ns = NULL;
	struct aa_namespace *ns = NULL;
	struct file_perms perms = {};
	struct file_perms perms = {};
@@ -770,7 +763,6 @@ int aa_change_profile(const char *ns_name, const char *hname, bool onexec,
	}
	}


	cred = get_current_cred();
	cred = get_current_cred();
	cxt = cred->security;
	profile = aa_cred_profile(cred);
	profile = aa_cred_profile(cred);


	/*
	/*
+11 −1
Original line number Original line Diff line number Diff line
@@ -15,6 +15,7 @@
#ifndef __APPARMOR_H
#ifndef __APPARMOR_H
#define __APPARMOR_H
#define __APPARMOR_H


#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/fs.h>


#include "match.h"
#include "match.h"
@@ -64,9 +65,18 @@ extern int apparmor_initialized __initdata;
/* fn's in lib */
/* fn's in lib */
char *aa_split_fqname(char *args, char **ns_name);
char *aa_split_fqname(char *args, char **ns_name);
void aa_info_message(const char *str);
void aa_info_message(const char *str);
void *kvmalloc(size_t size);
void *__aa_kvmalloc(size_t size, gfp_t flags);
void kvfree(void *buffer);
void kvfree(void *buffer);


static inline void *kvmalloc(size_t size)
{
	return __aa_kvmalloc(size, 0);
}

static inline void *kvzalloc(size_t size)
{
	return __aa_kvmalloc(size, __GFP_ZERO);
}


/**
/**
 * aa_strneq - compare null terminated @str to a non null terminated substring
 * aa_strneq - compare null terminated @str to a non null terminated substring
+43 −18
Original line number Original line Diff line number Diff line
@@ -21,6 +21,9 @@


#include "policy.h"
#include "policy.h"


#define cred_cxt(X) (X)->security
#define current_cxt() cred_cxt(current_cred())

/* struct aa_file_cxt - the AppArmor context the file was opened in
/* struct aa_file_cxt - the AppArmor context the file was opened in
 * @perms: the permission the file was opened with
 * @perms: the permission the file was opened with
 *
 *
@@ -80,23 +83,8 @@ int aa_replace_current_profile(struct aa_profile *profile);
int aa_set_current_onexec(struct aa_profile *profile);
int aa_set_current_onexec(struct aa_profile *profile);
int aa_set_current_hat(struct aa_profile *profile, u64 token);
int aa_set_current_hat(struct aa_profile *profile, u64 token);
int aa_restore_previous_profile(u64 cookie);
int aa_restore_previous_profile(u64 cookie);
struct aa_profile *aa_get_task_profile(struct task_struct *task);


/**
 * __aa_task_is_confined - determine if @task has any confinement
 * @task: task to check confinement of  (NOT NULL)
 *
 * If @task != current needs to be called in RCU safe critical section
 */
static inline bool __aa_task_is_confined(struct task_struct *task)
{
	struct aa_task_cxt *cxt = __task_cred(task)->security;

	BUG_ON(!cxt || !cxt->profile);
	if (unconfined(aa_newest_version(cxt->profile)))
		return 0;

	return 1;
}


/**
/**
 * aa_cred_profile - obtain cred's profiles
 * aa_cred_profile - obtain cred's profiles
@@ -108,11 +96,35 @@ static inline bool __aa_task_is_confined(struct task_struct *task)
 */
 */
static inline struct aa_profile *aa_cred_profile(const struct cred *cred)
static inline struct aa_profile *aa_cred_profile(const struct cred *cred)
{
{
	struct aa_task_cxt *cxt = cred->security;
	struct aa_task_cxt *cxt = cred_cxt(cred);
	BUG_ON(!cxt || !cxt->profile);
	BUG_ON(!cxt || !cxt->profile);
	return aa_newest_version(cxt->profile);
	return aa_newest_version(cxt->profile);
}
}


/**
 * __aa_task_profile - retrieve another task's profile
 * @task: task to query  (NOT NULL)
 *
 * Returns: @task's profile without incrementing its ref count
 *
 * If @task != current needs to be called in RCU safe critical section
 */
static inline struct aa_profile *__aa_task_profile(struct task_struct *task)
{
	return aa_cred_profile(__task_cred(task));
}

/**
 * __aa_task_is_confined - determine if @task has any confinement
 * @task: task to check confinement of  (NOT NULL)
 *
 * If @task != current needs to be called in RCU safe critical section
 */
static inline bool __aa_task_is_confined(struct task_struct *task)
{
	return !unconfined(__aa_task_profile(task));
}

/**
/**
 * __aa_current_profile - find the current tasks confining profile
 * __aa_current_profile - find the current tasks confining profile
 *
 *
@@ -136,7 +148,7 @@ static inline struct aa_profile *__aa_current_profile(void)
 */
 */
static inline struct aa_profile *aa_current_profile(void)
static inline struct aa_profile *aa_current_profile(void)
{
{
	const struct aa_task_cxt *cxt = current_cred()->security;
	const struct aa_task_cxt *cxt = current_cxt();
	struct aa_profile *profile;
	struct aa_profile *profile;
	BUG_ON(!cxt || !cxt->profile);
	BUG_ON(!cxt || !cxt->profile);


@@ -151,4 +163,17 @@ static inline struct aa_profile *aa_current_profile(void)
	return profile;
	return profile;
}
}


/**
 * aa_clear_task_cxt_trans - clear transition tracking info from the cxt
 * @cxt: task context to clear (NOT NULL)
 */
static inline void aa_clear_task_cxt_trans(struct aa_task_cxt *cxt)
{
	aa_put_profile(cxt->previous);
	aa_put_profile(cxt->onexec);
	cxt->previous = NULL;
	cxt->onexec = NULL;
	cxt->token = 0;
}

#endif /* __AA_CONTEXT_H */
#endif /* __AA_CONTEXT_H */
Loading