aboutsummaryrefslogtreecommitdiffstats
path: root/security/apparmor/include/lib.h
diff options
context:
space:
mode:
Diffstat (limited to 'security/apparmor/include/lib.h')
-rw-r--r--security/apparmor/include/lib.h120
1 files changed, 118 insertions, 2 deletions
diff --git a/security/apparmor/include/lib.h b/security/apparmor/include/lib.h
index 550a700563b4..436b3a722357 100644
--- a/security/apparmor/include/lib.h
+++ b/security/apparmor/include/lib.h
@@ -60,6 +60,7 @@
60extern int apparmor_initialized; 60extern int apparmor_initialized;
61 61
62/* fn's in lib */ 62/* fn's in lib */
63const char *skipn_spaces(const char *str, size_t n);
63char *aa_split_fqname(char *args, char **ns_name); 64char *aa_split_fqname(char *args, char **ns_name);
64const char *aa_splitn_fqname(const char *fqname, size_t n, const char **ns_name, 65const char *aa_splitn_fqname(const char *fqname, size_t n, const char **ns_name,
65 size_t *ns_len); 66 size_t *ns_len);
@@ -99,6 +100,36 @@ static inline bool path_mediated_fs(struct dentry *dentry)
99 return !(dentry->d_sb->s_flags & MS_NOUSER); 100 return !(dentry->d_sb->s_flags & MS_NOUSER);
100} 101}
101 102
103
104struct counted_str {
105 struct kref count;
106 char name[];
107};
108
109#define str_to_counted(str) \
110 ((struct counted_str *)(str - offsetof(struct counted_str, name)))
111
112#define __counted /* atm just a notation */
113
114void aa_str_kref(struct kref *kref);
115char *aa_str_alloc(int size, gfp_t gfp);
116
117
118static inline __counted char *aa_get_str(__counted char *str)
119{
120 if (str)
121 kref_get(&(str_to_counted(str)->count));
122
123 return str;
124}
125
126static inline void aa_put_str(__counted char *str)
127{
128 if (str)
129 kref_put(&str_to_counted(str)->count, aa_str_kref);
130}
131
132
102/* struct aa_policy - common part of both namespaces and profiles 133/* struct aa_policy - common part of both namespaces and profiles
103 * @name: name of the object 134 * @name: name of the object
104 * @hname - The hierarchical name 135 * @hname - The hierarchical name
@@ -107,7 +138,7 @@ static inline bool path_mediated_fs(struct dentry *dentry)
107 */ 138 */
108struct aa_policy { 139struct aa_policy {
109 const char *name; 140 const char *name;
110 const char *hname; 141 __counted char *hname;
111 struct list_head list; 142 struct list_head list;
112 struct list_head profiles; 143 struct list_head profiles;
113}; 144};
@@ -180,4 +211,89 @@ bool aa_policy_init(struct aa_policy *policy, const char *prefix,
180 const char *name, gfp_t gfp); 211 const char *name, gfp_t gfp);
181void aa_policy_destroy(struct aa_policy *policy); 212void aa_policy_destroy(struct aa_policy *policy);
182 213
183#endif /* AA_LIB_H */ 214
215/*
216 * fn_label_build - abstract out the build of a label transition
217 * @L: label the transition is being computed for
218 * @P: profile parameter derived from L by this macro, can be passed to FN
219 * @GFP: memory allocation type to use
220 * @FN: fn to call for each profile transition. @P is set to the profile
221 *
222 * Returns: new label on success
223 * ERR_PTR if build @FN fails
224 * NULL if label_build fails due to low memory conditions
225 *
226 * @FN must return a label or ERR_PTR on failure. NULL is not allowed
227 */
228#define fn_label_build(L, P, GFP, FN) \
229({ \
230 __label__ __cleanup, __done; \
231 struct aa_label *__new_; \
232 \
233 if ((L)->size > 1) { \
234 /* TODO: add cache of transitions already done */ \
235 struct label_it __i; \
236 int __j, __k, __count; \
237 DEFINE_VEC(label, __lvec); \
238 DEFINE_VEC(profile, __pvec); \
239 if (vec_setup(label, __lvec, (L)->size, (GFP))) { \
240 __new_ = NULL; \
241 goto __done; \
242 } \
243 __j = 0; \
244 label_for_each(__i, (L), (P)) { \
245 __new_ = (FN); \
246 AA_BUG(!__new_); \
247 if (IS_ERR(__new_)) \
248 goto __cleanup; \
249 __lvec[__j++] = __new_; \
250 } \
251 for (__j = __count = 0; __j < (L)->size; __j++) \
252 __count += __lvec[__j]->size; \
253 if (!vec_setup(profile, __pvec, __count, (GFP))) { \
254 for (__j = __k = 0; __j < (L)->size; __j++) { \
255 label_for_each(__i, __lvec[__j], (P)) \
256 __pvec[__k++] = aa_get_profile(P); \
257 } \
258 __count -= aa_vec_unique(__pvec, __count, 0); \
259 if (__count > 1) { \
260 __new_ = aa_vec_find_or_create_label(__pvec,\
261 __count, (GFP)); \
262 /* only fails if out of Mem */ \
263 if (!__new_) \
264 __new_ = NULL; \
265 } else \
266 __new_ = aa_get_label(&__pvec[0]->label); \
267 vec_cleanup(profile, __pvec, __count); \
268 } else \
269 __new_ = NULL; \
270__cleanup: \
271 vec_cleanup(label, __lvec, (L)->size); \
272 } else { \
273 (P) = labels_profile(L); \
274 __new_ = (FN); \
275 } \
276__done: \
277 if (!__new_) \
278 AA_DEBUG("label build failed\n"); \
279 (__new_); \
280})
281
282
283#define __fn_build_in_ns(NS, P, NS_FN, OTHER_FN) \
284({ \
285 struct aa_label *__new; \
286 if ((P)->ns != (NS)) \
287 __new = (OTHER_FN); \
288 else \
289 __new = (NS_FN); \
290 (__new); \
291})
292
293#define fn_label_build_in_ns(L, P, GFP, NS_FN, OTHER_FN) \
294({ \
295 fn_label_build((L), (P), (GFP), \
296 __fn_build_in_ns(labels_ns(L), (P), (NS_FN), (OTHER_FN))); \
297})
298
299#endif /* __AA_LIB_H */