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