Blame view
security/apparmor/task.c
4.15 KB
b886d83c5
|
1 |
// SPDX-License-Identifier: GPL-2.0-only |
c75afcd15
|
2 3 4 |
/* * AppArmor security module * |
de62de59c
|
5 |
* This file contains AppArmor task related definitions and mediation |
c75afcd15
|
6 |
* |
de62de59c
|
7 |
* Copyright 2017 Canonical Ltd. |
c75afcd15
|
8 |
* |
c75afcd15
|
9 10 11 12 |
* TODO * If a task uses change_hat it currently does not return to the old * cred or task context but instead creates a new one. Ideally the task * should return to the previous cred if it has not been modified. |
c75afcd15
|
13 |
*/ |
d8889d49e
|
14 |
#include "include/cred.h" |
de62de59c
|
15 |
#include "include/task.h" |
c75afcd15
|
16 17 |
/** |
637f688dc
|
18 |
* aa_get_task_label - Get another task's label |
3cfcc19e0
|
19 20 |
* @task: task to query (NOT NULL) * |
637f688dc
|
21 |
* Returns: counted reference to @task's label |
3cfcc19e0
|
22 |
*/ |
637f688dc
|
23 |
struct aa_label *aa_get_task_label(struct task_struct *task) |
3cfcc19e0
|
24 |
{ |
637f688dc
|
25 |
struct aa_label *p; |
3cfcc19e0
|
26 27 |
rcu_read_lock(); |
637f688dc
|
28 |
p = aa_get_newest_label(__aa_task_raw_label(task)); |
3cfcc19e0
|
29 30 31 32 33 34 |
rcu_read_unlock(); return p; } /** |
637f688dc
|
35 36 |
* aa_replace_current_label - replace the current tasks label * @label: new label (NOT NULL) |
c75afcd15
|
37 38 39 |
* * Returns: 0 or error on failure */ |
637f688dc
|
40 |
int aa_replace_current_label(struct aa_label *label) |
c75afcd15
|
41 |
{ |
d9087c49d
|
42 |
struct aa_label *old = aa_current_raw_label(); |
9fcf78cca
|
43 |
struct aa_task_ctx *ctx = task_ctx(current); |
c75afcd15
|
44 |
struct cred *new; |
d9087c49d
|
45 |
|
637f688dc
|
46 |
AA_BUG(!label); |
c75afcd15
|
47 |
|
d9087c49d
|
48 |
if (old == label) |
c75afcd15
|
49 |
return 0; |
a20aa95fb
|
50 51 |
if (current_cred() != current_real_cred()) return -EBUSY; |
c75afcd15
|
52 53 54 |
new = prepare_creds(); if (!new) return -ENOMEM; |
9fcf78cca
|
55 56 57 58 59 60 |
if (ctx->nnp && label_is_stale(ctx->nnp)) { struct aa_label *tmp = ctx->nnp; ctx->nnp = aa_get_newest_label(tmp); aa_put_label(tmp); } |
d9087c49d
|
61 62 63 |
if (unconfined(label) || (labels_ns(old) != labels_ns(label))) /* * if switching to unconfined or a different label namespace |
c75afcd15
|
64 65 |
* clear out context state */ |
de62de59c
|
66 |
aa_clear_task_ctx_trans(task_ctx(current)); |
7a2871b56
|
67 |
|
55a26ebf6
|
68 |
/* |
d9087c49d
|
69 70 71 72 |
* be careful switching cred label, when racing replacement it * is possible that the cred labels's->proxy->label is the reference * keeping @label valid, so make sure to get its reference before * dropping the reference on the cred's label |
55a26ebf6
|
73 |
*/ |
637f688dc
|
74 |
aa_get_label(label); |
d9087c49d
|
75 |
aa_put_label(cred_label(new)); |
69b5a44a9
|
76 |
set_cred_label(new, label); |
c75afcd15
|
77 78 79 80 |
commit_creds(new); return 0; } |
de62de59c
|
81 |
|
c75afcd15
|
82 83 |
/** * aa_set_current_onexec - set the tasks change_profile to happen onexec |
637f688dc
|
84 85 |
* @label: system label to set at exec (MAYBE NULL to clear value) * @stack: whether stacking should be done |
c75afcd15
|
86 87 |
* Returns: 0 or error on failure */ |
637f688dc
|
88 |
int aa_set_current_onexec(struct aa_label *label, bool stack) |
c75afcd15
|
89 |
{ |
de62de59c
|
90 |
struct aa_task_ctx *ctx = task_ctx(current); |
c75afcd15
|
91 |
|
637f688dc
|
92 |
aa_get_label(label); |
3b529a760
|
93 |
aa_put_label(ctx->onexec); |
637f688dc
|
94 95 |
ctx->onexec = label; ctx->token = stack; |
c75afcd15
|
96 |
|
c75afcd15
|
97 98 99 100 101 |
return 0; } /** * aa_set_current_hat - set the current tasks hat |
637f688dc
|
102 |
* @label: label to set as the current hat (NOT NULL) |
c75afcd15
|
103 104 105 106 107 108 109 |
* @token: token value that must be specified to change from the hat * * Do switch of tasks hat. If the task is currently in a hat * validate the token to match. * * Returns: 0 or error on failure */ |
637f688dc
|
110 |
int aa_set_current_hat(struct aa_label *label, u64 token) |
c75afcd15
|
111 |
{ |
de62de59c
|
112 |
struct aa_task_ctx *ctx = task_ctx(current); |
d9087c49d
|
113 |
struct cred *new; |
3b529a760
|
114 |
|
d9087c49d
|
115 |
new = prepare_creds(); |
c75afcd15
|
116 117 |
if (!new) return -ENOMEM; |
637f688dc
|
118 |
AA_BUG(!label); |
c75afcd15
|
119 |
|
f175221af
|
120 |
if (!ctx->previous) { |
c75afcd15
|
121 |
/* transfer refcount */ |
f175221af
|
122 123 124 |
ctx->previous = cred_label(new); ctx->token = token; } else if (ctx->token == token) { |
d9087c49d
|
125 |
aa_put_label(cred_label(new)); |
c75afcd15
|
126 |
} else { |
55a26ebf6
|
127 |
/* previous_profile && ctx->token != token */ |
c75afcd15
|
128 129 130 |
abort_creds(new); return -EACCES; } |
3b529a760
|
131 |
|
69b5a44a9
|
132 |
set_cred_label(new, aa_get_newest_label(label)); |
c75afcd15
|
133 |
/* clear exec on switching context */ |
f175221af
|
134 135 |
aa_put_label(ctx->onexec); ctx->onexec = NULL; |
c75afcd15
|
136 137 138 139 140 141 |
commit_creds(new); return 0; } /** |
637f688dc
|
142 |
* aa_restore_previous_label - exit from hat context restoring previous label |
c75afcd15
|
143 144 |
* @token: the token that must be matched to exit hat context * |
637f688dc
|
145 |
* Attempt to return out of a hat to the previous label. The token |
c75afcd15
|
146 147 148 149 |
* must match the stored token value. * * Returns: 0 or error of failure */ |
637f688dc
|
150 |
int aa_restore_previous_label(u64 token) |
c75afcd15
|
151 |
{ |
de62de59c
|
152 |
struct aa_task_ctx *ctx = task_ctx(current); |
3b529a760
|
153 |
struct cred *new; |
c75afcd15
|
154 |
|
f175221af
|
155 |
if (ctx->token != token) |
c75afcd15
|
156 |
return -EACCES; |
637f688dc
|
157 |
/* ignore restores when there is no saved label */ |
f175221af
|
158 |
if (!ctx->previous) |
c75afcd15
|
159 |
return 0; |
3b529a760
|
160 161 162 163 |
new = prepare_creds(); if (!new) return -ENOMEM; |
c75afcd15
|
164 |
|
d9087c49d
|
165 |
aa_put_label(cred_label(new)); |
69b5a44a9
|
166 |
set_cred_label(new, aa_get_newest_label(ctx->previous)); |
d9087c49d
|
167 |
AA_BUG(!cred_label(new)); |
7a2871b56
|
168 |
/* clear exec && prev information when restoring to previous context */ |
f175221af
|
169 |
aa_clear_task_ctx_trans(ctx); |
c75afcd15
|
170 171 |
commit_creds(new); |
3b529a760
|
172 |
|
c75afcd15
|
173 174 |
return 0; } |