|
@@ -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);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -85,6 +81,43 @@ struct aa_label *aa_get_task_label(struct task_struct *task)
|
|
|
return p;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * 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;
|
|
|
}
|