net: aquantia: cleanup err handing in hw_atl_utils_fw_rpc_wait
[linux/fpc-iii.git] / security / apparmor / task.c
blobc6b78a14da91842a7288e4c92e6db490284f0c4c
1 /*
2 * AppArmor security module
4 * This file contains AppArmor task related definitions and mediation
6 * Copyright 2017 Canonical Ltd.
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation, version 2 of the
11 * License.
13 * TODO
14 * If a task uses change_hat it currently does not return to the old
15 * cred or task context but instead creates a new one. Ideally the task
16 * should return to the previous cred if it has not been modified.
19 #include "include/cred.h"
20 #include "include/task.h"
22 /**
23 * aa_get_task_label - Get another task's label
24 * @task: task to query (NOT NULL)
26 * Returns: counted reference to @task's label
28 struct aa_label *aa_get_task_label(struct task_struct *task)
30 struct aa_label *p;
32 rcu_read_lock();
33 p = aa_get_newest_label(__aa_task_raw_label(task));
34 rcu_read_unlock();
36 return p;
39 /**
40 * aa_replace_current_label - replace the current tasks label
41 * @label: new label (NOT NULL)
43 * Returns: 0 or error on failure
45 int aa_replace_current_label(struct aa_label *label)
47 struct aa_label *old = aa_current_raw_label();
48 struct aa_task_ctx *ctx = task_ctx(current);
49 struct cred *new;
51 AA_BUG(!label);
53 if (old == label)
54 return 0;
56 if (current_cred() != current_real_cred())
57 return -EBUSY;
59 new = prepare_creds();
60 if (!new)
61 return -ENOMEM;
63 if (ctx->nnp && label_is_stale(ctx->nnp)) {
64 struct aa_label *tmp = ctx->nnp;
66 ctx->nnp = aa_get_newest_label(tmp);
67 aa_put_label(tmp);
69 if (unconfined(label) || (labels_ns(old) != labels_ns(label)))
71 * if switching to unconfined or a different label namespace
72 * clear out context state
74 aa_clear_task_ctx_trans(task_ctx(current));
77 * be careful switching cred label, when racing replacement it
78 * is possible that the cred labels's->proxy->label is the reference
79 * keeping @label valid, so make sure to get its reference before
80 * dropping the reference on the cred's label
82 aa_get_label(label);
83 aa_put_label(cred_label(new));
84 cred_label(new) = label;
86 commit_creds(new);
87 return 0;
91 /**
92 * aa_set_current_onexec - set the tasks change_profile to happen onexec
93 * @label: system label to set at exec (MAYBE NULL to clear value)
94 * @stack: whether stacking should be done
95 * Returns: 0 or error on failure
97 int aa_set_current_onexec(struct aa_label *label, bool stack)
99 struct aa_task_ctx *ctx = task_ctx(current);
101 aa_get_label(label);
102 aa_put_label(ctx->onexec);
103 ctx->onexec = label;
104 ctx->token = stack;
106 return 0;
110 * aa_set_current_hat - set the current tasks hat
111 * @label: label to set as the current hat (NOT NULL)
112 * @token: token value that must be specified to change from the hat
114 * Do switch of tasks hat. If the task is currently in a hat
115 * validate the token to match.
117 * Returns: 0 or error on failure
119 int aa_set_current_hat(struct aa_label *label, u64 token)
121 struct aa_task_ctx *ctx = task_ctx(current);
122 struct cred *new;
124 new = prepare_creds();
125 if (!new)
126 return -ENOMEM;
127 AA_BUG(!label);
129 if (!ctx->previous) {
130 /* transfer refcount */
131 ctx->previous = cred_label(new);
132 ctx->token = token;
133 } else if (ctx->token == token) {
134 aa_put_label(cred_label(new));
135 } else {
136 /* previous_profile && ctx->token != token */
137 abort_creds(new);
138 return -EACCES;
141 cred_label(new) = aa_get_newest_label(label);
142 /* clear exec on switching context */
143 aa_put_label(ctx->onexec);
144 ctx->onexec = NULL;
146 commit_creds(new);
147 return 0;
151 * aa_restore_previous_label - exit from hat context restoring previous label
152 * @token: the token that must be matched to exit hat context
154 * Attempt to return out of a hat to the previous label. The token
155 * must match the stored token value.
157 * Returns: 0 or error of failure
159 int aa_restore_previous_label(u64 token)
161 struct aa_task_ctx *ctx = task_ctx(current);
162 struct cred *new;
164 if (ctx->token != token)
165 return -EACCES;
166 /* ignore restores when there is no saved label */
167 if (!ctx->previous)
168 return 0;
170 new = prepare_creds();
171 if (!new)
172 return -ENOMEM;
174 aa_put_label(cred_label(new));
175 cred_label(new) = aa_get_newest_label(ctx->previous);
176 AA_BUG(!cred_label(new));
177 /* clear exec && prev information when restoring to previous context */
178 aa_clear_task_ctx_trans(ctx);
180 commit_creds(new);
182 return 0;