aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Garrett <mjg59@google.com>2018-05-24 16:27:46 -0400
committerJohn Johansen <john.johansen@canonical.com>2018-10-03 09:18:38 -0400
commit9caafbe2b4cf4c635826a2832e93cf648605de8b (patch)
tree3d09ad1db13f0be16c42f04133101b9a36f777e5
parent617a629c08bfffb05249131079d9a38322902e5b (diff)
apparmor: Parse secmark policy
Add support for parsing secmark policy provided by userspace, and store that in the overall policy. Signed-off-by: Matthew Garrett <mjg59@google.com> Signed-off-by: John Johansen <john.johansen@canonical.com>
-rw-r--r--security/apparmor/include/net.h10
-rw-r--r--security/apparmor/include/policy.h3
-rw-r--r--security/apparmor/policy.c3
-rw-r--r--security/apparmor/policy_unpack.c61
4 files changed, 77 insertions, 0 deletions
diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h
index ec7228e857a9..7334ac966d01 100644
--- a/security/apparmor/include/net.h
+++ b/security/apparmor/include/net.h
@@ -83,6 +83,13 @@ struct aa_sk_ctx {
83 __e; \ 83 __e; \
84}) 84})
85 85
86struct aa_secmark {
87 u8 audit;
88 u8 deny;
89 u32 secid;
90 char *label;
91};
92
86extern struct aa_sfs_entry aa_sfs_entry_network[]; 93extern struct aa_sfs_entry aa_sfs_entry_network[];
87 94
88void audit_net_cb(struct audit_buffer *ab, void *va); 95void audit_net_cb(struct audit_buffer *ab, void *va);
@@ -103,4 +110,7 @@ int aa_sk_perm(const char *op, u32 request, struct sock *sk);
103int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request, 110int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
104 struct socket *sock); 111 struct socket *sock);
105 112
113int apparmor_secmark_check(struct aa_label *label, char *op, u32 request,
114 u32 secid, struct sock *sk);
115
106#endif /* __AA_NET_H */ 116#endif /* __AA_NET_H */
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
index ab64c6b5db5a..8e6707c837be 100644
--- a/security/apparmor/include/policy.h
+++ b/security/apparmor/include/policy.h
@@ -155,6 +155,9 @@ struct aa_profile {
155 155
156 struct aa_rlimit rlimits; 156 struct aa_rlimit rlimits;
157 157
158 int secmark_count;
159 struct aa_secmark *secmark;
160
158 struct aa_loaddata *rawdata; 161 struct aa_loaddata *rawdata;
159 unsigned char *hash; 162 unsigned char *hash;
160 char *dirname; 163 char *dirname;
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index 1590e2de4e84..8d846a747b84 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -231,6 +231,9 @@ void aa_free_profile(struct aa_profile *profile)
231 for (i = 0; i < profile->xattr_count; i++) 231 for (i = 0; i < profile->xattr_count; i++)
232 kzfree(profile->xattrs[i]); 232 kzfree(profile->xattrs[i]);
233 kzfree(profile->xattrs); 233 kzfree(profile->xattrs);
234 for (i=0; i < profile->secmark_count; i++)
235 kzfree(profile->secmark[i].label);
236 kzfree(profile->secmark);
234 kzfree(profile->dirname); 237 kzfree(profile->dirname);
235 aa_put_dfa(profile->xmatch); 238 aa_put_dfa(profile->xmatch);
236 aa_put_dfa(profile->policy.dfa); 239 aa_put_dfa(profile->policy.dfa);
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
index 21cb384d712a..379682e2a8d5 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -292,6 +292,19 @@ fail:
292 return 0; 292 return 0;
293} 293}
294 294
295static bool unpack_u8(struct aa_ext *e, u8 *data, const char *name)
296{
297 if (unpack_nameX(e, AA_U8, name)) {
298 if (!inbounds(e, sizeof(u8)))
299 return 0;
300 if (data)
301 *data = get_unaligned((u8 *)e->pos);
302 e->pos += sizeof(u8);
303 return 1;
304 }
305 return 0;
306}
307
295static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name) 308static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name)
296{ 309{
297 if (unpack_nameX(e, AA_U32, name)) { 310 if (unpack_nameX(e, AA_U32, name)) {
@@ -529,6 +542,49 @@ fail:
529 return 0; 542 return 0;
530} 543}
531 544
545static bool unpack_secmark(struct aa_ext *e, struct aa_profile *profile)
546{
547 void *pos = e->pos;
548 int i, size;
549
550 if (unpack_nameX(e, AA_STRUCT, "secmark")) {
551 size = unpack_array(e, NULL);
552
553 profile->secmark = kcalloc(size, sizeof(struct aa_secmark),
554 GFP_KERNEL);
555 if (!profile->secmark)
556 goto fail;
557
558 profile->secmark_count = size;
559
560 for (i = 0; i < size; i++) {
561 if (!unpack_u8(e, &profile->secmark[i].audit, NULL))
562 goto fail;
563 if (!unpack_u8(e, &profile->secmark[i].deny, NULL))
564 goto fail;
565 if (!unpack_strdup(e, &profile->secmark[i].label, NULL))
566 goto fail;
567 }
568 if (!unpack_nameX(e, AA_ARRAYEND, NULL))
569 goto fail;
570 if (!unpack_nameX(e, AA_STRUCTEND, NULL))
571 goto fail;
572 }
573
574 return 1;
575
576fail:
577 if (profile->secmark) {
578 for (i = 0; i < size; i++)
579 kfree(profile->secmark[i].label);
580 kfree(profile->secmark);
581 profile->secmark_count = 0;
582 }
583
584 e->pos = pos;
585 return 0;
586}
587
532static bool unpack_rlimits(struct aa_ext *e, struct aa_profile *profile) 588static bool unpack_rlimits(struct aa_ext *e, struct aa_profile *profile)
533{ 589{
534 void *pos = e->pos; 590 void *pos = e->pos;
@@ -727,6 +783,11 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
727 goto fail; 783 goto fail;
728 } 784 }
729 785
786 if (!unpack_secmark(e, profile)) {
787 info = "failed to unpack profile secmark rules";
788 goto fail;
789 }
790
730 if (unpack_nameX(e, AA_STRUCT, "policydb")) { 791 if (unpack_nameX(e, AA_STRUCT, "policydb")) {
731 /* generic policy dfa - optional and may be NULL */ 792 /* generic policy dfa - optional and may be NULL */
732 info = "failed to unpack policydb"; 793 info = "failed to unpack policydb";