Skip to content

Commit 9afdc6a

Browse files
committed
apparmor: transition from a list of rules to a vector of rules
The set of rules on a profile is not dynamically extended, instead if a new ruleset is needed a new version of the profile is created. This allows us to use a vector of rules instead of a list, slightly reducing memory usage and simplifying the code. Signed-off-by: John Johansen <[email protected]>
1 parent f9c9dce commit 9afdc6a

File tree

15 files changed

+85
-113
lines changed

15 files changed

+85
-113
lines changed

security/apparmor/af_unix.c

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -202,8 +202,7 @@ static int profile_create_perm(struct aa_profile *profile, int family,
202202
int type, int protocol,
203203
struct apparmor_audit_data *ad)
204204
{
205-
struct aa_ruleset *rules = list_first_entry(&profile->rules,
206-
typeof(*rules), list);
205+
struct aa_ruleset *rules = profile->label.rules[0];
207206
aa_state_t state;
208207

209208
AA_BUG(!profile);
@@ -227,9 +226,7 @@ static int profile_sk_perm(struct aa_profile *profile,
227226
struct apparmor_audit_data *ad,
228227
u32 request, struct sock *sk, struct path *path)
229228
{
230-
struct aa_ruleset *rules = list_first_entry(&profile->rules,
231-
typeof(*rules),
232-
list);
229+
struct aa_ruleset *rules = profile->label.rules[0];
233230
struct aa_perms *p = NULL;
234231
aa_state_t state;
235232

@@ -257,8 +254,7 @@ static int profile_sk_perm(struct aa_profile *profile,
257254
static int profile_bind_perm(struct aa_profile *profile, struct sock *sk,
258255
struct apparmor_audit_data *ad)
259256
{
260-
struct aa_ruleset *rules = list_first_entry(&profile->rules,
261-
typeof(*rules), list);
257+
struct aa_ruleset *rules = profile->label.rules[0];
262258
struct aa_perms *p = NULL;
263259
aa_state_t state;
264260

@@ -289,8 +285,7 @@ static int profile_bind_perm(struct aa_profile *profile, struct sock *sk,
289285
static int profile_listen_perm(struct aa_profile *profile, struct sock *sk,
290286
int backlog, struct apparmor_audit_data *ad)
291287
{
292-
struct aa_ruleset *rules = list_first_entry(&profile->rules,
293-
typeof(*rules), list);
288+
struct aa_ruleset *rules = profile->label.rules[0];
294289
struct aa_perms *p = NULL;
295290
aa_state_t state;
296291

@@ -327,8 +322,7 @@ static int profile_accept_perm(struct aa_profile *profile,
327322
struct sock *sk,
328323
struct apparmor_audit_data *ad)
329324
{
330-
struct aa_ruleset *rules = list_first_entry(&profile->rules,
331-
typeof(*rules), list);
325+
struct aa_ruleset *rules = profile->label.rules[0];
332326
struct aa_perms *p = NULL;
333327
aa_state_t state;
334328

@@ -358,8 +352,7 @@ static int profile_opt_perm(struct aa_profile *profile, u32 request,
358352
struct sock *sk, int optname,
359353
struct apparmor_audit_data *ad)
360354
{
361-
struct aa_ruleset *rules = list_first_entry(&profile->rules,
362-
typeof(*rules), list);
355+
struct aa_ruleset *rules = profile->label.rules[0];
363356
struct aa_perms *p = NULL;
364357
aa_state_t state;
365358

@@ -399,8 +392,7 @@ static int profile_peer_perm(struct aa_profile *profile, u32 request,
399392
struct aa_label *peer_label,
400393
struct apparmor_audit_data *ad)
401394
{
402-
struct aa_ruleset *rules = list_first_entry(&profile->rules,
403-
typeof(*rules), list);
395+
struct aa_ruleset *rules = profile->label.rules[0];
404396
struct aa_perms *p = NULL;
405397
aa_state_t state;
406398

security/apparmor/apparmorfs.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -612,8 +612,7 @@ static const struct file_operations aa_fs_ns_revision_fops = {
612612
static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms,
613613
const char *match_str, size_t match_len)
614614
{
615-
struct aa_ruleset *rules = list_first_entry(&profile->rules,
616-
typeof(*rules), list);
615+
struct aa_ruleset *rules = profile->label.rules[0];
617616
struct aa_perms tmp = { };
618617
aa_state_t state = DFA_NOMATCH;
619618

security/apparmor/capability.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,7 @@ static int audit_caps(struct apparmor_audit_data *ad, struct aa_profile *profile
6969
{
7070
const u64 AUDIT_CACHE_TIMEOUT_NS = 1000*1000*1000; /* 1 second */
7171

72-
struct aa_ruleset *rules = list_first_entry(&profile->rules,
73-
typeof(*rules), list);
72+
struct aa_ruleset *rules = profile->label.rules[0];
7473
struct audit_cache *ent;
7574
int type = AUDIT_APPARMOR_AUTO;
7675

@@ -122,8 +121,7 @@ static int audit_caps(struct apparmor_audit_data *ad, struct aa_profile *profile
122121
static int profile_capable(struct aa_profile *profile, int cap,
123122
unsigned int opts, struct apparmor_audit_data *ad)
124123
{
125-
struct aa_ruleset *rules = list_first_entry(&profile->rules,
126-
typeof(*rules), list);
124+
struct aa_ruleset *rules = profile->label.rules[0];
127125
aa_state_t state;
128126
int error;
129127

@@ -195,8 +193,7 @@ int aa_capable(const struct cred *subj_cred, struct aa_label *label,
195193

196194
kernel_cap_t aa_profile_capget(struct aa_profile *profile)
197195
{
198-
struct aa_ruleset *rules = list_first_entry(&profile->rules,
199-
typeof(*rules), list);
196+
struct aa_ruleset *rules = profile->label.rules[0];
200197
aa_state_t state;
201198

202199
state = RULE_MEDIATES(rules, AA_CLASS_CAP);

security/apparmor/domain.c

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,7 @@ static inline aa_state_t match_component(struct aa_profile *profile,
9393
struct aa_profile *tp,
9494
bool stack, aa_state_t state)
9595
{
96-
struct aa_ruleset *rules = list_first_entry(&profile->rules,
97-
typeof(*rules), list);
96+
struct aa_ruleset *rules = profile->label.rules[0];
9897
const char *ns_name;
9998

10099
if (stack)
@@ -131,8 +130,7 @@ static int label_compound_match(struct aa_profile *profile,
131130
aa_state_t state, bool subns, u32 request,
132131
struct aa_perms *perms)
133132
{
134-
struct aa_ruleset *rules = list_first_entry(&profile->rules,
135-
typeof(*rules), list);
133+
struct aa_ruleset *rules = profile->label.rules[0];
136134
struct aa_profile *tp;
137135
struct label_it i;
138136
struct path_cond cond = { };
@@ -194,8 +192,7 @@ static int label_components_match(struct aa_profile *profile,
194192
aa_state_t start, bool subns, u32 request,
195193
struct aa_perms *perms)
196194
{
197-
struct aa_ruleset *rules = list_first_entry(&profile->rules,
198-
typeof(*rules), list);
195+
struct aa_ruleset *rules = profile->label.rules[0];
199196
struct aa_profile *tp;
200197
struct label_it i;
201198
struct aa_perms tmp;
@@ -520,8 +517,7 @@ static const char *next_name(int xtype, const char *name)
520517
struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex,
521518
const char **name)
522519
{
523-
struct aa_ruleset *rules = list_first_entry(&profile->rules,
524-
typeof(*rules), list);
520+
struct aa_ruleset *rules = profile->label.rules[0];
525521
struct aa_label *label = NULL;
526522
u32 xtype = xindex & AA_X_TYPE_MASK;
527523
int index = xindex & AA_X_INDEX_MASK;
@@ -575,8 +571,6 @@ static struct aa_label *x_to_label(struct aa_profile *profile,
575571
const char **lookupname,
576572
const char **info)
577573
{
578-
struct aa_ruleset *rules = list_first_entry(&profile->rules,
579-
typeof(*rules), list);
580574
struct aa_label *new = NULL;
581575
struct aa_label *stack = NULL;
582576
struct aa_ns *ns = profile->ns;
@@ -668,8 +662,7 @@ static struct aa_label *profile_transition(const struct cred *subj_cred,
668662
char *buffer, struct path_cond *cond,
669663
bool *secure_exec)
670664
{
671-
struct aa_ruleset *rules = list_first_entry(&profile->rules,
672-
typeof(*rules), list);
665+
struct aa_ruleset *rules = profile->label.rules[0];
673666
struct aa_label *new = NULL;
674667
struct aa_profile *new_profile = NULL;
675668
const char *info = NULL, *name = NULL, *target = NULL;
@@ -802,8 +795,7 @@ static int profile_onexec(const struct cred *subj_cred,
802795
char *buffer, struct path_cond *cond,
803796
bool *secure_exec)
804797
{
805-
struct aa_ruleset *rules = list_first_entry(&profile->rules,
806-
typeof(*rules), list);
798+
struct aa_ruleset *rules = profile->label.rules[0];
807799
aa_state_t state = rules->file->start[AA_CLASS_FILE];
808800
struct aa_perms perms = {};
809801
const char *xname = NULL, *info = "change_profile onexec";
@@ -1361,8 +1353,7 @@ static int change_profile_perms_wrapper(const char *op, const char *name,
13611353
struct aa_label *target, bool stack,
13621354
u32 request, struct aa_perms *perms)
13631355
{
1364-
struct aa_ruleset *rules = list_first_entry(&profile->rules,
1365-
typeof(*rules), list);
1356+
struct aa_ruleset *rules = profile->label.rules[0];
13661357
const char *info = NULL;
13671358
int error = 0;
13681359

security/apparmor/file.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,7 @@ int __aa_path_perm(const char *op, const struct cred *subj_cred,
223223
u32 request, struct path_cond *cond, int flags,
224224
struct aa_perms *perms)
225225
{
226-
struct aa_ruleset *rules = list_first_entry(&profile->rules,
227-
typeof(*rules), list);
226+
struct aa_ruleset *rules = profile->label.rules[0];
228227
int e = 0;
229228

230229
if (profile_unconfined(profile) ||
@@ -323,8 +322,7 @@ static int profile_path_link(const struct cred *subj_cred,
323322
const struct path *target, char *buffer2,
324323
struct path_cond *cond)
325324
{
326-
struct aa_ruleset *rules = list_first_entry(&profile->rules,
327-
typeof(*rules), list);
325+
struct aa_ruleset *rules = profile->label.rules[0];
328326
const char *lname, *tname = NULL;
329327
struct aa_perms lperms = {}, perms;
330328
const char *info = NULL;

security/apparmor/include/label.h

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "lib.h"
2020

2121
struct aa_ns;
22+
struct aa_ruleset;
2223

2324
#define LOCAL_VEC_ENTRIES 8
2425
#define DEFINE_VEC(T, V) \
@@ -109,7 +110,7 @@ struct label_it {
109110
int i, j;
110111
};
111112

112-
/* struct aa_label - lazy labeling struct
113+
/* struct aa_label_base - base info of label
113114
* @count: ref count of active users
114115
* @node: rbtree position
115116
* @rcu: rcu callback struct
@@ -118,7 +119,10 @@ struct label_it {
118119
* @flags: stale and other flags - values may change under label set lock
119120
* @secid: secid that references this label
120121
* @size: number of entries in @ent[]
121-
* @ent: set of profiles for label, actual size determined by @size
122+
* @mediates: bitmask for label_mediates
123+
* profile: label vec when embedded in a profile FLAG_PROFILE is set
124+
* rules: variable length rules in a profile FLAG_PROFILE is set
125+
* vec: vector of profiles comprising the compound label
122126
*/
123127
struct aa_label {
124128
struct kref count;
@@ -130,7 +134,17 @@ struct aa_label {
130134
u32 secid;
131135
int size;
132136
u64 mediates;
133-
struct aa_profile *vec[];
137+
union {
138+
struct {
139+
/* only used is the label is a profile, size of
140+
* rules[] is determined by the profile
141+
* profile[1] is poison or null as guard
142+
*/
143+
struct aa_profile *profile[2];
144+
DECLARE_FLEX_ARRAY(struct aa_ruleset *, rules);
145+
};
146+
DECLARE_FLEX_ARRAY(struct aa_profile *, vec);
147+
};
134148
};
135149

136150
#define last_error(E, FN) \

security/apparmor/include/policy.h

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,6 @@ struct aa_data {
165165
* @secmark: secmark label match info
166166
*/
167167
struct aa_ruleset {
168-
struct list_head list;
169-
170168
int size;
171169

172170
/* TODO: merge policy and file */
@@ -180,6 +178,7 @@ struct aa_ruleset {
180178
struct aa_secmark *secmark;
181179
};
182180

181+
183182
/* struct aa_attachment - data and rules for a profiles attachment
184183
* @list:
185184
* @xmatch_str: human readable attachment string
@@ -218,6 +217,7 @@ struct aa_attachment {
218217
* @dents: set of dentries associated with the profile
219218
* @data: hashtable for free-form policy aa_data
220219
* @label - label this profile is an extension of
220+
* @rules - label with the rule vec on its end
221221
*
222222
* The AppArmor profile contains the basic confinement data. Each profile
223223
* has a name, and exists in a namespace. The @name and @exec_match are
@@ -245,14 +245,14 @@ struct aa_profile {
245245
const char *disconnected;
246246

247247
struct aa_attachment attach;
248-
struct list_head rules;
249248

250249
struct aa_loaddata *rawdata;
251250
unsigned char *hash;
252251
char *dirname;
253252
struct dentry *dents[AAFS_PROF_SIZEOF];
254253
struct rhashtable *data;
255254

255+
int n_rules;
256256
/* special - variable length must be last entry in profile */
257257
struct aa_label label;
258258
};
@@ -332,16 +332,6 @@ static inline aa_state_t RULE_MEDIATES_NET(struct aa_ruleset *rules)
332332
}
333333

334334

335-
static inline aa_state_t ANY_RULE_MEDIATES(struct list_head *head,
336-
unsigned char class)
337-
{
338-
struct aa_ruleset *rule;
339-
340-
/* TODO: change to list walk */
341-
rule = list_first_entry(head, typeof(*rule), list);
342-
return RULE_MEDIATES(rule, class);
343-
}
344-
345335
void aa_compute_profile_mediates(struct aa_profile *profile);
346336
static inline bool profile_mediates(struct aa_profile *profile,
347337
unsigned char class)

security/apparmor/ipc.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,7 @@ static int profile_signal_perm(const struct cred *cred,
8080
struct aa_label *peer, u32 request,
8181
struct apparmor_audit_data *ad)
8282
{
83-
struct aa_ruleset *rules = list_first_entry(&profile->rules,
84-
typeof(*rules), list);
83+
struct aa_ruleset *rules = profile->label.rules[0];
8584
struct aa_perms perms;
8685
aa_state_t state;
8786

security/apparmor/lsm.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,7 @@ static int apparmor_capget(const struct task_struct *target, kernel_cap_t *effec
182182
struct aa_ruleset *rules;
183183
kernel_cap_t allowed;
184184

185-
rules = list_first_entry(&profile->rules,
186-
typeof(*rules), list);
185+
rules = profile->label.rules[0];
187186
allowed = aa_profile_capget(profile);
188187
*effective = cap_intersect(*effective, allowed);
189188
*permitted = cap_intersect(*permitted, allowed);
@@ -636,7 +635,7 @@ static int profile_uring(struct aa_profile *profile, u32 request,
636635

637636
AA_BUG(!profile);
638637

639-
rules = list_first_entry(&profile->rules, typeof(*rules), list);
638+
rules = profile->label.rules[0];
640639
state = RULE_MEDIATES(rules, AA_CLASS_IO_URING);
641640
if (state) {
642641
struct aa_perms perms = { };

security/apparmor/mount.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -311,8 +311,7 @@ static int match_mnt_path_str(const struct cred *subj_cred,
311311
{
312312
struct aa_perms perms = { };
313313
const char *mntpnt = NULL, *info = NULL;
314-
struct aa_ruleset *rules = list_first_entry(&profile->rules,
315-
typeof(*rules), list);
314+
struct aa_ruleset *rules = profile->label.rules[0];
316315
int pos, error;
317316

318317
AA_BUG(!profile);
@@ -371,8 +370,7 @@ static int match_mnt(const struct cred *subj_cred,
371370
bool binary)
372371
{
373372
const char *devname = NULL, *info = NULL;
374-
struct aa_ruleset *rules = list_first_entry(&profile->rules,
375-
typeof(*rules), list);
373+
struct aa_ruleset *rules = profile->label.rules[0];
376374
int error = -EACCES;
377375

378376
AA_BUG(!profile);
@@ -604,8 +602,7 @@ static int profile_umount(const struct cred *subj_cred,
604602
struct aa_profile *profile, const struct path *path,
605603
char *buffer)
606604
{
607-
struct aa_ruleset *rules = list_first_entry(&profile->rules,
608-
typeof(*rules), list);
605+
struct aa_ruleset *rules = profile->label.rules[0];
609606
struct aa_perms perms = { };
610607
const char *name = NULL, *info = NULL;
611608
aa_state_t state;
@@ -668,8 +665,7 @@ static struct aa_label *build_pivotroot(const struct cred *subj_cred,
668665
const struct path *old_path,
669666
char *old_buffer)
670667
{
671-
struct aa_ruleset *rules = list_first_entry(&profile->rules,
672-
typeof(*rules), list);
668+
struct aa_ruleset *rules = profile->label.rules[0];
673669
const char *old_name, *new_name = NULL, *info = NULL;
674670
const char *trans_name = NULL;
675671
struct aa_perms perms = { };

0 commit comments

Comments
 (0)