0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef __AA_LIB_H
0011 #define __AA_LIB_H
0012
0013 #include <linux/slab.h>
0014 #include <linux/fs.h>
0015 #include <linux/lsm_hooks.h>
0016
0017 #include "match.h"
0018
0019
0020
0021
0022
0023
0024 #define DEBUG_ON (aa_g_debug)
0025
0026
0027
0028
0029 #define AA_DEBUG_LABEL DEBUG_ON
0030 #define dbg_printk(__fmt, __args...) pr_debug(__fmt, ##__args)
0031 #define AA_DEBUG(fmt, args...) \
0032 do { \
0033 if (DEBUG_ON) \
0034 pr_debug_ratelimited("AppArmor: " fmt, ##args); \
0035 } while (0)
0036
0037 #define AA_WARN(X) WARN((X), "APPARMOR WARN %s: %s\n", __func__, #X)
0038
0039 #define AA_BUG(X, args...) \
0040 do { \
0041 _Pragma("GCC diagnostic ignored \"-Wformat-zero-length\""); \
0042 AA_BUG_FMT((X), "" args); \
0043 _Pragma("GCC diagnostic warning \"-Wformat-zero-length\""); \
0044 } while (0)
0045 #ifdef CONFIG_SECURITY_APPARMOR_DEBUG_ASSERTS
0046 #define AA_BUG_FMT(X, fmt, args...) \
0047 WARN((X), "AppArmor WARN %s: (" #X "): " fmt, __func__, ##args)
0048 #else
0049 #define AA_BUG_FMT(X, fmt, args...) no_printk(fmt, ##args)
0050 #endif
0051
0052 #define AA_ERROR(fmt, args...) \
0053 pr_err_ratelimited("AppArmor: " fmt, ##args)
0054
0055
0056 extern int apparmor_initialized;
0057
0058
0059 const char *skipn_spaces(const char *str, size_t n);
0060 char *aa_split_fqname(char *args, char **ns_name);
0061 const char *aa_splitn_fqname(const char *fqname, size_t n, const char **ns_name,
0062 size_t *ns_len);
0063 void aa_info_message(const char *str);
0064
0065
0066 extern struct lsm_blob_sizes apparmor_blob_sizes;
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076 static inline bool aa_strneq(const char *str, const char *sub, int len)
0077 {
0078 return !strncmp(str, sub, len) && !str[len];
0079 }
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090 static inline unsigned int aa_dfa_null_transition(struct aa_dfa *dfa,
0091 unsigned int start)
0092 {
0093
0094 return aa_dfa_next(dfa, start, 0);
0095 }
0096
0097 static inline bool path_mediated_fs(struct dentry *dentry)
0098 {
0099 return !(dentry->d_sb->s_flags & SB_NOUSER);
0100 }
0101
0102
0103 struct counted_str {
0104 struct kref count;
0105 char name[];
0106 };
0107
0108 #define str_to_counted(str) \
0109 ((struct counted_str *)(str - offsetof(struct counted_str, name)))
0110
0111 #define __counted
0112
0113 void aa_str_kref(struct kref *kref);
0114 char *aa_str_alloc(int size, gfp_t gfp);
0115
0116
0117 static inline __counted char *aa_get_str(__counted char *str)
0118 {
0119 if (str)
0120 kref_get(&(str_to_counted(str)->count));
0121
0122 return str;
0123 }
0124
0125 static inline void aa_put_str(__counted char *str)
0126 {
0127 if (str)
0128 kref_put(&str_to_counted(str)->count, aa_str_kref);
0129 }
0130
0131
0132
0133
0134
0135
0136
0137
0138 struct aa_policy {
0139 const char *name;
0140 __counted char *hname;
0141 struct list_head list;
0142 struct list_head profiles;
0143 };
0144
0145
0146
0147
0148
0149
0150
0151 static inline const char *basename(const char *hname)
0152 {
0153 char *split;
0154
0155 hname = strim((char *)hname);
0156 for (split = strstr(hname, "//"); split; split = strstr(hname, "//"))
0157 hname = split + 2;
0158
0159 return hname;
0160 }
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171 static inline struct aa_policy *__policy_find(struct list_head *head,
0172 const char *name)
0173 {
0174 struct aa_policy *policy;
0175
0176 list_for_each_entry_rcu(policy, head, list) {
0177 if (!strcmp(policy->name, name))
0178 return policy;
0179 }
0180 return NULL;
0181 }
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196 static inline struct aa_policy *__policy_strn_find(struct list_head *head,
0197 const char *str, int len)
0198 {
0199 struct aa_policy *policy;
0200
0201 list_for_each_entry_rcu(policy, head, list) {
0202 if (aa_strneq(policy->name, str, len))
0203 return policy;
0204 }
0205
0206 return NULL;
0207 }
0208
0209 bool aa_policy_init(struct aa_policy *policy, const char *prefix,
0210 const char *name, gfp_t gfp);
0211 void aa_policy_destroy(struct aa_policy *policy);
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227 #define fn_label_build(L, P, GFP, FN) \
0228 ({ \
0229 __label__ __cleanup, __done; \
0230 struct aa_label *__new_; \
0231 \
0232 if ((L)->size > 1) { \
0233 \
0234 struct label_it __i; \
0235 int __j, __k, __count; \
0236 DEFINE_VEC(label, __lvec); \
0237 DEFINE_VEC(profile, __pvec); \
0238 if (vec_setup(label, __lvec, (L)->size, (GFP))) { \
0239 __new_ = NULL; \
0240 goto __done; \
0241 } \
0242 __j = 0; \
0243 label_for_each(__i, (L), (P)) { \
0244 __new_ = (FN); \
0245 AA_BUG(!__new_); \
0246 if (IS_ERR(__new_)) \
0247 goto __cleanup; \
0248 __lvec[__j++] = __new_; \
0249 } \
0250 for (__j = __count = 0; __j < (L)->size; __j++) \
0251 __count += __lvec[__j]->size; \
0252 if (!vec_setup(profile, __pvec, __count, (GFP))) { \
0253 for (__j = __k = 0; __j < (L)->size; __j++) { \
0254 label_for_each(__i, __lvec[__j], (P)) \
0255 __pvec[__k++] = aa_get_profile(P); \
0256 } \
0257 __count -= aa_vec_unique(__pvec, __count, 0); \
0258 if (__count > 1) { \
0259 __new_ = aa_vec_find_or_create_label(__pvec,\
0260 __count, (GFP)); \
0261 \
0262 if (!__new_) \
0263 __new_ = NULL; \
0264 } else \
0265 __new_ = aa_get_label(&__pvec[0]->label); \
0266 vec_cleanup(profile, __pvec, __count); \
0267 } else \
0268 __new_ = NULL; \
0269 __cleanup: \
0270 vec_cleanup(label, __lvec, (L)->size); \
0271 } else { \
0272 (P) = labels_profile(L); \
0273 __new_ = (FN); \
0274 } \
0275 __done: \
0276 if (!__new_) \
0277 AA_DEBUG("label build failed\n"); \
0278 (__new_); \
0279 })
0280
0281
0282 #define __fn_build_in_ns(NS, P, NS_FN, OTHER_FN) \
0283 ({ \
0284 struct aa_label *__new; \
0285 if ((P)->ns != (NS)) \
0286 __new = (OTHER_FN); \
0287 else \
0288 __new = (NS_FN); \
0289 (__new); \
0290 })
0291
0292 #define fn_label_build_in_ns(L, P, GFP, NS_FN, OTHER_FN) \
0293 ({ \
0294 fn_label_build((L), (P), (GFP), \
0295 __fn_build_in_ns(labels_ns(L), (P), (NS_FN), (OTHER_FN))); \
0296 })
0297
0298 #endif