Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Matthew Garrett and committed by
John Johansen
9caafbe2 617a629c

+77
+10
security/apparmor/include/net.h
··· 83 83 __e; \ 84 84 }) 85 85 86 + struct aa_secmark { 87 + u8 audit; 88 + u8 deny; 89 + u32 secid; 90 + char *label; 91 + }; 92 + 86 93 extern struct aa_sfs_entry aa_sfs_entry_network[]; 87 94 88 95 void audit_net_cb(struct audit_buffer *ab, void *va); ··· 109 102 110 103 int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request, 111 104 struct socket *sock); 105 + 106 + int apparmor_secmark_check(struct aa_label *label, char *op, u32 request, 107 + u32 secid, struct sock *sk); 112 108 113 109 #endif /* __AA_NET_H */
+3
security/apparmor/include/policy.h
··· 155 155 156 156 struct aa_rlimit rlimits; 157 157 158 + int secmark_count; 159 + struct aa_secmark *secmark; 160 + 158 161 struct aa_loaddata *rawdata; 159 162 unsigned char *hash; 160 163 char *dirname;
+3
security/apparmor/policy.c
··· 231 231 for (i = 0; i < profile->xattr_count; i++) 232 232 kzfree(profile->xattrs[i]); 233 233 kzfree(profile->xattrs); 234 + for (i=0; i < profile->secmark_count; i++) 235 + kzfree(profile->secmark[i].label); 236 + kzfree(profile->secmark); 234 237 kzfree(profile->dirname); 235 238 aa_put_dfa(profile->xmatch); 236 239 aa_put_dfa(profile->policy.dfa);
+61
security/apparmor/policy_unpack.c
··· 292 292 return 0; 293 293 } 294 294 295 + static 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 + 295 308 static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name) 296 309 { 297 310 if (unpack_nameX(e, AA_U32, name)) { ··· 542 529 return 0; 543 530 } 544 531 532 + static bool unpack_secmark(struct aa_ext *e, struct aa_profile *profile) 533 + { 534 + void *pos = e->pos; 535 + int i, size; 536 + 537 + if (unpack_nameX(e, AA_STRUCT, "secmark")) { 538 + size = unpack_array(e, NULL); 539 + 540 + profile->secmark = kcalloc(size, sizeof(struct aa_secmark), 541 + GFP_KERNEL); 542 + if (!profile->secmark) 543 + goto fail; 544 + 545 + profile->secmark_count = size; 546 + 547 + for (i = 0; i < size; i++) { 548 + if (!unpack_u8(e, &profile->secmark[i].audit, NULL)) 549 + goto fail; 550 + if (!unpack_u8(e, &profile->secmark[i].deny, NULL)) 551 + goto fail; 552 + if (!unpack_strdup(e, &profile->secmark[i].label, NULL)) 553 + goto fail; 554 + } 555 + if (!unpack_nameX(e, AA_ARRAYEND, NULL)) 556 + goto fail; 557 + if (!unpack_nameX(e, AA_STRUCTEND, NULL)) 558 + goto fail; 559 + } 560 + 561 + return 1; 562 + 563 + fail: 564 + if (profile->secmark) { 565 + for (i = 0; i < size; i++) 566 + kfree(profile->secmark[i].label); 567 + kfree(profile->secmark); 568 + profile->secmark_count = 0; 569 + } 570 + 571 + e->pos = pos; 572 + return 0; 573 + } 574 + 545 575 static bool unpack_rlimits(struct aa_ext *e, struct aa_profile *profile) 546 576 { 547 577 void *pos = e->pos; ··· 780 724 781 725 if (!unpack_rlimits(e, profile)) { 782 726 info = "failed to unpack profile rlimits"; 727 + goto fail; 728 + } 729 + 730 + if (!unpack_secmark(e, profile)) { 731 + info = "failed to unpack profile secmark rules"; 783 732 goto fail; 784 733 } 785 734