xref: /linux/security/apparmor/include/cred.h (revision 69b5a44a95bb86f3ad8a50bf2e354057ec450082)
1d8889d49SJohn Johansen /*
2d8889d49SJohn Johansen  * AppArmor security module
3d8889d49SJohn Johansen  *
4d8889d49SJohn Johansen  * This file contains AppArmor contexts used to associate "labels" to objects.
5d8889d49SJohn Johansen  *
6d8889d49SJohn Johansen  * Copyright (C) 1998-2008 Novell/SUSE
7d8889d49SJohn Johansen  * Copyright 2009-2010 Canonical Ltd.
8d8889d49SJohn Johansen  *
9d8889d49SJohn Johansen  * This program is free software; you can redistribute it and/or
10d8889d49SJohn Johansen  * modify it under the terms of the GNU General Public License as
11d8889d49SJohn Johansen  * published by the Free Software Foundation, version 2 of the
12d8889d49SJohn Johansen  * License.
13d8889d49SJohn Johansen  */
14d8889d49SJohn Johansen 
15d8889d49SJohn Johansen #ifndef __AA_CONTEXT_H
16d8889d49SJohn Johansen #define __AA_CONTEXT_H
17d8889d49SJohn Johansen 
18d8889d49SJohn Johansen #include <linux/cred.h>
19d8889d49SJohn Johansen #include <linux/slab.h>
20d8889d49SJohn Johansen #include <linux/sched.h>
21d8889d49SJohn Johansen 
22d8889d49SJohn Johansen #include "label.h"
23d8889d49SJohn Johansen #include "policy_ns.h"
24d8889d49SJohn Johansen #include "task.h"
25d8889d49SJohn Johansen 
26*69b5a44aSCasey Schaufler static inline struct aa_label *cred_label(const struct cred *cred)
27*69b5a44aSCasey Schaufler {
28*69b5a44aSCasey Schaufler 	struct aa_label **blob = cred->security;
29d8889d49SJohn Johansen 
30*69b5a44aSCasey Schaufler 	AA_BUG(!blob);
31*69b5a44aSCasey Schaufler 	return *blob;
32*69b5a44aSCasey Schaufler }
33*69b5a44aSCasey Schaufler 
34*69b5a44aSCasey Schaufler static inline void set_cred_label(const struct cred *cred,
35*69b5a44aSCasey Schaufler 				  struct aa_label *label)
36*69b5a44aSCasey Schaufler {
37*69b5a44aSCasey Schaufler 	struct aa_label **blob = cred->security;
38*69b5a44aSCasey Schaufler 
39*69b5a44aSCasey Schaufler 	AA_BUG(!blob);
40*69b5a44aSCasey Schaufler 	*blob = label;
41*69b5a44aSCasey Schaufler }
42d8889d49SJohn Johansen 
43d8889d49SJohn Johansen /**
44d8889d49SJohn Johansen  * aa_cred_raw_label - obtain cred's label
45d8889d49SJohn Johansen  * @cred: cred to obtain label from  (NOT NULL)
46d8889d49SJohn Johansen  *
47d8889d49SJohn Johansen  * Returns: confining label
48d8889d49SJohn Johansen  *
49d8889d49SJohn Johansen  * does NOT increment reference count
50d8889d49SJohn Johansen  */
51d8889d49SJohn Johansen static inline struct aa_label *aa_cred_raw_label(const struct cred *cred)
52d8889d49SJohn Johansen {
53d8889d49SJohn Johansen 	struct aa_label *label = cred_label(cred);
54d8889d49SJohn Johansen 
55d8889d49SJohn Johansen 	AA_BUG(!label);
56d8889d49SJohn Johansen 	return label;
57d8889d49SJohn Johansen }
58d8889d49SJohn Johansen 
59d8889d49SJohn Johansen /**
60d8889d49SJohn Johansen  * aa_get_newest_cred_label - obtain the newest label on a cred
61d8889d49SJohn Johansen  * @cred: cred to obtain label from (NOT NULL)
62d8889d49SJohn Johansen  *
63d8889d49SJohn Johansen  * Returns: newest version of confining label
64d8889d49SJohn Johansen  */
65d8889d49SJohn Johansen static inline struct aa_label *aa_get_newest_cred_label(const struct cred *cred)
66d8889d49SJohn Johansen {
67d8889d49SJohn Johansen 	return aa_get_newest_label(aa_cred_raw_label(cred));
68d8889d49SJohn Johansen }
69d8889d49SJohn Johansen 
70d8889d49SJohn Johansen /**
71d8889d49SJohn Johansen  * __aa_task_raw_label - retrieve another task's label
72d8889d49SJohn Johansen  * @task: task to query  (NOT NULL)
73d8889d49SJohn Johansen  *
74d8889d49SJohn Johansen  * Returns: @task's label without incrementing its ref count
75d8889d49SJohn Johansen  *
76d8889d49SJohn Johansen  * If @task != current needs to be called in RCU safe critical section
77d8889d49SJohn Johansen  */
78d8889d49SJohn Johansen static inline struct aa_label *__aa_task_raw_label(struct task_struct *task)
79d8889d49SJohn Johansen {
80d8889d49SJohn Johansen 	return aa_cred_raw_label(__task_cred(task));
81d8889d49SJohn Johansen }
82d8889d49SJohn Johansen 
83d8889d49SJohn Johansen /**
84d8889d49SJohn Johansen  * aa_current_raw_label - find the current tasks confining label
85d8889d49SJohn Johansen  *
86d8889d49SJohn Johansen  * Returns: up to date confining label or the ns unconfined label (NOT NULL)
87d8889d49SJohn Johansen  *
88d8889d49SJohn Johansen  * This fn will not update the tasks cred to the most up to date version
89d8889d49SJohn Johansen  * of the label so it is safe to call when inside of locks.
90d8889d49SJohn Johansen  */
91d8889d49SJohn Johansen static inline struct aa_label *aa_current_raw_label(void)
92d8889d49SJohn Johansen {
93d8889d49SJohn Johansen 	return aa_cred_raw_label(current_cred());
94d8889d49SJohn Johansen }
95d8889d49SJohn Johansen 
96d8889d49SJohn Johansen /**
97d8889d49SJohn Johansen  * aa_get_current_label - get the newest version of the current tasks label
98d8889d49SJohn Johansen  *
99d8889d49SJohn Johansen  * Returns: newest version of confining label (NOT NULL)
100d8889d49SJohn Johansen  *
101d8889d49SJohn Johansen  * This fn will not update the tasks cred, so it is safe inside of locks
102d8889d49SJohn Johansen  *
103d8889d49SJohn Johansen  * The returned reference must be put with aa_put_label()
104d8889d49SJohn Johansen  */
105d8889d49SJohn Johansen static inline struct aa_label *aa_get_current_label(void)
106d8889d49SJohn Johansen {
107d8889d49SJohn Johansen 	struct aa_label *l = aa_current_raw_label();
108d8889d49SJohn Johansen 
109d8889d49SJohn Johansen 	if (label_is_stale(l))
110d8889d49SJohn Johansen 		return aa_get_newest_label(l);
111d8889d49SJohn Johansen 	return aa_get_label(l);
112d8889d49SJohn Johansen }
113d8889d49SJohn Johansen 
114d8889d49SJohn Johansen #define __end_current_label_crit_section(X) end_current_label_crit_section(X)
115d8889d49SJohn Johansen 
116d8889d49SJohn Johansen /**
117d8889d49SJohn Johansen  * end_label_crit_section - put a reference found with begin_current_label..
118d8889d49SJohn Johansen  * @label: label reference to put
119d8889d49SJohn Johansen  *
120d8889d49SJohn Johansen  * Should only be used with a reference obtained with
121d8889d49SJohn Johansen  * begin_current_label_crit_section and never used in situations where the
122d8889d49SJohn Johansen  * task cred may be updated
123d8889d49SJohn Johansen  */
124d8889d49SJohn Johansen static inline void end_current_label_crit_section(struct aa_label *label)
125d8889d49SJohn Johansen {
126d8889d49SJohn Johansen 	if (label != aa_current_raw_label())
127d8889d49SJohn Johansen 		aa_put_label(label);
128d8889d49SJohn Johansen }
129d8889d49SJohn Johansen 
130d8889d49SJohn Johansen /**
131d8889d49SJohn Johansen  * __begin_current_label_crit_section - current's confining label
132d8889d49SJohn Johansen  *
133d8889d49SJohn Johansen  * Returns: up to date confining label or the ns unconfined label (NOT NULL)
134d8889d49SJohn Johansen  *
135d8889d49SJohn Johansen  * safe to call inside locks
136d8889d49SJohn Johansen  *
137d8889d49SJohn Johansen  * The returned reference must be put with __end_current_label_crit_section()
138d8889d49SJohn Johansen  * This must NOT be used if the task cred could be updated within the
139d8889d49SJohn Johansen  * critical section between __begin_current_label_crit_section() ..
140d8889d49SJohn Johansen  * __end_current_label_crit_section()
141d8889d49SJohn Johansen  */
142d8889d49SJohn Johansen static inline struct aa_label *__begin_current_label_crit_section(void)
143d8889d49SJohn Johansen {
144d8889d49SJohn Johansen 	struct aa_label *label = aa_current_raw_label();
145d8889d49SJohn Johansen 
146d8889d49SJohn Johansen 	if (label_is_stale(label))
147d8889d49SJohn Johansen 		label = aa_get_newest_label(label);
148d8889d49SJohn Johansen 
149d8889d49SJohn Johansen 	return label;
150d8889d49SJohn Johansen }
151d8889d49SJohn Johansen 
152d8889d49SJohn Johansen /**
153d8889d49SJohn Johansen  * begin_current_label_crit_section - current's confining label and update it
154d8889d49SJohn Johansen  *
155d8889d49SJohn Johansen  * Returns: up to date confining label or the ns unconfined label (NOT NULL)
156d8889d49SJohn Johansen  *
157d8889d49SJohn Johansen  * Not safe to call inside locks
158d8889d49SJohn Johansen  *
159d8889d49SJohn Johansen  * The returned reference must be put with end_current_label_crit_section()
160d8889d49SJohn Johansen  * This must NOT be used if the task cred could be updated within the
161d8889d49SJohn Johansen  * critical section between begin_current_label_crit_section() ..
162d8889d49SJohn Johansen  * end_current_label_crit_section()
163d8889d49SJohn Johansen  */
164d8889d49SJohn Johansen static inline struct aa_label *begin_current_label_crit_section(void)
165d8889d49SJohn Johansen {
166d8889d49SJohn Johansen 	struct aa_label *label = aa_current_raw_label();
167d8889d49SJohn Johansen 
1681f8266ffSJann Horn 	might_sleep();
1691f8266ffSJann Horn 
170d8889d49SJohn Johansen 	if (label_is_stale(label)) {
171d8889d49SJohn Johansen 		label = aa_get_newest_label(label);
172d8889d49SJohn Johansen 		if (aa_replace_current_label(label) == 0)
173d8889d49SJohn Johansen 			/* task cred will keep the reference */
174d8889d49SJohn Johansen 			aa_put_label(label);
175d8889d49SJohn Johansen 	}
176d8889d49SJohn Johansen 
177d8889d49SJohn Johansen 	return label;
178d8889d49SJohn Johansen }
179d8889d49SJohn Johansen 
180d8889d49SJohn Johansen static inline struct aa_ns *aa_get_current_ns(void)
181d8889d49SJohn Johansen {
182d8889d49SJohn Johansen 	struct aa_label *label;
183d8889d49SJohn Johansen 	struct aa_ns *ns;
184d8889d49SJohn Johansen 
185d8889d49SJohn Johansen 	label  = __begin_current_label_crit_section();
186d8889d49SJohn Johansen 	ns = aa_get_ns(labels_ns(label));
187d8889d49SJohn Johansen 	__end_current_label_crit_section(label);
188d8889d49SJohn Johansen 
189d8889d49SJohn Johansen 	return ns;
190d8889d49SJohn Johansen }
191d8889d49SJohn Johansen 
192d8889d49SJohn Johansen #endif /* __AA_CONTEXT_H */
193