Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /* SPDX-License-Identifier: GPL-2.0-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * AppArmor security module
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * This file contains AppArmor lib definitions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * 2017 Canonical Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #ifndef __AA_LIB_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #define __AA_LIB_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/lsm_hooks.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include "match.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  * DEBUG remains global (no per profile flag) since it is mostly used in sysctl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * which is not related to profile accesses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define DEBUG_ON (aa_g_debug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define dbg_printk(__fmt, __args...) pr_debug(__fmt, ##__args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define AA_DEBUG(fmt, args...)						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	do {								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 		if (DEBUG_ON)						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 			pr_debug_ratelimited("AppArmor: " fmt, ##args);	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define AA_WARN(X) WARN((X), "APPARMOR WARN %s: %s\n", __func__, #X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define AA_BUG(X, args...) AA_BUG_FMT((X), "" args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #ifdef CONFIG_SECURITY_APPARMOR_DEBUG_ASSERTS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define AA_BUG_FMT(X, fmt, args...)					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	WARN((X), "AppArmor WARN %s: (" #X "): " fmt, __func__, ##args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define AA_BUG_FMT(X, fmt, args...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #define AA_ERROR(fmt, args...)						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	pr_err_ratelimited("AppArmor: " fmt, ##args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) /* Flag indicating whether initialization completed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) extern int apparmor_initialized;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) /* fn's in lib */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) const char *skipn_spaces(const char *str, size_t n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) char *aa_split_fqname(char *args, char **ns_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) const char *aa_splitn_fqname(const char *fqname, size_t n, const char **ns_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 			     size_t *ns_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) void aa_info_message(const char *str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) /* Security blob offsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) extern struct lsm_blob_sizes apparmor_blob_sizes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  * aa_strneq - compare null terminated @str to a non null terminated substring
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)  * @str: a null terminated string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61)  * @sub: a substring, not necessarily null terminated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)  * @len: length of @sub to compare
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)  * The @str string must be full consumed for this to be considered a match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) static inline bool aa_strneq(const char *str, const char *sub, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	return !strncmp(str, sub, len) && !str[len];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)  * aa_dfa_null_transition - step to next state after null character
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)  * @dfa: the dfa to match against
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)  * @start: the state of the dfa to start matching in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)  * aa_dfa_null_transition transitions to the next state after a null
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)  * character which is not used in standard matching and is only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)  * used to separate pairs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) static inline unsigned int aa_dfa_null_transition(struct aa_dfa *dfa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 						  unsigned int start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	/* the null transition only needs the string's null terminator byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	return aa_dfa_next(dfa, start, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) static inline bool path_mediated_fs(struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	return !(dentry->d_sb->s_flags & SB_NOUSER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) struct counted_str {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	struct kref count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	char name[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) #define str_to_counted(str) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	((struct counted_str *)(str - offsetof(struct counted_str, name)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define __counted	/* atm just a notation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) void aa_str_kref(struct kref *kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) char *aa_str_alloc(int size, gfp_t gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static inline __counted char *aa_get_str(__counted char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	if (str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		kref_get(&(str_to_counted(str)->count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	return str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static inline void aa_put_str(__counted char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	if (str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		kref_put(&str_to_counted(str)->count, aa_str_kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /* struct aa_policy - common part of both namespaces and profiles
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)  * @name: name of the object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)  * @hname - The hierarchical name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)  * @list: list policy object is on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)  * @profiles: head of the profiles list contained in the object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct aa_policy {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	__counted char *hname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	struct list_head profiles;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)  * basename - find the last component of an hname
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)  * @name: hname to find the base profile name component of  (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)  * Returns: the tail (base profile name) name component of an hname
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static inline const char *basename(const char *hname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	char *split;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	hname = strim((char *)hname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	for (split = strstr(hname, "//"); split; split = strstr(hname, "//"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		hname = split + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	return hname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)  * __policy_find - find a policy by @name on a policy list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)  * @head: list to search  (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)  * @name: name to search for  (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)  * Requires: rcu_read_lock be held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)  * Returns: unrefcounted policy that match @name or NULL if not found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) static inline struct aa_policy *__policy_find(struct list_head *head,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 					      const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	struct aa_policy *policy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	list_for_each_entry_rcu(policy, head, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		if (!strcmp(policy->name, name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 			return policy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)  * __policy_strn_find - find a policy that's name matches @len chars of @str
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)  * @head: list to search  (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)  * @str: string to search for  (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)  * @len: length of match required
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)  * Requires: rcu_read_lock be held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)  * Returns: unrefcounted policy that match @str or NULL if not found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)  * if @len == strlen(@strlen) then this is equiv to __policy_find
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)  * other wise it allows searching for policy by a partial match of name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static inline struct aa_policy *__policy_strn_find(struct list_head *head,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 					    const char *str, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	struct aa_policy *policy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	list_for_each_entry_rcu(policy, head, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		if (aa_strneq(policy->name, str, len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 			return policy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) bool aa_policy_init(struct aa_policy *policy, const char *prefix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		    const char *name, gfp_t gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) void aa_policy_destroy(struct aa_policy *policy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)  * fn_label_build - abstract out the build of a label transition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)  * @L: label the transition is being computed for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)  * @P: profile parameter derived from L by this macro, can be passed to FN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)  * @GFP: memory allocation type to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)  * @FN: fn to call for each profile transition. @P is set to the profile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)  * Returns: new label on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)  *          ERR_PTR if build @FN fails
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)  *          NULL if label_build fails due to low memory conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)  * @FN must return a label or ERR_PTR on failure. NULL is not allowed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) #define fn_label_build(L, P, GFP, FN)					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) ({									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	__label__ __cleanup, __done;					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	struct aa_label *__new_;					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	if ((L)->size > 1) {						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		/* TODO: add cache of transitions already done */	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		struct label_it __i;					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		int __j, __k, __count;					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		DEFINE_VEC(label, __lvec);				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		DEFINE_VEC(profile, __pvec);				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		if (vec_setup(label, __lvec, (L)->size, (GFP)))	{	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 			__new_ = NULL;					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 			goto __done;					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		}							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		__j = 0;						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		label_for_each(__i, (L), (P)) {				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 			__new_ = (FN);					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 			AA_BUG(!__new_);				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 			if (IS_ERR(__new_))				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 				goto __cleanup;				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 			__lvec[__j++] = __new_;				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		}							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		for (__j = __count = 0; __j < (L)->size; __j++)		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 			__count += __lvec[__j]->size;			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		if (!vec_setup(profile, __pvec, __count, (GFP))) {	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 			for (__j = __k = 0; __j < (L)->size; __j++) {	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 				label_for_each(__i, __lvec[__j], (P))	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 					__pvec[__k++] = aa_get_profile(P); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 			}						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 			__count -= aa_vec_unique(__pvec, __count, 0);	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 			if (__count > 1) {				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 				__new_ = aa_vec_find_or_create_label(__pvec,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 						     __count, (GFP));	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 				/* only fails if out of Mem */		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 				if (!__new_)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 					__new_ = NULL;			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 			} else						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 				__new_ = aa_get_label(&__pvec[0]->label); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 			vec_cleanup(profile, __pvec, __count);		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		} else							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 			__new_ = NULL;					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) __cleanup:								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		vec_cleanup(label, __lvec, (L)->size);			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	} else {							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		(P) = labels_profile(L);				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		__new_ = (FN);						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	}								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) __done:									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	if (!__new_)							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		AA_DEBUG("label build failed\n");			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	(__new_);							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) #define __fn_build_in_ns(NS, P, NS_FN, OTHER_FN)			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) ({									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	struct aa_label *__new;						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	if ((P)->ns != (NS))						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		__new = (OTHER_FN);					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	else								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		__new = (NS_FN);					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	(__new);							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) #define fn_label_build_in_ns(L, P, GFP, NS_FN, OTHER_FN)		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) ({									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	fn_label_build((L), (P), (GFP),					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		__fn_build_in_ns(labels_ns(L), (P), (NS_FN), (OTHER_FN))); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) #endif /* __AA_LIB_H */