Skip to content

Commit 637f688

Browse files
committed
apparmor: switch from profiles to using labels on contexts
Begin the actual switch to using domain labels by storing them on the context and converting the label to a singular profile where possible. Signed-off-by: John Johansen <[email protected]>
1 parent f1bd904 commit 637f688

File tree

20 files changed

+686
-529
lines changed

20 files changed

+686
-529
lines changed

security/apparmor/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
44

55
apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
66
path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
7-
resource.o secid.o file.o policy_ns.o
7+
resource.o secid.o file.o policy_ns.o label.o
88
apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o
99

1010
clean-files := capability_names.h rlim_names.h

security/apparmor/apparmorfs.c

Lines changed: 70 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -405,26 +405,26 @@ static struct aa_loaddata *aa_simple_write_to_buffer(const char __user *userbuf,
405405
static ssize_t policy_update(u32 mask, const char __user *buf, size_t size,
406406
loff_t *pos, struct aa_ns *ns)
407407
{
408-
ssize_t error;
409408
struct aa_loaddata *data;
410-
struct aa_profile *profile;
409+
struct aa_label *label;
410+
ssize_t error;
411411

412-
profile = begin_current_profile_crit_section();
412+
label = begin_current_label_crit_section();
413413

414414
/* high level check about policy management - fine grained in
415415
* below after unpack
416416
*/
417-
error = aa_may_manage_policy(profile, ns, mask);
417+
error = aa_may_manage_policy(label, ns, mask);
418418
if (error)
419419
return error;
420420

421421
data = aa_simple_write_to_buffer(buf, size, size, pos);
422422
error = PTR_ERR(data);
423423
if (!IS_ERR(data)) {
424-
error = aa_replace_profiles(ns, profile, mask, data);
424+
error = aa_replace_profiles(ns, label, mask, data);
425425
aa_put_loaddata(data);
426426
}
427-
end_current_profile_crit_section(profile);
427+
end_current_label_crit_section(label);
428428

429429
return error;
430430
}
@@ -468,15 +468,15 @@ static ssize_t profile_remove(struct file *f, const char __user *buf,
468468
size_t size, loff_t *pos)
469469
{
470470
struct aa_loaddata *data;
471-
struct aa_profile *profile;
471+
struct aa_label *label;
472472
ssize_t error;
473473
struct aa_ns *ns = aa_get_ns(f->f_inode->i_private);
474474

475-
profile = begin_current_profile_crit_section();
475+
label = begin_current_label_crit_section();
476476
/* high level check about policy management - fine grained in
477477
* below after unpack
478478
*/
479-
error = aa_may_manage_policy(profile, ns, AA_MAY_REMOVE_POLICY);
479+
error = aa_may_manage_policy(label, ns, AA_MAY_REMOVE_POLICY);
480480
if (error)
481481
goto out;
482482

@@ -489,11 +489,11 @@ static ssize_t profile_remove(struct file *f, const char __user *buf,
489489
error = PTR_ERR(data);
490490
if (!IS_ERR(data)) {
491491
data->data[size] = 0;
492-
error = aa_remove_profiles(ns, profile, data->data, size);
492+
error = aa_remove_profiles(ns, label, data->data, size);
493493
aa_put_loaddata(data);
494494
}
495495
out:
496-
end_current_profile_crit_section(profile);
496+
end_current_label_crit_section(label);
497497
aa_put_ns(ns);
498498
return error;
499499
}
@@ -605,7 +605,7 @@ static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms,
605605
struct aa_dfa *dfa;
606606
unsigned int state = 0;
607607

608-
if (unconfined(profile))
608+
if (profile_unconfined(profile))
609609
return;
610610
if (profile->file.dfa && *match_str == AA_CLASS_FILE) {
611611
dfa = profile->file.dfa;
@@ -655,7 +655,7 @@ static ssize_t query_data(char *buf, size_t buf_len,
655655
{
656656
char *out;
657657
const char *key;
658-
struct aa_profile *profile, *curr;
658+
struct aa_label *label, *curr;
659659
struct aa_data *data;
660660
u32 bytes, blocks;
661661
__le32 outle32;
@@ -672,11 +672,11 @@ static ssize_t query_data(char *buf, size_t buf_len,
672672
if (buf_len < sizeof(bytes) + sizeof(blocks))
673673
return -EINVAL; /* not enough space */
674674

675-
curr = begin_current_profile_crit_section();
676-
profile = aa_fqlookupn_profile(curr, query, strnlen(query, query_len));
677-
end_current_profile_crit_section(curr);
678-
if (!profile)
679-
return -ENOENT;
675+
curr = begin_current_label_crit_section();
676+
label = aa_label_parse(curr, query, GFP_KERNEL, false, false);
677+
end_current_label_crit_section(curr);
678+
if (IS_ERR(label))
679+
return PTR_ERR(label);
680680

681681
/* We are going to leave space for two numbers. The first is the total
682682
* number of bytes we are writing after the first number. This is so
@@ -690,13 +690,16 @@ static ssize_t query_data(char *buf, size_t buf_len,
690690
out = buf + sizeof(bytes) + sizeof(blocks);
691691

692692
blocks = 0;
693-
if (profile->data) {
694-
data = rhashtable_lookup_fast(profile->data, &key,
695-
profile->data->p);
693+
if (labels_profile(label)->data) {
694+
data = rhashtable_lookup_fast(labels_profile(label)->data, &key,
695+
labels_profile(label)->data->p);
696696

697697
if (data) {
698-
if (out + sizeof(outle32) + data->size > buf + buf_len)
698+
if (out + sizeof(outle32) + data->size >
699+
buf + buf_len) {
700+
aa_put_label(label);
699701
return -EINVAL; /* not enough space */
702+
}
700703
outle32 = __cpu_to_le32(data->size);
701704
memcpy(out, &outle32, sizeof(outle32));
702705
out += sizeof(outle32);
@@ -705,7 +708,7 @@ static ssize_t query_data(char *buf, size_t buf_len,
705708
blocks++;
706709
}
707710
}
708-
aa_put_profile(profile);
711+
aa_put_label(label);
709712

710713
outle32 = __cpu_to_le32(out - buf - sizeof(bytes));
711714
memcpy(buf, &outle32, sizeof(outle32));
@@ -738,7 +741,7 @@ static ssize_t query_data(char *buf, size_t buf_len,
738741
static ssize_t query_label(char *buf, size_t buf_len,
739742
char *query, size_t query_len, bool view_only)
740743
{
741-
struct aa_profile *profile, *curr;
744+
struct aa_label *label, *curr;
742745
char *label_name, *match_str;
743746
size_t label_name_len, match_len;
744747
struct aa_perms perms;
@@ -760,14 +763,14 @@ static ssize_t query_label(char *buf, size_t buf_len,
760763
match_str = label_name + label_name_len + 1;
761764
match_len = query_len - label_name_len - 1;
762765

763-
curr = begin_current_profile_crit_section();
764-
profile = aa_fqlookupn_profile(curr, label_name, label_name_len);
765-
end_current_profile_crit_section(curr);
766-
if (!profile)
767-
return -ENOENT;
766+
curr = begin_current_label_crit_section();
767+
label = aa_label_parse(curr, label_name, GFP_KERNEL, false, false);
768+
end_current_label_crit_section(curr);
769+
if (IS_ERR(label))
770+
return PTR_ERR(label);
768771

769772
perms = allperms;
770-
profile_query_cb(profile, &perms, match_str, match_len);
773+
profile_query_cb(labels_profile(label), &perms, match_str, match_len);
771774

772775
return scnprintf(buf, buf_len,
773776
"allow 0x%08x\ndeny 0x%08x\naudit 0x%08x\nquiet 0x%08x\n",
@@ -1026,50 +1029,54 @@ static int seq_profile_release(struct inode *inode, struct file *file)
10261029
static int seq_profile_name_show(struct seq_file *seq, void *v)
10271030
{
10281031
struct aa_proxy *proxy = seq->private;
1029-
struct aa_profile *profile = aa_get_profile_rcu(&proxy->profile);
1032+
struct aa_label *label = aa_get_label_rcu(&proxy->label);
1033+
struct aa_profile *profile = labels_profile(label);
10301034
seq_printf(seq, "%s\n", profile->base.name);
1031-
aa_put_profile(profile);
1035+
aa_put_label(label);
10321036

10331037
return 0;
10341038
}
10351039

10361040
static int seq_profile_mode_show(struct seq_file *seq, void *v)
10371041
{
10381042
struct aa_proxy *proxy = seq->private;
1039-
struct aa_profile *profile = aa_get_profile_rcu(&proxy->profile);
1043+
struct aa_label *label = aa_get_label_rcu(&proxy->label);
1044+
struct aa_profile *profile = labels_profile(label);
10401045
seq_printf(seq, "%s\n", aa_profile_mode_names[profile->mode]);
1041-
aa_put_profile(profile);
1046+
aa_put_label(label);
10421047

10431048
return 0;
10441049
}
10451050

10461051
static int seq_profile_attach_show(struct seq_file *seq, void *v)
10471052
{
10481053
struct aa_proxy *proxy = seq->private;
1049-
struct aa_profile *profile = aa_get_profile_rcu(&proxy->profile);
1054+
struct aa_label *label = aa_get_label_rcu(&proxy->label);
1055+
struct aa_profile *profile = labels_profile(label);
10501056
if (profile->attach)
10511057
seq_printf(seq, "%s\n", profile->attach);
10521058
else if (profile->xmatch)
10531059
seq_puts(seq, "<unknown>\n");
10541060
else
10551061
seq_printf(seq, "%s\n", profile->base.name);
1056-
aa_put_profile(profile);
1062+
aa_put_label(label);
10571063

10581064
return 0;
10591065
}
10601066

10611067
static int seq_profile_hash_show(struct seq_file *seq, void *v)
10621068
{
10631069
struct aa_proxy *proxy = seq->private;
1064-
struct aa_profile *profile = aa_get_profile_rcu(&proxy->profile);
1070+
struct aa_label *label = aa_get_label_rcu(&proxy->label);
1071+
struct aa_profile *profile = labels_profile(label);
10651072
unsigned int i, size = aa_hash_size();
10661073

10671074
if (profile->hash) {
10681075
for (i = 0; i < size; i++)
10691076
seq_printf(seq, "%.2x", profile->hash[i]);
10701077
seq_putc(seq, '\n');
10711078
}
1072-
aa_put_profile(profile);
1079+
aa_put_label(label);
10731080

10741081
return 0;
10751082
}
@@ -1101,22 +1108,22 @@ static const struct file_operations seq_ns_ ##NAME ##_fops = { \
11011108

11021109
static int seq_ns_level_show(struct seq_file *seq, void *v)
11031110
{
1104-
struct aa_profile *profile;
1111+
struct aa_label *label;
11051112

1106-
profile = begin_current_profile_crit_section();
1107-
seq_printf(seq, "%d\n", profile->ns->level);
1108-
end_current_profile_crit_section(profile);
1113+
label = begin_current_label_crit_section();
1114+
seq_printf(seq, "%d\n", labels_ns(label)->level);
1115+
end_current_label_crit_section(label);
11091116

11101117
return 0;
11111118
}
11121119

11131120
static int seq_ns_name_show(struct seq_file *seq, void *v)
11141121
{
1115-
struct aa_profile *profile;
1122+
struct aa_label *label = begin_current_label_crit_section();
11161123

1117-
profile = begin_current_profile_crit_section();
1118-
seq_printf(seq, "%s\n", aa_ns_name(profile->ns, profile->ns, true));
1119-
end_current_profile_crit_section(profile);
1124+
seq_printf(seq, "%s\n", aa_ns_name(labels_ns(label),
1125+
labels_ns(label), true));
1126+
end_current_label_crit_section(label);
11201127

11211128
return 0;
11221129
}
@@ -1380,7 +1387,7 @@ static struct dentry *create_profile_file(struct dentry *dir, const char *name,
13801387
struct aa_profile *profile,
13811388
const struct file_operations *fops)
13821389
{
1383-
struct aa_proxy *proxy = aa_get_proxy(profile->proxy);
1390+
struct aa_proxy *proxy = aa_get_proxy(profile->label.proxy);
13841391
struct dentry *dent;
13851392

13861393
dent = aafs_create_file(name, S_IFREG | 0444, dir, proxy, fops);
@@ -1541,9 +1548,12 @@ static int ns_mkdir_op(struct inode *dir, struct dentry *dentry, umode_t mode)
15411548
{
15421549
struct aa_ns *ns, *parent;
15431550
/* TODO: improve permission check */
1544-
struct aa_profile *profile = begin_current_profile_crit_section();
1545-
int error = aa_may_manage_policy(profile, NULL, AA_MAY_LOAD_POLICY);
1546-
end_current_profile_crit_section(profile);
1551+
struct aa_label *label;
1552+
int error;
1553+
1554+
label = begin_current_label_crit_section();
1555+
error = aa_may_manage_policy(label, NULL, AA_MAY_LOAD_POLICY);
1556+
end_current_label_crit_section(label);
15471557
if (error)
15481558
return error;
15491559

@@ -1587,13 +1597,16 @@ static int ns_rmdir_op(struct inode *dir, struct dentry *dentry)
15871597
{
15881598
struct aa_ns *ns, *parent;
15891599
/* TODO: improve permission check */
1590-
struct aa_profile *profile = begin_current_profile_crit_section();
1591-
int error = aa_may_manage_policy(profile, NULL, AA_MAY_LOAD_POLICY);
1592-
end_current_profile_crit_section(profile);
1600+
struct aa_label *label;
1601+
int error;
1602+
1603+
label = begin_current_label_crit_section();
1604+
error = aa_may_manage_policy(label, NULL, AA_MAY_LOAD_POLICY);
1605+
end_current_label_crit_section(label);
15931606
if (error)
15941607
return error;
15951608

1596-
parent = aa_get_ns(dir->i_private);
1609+
parent = aa_get_ns(dir->i_private);
15971610
/* rmdir calls the generic securityfs functions to remove files
15981611
* from the apparmor dir. It is up to the apparmor ns locking
15991612
* to avoid races.
@@ -1999,10 +2012,9 @@ static int seq_show_profile(struct seq_file *f, void *p)
19992012
struct aa_profile *profile = (struct aa_profile *)p;
20002013
struct aa_ns *root = f->private;
20012014

2002-
if (profile->ns != root)
2003-
seq_printf(f, ":%s://", aa_ns_name(root, profile->ns, true));
2004-
seq_printf(f, "%s (%s)\n", profile->base.hname,
2005-
aa_profile_mode_names[profile->mode]);
2015+
aa_label_seq_xprint(f, root, &profile->label,
2016+
FLAG_SHOW_MODE | FLAG_VIEW_SUBNS, GFP_KERNEL);
2017+
seq_putc(f, '\n');
20062018

20072019
return 0;
20082020
}

security/apparmor/audit.c

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,24 @@ static void audit_pre(struct audit_buffer *ab, void *ca)
7777
audit_log_format(ab, " error=%d", aad(sa)->error);
7878
}
7979

80-
if (aad(sa)->profile) {
81-
struct aa_profile *profile = aad(sa)->profile;
82-
if (profile->ns != root_ns) {
83-
audit_log_format(ab, " namespace=");
84-
audit_log_untrustedstring(ab, profile->ns->base.hname);
80+
if (aad(sa)->label) {
81+
struct aa_label *label = aad(sa)->label;
82+
83+
if (label_isprofile(label)) {
84+
struct aa_profile *profile = labels_profile(label);
85+
86+
if (profile->ns != root_ns) {
87+
audit_log_format(ab, " namespace=");
88+
audit_log_untrustedstring(ab,
89+
profile->ns->base.hname);
90+
}
91+
audit_log_format(ab, " profile=");
92+
audit_log_untrustedstring(ab, profile->base.hname);
93+
} else {
94+
audit_log_format(ab, " label=");
95+
aa_label_xaudit(ab, root_ns, label, FLAG_VIEW_SUBNS,
96+
GFP_ATOMIC);
8597
}
86-
audit_log_format(ab, " profile=");
87-
audit_log_untrustedstring(ab, profile->base.hname);
8898
}
8999

90100
if (aad(sa)->name) {
@@ -139,8 +149,7 @@ int aa_audit(int type, struct aa_profile *profile, struct common_audit_data *sa,
139149
if (KILL_MODE(profile) && type == AUDIT_APPARMOR_DENIED)
140150
type = AUDIT_APPARMOR_KILL;
141151

142-
if (!unconfined(profile))
143-
aad(sa)->profile = profile;
152+
aad(sa)->label = &profile->label;
144153

145154
aa_audit_msg(type, sa, cb);
146155

0 commit comments

Comments
 (0)