Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/security/apparmor/include/policy.h
26444 views
1
/* SPDX-License-Identifier: GPL-2.0-only */
2
/*
3
* AppArmor security module
4
*
5
* This file contains AppArmor policy definitions.
6
*
7
* Copyright (C) 1998-2008 Novell/SUSE
8
* Copyright 2009-2010 Canonical Ltd.
9
*/
10
11
#ifndef __AA_POLICY_H
12
#define __AA_POLICY_H
13
14
#include <linux/capability.h>
15
#include <linux/cred.h>
16
#include <linux/kref.h>
17
#include <linux/rhashtable.h>
18
#include <linux/sched.h>
19
#include <linux/slab.h>
20
#include <linux/socket.h>
21
22
#include "apparmor.h"
23
#include "audit.h"
24
#include "capability.h"
25
#include "domain.h"
26
#include "file.h"
27
#include "lib.h"
28
#include "label.h"
29
#include "net.h"
30
#include "perms.h"
31
#include "resource.h"
32
33
34
struct aa_ns;
35
36
extern int unprivileged_userns_apparmor_policy;
37
extern int aa_unprivileged_unconfined_restricted;
38
39
extern const char *const aa_profile_mode_names[];
40
#define APPARMOR_MODE_NAMES_MAX_INDEX 4
41
42
#define PROFILE_MODE(_profile, _mode) \
43
((aa_g_profile_mode == (_mode)) || \
44
((_profile)->mode == (_mode)))
45
46
#define COMPLAIN_MODE(_profile) PROFILE_MODE((_profile), APPARMOR_COMPLAIN)
47
48
#define USER_MODE(_profile) PROFILE_MODE((_profile), APPARMOR_USER)
49
50
#define KILL_MODE(_profile) PROFILE_MODE((_profile), APPARMOR_KILL)
51
52
#define PROFILE_IS_HAT(_profile) ((_profile)->label.flags & FLAG_HAT)
53
54
#define CHECK_DEBUG1(_profile) ((_profile)->label.flags & FLAG_DEBUG1)
55
56
#define CHECK_DEBUG2(_profile) ((_profile)->label.flags & FLAG_DEBUG2)
57
58
#define profile_is_stale(_profile) (label_is_stale(&(_profile)->label))
59
60
#define on_list_rcu(X) (!list_empty(X) && (X)->prev != LIST_POISON2)
61
62
/* flags in the dfa accept2 table */
63
enum dfa_accept_flags {
64
ACCEPT_FLAG_OWNER = 1,
65
};
66
67
/*
68
* FIXME: currently need a clean way to replace and remove profiles as a
69
* set. It should be done at the namespace level.
70
* Either, with a set of profiles loaded at the namespace level or via
71
* a mark and remove marked interface.
72
*/
73
enum profile_mode {
74
APPARMOR_ENFORCE, /* enforce access rules */
75
APPARMOR_COMPLAIN, /* allow and log access violations */
76
APPARMOR_KILL, /* kill task on access violation */
77
APPARMOR_UNCONFINED, /* profile set to unconfined */
78
APPARMOR_USER, /* modified complain mode to userspace */
79
};
80
81
82
/* struct aa_policydb - match engine for a policy
83
* count: refcount for the pdb
84
* dfa: dfa pattern match
85
* perms: table of permissions
86
* strs: table of strings, index by x
87
* start: set of start states for the different classes of data
88
*/
89
struct aa_policydb {
90
struct kref count;
91
struct aa_dfa *dfa;
92
struct {
93
struct aa_perms *perms;
94
u32 size;
95
};
96
struct aa_str_table trans;
97
aa_state_t start[AA_CLASS_LAST + 1];
98
};
99
100
extern struct aa_policydb *nullpdb;
101
102
struct aa_policydb *aa_alloc_pdb(gfp_t gfp);
103
void aa_pdb_free_kref(struct kref *kref);
104
105
/**
106
* aa_get_pdb - increment refcount on @pdb
107
* @pdb: policydb (MAYBE NULL)
108
*
109
* Returns: pointer to @pdb if @pdb is NULL will return NULL
110
* Requires: @pdb must be held with valid refcount when called
111
*/
112
static inline struct aa_policydb *aa_get_pdb(struct aa_policydb *pdb)
113
{
114
if (pdb)
115
kref_get(&(pdb->count));
116
117
return pdb;
118
}
119
120
/**
121
* aa_put_pdb - put a pdb refcount
122
* @pdb: pdb to put refcount (MAYBE NULL)
123
*
124
* Requires: if @pdb != NULL that a valid refcount be held
125
*/
126
static inline void aa_put_pdb(struct aa_policydb *pdb)
127
{
128
if (pdb)
129
kref_put(&pdb->count, aa_pdb_free_kref);
130
}
131
132
/* lookup perm that doesn't have and object conditional */
133
static inline struct aa_perms *aa_lookup_perms(struct aa_policydb *policy,
134
aa_state_t state)
135
{
136
unsigned int index = ACCEPT_TABLE(policy->dfa)[state];
137
138
if (!(policy->perms))
139
return &default_perms;
140
141
return &(policy->perms[index]);
142
}
143
144
/* struct aa_data - generic data structure
145
* key: name for retrieving this data
146
* size: size of data in bytes
147
* data: binary data
148
* head: reserved for rhashtable
149
*/
150
struct aa_data {
151
char *key;
152
u32 size;
153
char *data;
154
struct rhash_head head;
155
};
156
157
/* struct aa_ruleset - data covering mediation rules
158
* @list: list the rule is on
159
* @size: the memory consumed by this ruleset
160
* @policy: general match rules governing policy
161
* @file: The set of rules governing basic file access and domain transitions
162
* @caps: capabilities for the profile
163
* @rlimits: rlimits for the profile
164
* @secmark_count: number of secmark entries
165
* @secmark: secmark label match info
166
*/
167
struct aa_ruleset {
168
int size;
169
170
/* TODO: merge policy and file */
171
struct aa_policydb *policy;
172
struct aa_policydb *file;
173
struct aa_caps caps;
174
175
struct aa_rlimit rlimits;
176
177
int secmark_count;
178
struct aa_secmark *secmark;
179
};
180
181
182
/* struct aa_attachment - data and rules for a profiles attachment
183
* @list:
184
* @xmatch_str: human readable attachment string
185
* @xmatch: optional extended matching for unconfined executables names
186
* @xmatch_len: xmatch prefix len, used to determine xmatch priority
187
* @xattr_count: number of xattrs in table
188
* @xattrs: table of xattrs
189
*/
190
struct aa_attachment {
191
const char *xmatch_str;
192
struct aa_policydb *xmatch;
193
unsigned int xmatch_len;
194
int xattr_count;
195
char **xattrs;
196
};
197
198
/* struct aa_profile - basic confinement data
199
* @base - base components of the profile (name, refcount, lists, lock ...)
200
* @parent: parent of profile
201
* @ns: namespace the profile is in
202
* @rename: optional profile name that this profile renamed
203
*
204
* @audit: the auditing mode of the profile
205
* @mode: the enforcement mode of the profile
206
* @path_flags: flags controlling path generation behavior
207
* @signal: the signal that should be used when kill is used
208
* @disconnected: what to prepend if attach_disconnected is specified
209
* @attach: attachment rules for the profile
210
* @rules: rules to be enforced
211
*
212
* learning_cache: the accesses learned in complain mode
213
* raw_data: rawdata of the loaded profile policy
214
* hash: cryptographic hash of the profile
215
* @dents: dentries for the profiles file entries in apparmorfs
216
* @dirname: name of the profile dir in apparmorfs
217
* @dents: set of dentries associated with the profile
218
* @data: hashtable for free-form policy aa_data
219
* @label - label this profile is an extension of
220
* @rules - label with the rule vec on its end
221
*
222
* The AppArmor profile contains the basic confinement data. Each profile
223
* has a name, and exists in a namespace. The @name and @exec_match are
224
* used to determine profile attachment against unconfined tasks. All other
225
* attachments are determined by profile X transition rules.
226
*
227
* Profiles have a hierarchy where hats and children profiles keep
228
* a reference to their parent.
229
*
230
* Profile names can not begin with a : and can not contain the \0
231
* character. If a profile name begins with / it will be considered when
232
* determining profile attachment on "unconfined" tasks.
233
*/
234
struct aa_profile {
235
struct aa_policy base;
236
struct aa_profile __rcu *parent;
237
238
struct aa_ns *ns;
239
const char *rename;
240
241
enum audit_mode audit;
242
long mode;
243
u32 path_flags;
244
int signal;
245
const char *disconnected;
246
247
struct aa_attachment attach;
248
249
struct aa_loaddata *rawdata;
250
unsigned char *hash;
251
char *dirname;
252
struct dentry *dents[AAFS_PROF_SIZEOF];
253
struct rhashtable *data;
254
255
int n_rules;
256
/* special - variable length must be last entry in profile */
257
struct aa_label label;
258
};
259
260
extern enum profile_mode aa_g_profile_mode;
261
262
#define AA_MAY_LOAD_POLICY AA_MAY_APPEND
263
#define AA_MAY_REPLACE_POLICY AA_MAY_WRITE
264
#define AA_MAY_REMOVE_POLICY AA_MAY_DELETE
265
266
#define profiles_ns(P) ((P)->ns)
267
#define name_is_shared(A, B) ((A)->hname && (A)->hname == (B)->hname)
268
269
struct aa_ruleset *aa_alloc_ruleset(gfp_t gfp);
270
struct aa_profile *aa_alloc_profile(const char *name, struct aa_proxy *proxy,
271
gfp_t gfp);
272
struct aa_profile *aa_alloc_null(struct aa_profile *parent, const char *name,
273
gfp_t gfp);
274
struct aa_profile *aa_new_learning_profile(struct aa_profile *parent, bool hat,
275
const char *base, gfp_t gfp);
276
void aa_free_profile(struct aa_profile *profile);
277
struct aa_profile *aa_find_child(struct aa_profile *parent, const char *name);
278
struct aa_profile *aa_lookupn_profile(struct aa_ns *ns, const char *hname,
279
size_t n);
280
struct aa_profile *aa_fqlookupn_profile(struct aa_label *base,
281
const char *fqname, size_t n);
282
283
ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_label *label,
284
u32 mask, struct aa_loaddata *udata);
285
ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_label *label,
286
char *name, size_t size);
287
void __aa_profile_list_release(struct list_head *head);
288
289
#define profile_unconfined(X) ((X)->mode == APPARMOR_UNCONFINED)
290
291
/**
292
* aa_get_newest_profile - simple wrapper fn to wrap the label version
293
* @p: profile (NOT NULL)
294
*
295
* Returns refcount to newest version of the profile (maybe @p)
296
*
297
* Requires: @p must be held with a valid refcount
298
*/
299
static inline struct aa_profile *aa_get_newest_profile(struct aa_profile *p)
300
{
301
return labels_profile(aa_get_newest_label(&p->label));
302
}
303
304
static inline aa_state_t RULE_MEDIATES(struct aa_ruleset *rules,
305
unsigned char class)
306
{
307
if (class <= AA_CLASS_LAST)
308
return rules->policy->start[class];
309
else
310
return aa_dfa_match_len(rules->policy->dfa,
311
rules->policy->start[0], &class, 1);
312
}
313
314
static inline aa_state_t RULE_MEDIATES_v9NET(struct aa_ruleset *rules)
315
{
316
return RULE_MEDIATES(rules, AA_CLASS_NETV9);
317
}
318
319
static inline aa_state_t RULE_MEDIATES_NET(struct aa_ruleset *rules)
320
{
321
/* can not use RULE_MEDIATE_v9AF here, because AF match fail
322
* can not be distiguished from class match fail, and we only
323
* fallback to checking older class on class match failure
324
*/
325
aa_state_t state = RULE_MEDIATES(rules, AA_CLASS_NETV9);
326
327
/* fallback and check v7/8 if v9 is NOT mediated */
328
if (!state)
329
state = RULE_MEDIATES(rules, AA_CLASS_NET);
330
331
return state;
332
}
333
334
335
void aa_compute_profile_mediates(struct aa_profile *profile);
336
static inline bool profile_mediates(struct aa_profile *profile,
337
unsigned char class)
338
{
339
return label_mediates(&profile->label, class);
340
}
341
342
static inline bool profile_mediates_safe(struct aa_profile *profile,
343
unsigned char class)
344
{
345
return label_mediates_safe(&profile->label, class);
346
}
347
348
/**
349
* aa_get_profile - increment refcount on profile @p
350
* @p: profile (MAYBE NULL)
351
*
352
* Returns: pointer to @p if @p is NULL will return NULL
353
* Requires: @p must be held with valid refcount when called
354
*/
355
static inline struct aa_profile *aa_get_profile(struct aa_profile *p)
356
{
357
if (p)
358
kref_get(&(p->label.count));
359
360
return p;
361
}
362
363
/**
364
* aa_get_profile_not0 - increment refcount on profile @p found via lookup
365
* @p: profile (MAYBE NULL)
366
*
367
* Returns: pointer to @p if @p is NULL will return NULL
368
* Requires: @p must be held with valid refcount when called
369
*/
370
static inline struct aa_profile *aa_get_profile_not0(struct aa_profile *p)
371
{
372
if (p && kref_get_unless_zero(&p->label.count))
373
return p;
374
375
return NULL;
376
}
377
378
/**
379
* aa_get_profile_rcu - increment a refcount profile that can be replaced
380
* @p: pointer to profile that can be replaced (NOT NULL)
381
*
382
* Returns: pointer to a refcounted profile.
383
* else NULL if no profile
384
*/
385
static inline struct aa_profile *aa_get_profile_rcu(struct aa_profile __rcu **p)
386
{
387
struct aa_profile *c;
388
389
rcu_read_lock();
390
do {
391
c = rcu_dereference(*p);
392
} while (c && !kref_get_unless_zero(&c->label.count));
393
rcu_read_unlock();
394
395
return c;
396
}
397
398
/**
399
* aa_put_profile - decrement refcount on profile @p
400
* @p: profile (MAYBE NULL)
401
*/
402
static inline void aa_put_profile(struct aa_profile *p)
403
{
404
if (p)
405
kref_put(&p->label.count, aa_label_kref);
406
}
407
408
static inline int AUDIT_MODE(struct aa_profile *profile)
409
{
410
if (aa_g_audit != AUDIT_NORMAL)
411
return aa_g_audit;
412
413
return profile->audit;
414
}
415
416
bool aa_policy_view_capable(const struct cred *subj_cred,
417
struct aa_label *label, struct aa_ns *ns);
418
bool aa_policy_admin_capable(const struct cred *subj_cred,
419
struct aa_label *label, struct aa_ns *ns);
420
int aa_may_manage_policy(const struct cred *subj_cred,
421
struct aa_label *label, struct aa_ns *ns,
422
u32 mask);
423
bool aa_current_policy_view_capable(struct aa_ns *ns);
424
bool aa_current_policy_admin_capable(struct aa_ns *ns);
425
426
#endif /* __AA_POLICY_H */
427
428