Linux Audio

Check our new training course

Loading...
v5.4
  1/* SPDX-License-Identifier: GPL-2.0-only */
  2/*
  3 * AppArmor security module
  4 *
  5 * This file contains AppArmor label definitions
  6 *
  7 * Copyright 2017 Canonical Ltd.
 
 
 
 
 
  8 */
  9
 10#ifndef __AA_LABEL_H
 11#define __AA_LABEL_H
 12
 13#include <linux/atomic.h>
 14#include <linux/audit.h>
 15#include <linux/rbtree.h>
 16#include <linux/rcupdate.h>
 17
 18#include "apparmor.h"
 19#include "lib.h"
 20
 21struct aa_ns;
 22
 23#define LOCAL_VEC_ENTRIES 8
 24#define DEFINE_VEC(T, V)						\
 25	struct aa_ ## T *(_ ## V ## _localtmp)[LOCAL_VEC_ENTRIES];	\
 26	struct aa_ ## T **(V)
 27
 28#define vec_setup(T, V, N, GFP)						\
 29({									\
 30	if ((N) <= LOCAL_VEC_ENTRIES) {					\
 31		typeof(N) i;						\
 32		(V) = (_ ## V ## _localtmp);				\
 33		for (i = 0; i < (N); i++)				\
 34			(V)[i] = NULL;					\
 35	} else								\
 36		(V) = kzalloc(sizeof(struct aa_ ## T *) * (N), (GFP));	\
 37	(V) ? 0 : -ENOMEM;						\
 38})
 39
 40#define vec_cleanup(T, V, N)						\
 41do {									\
 42	int i;								\
 43	for (i = 0; i < (N); i++) {					\
 44		if (!IS_ERR_OR_NULL((V)[i]))				\
 45			aa_put_ ## T((V)[i]);				\
 46	}								\
 47	if ((V) != _ ## V ## _localtmp)					\
 48		kfree(V);						\
 49} while (0)
 50
 51#define vec_last(VEC, SIZE) ((VEC)[(SIZE) - 1])
 52#define vec_ns(VEC, SIZE) (vec_last((VEC), (SIZE))->ns)
 53#define vec_labelset(VEC, SIZE) (&vec_ns((VEC), (SIZE))->labels)
 54#define cleanup_domain_vec(V, L) cleanup_label_vec((V), (L)->size)
 55
 56struct aa_profile;
 57#define VEC_FLAG_TERMINATE 1
 58int aa_vec_unique(struct aa_profile **vec, int n, int flags);
 59struct aa_label *aa_vec_find_or_create_label(struct aa_profile **vec, int len,
 60					     gfp_t gfp);
 61#define aa_sort_and_merge_vec(N, V) \
 62	aa_sort_and_merge_profiles((N), (struct aa_profile **)(V))
 63
 64
 65/* struct aa_labelset - set of labels for a namespace
 66 *
 67 * Labels are reference counted; aa_labelset does not contribute to label
 68 * reference counts. Once a label's last refcount is put it is removed from
 69 * the set.
 70 */
 71struct aa_labelset {
 72	rwlock_t lock;
 73
 74	struct rb_root root;
 75};
 76
 77#define __labelset_for_each(LS, N) \
 78	for ((N) = rb_first(&(LS)->root); (N); (N) = rb_next(N))
 79
 80void aa_labelset_destroy(struct aa_labelset *ls);
 81void aa_labelset_init(struct aa_labelset *ls);
 82
 83
 84enum label_flags {
 85	FLAG_HAT = 1,			/* profile is a hat */
 86	FLAG_UNCONFINED = 2,		/* label unconfined only if all */
 87	FLAG_NULL = 4,			/* profile is null learning profile */
 88	FLAG_IX_ON_NAME_ERROR = 8,	/* fallback to ix on name lookup fail */
 89	FLAG_IMMUTIBLE = 0x10,		/* don't allow changes/replacement */
 90	FLAG_USER_DEFINED = 0x20,	/* user based profile - lower privs */
 91	FLAG_NO_LIST_REF = 0x40,	/* list doesn't keep profile ref */
 92	FLAG_NS_COUNT = 0x80,		/* carries NS ref count */
 93	FLAG_IN_TREE = 0x100,		/* label is in tree */
 94	FLAG_PROFILE = 0x200,		/* label is a profile */
 95	FLAG_EXPLICIT = 0x400,		/* explicit static label */
 96	FLAG_STALE = 0x800,		/* replaced/removed */
 97	FLAG_RENAMED = 0x1000,		/* label has renaming in it */
 98	FLAG_REVOKED = 0x2000,		/* label has revocation in it */
 99
100	/* These flags must correspond with PATH_flags */
101	/* TODO: add new path flags */
102};
103
104struct aa_label;
105struct aa_proxy {
106	struct kref count;
107	struct aa_label __rcu *label;
108};
109
110struct label_it {
111	int i, j;
112};
113
114/* struct aa_label - lazy labeling struct
115 * @count: ref count of active users
116 * @node: rbtree position
117 * @rcu: rcu callback struct
118 * @proxy: is set to the label that replaced this label
119 * @hname: text representation of the label (MAYBE_NULL)
120 * @flags: stale and other flags - values may change under label set lock
121 * @secid: secid that references this label
122 * @size: number of entries in @ent[]
123 * @ent: set of profiles for label, actual size determined by @size
124 */
125struct aa_label {
126	struct kref count;
127	struct rb_node node;
128	struct rcu_head rcu;
129	struct aa_proxy *proxy;
130	__counted char *hname;
131	long flags;
132	u32 secid;
133	int size;
134	struct aa_profile *vec[];
135};
136
137#define last_error(E, FN)				\
138do {							\
139	int __subE = (FN);				\
140	if (__subE)					\
141		(E) = __subE;				\
142} while (0)
143
144#define label_isprofile(X) ((X)->flags & FLAG_PROFILE)
145#define label_unconfined(X) ((X)->flags & FLAG_UNCONFINED)
146#define unconfined(X) label_unconfined(X)
147#define label_is_stale(X) ((X)->flags & FLAG_STALE)
148#define __label_make_stale(X) ((X)->flags |= FLAG_STALE)
149#define labels_ns(X) (vec_ns(&((X)->vec[0]), (X)->size))
150#define labels_set(X) (&labels_ns(X)->labels)
151#define labels_profile(X) ((X)->vec[(X)->size - 1])
152
153
154int aa_label_next_confined(struct aa_label *l, int i);
155
156/* for each profile in a label */
157#define label_for_each(I, L, P)						\
158	for ((I).i = 0; ((P) = (L)->vec[(I).i]); ++((I).i))
159
160/* assumes break/goto ended label_for_each */
161#define label_for_each_cont(I, L, P)					\
162	for (++((I).i); ((P) = (L)->vec[(I).i]); ++((I).i))
163
164#define next_comb(I, L1, L2)						\
165do {									\
166	(I).j++;							\
167	if ((I).j >= (L2)->size) {					\
168		(I).i++;						\
169		(I).j = 0;						\
170	}								\
171} while (0)
172
173
174/* for each combination of P1 in L1, and P2 in L2 */
175#define label_for_each_comb(I, L1, L2, P1, P2)				\
176for ((I).i = (I).j = 0;							\
177	((P1) = (L1)->vec[(I).i]) && ((P2) = (L2)->vec[(I).j]);		\
178	(I) = next_comb(I, L1, L2))
179
180#define fn_for_each_comb(L1, L2, P1, P2, FN)				\
181({									\
182	struct label_it i;						\
183	int __E = 0;							\
184	label_for_each_comb(i, (L1), (L2), (P1), (P2)) {		\
185		last_error(__E, (FN));					\
186	}								\
187	__E;								\
188})
189
190/* for each profile that is enforcing confinement in a label */
191#define label_for_each_confined(I, L, P)				\
192	for ((I).i = aa_label_next_confined((L), 0);			\
193	     ((P) = (L)->vec[(I).i]);					\
194	     (I).i = aa_label_next_confined((L), (I).i + 1))
195
196#define label_for_each_in_merge(I, A, B, P)				\
197	for ((I).i = (I).j = 0;						\
198	     ((P) = aa_label_next_in_merge(&(I), (A), (B)));		\
199	     )
200
201#define label_for_each_not_in_set(I, SET, SUB, P)			\
202	for ((I).i = (I).j = 0;						\
203	     ((P) = __aa_label_next_not_in_set(&(I), (SET), (SUB)));	\
204	     )
205
206#define next_in_ns(i, NS, L)						\
207({									\
208	typeof(i) ___i = (i);						\
209	while ((L)->vec[___i] && (L)->vec[___i]->ns != (NS))		\
210		(___i)++;						\
211	(___i);								\
212})
213
214#define label_for_each_in_ns(I, NS, L, P)				\
215	for ((I).i = next_in_ns(0, (NS), (L));				\
216	     ((P) = (L)->vec[(I).i]);					\
217	     (I).i = next_in_ns((I).i + 1, (NS), (L)))
218
219#define fn_for_each_in_ns(L, P, FN)					\
220({									\
221	struct label_it __i;						\
222	struct aa_ns *__ns = labels_ns(L);				\
223	int __E = 0;							\
224	label_for_each_in_ns(__i, __ns, (L), (P)) {			\
225		last_error(__E, (FN));					\
226	}								\
227	__E;								\
228})
229
230
231#define fn_for_each_XXX(L, P, FN, ...)					\
232({									\
233	struct label_it i;						\
234	int __E = 0;							\
235	label_for_each ## __VA_ARGS__(i, (L), (P)) {			\
236		last_error(__E, (FN));					\
237	}								\
238	__E;								\
239})
240
241#define fn_for_each(L, P, FN) fn_for_each_XXX(L, P, FN)
242#define fn_for_each_confined(L, P, FN) fn_for_each_XXX(L, P, FN, _confined)
243
244#define fn_for_each2_XXX(L1, L2, P, FN, ...)				\
245({									\
246	struct label_it i;						\
247	int __E = 0;							\
248	label_for_each ## __VA_ARGS__(i, (L1), (L2), (P)) {		\
249		last_error(__E, (FN));					\
250	}								\
251	__E;								\
252})
253
254#define fn_for_each_in_merge(L1, L2, P, FN)				\
255	fn_for_each2_XXX((L1), (L2), P, FN, _in_merge)
256#define fn_for_each_not_in_set(L1, L2, P, FN)				\
257	fn_for_each2_XXX((L1), (L2), P, FN, _not_in_set)
258
259#define LABEL_MEDIATES(L, C)						\
260({									\
261	struct aa_profile *profile;					\
262	struct label_it i;						\
263	int ret = 0;							\
264	label_for_each(i, (L), profile) {				\
265		if (PROFILE_MEDIATES(profile, (C))) {			\
266			ret = 1;					\
267			break;						\
268		}							\
269	}								\
270	ret;								\
271})
272
273
274void aa_labelset_destroy(struct aa_labelset *ls);
275void aa_labelset_init(struct aa_labelset *ls);
276void __aa_labelset_update_subtree(struct aa_ns *ns);
277
278void aa_label_free(struct aa_label *label);
279void aa_label_kref(struct kref *kref);
280bool aa_label_init(struct aa_label *label, int size, gfp_t gfp);
281struct aa_label *aa_label_alloc(int size, struct aa_proxy *proxy, gfp_t gfp);
282
283bool aa_label_is_subset(struct aa_label *set, struct aa_label *sub);
284struct aa_profile *__aa_label_next_not_in_set(struct label_it *I,
285					     struct aa_label *set,
286					     struct aa_label *sub);
287bool aa_label_remove(struct aa_label *label);
288struct aa_label *aa_label_insert(struct aa_labelset *ls, struct aa_label *l);
289bool aa_label_replace(struct aa_label *old, struct aa_label *new);
290bool aa_label_make_newest(struct aa_labelset *ls, struct aa_label *old,
291			  struct aa_label *new);
292
293struct aa_label *aa_label_find(struct aa_label *l);
294
295struct aa_profile *aa_label_next_in_merge(struct label_it *I,
296					  struct aa_label *a,
297					  struct aa_label *b);
298struct aa_label *aa_label_find_merge(struct aa_label *a, struct aa_label *b);
299struct aa_label *aa_label_merge(struct aa_label *a, struct aa_label *b,
300				gfp_t gfp);
301
302
303bool aa_update_label_name(struct aa_ns *ns, struct aa_label *label, gfp_t gfp);
304
305#define FLAGS_NONE 0
306#define FLAG_SHOW_MODE 1
307#define FLAG_VIEW_SUBNS 2
308#define FLAG_HIDDEN_UNCONFINED 4
309#define FLAG_ABS_ROOT 8
310int aa_label_snxprint(char *str, size_t size, struct aa_ns *view,
311		      struct aa_label *label, int flags);
312int aa_label_asxprint(char **strp, struct aa_ns *ns, struct aa_label *label,
313		      int flags, gfp_t gfp);
314int aa_label_acntsxprint(char __counted **strp, struct aa_ns *ns,
315			 struct aa_label *label, int flags, gfp_t gfp);
316void aa_label_xaudit(struct audit_buffer *ab, struct aa_ns *ns,
317		     struct aa_label *label, int flags, gfp_t gfp);
318void aa_label_seq_xprint(struct seq_file *f, struct aa_ns *ns,
319			 struct aa_label *label, int flags, gfp_t gfp);
320void aa_label_xprintk(struct aa_ns *ns, struct aa_label *label, int flags,
321		      gfp_t gfp);
322void aa_label_audit(struct audit_buffer *ab, struct aa_label *label, gfp_t gfp);
323void aa_label_seq_print(struct seq_file *f, struct aa_label *label, gfp_t gfp);
324void aa_label_printk(struct aa_label *label, gfp_t gfp);
325
326struct aa_label *aa_label_strn_parse(struct aa_label *base, const char *str,
327				     size_t n, gfp_t gfp, bool create,
328				     bool force_stack);
329struct aa_label *aa_label_parse(struct aa_label *base, const char *str,
330				gfp_t gfp, bool create, bool force_stack);
331
332static inline const char *aa_label_strn_split(const char *str, int n)
333{
334	const char *pos;
335	unsigned int state;
336
337	state = aa_dfa_matchn_until(stacksplitdfa, DFA_START, str, n, &pos);
338	if (!ACCEPT_TABLE(stacksplitdfa)[state])
339		return NULL;
340
341	return pos - 3;
342}
343
344static inline const char *aa_label_str_split(const char *str)
345{
346	const char *pos;
347	unsigned int state;
348
349	state = aa_dfa_match_until(stacksplitdfa, DFA_START, str, &pos);
350	if (!ACCEPT_TABLE(stacksplitdfa)[state])
351		return NULL;
352
353	return pos - 3;
354}
355
356
357
358struct aa_perms;
359int aa_label_match(struct aa_profile *profile, struct aa_label *label,
360		   unsigned int state, bool subns, u32 request,
361		   struct aa_perms *perms);
362
363
364/**
365 * __aa_get_label - get a reference count to uncounted label reference
366 * @l: reference to get a count on
367 *
368 * Returns: pointer to reference OR NULL if race is lost and reference is
369 *          being repeated.
370 * Requires: lock held, and the return code MUST be checked
371 */
372static inline struct aa_label *__aa_get_label(struct aa_label *l)
373{
374	if (l && kref_get_unless_zero(&l->count))
375		return l;
376
377	return NULL;
378}
379
380static inline struct aa_label *aa_get_label(struct aa_label *l)
381{
382	if (l)
383		kref_get(&(l->count));
384
385	return l;
386}
387
388
389/**
390 * aa_get_label_rcu - increment refcount on a label that can be replaced
391 * @l: pointer to label that can be replaced (NOT NULL)
392 *
393 * Returns: pointer to a refcounted label.
394 *     else NULL if no label
395 */
396static inline struct aa_label *aa_get_label_rcu(struct aa_label __rcu **l)
397{
398	struct aa_label *c;
399
400	rcu_read_lock();
401	do {
402		c = rcu_dereference(*l);
403	} while (c && !kref_get_unless_zero(&c->count));
404	rcu_read_unlock();
405
406	return c;
407}
408
409/**
410 * aa_get_newest_label - find the newest version of @l
411 * @l: the label to check for newer versions of
412 *
413 * Returns: refcounted newest version of @l taking into account
414 *          replacement, renames and removals
415 *          return @l.
416 */
417static inline struct aa_label *aa_get_newest_label(struct aa_label *l)
418{
419	if (!l)
420		return NULL;
421
422	if (label_is_stale(l)) {
423		struct aa_label *tmp;
424
425		AA_BUG(!l->proxy);
426		AA_BUG(!l->proxy->label);
427		/* BUG: only way this can happen is @l ref count and its
428		 * replacement count have gone to 0 and are on their way
429		 * to destruction. ie. we have a refcounting error
430		 */
431		tmp = aa_get_label_rcu(&l->proxy->label);
432		AA_BUG(!tmp);
433
434		return tmp;
435	}
436
437	return aa_get_label(l);
438}
439
440static inline void aa_put_label(struct aa_label *l)
441{
442	if (l)
443		kref_put(&l->count, aa_label_kref);
444}
445
446
447struct aa_proxy *aa_alloc_proxy(struct aa_label *l, gfp_t gfp);
448void aa_proxy_kref(struct kref *kref);
449
450static inline struct aa_proxy *aa_get_proxy(struct aa_proxy *proxy)
451{
452	if (proxy)
453		kref_get(&(proxy->count));
454
455	return proxy;
456}
457
458static inline void aa_put_proxy(struct aa_proxy *proxy)
459{
460	if (proxy)
461		kref_put(&proxy->count, aa_proxy_kref);
462}
463
464void __aa_proxy_redirect(struct aa_label *orig, struct aa_label *new);
465
466#endif /* __AA_LABEL_H */
v4.17
 
  1/*
  2 * AppArmor security module
  3 *
  4 * This file contains AppArmor label definitions
  5 *
  6 * Copyright 2017 Canonical Ltd.
  7 *
  8 * This program is free software; you can redistribute it and/or
  9 * modify it under the terms of the GNU General Public License as
 10 * published by the Free Software Foundation, version 2 of the
 11 * License.
 12 */
 13
 14#ifndef __AA_LABEL_H
 15#define __AA_LABEL_H
 16
 17#include <linux/atomic.h>
 18#include <linux/audit.h>
 19#include <linux/rbtree.h>
 20#include <linux/rcupdate.h>
 21
 22#include "apparmor.h"
 23#include "lib.h"
 24
 25struct aa_ns;
 26
 27#define LOCAL_VEC_ENTRIES 8
 28#define DEFINE_VEC(T, V)						\
 29	struct aa_ ## T *(_ ## V ## _localtmp)[LOCAL_VEC_ENTRIES];	\
 30	struct aa_ ## T **(V)
 31
 32#define vec_setup(T, V, N, GFP)						\
 33({									\
 34	if ((N) <= LOCAL_VEC_ENTRIES) {					\
 35		typeof(N) i;						\
 36		(V) = (_ ## V ## _localtmp);				\
 37		for (i = 0; i < (N); i++)				\
 38			(V)[i] = NULL;					\
 39	} else								\
 40		(V) = kzalloc(sizeof(struct aa_ ## T *) * (N), (GFP));	\
 41	(V) ? 0 : -ENOMEM;						\
 42})
 43
 44#define vec_cleanup(T, V, N)						\
 45do {									\
 46	int i;								\
 47	for (i = 0; i < (N); i++) {					\
 48		if (!IS_ERR_OR_NULL((V)[i]))				\
 49			aa_put_ ## T((V)[i]);				\
 50	}								\
 51	if ((V) != _ ## V ## _localtmp)					\
 52		kfree(V);						\
 53} while (0)
 54
 55#define vec_last(VEC, SIZE) ((VEC)[(SIZE) - 1])
 56#define vec_ns(VEC, SIZE) (vec_last((VEC), (SIZE))->ns)
 57#define vec_labelset(VEC, SIZE) (&vec_ns((VEC), (SIZE))->labels)
 58#define cleanup_domain_vec(V, L) cleanup_label_vec((V), (L)->size)
 59
 60struct aa_profile;
 61#define VEC_FLAG_TERMINATE 1
 62int aa_vec_unique(struct aa_profile **vec, int n, int flags);
 63struct aa_label *aa_vec_find_or_create_label(struct aa_profile **vec, int len,
 64					     gfp_t gfp);
 65#define aa_sort_and_merge_vec(N, V) \
 66	aa_sort_and_merge_profiles((N), (struct aa_profile **)(V))
 67
 68
 69/* struct aa_labelset - set of labels for a namespace
 70 *
 71 * Labels are reference counted; aa_labelset does not contribute to label
 72 * reference counts. Once a label's last refcount is put it is removed from
 73 * the set.
 74 */
 75struct aa_labelset {
 76	rwlock_t lock;
 77
 78	struct rb_root root;
 79};
 80
 81#define __labelset_for_each(LS, N) \
 82	for ((N) = rb_first(&(LS)->root); (N); (N) = rb_next(N))
 83
 84void aa_labelset_destroy(struct aa_labelset *ls);
 85void aa_labelset_init(struct aa_labelset *ls);
 86
 87
 88enum label_flags {
 89	FLAG_HAT = 1,			/* profile is a hat */
 90	FLAG_UNCONFINED = 2,		/* label unconfined only if all */
 91	FLAG_NULL = 4,			/* profile is null learning profile */
 92	FLAG_IX_ON_NAME_ERROR = 8,	/* fallback to ix on name lookup fail */
 93	FLAG_IMMUTIBLE = 0x10,		/* don't allow changes/replacement */
 94	FLAG_USER_DEFINED = 0x20,	/* user based profile - lower privs */
 95	FLAG_NO_LIST_REF = 0x40,	/* list doesn't keep profile ref */
 96	FLAG_NS_COUNT = 0x80,		/* carries NS ref count */
 97	FLAG_IN_TREE = 0x100,		/* label is in tree */
 98	FLAG_PROFILE = 0x200,		/* label is a profile */
 99	FLAG_EXPLICIT = 0x400,		/* explicit static label */
100	FLAG_STALE = 0x800,		/* replaced/removed */
101	FLAG_RENAMED = 0x1000,		/* label has renaming in it */
102	FLAG_REVOKED = 0x2000,		/* label has revocation in it */
103
104	/* These flags must correspond with PATH_flags */
105	/* TODO: add new path flags */
106};
107
108struct aa_label;
109struct aa_proxy {
110	struct kref count;
111	struct aa_label __rcu *label;
112};
113
114struct label_it {
115	int i, j;
116};
117
118/* struct aa_label - lazy labeling struct
119 * @count: ref count of active users
120 * @node: rbtree position
121 * @rcu: rcu callback struct
122 * @proxy: is set to the label that replaced this label
123 * @hname: text representation of the label (MAYBE_NULL)
124 * @flags: stale and other flags - values may change under label set lock
125 * @secid: secid that references this label
126 * @size: number of entries in @ent[]
127 * @ent: set of profiles for label, actual size determined by @size
128 */
129struct aa_label {
130	struct kref count;
131	struct rb_node node;
132	struct rcu_head rcu;
133	struct aa_proxy *proxy;
134	__counted char *hname;
135	long flags;
136	u32 secid;
137	int size;
138	struct aa_profile *vec[];
139};
140
141#define last_error(E, FN)				\
142do {							\
143	int __subE = (FN);				\
144	if (__subE)					\
145		(E) = __subE;				\
146} while (0)
147
148#define label_isprofile(X) ((X)->flags & FLAG_PROFILE)
149#define label_unconfined(X) ((X)->flags & FLAG_UNCONFINED)
150#define unconfined(X) label_unconfined(X)
151#define label_is_stale(X) ((X)->flags & FLAG_STALE)
152#define __label_make_stale(X) ((X)->flags |= FLAG_STALE)
153#define labels_ns(X) (vec_ns(&((X)->vec[0]), (X)->size))
154#define labels_set(X) (&labels_ns(X)->labels)
155#define labels_profile(X) ((X)->vec[(X)->size - 1])
156
157
158int aa_label_next_confined(struct aa_label *l, int i);
159
160/* for each profile in a label */
161#define label_for_each(I, L, P)						\
162	for ((I).i = 0; ((P) = (L)->vec[(I).i]); ++((I).i))
163
164/* assumes break/goto ended label_for_each */
165#define label_for_each_cont(I, L, P)					\
166	for (++((I).i); ((P) = (L)->vec[(I).i]); ++((I).i))
167
168#define next_comb(I, L1, L2)						\
169do {									\
170	(I).j++;							\
171	if ((I).j >= (L2)->size) {					\
172		(I).i++;						\
173		(I).j = 0;						\
174	}								\
175} while (0)
176
177
178/* for each combination of P1 in L1, and P2 in L2 */
179#define label_for_each_comb(I, L1, L2, P1, P2)				\
180for ((I).i = (I).j = 0;							\
181	((P1) = (L1)->vec[(I).i]) && ((P2) = (L2)->vec[(I).j]);		\
182	(I) = next_comb(I, L1, L2))
183
184#define fn_for_each_comb(L1, L2, P1, P2, FN)				\
185({									\
186	struct label_it i;						\
187	int __E = 0;							\
188	label_for_each_comb(i, (L1), (L2), (P1), (P2)) {		\
189		last_error(__E, (FN));					\
190	}								\
191	__E;								\
192})
193
194/* for each profile that is enforcing confinement in a label */
195#define label_for_each_confined(I, L, P)				\
196	for ((I).i = aa_label_next_confined((L), 0);			\
197	     ((P) = (L)->vec[(I).i]);					\
198	     (I).i = aa_label_next_confined((L), (I).i + 1))
199
200#define label_for_each_in_merge(I, A, B, P)				\
201	for ((I).i = (I).j = 0;						\
202	     ((P) = aa_label_next_in_merge(&(I), (A), (B)));		\
203	     )
204
205#define label_for_each_not_in_set(I, SET, SUB, P)			\
206	for ((I).i = (I).j = 0;						\
207	     ((P) = __aa_label_next_not_in_set(&(I), (SET), (SUB)));	\
208	     )
209
210#define next_in_ns(i, NS, L)						\
211({									\
212	typeof(i) ___i = (i);						\
213	while ((L)->vec[___i] && (L)->vec[___i]->ns != (NS))		\
214		(___i)++;						\
215	(___i);								\
216})
217
218#define label_for_each_in_ns(I, NS, L, P)				\
219	for ((I).i = next_in_ns(0, (NS), (L));				\
220	     ((P) = (L)->vec[(I).i]);					\
221	     (I).i = next_in_ns((I).i + 1, (NS), (L)))
222
223#define fn_for_each_in_ns(L, P, FN)					\
224({									\
225	struct label_it __i;						\
226	struct aa_ns *__ns = labels_ns(L);				\
227	int __E = 0;							\
228	label_for_each_in_ns(__i, __ns, (L), (P)) {			\
229		last_error(__E, (FN));					\
230	}								\
231	__E;								\
232})
233
234
235#define fn_for_each_XXX(L, P, FN, ...)					\
236({									\
237	struct label_it i;						\
238	int __E = 0;							\
239	label_for_each ## __VA_ARGS__(i, (L), (P)) {			\
240		last_error(__E, (FN));					\
241	}								\
242	__E;								\
243})
244
245#define fn_for_each(L, P, FN) fn_for_each_XXX(L, P, FN)
246#define fn_for_each_confined(L, P, FN) fn_for_each_XXX(L, P, FN, _confined)
247
248#define fn_for_each2_XXX(L1, L2, P, FN, ...)				\
249({									\
250	struct label_it i;						\
251	int __E = 0;							\
252	label_for_each ## __VA_ARGS__(i, (L1), (L2), (P)) {		\
253		last_error(__E, (FN));					\
254	}								\
255	__E;								\
256})
257
258#define fn_for_each_in_merge(L1, L2, P, FN)				\
259	fn_for_each2_XXX((L1), (L2), P, FN, _in_merge)
260#define fn_for_each_not_in_set(L1, L2, P, FN)				\
261	fn_for_each2_XXX((L1), (L2), P, FN, _not_in_set)
262
263#define LABEL_MEDIATES(L, C)						\
264({									\
265	struct aa_profile *profile;					\
266	struct label_it i;						\
267	int ret = 0;							\
268	label_for_each(i, (L), profile) {				\
269		if (PROFILE_MEDIATES(profile, (C))) {			\
270			ret = 1;					\
271			break;						\
272		}							\
273	}								\
274	ret;								\
275})
276
277
278void aa_labelset_destroy(struct aa_labelset *ls);
279void aa_labelset_init(struct aa_labelset *ls);
280void __aa_labelset_update_subtree(struct aa_ns *ns);
281
282void aa_label_free(struct aa_label *label);
283void aa_label_kref(struct kref *kref);
284bool aa_label_init(struct aa_label *label, int size);
285struct aa_label *aa_label_alloc(int size, struct aa_proxy *proxy, gfp_t gfp);
286
287bool aa_label_is_subset(struct aa_label *set, struct aa_label *sub);
288struct aa_profile *__aa_label_next_not_in_set(struct label_it *I,
289					     struct aa_label *set,
290					     struct aa_label *sub);
291bool aa_label_remove(struct aa_label *label);
292struct aa_label *aa_label_insert(struct aa_labelset *ls, struct aa_label *l);
293bool aa_label_replace(struct aa_label *old, struct aa_label *new);
294bool aa_label_make_newest(struct aa_labelset *ls, struct aa_label *old,
295			  struct aa_label *new);
296
297struct aa_label *aa_label_find(struct aa_label *l);
298
299struct aa_profile *aa_label_next_in_merge(struct label_it *I,
300					  struct aa_label *a,
301					  struct aa_label *b);
302struct aa_label *aa_label_find_merge(struct aa_label *a, struct aa_label *b);
303struct aa_label *aa_label_merge(struct aa_label *a, struct aa_label *b,
304				gfp_t gfp);
305
306
307bool aa_update_label_name(struct aa_ns *ns, struct aa_label *label, gfp_t gfp);
308
309#define FLAGS_NONE 0
310#define FLAG_SHOW_MODE 1
311#define FLAG_VIEW_SUBNS 2
312#define FLAG_HIDDEN_UNCONFINED 4
313#define FLAG_ABS_ROOT 8
314int aa_label_snxprint(char *str, size_t size, struct aa_ns *view,
315		      struct aa_label *label, int flags);
316int aa_label_asxprint(char **strp, struct aa_ns *ns, struct aa_label *label,
317		      int flags, gfp_t gfp);
318int aa_label_acntsxprint(char __counted **strp, struct aa_ns *ns,
319			 struct aa_label *label, int flags, gfp_t gfp);
320void aa_label_xaudit(struct audit_buffer *ab, struct aa_ns *ns,
321		     struct aa_label *label, int flags, gfp_t gfp);
322void aa_label_seq_xprint(struct seq_file *f, struct aa_ns *ns,
323			 struct aa_label *label, int flags, gfp_t gfp);
324void aa_label_xprintk(struct aa_ns *ns, struct aa_label *label, int flags,
325		      gfp_t gfp);
326void aa_label_audit(struct audit_buffer *ab, struct aa_label *label, gfp_t gfp);
327void aa_label_seq_print(struct seq_file *f, struct aa_label *label, gfp_t gfp);
328void aa_label_printk(struct aa_label *label, gfp_t gfp);
329
330struct aa_label *aa_label_strn_parse(struct aa_label *base, const char *str,
331				     size_t n, gfp_t gfp, bool create,
332				     bool force_stack);
333struct aa_label *aa_label_parse(struct aa_label *base, const char *str,
334				gfp_t gfp, bool create, bool force_stack);
335
336static inline const char *aa_label_strn_split(const char *str, int n)
337{
338	const char *pos;
339	unsigned int state;
340
341	state = aa_dfa_matchn_until(stacksplitdfa, DFA_START, str, n, &pos);
342	if (!ACCEPT_TABLE(stacksplitdfa)[state])
343		return NULL;
344
345	return pos - 3;
346}
347
348static inline const char *aa_label_str_split(const char *str)
349{
350	const char *pos;
351	unsigned int state;
352
353	state = aa_dfa_match_until(stacksplitdfa, DFA_START, str, &pos);
354	if (!ACCEPT_TABLE(stacksplitdfa)[state])
355		return NULL;
356
357	return pos - 3;
358}
359
360
361
362struct aa_perms;
363int aa_label_match(struct aa_profile *profile, struct aa_label *label,
364		   unsigned int state, bool subns, u32 request,
365		   struct aa_perms *perms);
366
367
368/**
369 * __aa_get_label - get a reference count to uncounted label reference
370 * @l: reference to get a count on
371 *
372 * Returns: pointer to reference OR NULL if race is lost and reference is
373 *          being repeated.
374 * Requires: lock held, and the return code MUST be checked
375 */
376static inline struct aa_label *__aa_get_label(struct aa_label *l)
377{
378	if (l && kref_get_unless_zero(&l->count))
379		return l;
380
381	return NULL;
382}
383
384static inline struct aa_label *aa_get_label(struct aa_label *l)
385{
386	if (l)
387		kref_get(&(l->count));
388
389	return l;
390}
391
392
393/**
394 * aa_get_label_rcu - increment refcount on a label that can be replaced
395 * @l: pointer to label that can be replaced (NOT NULL)
396 *
397 * Returns: pointer to a refcounted label.
398 *     else NULL if no label
399 */
400static inline struct aa_label *aa_get_label_rcu(struct aa_label __rcu **l)
401{
402	struct aa_label *c;
403
404	rcu_read_lock();
405	do {
406		c = rcu_dereference(*l);
407	} while (c && !kref_get_unless_zero(&c->count));
408	rcu_read_unlock();
409
410	return c;
411}
412
413/**
414 * aa_get_newest_label - find the newest version of @l
415 * @l: the label to check for newer versions of
416 *
417 * Returns: refcounted newest version of @l taking into account
418 *          replacement, renames and removals
419 *          return @l.
420 */
421static inline struct aa_label *aa_get_newest_label(struct aa_label *l)
422{
423	if (!l)
424		return NULL;
425
426	if (label_is_stale(l)) {
427		struct aa_label *tmp;
428
429		AA_BUG(!l->proxy);
430		AA_BUG(!l->proxy->label);
431		/* BUG: only way this can happen is @l ref count and its
432		 * replacement count have gone to 0 and are on their way
433		 * to destruction. ie. we have a refcounting error
434		 */
435		tmp = aa_get_label_rcu(&l->proxy->label);
436		AA_BUG(!tmp);
437
438		return tmp;
439	}
440
441	return aa_get_label(l);
442}
443
444static inline void aa_put_label(struct aa_label *l)
445{
446	if (l)
447		kref_put(&l->count, aa_label_kref);
448}
449
450
451struct aa_proxy *aa_alloc_proxy(struct aa_label *l, gfp_t gfp);
452void aa_proxy_kref(struct kref *kref);
453
454static inline struct aa_proxy *aa_get_proxy(struct aa_proxy *proxy)
455{
456	if (proxy)
457		kref_get(&(proxy->count));
458
459	return proxy;
460}
461
462static inline void aa_put_proxy(struct aa_proxy *proxy)
463{
464	if (proxy)
465		kref_put(&proxy->count, aa_proxy_kref);
466}
467
468void __aa_proxy_redirect(struct aa_label *orig, struct aa_label *new);
469
470#endif /* __AA_LABEL_H */