xref: /openbmc/linux/security/apparmor/include/cred.h (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
1*b886d83cSThomas 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 
cred_label(const struct cred * cred)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 
set_cred_label(const struct cred * cred,struct aa_label * label)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  */
aa_cred_raw_label(const struct cred * cred)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  */
aa_get_newest_cred_label(const struct cred * cred)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 
66d8889d49SJohn Johansen /**
67d8889d49SJohn Johansen  * aa_current_raw_label - find the current tasks confining label
68d8889d49SJohn Johansen  *
69d8889d49SJohn Johansen  * Returns: up to date confining label or the ns unconfined label (NOT NULL)
70d8889d49SJohn Johansen  *
71d8889d49SJohn Johansen  * This fn will not update the tasks cred to the most up to date version
72d8889d49SJohn Johansen  * of the label so it is safe to call when inside of locks.
73d8889d49SJohn Johansen  */
aa_current_raw_label(void)74d8889d49SJohn Johansen static inline struct aa_label *aa_current_raw_label(void)
75d8889d49SJohn Johansen {
76d8889d49SJohn Johansen 	return aa_cred_raw_label(current_cred());
77d8889d49SJohn Johansen }
78d8889d49SJohn Johansen 
79d8889d49SJohn Johansen /**
80d8889d49SJohn Johansen  * aa_get_current_label - get the newest version of the current tasks label
81d8889d49SJohn Johansen  *
82d8889d49SJohn Johansen  * Returns: newest version of confining label (NOT NULL)
83d8889d49SJohn Johansen  *
84d8889d49SJohn Johansen  * This fn will not update the tasks cred, so it is safe inside of locks
85d8889d49SJohn Johansen  *
86d8889d49SJohn Johansen  * The returned reference must be put with aa_put_label()
87d8889d49SJohn Johansen  */
aa_get_current_label(void)88d8889d49SJohn Johansen static inline struct aa_label *aa_get_current_label(void)
89d8889d49SJohn Johansen {
90d8889d49SJohn Johansen 	struct aa_label *l = aa_current_raw_label();
91d8889d49SJohn Johansen 
92d8889d49SJohn Johansen 	if (label_is_stale(l))
93d8889d49SJohn Johansen 		return aa_get_newest_label(l);
94d8889d49SJohn Johansen 	return aa_get_label(l);
95d8889d49SJohn Johansen }
96d8889d49SJohn Johansen 
97d8889d49SJohn Johansen #define __end_current_label_crit_section(X) end_current_label_crit_section(X)
98d8889d49SJohn Johansen 
99d8889d49SJohn Johansen /**
100d8889d49SJohn Johansen  * end_label_crit_section - put a reference found with begin_current_label..
101d8889d49SJohn Johansen  * @label: label reference to put
102d8889d49SJohn Johansen  *
103d8889d49SJohn Johansen  * Should only be used with a reference obtained with
104d8889d49SJohn Johansen  * begin_current_label_crit_section and never used in situations where the
105d8889d49SJohn Johansen  * task cred may be updated
106d8889d49SJohn Johansen  */
end_current_label_crit_section(struct aa_label * label)107d8889d49SJohn Johansen static inline void end_current_label_crit_section(struct aa_label *label)
108d8889d49SJohn Johansen {
109d8889d49SJohn Johansen 	if (label != aa_current_raw_label())
110d8889d49SJohn Johansen 		aa_put_label(label);
111d8889d49SJohn Johansen }
112d8889d49SJohn Johansen 
113d8889d49SJohn Johansen /**
114d8889d49SJohn Johansen  * __begin_current_label_crit_section - current's confining label
115d8889d49SJohn Johansen  *
116d8889d49SJohn Johansen  * Returns: up to date confining label or the ns unconfined label (NOT NULL)
117d8889d49SJohn Johansen  *
118d8889d49SJohn Johansen  * safe to call inside locks
119d8889d49SJohn Johansen  *
120d8889d49SJohn Johansen  * The returned reference must be put with __end_current_label_crit_section()
121d8889d49SJohn Johansen  * This must NOT be used if the task cred could be updated within the
122d8889d49SJohn Johansen  * critical section between __begin_current_label_crit_section() ..
123d8889d49SJohn Johansen  * __end_current_label_crit_section()
124d8889d49SJohn Johansen  */
__begin_current_label_crit_section(void)125d8889d49SJohn Johansen static inline struct aa_label *__begin_current_label_crit_section(void)
126d8889d49SJohn Johansen {
127d8889d49SJohn Johansen 	struct aa_label *label = aa_current_raw_label();
128d8889d49SJohn Johansen 
129d8889d49SJohn Johansen 	if (label_is_stale(label))
130d8889d49SJohn Johansen 		label = aa_get_newest_label(label);
131d8889d49SJohn Johansen 
132d8889d49SJohn Johansen 	return label;
133d8889d49SJohn Johansen }
134d8889d49SJohn Johansen 
135d8889d49SJohn Johansen /**
136d8889d49SJohn Johansen  * begin_current_label_crit_section - current's confining label and update it
137d8889d49SJohn Johansen  *
138d8889d49SJohn Johansen  * Returns: up to date confining label or the ns unconfined label (NOT NULL)
139d8889d49SJohn Johansen  *
140d8889d49SJohn Johansen  * Not safe to call inside locks
141d8889d49SJohn Johansen  *
142d8889d49SJohn Johansen  * The returned reference must be put with end_current_label_crit_section()
143d8889d49SJohn Johansen  * This must NOT be used if the task cred could be updated within the
144d8889d49SJohn Johansen  * critical section between begin_current_label_crit_section() ..
145d8889d49SJohn Johansen  * end_current_label_crit_section()
146d8889d49SJohn Johansen  */
begin_current_label_crit_section(void)147d8889d49SJohn Johansen static inline struct aa_label *begin_current_label_crit_section(void)
148d8889d49SJohn Johansen {
149d8889d49SJohn Johansen 	struct aa_label *label = aa_current_raw_label();
150d8889d49SJohn Johansen 
1511f8266ffSJann Horn 	might_sleep();
1521f8266ffSJann Horn 
153d8889d49SJohn Johansen 	if (label_is_stale(label)) {
154d8889d49SJohn Johansen 		label = aa_get_newest_label(label);
155d8889d49SJohn Johansen 		if (aa_replace_current_label(label) == 0)
156d8889d49SJohn Johansen 			/* task cred will keep the reference */
157d8889d49SJohn Johansen 			aa_put_label(label);
158d8889d49SJohn Johansen 	}
159d8889d49SJohn Johansen 
160d8889d49SJohn Johansen 	return label;
161d8889d49SJohn Johansen }
162d8889d49SJohn Johansen 
aa_get_current_ns(void)163d8889d49SJohn Johansen static inline struct aa_ns *aa_get_current_ns(void)
164d8889d49SJohn Johansen {
165d8889d49SJohn Johansen 	struct aa_label *label;
166d8889d49SJohn Johansen 	struct aa_ns *ns;
167d8889d49SJohn Johansen 
168d8889d49SJohn Johansen 	label  = __begin_current_label_crit_section();
169d8889d49SJohn Johansen 	ns = aa_get_ns(labels_ns(label));
170d8889d49SJohn Johansen 	__end_current_label_crit_section(label);
171d8889d49SJohn Johansen 
172d8889d49SJohn Johansen 	return ns;
173d8889d49SJohn Johansen }
174d8889d49SJohn Johansen 
175d8889d49SJohn Johansen #endif /* __AA_CONTEXT_H */
176