xref: /linux/security/apparmor/include/cred.h (revision 1f8266ff58840d698a1e96d2274189de1bdf7969)
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 
26d8889d49SJohn Johansen #define cred_label(X) ((X)->security)
27d8889d49SJohn Johansen 
28d8889d49SJohn Johansen 
29d8889d49SJohn Johansen /**
30d8889d49SJohn Johansen  * aa_cred_raw_label - obtain cred's label
31d8889d49SJohn Johansen  * @cred: cred to obtain label from  (NOT NULL)
32d8889d49SJohn Johansen  *
33d8889d49SJohn Johansen  * Returns: confining label
34d8889d49SJohn Johansen  *
35d8889d49SJohn Johansen  * does NOT increment reference count
36d8889d49SJohn Johansen  */
37d8889d49SJohn Johansen static inline struct aa_label *aa_cred_raw_label(const struct cred *cred)
38d8889d49SJohn Johansen {
39d8889d49SJohn Johansen 	struct aa_label *label = cred_label(cred);
40d8889d49SJohn Johansen 
41d8889d49SJohn Johansen 	AA_BUG(!label);
42d8889d49SJohn Johansen 	return label;
43d8889d49SJohn Johansen }
44d8889d49SJohn Johansen 
45d8889d49SJohn Johansen /**
46d8889d49SJohn Johansen  * aa_get_newest_cred_label - obtain the newest label on a cred
47d8889d49SJohn Johansen  * @cred: cred to obtain label from (NOT NULL)
48d8889d49SJohn Johansen  *
49d8889d49SJohn Johansen  * Returns: newest version of confining label
50d8889d49SJohn Johansen  */
51d8889d49SJohn Johansen static inline struct aa_label *aa_get_newest_cred_label(const struct cred *cred)
52d8889d49SJohn Johansen {
53d8889d49SJohn Johansen 	return aa_get_newest_label(aa_cred_raw_label(cred));
54d8889d49SJohn Johansen }
55d8889d49SJohn Johansen 
56d8889d49SJohn Johansen /**
57d8889d49SJohn Johansen  * __aa_task_raw_label - retrieve another task's label
58d8889d49SJohn Johansen  * @task: task to query  (NOT NULL)
59d8889d49SJohn Johansen  *
60d8889d49SJohn Johansen  * Returns: @task's label without incrementing its ref count
61d8889d49SJohn Johansen  *
62d8889d49SJohn Johansen  * If @task != current needs to be called in RCU safe critical section
63d8889d49SJohn Johansen  */
64d8889d49SJohn Johansen static inline struct aa_label *__aa_task_raw_label(struct task_struct *task)
65d8889d49SJohn Johansen {
66d8889d49SJohn Johansen 	return aa_cred_raw_label(__task_cred(task));
67d8889d49SJohn Johansen }
68d8889d49SJohn Johansen 
69d8889d49SJohn Johansen /**
70d8889d49SJohn Johansen  * aa_current_raw_label - find the current tasks confining label
71d8889d49SJohn Johansen  *
72d8889d49SJohn Johansen  * Returns: up to date confining label or the ns unconfined label (NOT NULL)
73d8889d49SJohn Johansen  *
74d8889d49SJohn Johansen  * This fn will not update the tasks cred to the most up to date version
75d8889d49SJohn Johansen  * of the label so it is safe to call when inside of locks.
76d8889d49SJohn Johansen  */
77d8889d49SJohn Johansen static inline struct aa_label *aa_current_raw_label(void)
78d8889d49SJohn Johansen {
79d8889d49SJohn Johansen 	return aa_cred_raw_label(current_cred());
80d8889d49SJohn Johansen }
81d8889d49SJohn Johansen 
82d8889d49SJohn Johansen /**
83d8889d49SJohn Johansen  * aa_get_current_label - get the newest version of the current tasks label
84d8889d49SJohn Johansen  *
85d8889d49SJohn Johansen  * Returns: newest version of confining label (NOT NULL)
86d8889d49SJohn Johansen  *
87d8889d49SJohn Johansen  * This fn will not update the tasks cred, so it is safe inside of locks
88d8889d49SJohn Johansen  *
89d8889d49SJohn Johansen  * The returned reference must be put with aa_put_label()
90d8889d49SJohn Johansen  */
91d8889d49SJohn Johansen static inline struct aa_label *aa_get_current_label(void)
92d8889d49SJohn Johansen {
93d8889d49SJohn Johansen 	struct aa_label *l = aa_current_raw_label();
94d8889d49SJohn Johansen 
95d8889d49SJohn Johansen 	if (label_is_stale(l))
96d8889d49SJohn Johansen 		return aa_get_newest_label(l);
97d8889d49SJohn Johansen 	return aa_get_label(l);
98d8889d49SJohn Johansen }
99d8889d49SJohn Johansen 
100d8889d49SJohn Johansen #define __end_current_label_crit_section(X) end_current_label_crit_section(X)
101d8889d49SJohn Johansen 
102d8889d49SJohn Johansen /**
103d8889d49SJohn Johansen  * end_label_crit_section - put a reference found with begin_current_label..
104d8889d49SJohn Johansen  * @label: label reference to put
105d8889d49SJohn Johansen  *
106d8889d49SJohn Johansen  * Should only be used with a reference obtained with
107d8889d49SJohn Johansen  * begin_current_label_crit_section and never used in situations where the
108d8889d49SJohn Johansen  * task cred may be updated
109d8889d49SJohn Johansen  */
110d8889d49SJohn Johansen static inline void end_current_label_crit_section(struct aa_label *label)
111d8889d49SJohn Johansen {
112d8889d49SJohn Johansen 	if (label != aa_current_raw_label())
113d8889d49SJohn Johansen 		aa_put_label(label);
114d8889d49SJohn Johansen }
115d8889d49SJohn Johansen 
116d8889d49SJohn Johansen /**
117d8889d49SJohn Johansen  * __begin_current_label_crit_section - current's confining label
118d8889d49SJohn Johansen  *
119d8889d49SJohn Johansen  * Returns: up to date confining label or the ns unconfined label (NOT NULL)
120d8889d49SJohn Johansen  *
121d8889d49SJohn Johansen  * safe to call inside locks
122d8889d49SJohn Johansen  *
123d8889d49SJohn Johansen  * The returned reference must be put with __end_current_label_crit_section()
124d8889d49SJohn Johansen  * This must NOT be used if the task cred could be updated within the
125d8889d49SJohn Johansen  * critical section between __begin_current_label_crit_section() ..
126d8889d49SJohn Johansen  * __end_current_label_crit_section()
127d8889d49SJohn Johansen  */
128d8889d49SJohn Johansen static inline struct aa_label *__begin_current_label_crit_section(void)
129d8889d49SJohn Johansen {
130d8889d49SJohn Johansen 	struct aa_label *label = aa_current_raw_label();
131d8889d49SJohn Johansen 
132d8889d49SJohn Johansen 	if (label_is_stale(label))
133d8889d49SJohn Johansen 		label = aa_get_newest_label(label);
134d8889d49SJohn Johansen 
135d8889d49SJohn Johansen 	return label;
136d8889d49SJohn Johansen }
137d8889d49SJohn Johansen 
138d8889d49SJohn Johansen /**
139d8889d49SJohn Johansen  * begin_current_label_crit_section - current's confining label and update it
140d8889d49SJohn Johansen  *
141d8889d49SJohn Johansen  * Returns: up to date confining label or the ns unconfined label (NOT NULL)
142d8889d49SJohn Johansen  *
143d8889d49SJohn Johansen  * Not safe to call inside locks
144d8889d49SJohn Johansen  *
145d8889d49SJohn Johansen  * The returned reference must be put with end_current_label_crit_section()
146d8889d49SJohn Johansen  * This must NOT be used if the task cred could be updated within the
147d8889d49SJohn Johansen  * critical section between begin_current_label_crit_section() ..
148d8889d49SJohn Johansen  * end_current_label_crit_section()
149d8889d49SJohn Johansen  */
150d8889d49SJohn Johansen static inline struct aa_label *begin_current_label_crit_section(void)
151d8889d49SJohn Johansen {
152d8889d49SJohn Johansen 	struct aa_label *label = aa_current_raw_label();
153d8889d49SJohn Johansen 
154*1f8266ffSJann Horn 	might_sleep();
155*1f8266ffSJann Horn 
156d8889d49SJohn Johansen 	if (label_is_stale(label)) {
157d8889d49SJohn Johansen 		label = aa_get_newest_label(label);
158d8889d49SJohn Johansen 		if (aa_replace_current_label(label) == 0)
159d8889d49SJohn Johansen 			/* task cred will keep the reference */
160d8889d49SJohn Johansen 			aa_put_label(label);
161d8889d49SJohn Johansen 	}
162d8889d49SJohn Johansen 
163d8889d49SJohn Johansen 	return label;
164d8889d49SJohn Johansen }
165d8889d49SJohn Johansen 
166d8889d49SJohn Johansen static inline struct aa_ns *aa_get_current_ns(void)
167d8889d49SJohn Johansen {
168d8889d49SJohn Johansen 	struct aa_label *label;
169d8889d49SJohn Johansen 	struct aa_ns *ns;
170d8889d49SJohn Johansen 
171d8889d49SJohn Johansen 	label  = __begin_current_label_crit_section();
172d8889d49SJohn Johansen 	ns = aa_get_ns(labels_ns(label));
173d8889d49SJohn Johansen 	__end_current_label_crit_section(label);
174d8889d49SJohn Johansen 
175d8889d49SJohn Johansen 	return ns;
176d8889d49SJohn Johansen }
177d8889d49SJohn Johansen 
178d8889d49SJohn Johansen #endif /* __AA_CONTEXT_H */
179