]>
Commit | Line | Data |
---|---|---|
c75afcd1 JJ |
1 | /* |
2 | * AppArmor security module | |
3 | * | |
4 | * This file contains AppArmor contexts used to associate "labels" to objects. | |
5 | * | |
6 | * Copyright (C) 1998-2008 Novell/SUSE | |
7 | * Copyright 2009-2010 Canonical Ltd. | |
8 | * | |
9 | * This program is free software; you can redistribute it and/or | |
10 | * modify it under the terms of the GNU General Public License as | |
11 | * published by the Free Software Foundation, version 2 of the | |
12 | * License. | |
13 | */ | |
14 | ||
15 | #ifndef __AA_CONTEXT_H | |
16 | #define __AA_CONTEXT_H | |
17 | ||
18 | #include <linux/cred.h> | |
19 | #include <linux/slab.h> | |
20 | #include <linux/sched.h> | |
21 | ||
a3c6147c JJ |
22 | #include "label.h" |
23 | #include "policy_ns.h" | |
c75afcd1 | 24 | |
a3c6147c JJ |
25 | #define cred_ctx(X) (X)->security |
26 | #define current_ctx() cred_ctx(current_cred()) | |
c75afcd1 JJ |
27 | |
28 | /** | |
a3c6147c JJ |
29 | * struct aa_task_ctx - primary label for confined tasks |
30 | * @label: the current label (NOT NULL) | |
31 | * @exec: label to transition to on next exec (MAYBE NULL) | |
32 | * @previous: label the task may return to (MAYBE NULL) | |
33 | * @token: magic value the task must know for returning to @previous | |
c75afcd1 | 34 | * |
a3c6147c | 35 | * Contains the task's current label (which could change due to |
c75afcd1 JJ |
36 | * change_hat). Plus the hat_magic needed during change_hat. |
37 | * | |
38 | * TODO: make so a task can be confined by a stack of contexts | |
39 | */ | |
a3c6147c JJ |
40 | struct aa_task_ctx { |
41 | struct aa_label *label; | |
42 | struct aa_label *onexec; | |
43 | struct aa_label *previous; | |
c75afcd1 JJ |
44 | u64 token; |
45 | }; | |
46 | ||
a3c6147c JJ |
47 | struct aa_task_ctx *aa_alloc_task_context(gfp_t flags); |
48 | void aa_free_task_context(struct aa_task_ctx *ctx); | |
49 | void aa_dup_task_context(struct aa_task_ctx *new, | |
50 | const struct aa_task_ctx *old); | |
51 | int aa_replace_current_label(struct aa_label *label); | |
52 | int aa_set_current_onexec(struct aa_label *label, bool stack); | |
53 | int aa_set_current_hat(struct aa_label *label, u64 token); | |
54 | int aa_restore_previous_label(u64 cookie); | |
55 | struct aa_label *aa_get_task_label(struct task_struct *task); | |
c75afcd1 | 56 | |
c75afcd1 JJ |
57 | |
58 | /** | |
a3c6147c JJ |
59 | * aa_cred_raw_label - obtain cred's label |
60 | * @cred: cred to obtain label from (NOT NULL) | |
c75afcd1 | 61 | * |
a3c6147c | 62 | * Returns: confining label |
c75afcd1 JJ |
63 | * |
64 | * does NOT increment reference count | |
65 | */ | |
a3c6147c | 66 | static inline struct aa_label *aa_cred_raw_label(const struct cred *cred) |
c75afcd1 | 67 | { |
a3c6147c JJ |
68 | struct aa_task_ctx *ctx = cred_ctx(cred); |
69 | BUG_ON(!ctx || !ctx->label); | |
70 | return ctx->label; | |
c75afcd1 JJ |
71 | } |
72 | ||
3cfcc19e | 73 | /** |
a3c6147c JJ |
74 | * aa_get_newest_cred_label - obtain the newest version of the label on a cred |
75 | * @cred: cred to obtain label from (NOT NULL) | |
76 | * | |
77 | * Returns: newest version of confining label | |
78 | */ | |
79 | static inline struct aa_label *aa_get_newest_cred_label(const struct cred *cred) | |
80 | { | |
81 | return aa_get_newest_label(aa_cred_raw_label(cred)); | |
82 | } | |
83 | ||
84 | /** | |
85 | * __aa_task_raw_label - retrieve another task's label | |
3cfcc19e JJ |
86 | * @task: task to query (NOT NULL) |
87 | * | |
a3c6147c | 88 | * Returns: @task's label without incrementing its ref count |
3cfcc19e JJ |
89 | * |
90 | * If @task != current needs to be called in RCU safe critical section | |
91 | */ | |
a3c6147c | 92 | static inline struct aa_label *__aa_task_raw_label(struct task_struct *task) |
3cfcc19e | 93 | { |
a3c6147c | 94 | return aa_cred_raw_label(__task_cred(task)); |
3cfcc19e JJ |
95 | } |
96 | ||
97 | /** | |
98 | * __aa_task_is_confined - determine if @task has any confinement | |
99 | * @task: task to check confinement of (NOT NULL) | |
100 | * | |
101 | * If @task != current needs to be called in RCU safe critical section | |
102 | */ | |
103 | static inline bool __aa_task_is_confined(struct task_struct *task) | |
104 | { | |
a3c6147c | 105 | return !unconfined(__aa_task_raw_label(task)); |
3cfcc19e JJ |
106 | } |
107 | ||
c75afcd1 | 108 | /** |
a3c6147c | 109 | * aa_current_raw_label - find the current tasks confining label |
c75afcd1 | 110 | * |
a3c6147c | 111 | * Returns: up to date confining label or the ns unconfined label (NOT NULL) |
c75afcd1 JJ |
112 | * |
113 | * This fn will not update the tasks cred to the most up to date version | |
a3c6147c | 114 | * of the label so it is safe to call when inside of locks. |
c75afcd1 | 115 | */ |
a3c6147c | 116 | static inline struct aa_label *aa_current_raw_label(void) |
c75afcd1 | 117 | { |
a3c6147c | 118 | return aa_cred_raw_label(current_cred()); |
c75afcd1 JJ |
119 | } |
120 | ||
121 | /** | |
a3c6147c JJ |
122 | * aa_get_current_label - get the newest version of the current tasks label |
123 | * | |
124 | * Returns: newest version of confining label (NOT NULL) | |
c75afcd1 | 125 | * |
a3c6147c | 126 | * This fn will not update the tasks cred, so it is safe inside of locks |
c75afcd1 | 127 | * |
a3c6147c | 128 | * The returned reference must be put with aa_put_label() |
c75afcd1 | 129 | */ |
a3c6147c | 130 | static inline struct aa_label *aa_get_current_label(void) |
c75afcd1 | 131 | { |
a3c6147c JJ |
132 | struct aa_label *l = aa_current_raw_label(); |
133 | ||
134 | if (label_is_stale(l)) | |
135 | return aa_get_newest_label(l); | |
136 | return aa_get_label(l); | |
137 | } | |
138 | ||
139 | /** | |
140 | * aa_end_current_label - put a reference found with aa_begin_current_label | |
141 | * @label: label reference to put | |
142 | * | |
143 | * Should only be used with a reference obtained with aa_begin_current_label | |
144 | * and never used in situations where the task cred may be updated | |
145 | */ | |
146 | static inline void aa_end_current_label(struct aa_label *label) | |
147 | { | |
148 | if (label != aa_current_raw_label()) | |
149 | aa_put_label(label); | |
150 | } | |
151 | ||
152 | /** | |
153 | * aa_begin_current_label - find the current tasks confining label and update it | |
154 | * @update: whether the current label can be updated | |
155 | * | |
156 | * Returns: up to date confining label or the ns unconfined label (NOT NULL) | |
157 | * | |
158 | * If @update is true this fn will update the tasks cred structure if the | |
159 | * label has been replaced. Not safe to call inside locks | |
160 | * else | |
161 | * just return the up to date label | |
162 | * | |
163 | * The returned reference must be put with aa_end_current_label() | |
164 | * This must NOT be used if the task cred could be updated within the | |
165 | * critical section between aa_begin_current_label() .. aa_end_current_label() | |
166 | */ | |
167 | static inline struct aa_label *aa_begin_current_label(bool update) | |
168 | { | |
169 | struct aa_label *label = aa_current_raw_label(); | |
170 | ||
171 | if (label_is_stale(label)) { | |
172 | label = aa_get_newest_label(label); | |
173 | if (update && aa_replace_current_label(label) == 0) | |
174 | /* task cred will keep the reference */ | |
175 | aa_put_label(label); | |
77b071b3 | 176 | } |
c75afcd1 | 177 | |
a3c6147c JJ |
178 | return label; |
179 | } | |
180 | ||
181 | #define NO_UPDATE false | |
182 | #define DO_UPDATE true | |
183 | ||
184 | static inline struct aa_ns *aa_get_current_ns(void) | |
185 | { | |
186 | struct aa_label *label = aa_begin_current_label(NO_UPDATE); | |
187 | struct aa_ns *ns = aa_get_ns(labels_ns(label)); | |
188 | aa_end_current_label(label); | |
189 | ||
190 | return ns; | |
c75afcd1 JJ |
191 | } |
192 | ||
7a2871b5 | 193 | /** |
a3c6147c JJ |
194 | * aa_clear_task_ctx_trans - clear transition tracking info from the ctx |
195 | * @ctx: task context to clear (NOT NULL) | |
7a2871b5 | 196 | */ |
a3c6147c | 197 | static inline void aa_clear_task_ctx_trans(struct aa_task_ctx *ctx) |
7a2871b5 | 198 | { |
a3c6147c JJ |
199 | aa_put_label(ctx->previous); |
200 | aa_put_label(ctx->onexec); | |
201 | ctx->previous = NULL; | |
202 | ctx->onexec = NULL; | |
203 | ctx->token = 0; | |
7a2871b5 JJ |
204 | } |
205 | ||
c75afcd1 | 206 | #endif /* __AA_CONTEXT_H */ |