xref: /linux/security/apparmor/include/cred.h (revision f4fee216df7d28b87d1c9cc60bcebfecb51c1a05)
1b886d83cSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
2d8889d49SJohn Johansen /*
3d8889d49SJohn Johansen  * AppArmor security module
4d8889d49SJohn Johansen  *
5d8889d49SJohn Johansen  * This file contains AppArmor contexts used to associate "labels" to objects.
6d8889d49SJohn Johansen  *
7d8889d49SJohn Johansen  * Copyright (C) 1998-2008 Novell/SUSE
8d8889d49SJohn Johansen  * Copyright 2009-2010 Canonical Ltd.
9d8889d49SJohn Johansen  */
10d8889d49SJohn Johansen 
11d8889d49SJohn Johansen #ifndef __AA_CONTEXT_H
12d8889d49SJohn Johansen #define __AA_CONTEXT_H
13d8889d49SJohn Johansen 
14d8889d49SJohn Johansen #include <linux/cred.h>
15d8889d49SJohn Johansen #include <linux/slab.h>
16d8889d49SJohn Johansen #include <linux/sched.h>
17d8889d49SJohn Johansen 
18d8889d49SJohn Johansen #include "label.h"
19d8889d49SJohn Johansen #include "policy_ns.h"
20d8889d49SJohn Johansen #include "task.h"
21d8889d49SJohn Johansen 
2269b5a44aSCasey Schaufler static inline struct aa_label *cred_label(const struct cred *cred)
2369b5a44aSCasey Schaufler {
24bbd3662aSCasey Schaufler 	struct aa_label **blob = cred->security + apparmor_blob_sizes.lbs_cred;
25d8889d49SJohn Johansen 
2669b5a44aSCasey Schaufler 	AA_BUG(!blob);
2769b5a44aSCasey Schaufler 	return *blob;
2869b5a44aSCasey Schaufler }
2969b5a44aSCasey Schaufler 
3069b5a44aSCasey Schaufler static inline void set_cred_label(const struct cred *cred,
3169b5a44aSCasey Schaufler 				  struct aa_label *label)
3269b5a44aSCasey Schaufler {
33bbd3662aSCasey Schaufler 	struct aa_label **blob = cred->security + apparmor_blob_sizes.lbs_cred;
3469b5a44aSCasey Schaufler 
3569b5a44aSCasey Schaufler 	AA_BUG(!blob);
3669b5a44aSCasey Schaufler 	*blob = label;
3769b5a44aSCasey Schaufler }
38d8889d49SJohn Johansen 
39d8889d49SJohn Johansen /**
40d8889d49SJohn Johansen  * aa_cred_raw_label - obtain cred's label
41d8889d49SJohn Johansen  * @cred: cred to obtain label from  (NOT NULL)
42d8889d49SJohn Johansen  *
43d8889d49SJohn Johansen  * Returns: confining label
44d8889d49SJohn Johansen  *
45d8889d49SJohn Johansen  * does NOT increment reference count
46d8889d49SJohn Johansen  */
47d8889d49SJohn Johansen static inline struct aa_label *aa_cred_raw_label(const struct cred *cred)
48d8889d49SJohn Johansen {
49d8889d49SJohn Johansen 	struct aa_label *label = cred_label(cred);
50d8889d49SJohn Johansen 
51d8889d49SJohn Johansen 	AA_BUG(!label);
52d8889d49SJohn Johansen 	return label;
53d8889d49SJohn Johansen }
54d8889d49SJohn Johansen 
55d8889d49SJohn Johansen /**
56d8889d49SJohn Johansen  * aa_get_newest_cred_label - obtain the newest label on a cred
57d8889d49SJohn Johansen  * @cred: cred to obtain label from (NOT NULL)
58d8889d49SJohn Johansen  *
59d8889d49SJohn Johansen  * Returns: newest version of confining label
60d8889d49SJohn Johansen  */
61d8889d49SJohn Johansen static inline struct aa_label *aa_get_newest_cred_label(const struct cred *cred)
62d8889d49SJohn Johansen {
63d8889d49SJohn Johansen 	return aa_get_newest_label(aa_cred_raw_label(cred));
64d8889d49SJohn Johansen }
65d8889d49SJohn Johansen 
66*f4fee216SMateusz Guzik static inline struct aa_label *aa_get_newest_cred_label_condref(const struct cred *cred,
67*f4fee216SMateusz Guzik 								bool *needput)
68*f4fee216SMateusz Guzik {
69*f4fee216SMateusz Guzik 	struct aa_label *l = aa_cred_raw_label(cred);
70*f4fee216SMateusz Guzik 
71*f4fee216SMateusz Guzik 	if (unlikely(label_is_stale(l))) {
72*f4fee216SMateusz Guzik 		*needput = true;
73*f4fee216SMateusz Guzik 		return aa_get_newest_label(l);
74*f4fee216SMateusz Guzik 	}
75*f4fee216SMateusz Guzik 
76*f4fee216SMateusz Guzik 	*needput = false;
77*f4fee216SMateusz Guzik 	return l;
78*f4fee216SMateusz Guzik }
79*f4fee216SMateusz Guzik 
80*f4fee216SMateusz Guzik static inline void aa_put_label_condref(struct aa_label *l, bool needput)
81*f4fee216SMateusz Guzik {
82*f4fee216SMateusz Guzik 	if (unlikely(needput))
83*f4fee216SMateusz Guzik 		aa_put_label(l);
84*f4fee216SMateusz Guzik }
85*f4fee216SMateusz Guzik 
86d8889d49SJohn Johansen /**
87d8889d49SJohn Johansen  * aa_current_raw_label - find the current tasks confining label
88d8889d49SJohn Johansen  *
89d8889d49SJohn Johansen  * Returns: up to date confining label or the ns unconfined label (NOT NULL)
90d8889d49SJohn Johansen  *
91d8889d49SJohn Johansen  * This fn will not update the tasks cred to the most up to date version
92d8889d49SJohn Johansen  * of the label so it is safe to call when inside of locks.
93d8889d49SJohn Johansen  */
94d8889d49SJohn Johansen static inline struct aa_label *aa_current_raw_label(void)
95d8889d49SJohn Johansen {
96d8889d49SJohn Johansen 	return aa_cred_raw_label(current_cred());
97d8889d49SJohn Johansen }
98d8889d49SJohn Johansen 
99d8889d49SJohn Johansen /**
100d8889d49SJohn Johansen  * aa_get_current_label - get the newest version of the current tasks label
101d8889d49SJohn Johansen  *
102d8889d49SJohn Johansen  * Returns: newest version of confining label (NOT NULL)
103d8889d49SJohn Johansen  *
104d8889d49SJohn Johansen  * This fn will not update the tasks cred, so it is safe inside of locks
105d8889d49SJohn Johansen  *
106d8889d49SJohn Johansen  * The returned reference must be put with aa_put_label()
107d8889d49SJohn Johansen  */
108d8889d49SJohn Johansen static inline struct aa_label *aa_get_current_label(void)
109d8889d49SJohn Johansen {
110d8889d49SJohn Johansen 	struct aa_label *l = aa_current_raw_label();
111d8889d49SJohn Johansen 
112d8889d49SJohn Johansen 	if (label_is_stale(l))
113d8889d49SJohn Johansen 		return aa_get_newest_label(l);
114d8889d49SJohn Johansen 	return aa_get_label(l);
115d8889d49SJohn Johansen }
116d8889d49SJohn Johansen 
117d8889d49SJohn Johansen #define __end_current_label_crit_section(X) end_current_label_crit_section(X)
118d8889d49SJohn Johansen 
119d8889d49SJohn Johansen /**
120d8889d49SJohn Johansen  * end_label_crit_section - put a reference found with begin_current_label..
121d8889d49SJohn Johansen  * @label: label reference to put
122d8889d49SJohn Johansen  *
123d8889d49SJohn Johansen  * Should only be used with a reference obtained with
124d8889d49SJohn Johansen  * begin_current_label_crit_section and never used in situations where the
125d8889d49SJohn Johansen  * task cred may be updated
126d8889d49SJohn Johansen  */
127d8889d49SJohn Johansen static inline void end_current_label_crit_section(struct aa_label *label)
128d8889d49SJohn Johansen {
129d8889d49SJohn Johansen 	if (label != aa_current_raw_label())
130d8889d49SJohn Johansen 		aa_put_label(label);
131d8889d49SJohn Johansen }
132d8889d49SJohn Johansen 
133d8889d49SJohn Johansen /**
134d8889d49SJohn Johansen  * __begin_current_label_crit_section - current's confining label
135d8889d49SJohn Johansen  *
136d8889d49SJohn Johansen  * Returns: up to date confining label or the ns unconfined label (NOT NULL)
137d8889d49SJohn Johansen  *
138d8889d49SJohn Johansen  * safe to call inside locks
139d8889d49SJohn Johansen  *
140d8889d49SJohn Johansen  * The returned reference must be put with __end_current_label_crit_section()
141d8889d49SJohn Johansen  * This must NOT be used if the task cred could be updated within the
142d8889d49SJohn Johansen  * critical section between __begin_current_label_crit_section() ..
143d8889d49SJohn Johansen  * __end_current_label_crit_section()
144d8889d49SJohn Johansen  */
145d8889d49SJohn Johansen static inline struct aa_label *__begin_current_label_crit_section(void)
146d8889d49SJohn Johansen {
147d8889d49SJohn Johansen 	struct aa_label *label = aa_current_raw_label();
148d8889d49SJohn Johansen 
149d8889d49SJohn Johansen 	if (label_is_stale(label))
150d8889d49SJohn Johansen 		label = aa_get_newest_label(label);
151d8889d49SJohn Johansen 
152d8889d49SJohn Johansen 	return label;
153d8889d49SJohn Johansen }
154d8889d49SJohn Johansen 
155d8889d49SJohn Johansen /**
156d8889d49SJohn Johansen  * begin_current_label_crit_section - current's confining label and update it
157d8889d49SJohn Johansen  *
158d8889d49SJohn Johansen  * Returns: up to date confining label or the ns unconfined label (NOT NULL)
159d8889d49SJohn Johansen  *
160d8889d49SJohn Johansen  * Not safe to call inside locks
161d8889d49SJohn Johansen  *
162d8889d49SJohn Johansen  * The returned reference must be put with end_current_label_crit_section()
163d8889d49SJohn Johansen  * This must NOT be used if the task cred could be updated within the
164d8889d49SJohn Johansen  * critical section between begin_current_label_crit_section() ..
165d8889d49SJohn Johansen  * end_current_label_crit_section()
166d8889d49SJohn Johansen  */
167d8889d49SJohn Johansen static inline struct aa_label *begin_current_label_crit_section(void)
168d8889d49SJohn Johansen {
169d8889d49SJohn Johansen 	struct aa_label *label = aa_current_raw_label();
170d8889d49SJohn Johansen 
1711f8266ffSJann Horn 	might_sleep();
1721f8266ffSJann Horn 
173d8889d49SJohn Johansen 	if (label_is_stale(label)) {
174d8889d49SJohn Johansen 		label = aa_get_newest_label(label);
175d8889d49SJohn Johansen 		if (aa_replace_current_label(label) == 0)
176d8889d49SJohn Johansen 			/* task cred will keep the reference */
177d8889d49SJohn Johansen 			aa_put_label(label);
178d8889d49SJohn Johansen 	}
179d8889d49SJohn Johansen 
180d8889d49SJohn Johansen 	return label;
181d8889d49SJohn Johansen }
182d8889d49SJohn Johansen 
183d8889d49SJohn Johansen static inline struct aa_ns *aa_get_current_ns(void)
184d8889d49SJohn Johansen {
185d8889d49SJohn Johansen 	struct aa_label *label;
186d8889d49SJohn Johansen 	struct aa_ns *ns;
187d8889d49SJohn Johansen 
188d8889d49SJohn Johansen 	label  = __begin_current_label_crit_section();
189d8889d49SJohn Johansen 	ns = aa_get_ns(labels_ns(label));
190d8889d49SJohn Johansen 	__end_current_label_crit_section(label);
191d8889d49SJohn Johansen 
192d8889d49SJohn Johansen 	return ns;
193d8889d49SJohn Johansen }
194d8889d49SJohn Johansen 
195d8889d49SJohn Johansen #endif /* __AA_CONTEXT_H */
196