summaryrefslogtreecommitdiff
path: root/security/apparmor/context.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/apparmor/context.c')
-rw-r--r--security/apparmor/context.c91
1 files changed, 61 insertions, 30 deletions
diff --git a/security/apparmor/context.c b/security/apparmor/context.c
index 89c03053303e..432672b18945 100644
--- a/security/apparmor/context.c
+++ b/security/apparmor/context.c
@@ -48,8 +48,6 @@ void aa_free_cred_ctx(struct aa_cred_ctx *ctx)
{
if (ctx) {
aa_put_label(ctx->label);
- aa_put_label(ctx->previous);
- aa_put_label(ctx->onexec);
kzfree(ctx);
}
@@ -64,8 +62,6 @@ void aa_dup_cred_ctx(struct aa_cred_ctx *new, const struct aa_cred_ctx *old)
{
*new = *old;
aa_get_label(new->label);
- aa_get_label(new->previous);
- aa_get_label(new->onexec);
}
/**
@@ -86,6 +82,43 @@ struct aa_label *aa_get_task_label(struct task_struct *task)
}
/**
+ * aa_alloc_task_ctx - allocate a new task_ctx
+ * @flags: gfp flags for allocation
+ *
+ * Returns: allocated buffer or NULL on failure
+ */
+struct aa_task_ctx *aa_alloc_task_ctx(gfp_t flags)
+{
+ return kzalloc(sizeof(struct aa_task_ctx), flags);
+}
+
+/**
+ * aa_free_task_ctx - free a task_ctx
+ * @ctx: task_ctx to free (MAYBE NULL)
+ */
+void aa_free_task_ctx(struct aa_task_ctx *ctx)
+{
+ if (ctx) {
+ aa_put_label(ctx->previous);
+ aa_put_label(ctx->onexec);
+
+ kzfree(ctx);
+ }
+}
+
+/**
+ * aa_dup_task_ctx - duplicate a task context, incrementing reference counts
+ * @new: a blank task context (NOT NULL)
+ * @old: the task context to copy (NOT NULL)
+ */
+void aa_dup_task_ctx(struct aa_task_ctx *new, const struct aa_task_ctx *old)
+{
+ *new = *old;
+ aa_get_label(new->previous);
+ aa_get_label(new->onexec);
+}
+
+/**
* aa_replace_current_label - replace the current tasks label
* @label: new label (NOT NULL)
*
@@ -112,7 +145,7 @@ int aa_replace_current_label(struct aa_label *label)
/* if switching to unconfined or a different label namespace
* clear out context state
*/
- aa_clear_cred_ctx_trans(ctx);
+ aa_clear_task_ctx_trans(current_task_ctx());
/*
* be careful switching ctx->profile, when racing replacement it
@@ -136,18 +169,13 @@ int aa_replace_current_label(struct aa_label *label)
*/
int aa_set_current_onexec(struct aa_label *label, bool stack)
{
- struct aa_cred_ctx *ctx;
- struct cred *new = prepare_creds();
- if (!new)
- return -ENOMEM;
+ struct aa_task_ctx *ctx = current_task_ctx();
- ctx = cred_ctx(new);
aa_get_label(label);
- aa_clear_cred_ctx_trans(ctx);
+ aa_put_label(ctx->onexec);
ctx->onexec = label;
ctx->token = stack;
- commit_creds(new);
return 0;
}
@@ -163,28 +191,31 @@ int aa_set_current_onexec(struct aa_label *label, bool stack)
*/
int aa_set_current_hat(struct aa_label *label, u64 token)
{
+ struct aa_task_ctx *tctx = current_task_ctx();
struct aa_cred_ctx *ctx;
struct cred *new = prepare_creds();
+
if (!new)
return -ENOMEM;
AA_BUG(!label);
ctx = cred_ctx(new);
- if (!ctx->previous) {
+ if (!tctx->previous) {
/* transfer refcount */
- ctx->previous = ctx->label;
- ctx->token = token;
- } else if (ctx->token == token) {
+ tctx->previous = ctx->label;
+ tctx->token = token;
+ } else if (tctx->token == token) {
aa_put_label(ctx->label);
} else {
/* previous_profile && ctx->token != token */
abort_creds(new);
return -EACCES;
}
+
ctx->label = aa_get_newest_label(label);
/* clear exec on switching context */
- aa_put_label(ctx->onexec);
- ctx->onexec = NULL;
+ aa_put_label(tctx->onexec);
+ tctx->onexec = NULL;
commit_creds(new);
return 0;
@@ -201,28 +232,28 @@ int aa_set_current_hat(struct aa_label *label, u64 token)
*/
int aa_restore_previous_label(u64 token)
{
+ struct aa_task_ctx *tctx = current_task_ctx();
struct aa_cred_ctx *ctx;
- struct cred *new = prepare_creds();
- if (!new)
- return -ENOMEM;
+ struct cred *new;
- ctx = cred_ctx(new);
- if (ctx->token != token) {
- abort_creds(new);
+ if (tctx->token != token)
return -EACCES;
- }
/* ignore restores when there is no saved label */
- if (!ctx->previous) {
- abort_creds(new);
+ if (!tctx->previous)
return 0;
- }
+
+ new = prepare_creds();
+ if (!new)
+ return -ENOMEM;
+ ctx = cred_ctx(new);
aa_put_label(ctx->label);
- ctx->label = aa_get_newest_label(ctx->previous);
+ ctx->label = aa_get_newest_label(tctx->previous);
AA_BUG(!ctx->label);
/* clear exec && prev information when restoring to previous context */
- aa_clear_cred_ctx_trans(ctx);
+ aa_clear_task_ctx_trans(tctx);
commit_creds(new);
+
return 0;
}