apparmor: add the base fns() for domain labels
[linux-2.6-block.git] / security / apparmor / include / context.h
CommitLineData
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
22#include "policy.h"
2bd8dbbf 23#include "policy_ns.h"
c75afcd1 24
55a26ebf
JJ
25#define cred_ctx(X) ((X)->security)
26#define current_ctx() cred_ctx(current_cred())
214beaca 27
c75afcd1 28/**
55a26ebf 29 * struct aa_task_ctx - primary label for confined tasks
c75afcd1
JJ
30 * @profile: the current profile (NOT NULL)
31 * @exec: profile to transition to on next exec (MAYBE NULL)
32 * @previous: profile the task may return to (MAYBE NULL)
33 * @token: magic value the task must know for returning to @previous_profile
34 *
35 * Contains the task's current profile (which could change due to
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 */
55a26ebf 40struct aa_task_ctx {
c75afcd1
JJ
41 struct aa_profile *profile;
42 struct aa_profile *onexec;
43 struct aa_profile *previous;
44 u64 token;
45};
46
55a26ebf
JJ
47struct aa_task_ctx *aa_alloc_task_context(gfp_t flags);
48void aa_free_task_context(struct aa_task_ctx *ctx);
49void aa_dup_task_context(struct aa_task_ctx *new,
50 const struct aa_task_ctx *old);
c75afcd1
JJ
51int aa_replace_current_profile(struct aa_profile *profile);
52int aa_set_current_onexec(struct aa_profile *profile);
53int aa_set_current_hat(struct aa_profile *profile, u64 token);
54int aa_restore_previous_profile(u64 cookie);
3cfcc19e 55struct aa_profile *aa_get_task_profile(struct task_struct *task);
c75afcd1 56
c75afcd1
JJ
57
58/**
cf797c0e 59 * aa_cred_raw_profile - obtain cred's profiles
c75afcd1
JJ
60 * @cred: cred to obtain profiles from (NOT NULL)
61 *
62 * Returns: confining profile
63 *
64 * does NOT increment reference count
65 */
cf797c0e 66static inline struct aa_profile *aa_cred_raw_profile(const struct cred *cred)
c75afcd1 67{
55a26ebf
JJ
68 struct aa_task_ctx *ctx = cred_ctx(cred);
69
70 AA_BUG(!ctx || !ctx->profile);
71 return ctx->profile;
c75afcd1
JJ
72}
73
3cfcc19e 74/**
cf797c0e
JJ
75 * aa_get_newest_cred_profile - obtain the newest profile on a cred
76 * @cred: cred to obtain profile from (NOT NULL)
77 *
78 * Returns: newest version of confining profile
79 */
80static inline
81struct aa_profile *aa_get_newest_cred_profile(const struct cred *cred)
82{
83 return aa_get_newest_profile(aa_cred_raw_profile(cred));
84}
85
86/**
87 * __aa_task_raw_profile - retrieve another task's profile
3cfcc19e
JJ
88 * @task: task to query (NOT NULL)
89 *
90 * Returns: @task's profile without incrementing its ref count
91 *
92 * If @task != current needs to be called in RCU safe critical section
93 */
cf797c0e 94static inline struct aa_profile *__aa_task_raw_profile(struct task_struct *task)
3cfcc19e 95{
cf797c0e 96 return aa_cred_raw_profile(__task_cred(task));
3cfcc19e
JJ
97}
98
99/**
100 * __aa_task_is_confined - determine if @task has any confinement
101 * @task: task to check confinement of (NOT NULL)
102 *
103 * If @task != current needs to be called in RCU safe critical section
104 */
105static inline bool __aa_task_is_confined(struct task_struct *task)
106{
cf797c0e 107 return !unconfined(__aa_task_raw_profile(task));
3cfcc19e
JJ
108}
109
c75afcd1 110/**
cf797c0e 111 * aa_current_raw_profile - find the current tasks confining profile
c75afcd1
JJ
112 *
113 * Returns: up to date confining profile or the ns unconfined profile (NOT NULL)
114 *
115 * This fn will not update the tasks cred to the most up to date version
116 * of the profile so it is safe to call when inside of locks.
117 */
cf797c0e 118static inline struct aa_profile *aa_current_raw_profile(void)
c75afcd1 119{
cf797c0e 120 return aa_cred_raw_profile(current_cred());
c75afcd1
JJ
121}
122
123/**
cf797c0e 124 * aa_get_current_profile - get the newest version of the current tasks profile
c75afcd1 125 *
cf797c0e
JJ
126 * Returns: newest version of confining profile (NOT NULL)
127 *
128 * This fn will not update the tasks cred, so it is safe inside of locks
c75afcd1 129 *
cf797c0e 130 * The returned reference must be put with aa_put_profile()
c75afcd1 131 */
cf797c0e 132static inline struct aa_profile *aa_get_current_profile(void)
c75afcd1 133{
cf797c0e 134 struct aa_profile *p = aa_current_raw_profile();
c75afcd1 135
cf797c0e
JJ
136 if (profile_is_stale(p))
137 return aa_get_newest_profile(p);
138 return aa_get_profile(p);
139}
55a26ebf 140
cf797c0e
JJ
141#define __end_current_profile_crit_section(X) \
142 end_current_profile_crit_section(X)
143
144/**
145 * end_profile_crit_section - put a reference found with begin_current_profile..
146 * @profile: profile reference to put
147 *
148 * Should only be used with a reference obtained with
149 * begin_current_profile_crit_section and never used in situations where the
150 * task cred may be updated
151 */
152static inline void end_current_profile_crit_section(struct aa_profile *profile)
153{
154 if (profile != aa_current_raw_profile())
77b071b3 155 aa_put_profile(profile);
cf797c0e
JJ
156}
157
158/**
159 * __begin_current_profile_crit_section - current's confining profile
160 *
161 * Returns: up to date confining profile or the ns unconfined profile (NOT NULL)
162 *
163 * safe to call inside locks
164 *
165 * The returned reference must be put with __end_current_profile_crit_section()
166 * This must NOT be used if the task cred could be updated within the
167 * critical section between __begin_current_profile_crit_section() ..
168 * __end_current_profile_crit_section()
169 */
170static inline struct aa_profile *__begin_current_profile_crit_section(void)
171{
172 struct aa_profile *profile = aa_current_raw_profile();
173
174 if (profile_is_stale(profile))
175 profile = aa_get_newest_profile(profile);
176
177 return profile;
178}
179
180/**
181 * begin_current_profile_crit_section - current's profile and update if needed
182 *
183 * Returns: up to date confining profile or the ns unconfined profile (NOT NULL)
184 *
185 * Not safe to call inside locks
186 *
187 * The returned reference must be put with end_current_profile_crit_section()
188 * This must NOT be used if the task cred could be updated within the
189 * critical section between begin_current_profile_crit_section() ..
190 * end_current_profile_crit_section()
191 */
192static inline struct aa_profile *begin_current_profile_crit_section(void)
193{
194 struct aa_profile *profile = aa_current_raw_profile();
195
196 if (profile_is_stale(profile)) {
197 profile = aa_get_newest_profile(profile);
198 if (aa_replace_current_profile(profile) == 0)
199 /* task cred will keep the reference */
200 aa_put_profile(profile);
77b071b3 201 }
c75afcd1 202
cf797c0e 203 return profile;
c75afcd1
JJ
204}
205
2bd8dbbf
JJ
206static inline struct aa_ns *aa_get_current_ns(void)
207{
cf797c0e
JJ
208 struct aa_profile *profile;
209 struct aa_ns *ns;
210
211 profile = __begin_current_profile_crit_section();
212 ns = aa_get_ns(profile->ns);
213 __end_current_profile_crit_section(profile);
214
215 return ns;
2bd8dbbf
JJ
216}
217
7a2871b5 218/**
55a26ebf
JJ
219 * aa_clear_task_ctx_trans - clear transition tracking info from the ctx
220 * @ctx: task context to clear (NOT NULL)
7a2871b5 221 */
55a26ebf 222static inline void aa_clear_task_ctx_trans(struct aa_task_ctx *ctx)
7a2871b5 223{
55a26ebf
JJ
224 aa_put_profile(ctx->previous);
225 aa_put_profile(ctx->onexec);
226 ctx->previous = NULL;
227 ctx->onexec = NULL;
228 ctx->token = 0;
7a2871b5
JJ
229}
230
c75afcd1 231#endif /* __AA_CONTEXT_H */