aboutsummaryrefslogtreecommitdiffstats
path: root/security/apparmor/policy_unpack.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/apparmor/policy_unpack.c')
-rw-r--r--security/apparmor/policy_unpack.c105
1 files changed, 87 insertions, 18 deletions
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
index c600f4dd1783..5a2aec358322 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -85,9 +85,9 @@ static void audit_cb(struct audit_buffer *ab, void *va)
85 audit_log_format(ab, " ns="); 85 audit_log_format(ab, " ns=");
86 audit_log_untrustedstring(ab, aad(sa)->iface.ns); 86 audit_log_untrustedstring(ab, aad(sa)->iface.ns);
87 } 87 }
88 if (aad(sa)->iface.name) { 88 if (aad(sa)->name) {
89 audit_log_format(ab, " name="); 89 audit_log_format(ab, " name=");
90 audit_log_untrustedstring(ab, aad(sa)->iface.name); 90 audit_log_untrustedstring(ab, aad(sa)->name);
91 } 91 }
92 if (aad(sa)->iface.pos) 92 if (aad(sa)->iface.pos)
93 audit_log_format(ab, " offset=%ld", aad(sa)->iface.pos); 93 audit_log_format(ab, " offset=%ld", aad(sa)->iface.pos);
@@ -114,9 +114,9 @@ static int audit_iface(struct aa_profile *new, const char *ns_name,
114 aad(&sa)->iface.pos = e->pos - e->start; 114 aad(&sa)->iface.pos = e->pos - e->start;
115 aad(&sa)->iface.ns = ns_name; 115 aad(&sa)->iface.ns = ns_name;
116 if (new) 116 if (new)
117 aad(&sa)->iface.name = new->base.hname; 117 aad(&sa)->name = new->base.hname;
118 else 118 else
119 aad(&sa)->iface.name = name; 119 aad(&sa)->name = name;
120 aad(&sa)->info = info; 120 aad(&sa)->info = info;
121 aad(&sa)->error = error; 121 aad(&sa)->error = error;
122 122
@@ -275,6 +275,19 @@ fail:
275 return 0; 275 return 0;
276} 276}
277 277
278static bool unpack_u16(struct aa_ext *e, u16 *data, const char *name)
279{
280 if (unpack_nameX(e, AA_U16, name)) {
281 if (!inbounds(e, sizeof(u16)))
282 return 0;
283 if (data)
284 *data = le16_to_cpu(get_unaligned((__le16 *) e->pos));
285 e->pos += sizeof(u16);
286 return 1;
287 }
288 return 0;
289}
290
278static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name) 291static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name)
279{ 292{
280 if (unpack_nameX(e, AA_U32, name)) { 293 if (unpack_nameX(e, AA_U32, name)) {
@@ -448,7 +461,7 @@ fail:
448 */ 461 */
449static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile) 462static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile)
450{ 463{
451 void *pos = e->pos; 464 void *saved_pos = e->pos;
452 465
453 /* exec table is optional */ 466 /* exec table is optional */
454 if (unpack_nameX(e, AA_STRUCT, "xtable")) { 467 if (unpack_nameX(e, AA_STRUCT, "xtable")) {
@@ -511,7 +524,7 @@ static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile)
511 524
512fail: 525fail:
513 aa_free_domain_entries(&profile->file.trans); 526 aa_free_domain_entries(&profile->file.trans);
514 e->pos = pos; 527 e->pos = saved_pos;
515 return 0; 528 return 0;
516} 529}
517 530
@@ -583,7 +596,8 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
583{ 596{
584 struct aa_profile *profile = NULL; 597 struct aa_profile *profile = NULL;
585 const char *tmpname, *tmpns = NULL, *name = NULL; 598 const char *tmpname, *tmpns = NULL, *name = NULL;
586 size_t ns_len; 599 const char *info = "failed to unpack profile";
600 size_t size = 0, ns_len;
587 struct rhashtable_params params = { 0 }; 601 struct rhashtable_params params = { 0 };
588 char *key = NULL; 602 char *key = NULL;
589 struct aa_data *data; 603 struct aa_data *data;
@@ -604,8 +618,10 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
604 tmpname = aa_splitn_fqname(name, strlen(name), &tmpns, &ns_len); 618 tmpname = aa_splitn_fqname(name, strlen(name), &tmpns, &ns_len);
605 if (tmpns) { 619 if (tmpns) {
606 *ns_name = kstrndup(tmpns, ns_len, GFP_KERNEL); 620 *ns_name = kstrndup(tmpns, ns_len, GFP_KERNEL);
607 if (!*ns_name) 621 if (!*ns_name) {
622 info = "out of memory";
608 goto fail; 623 goto fail;
624 }
609 name = tmpname; 625 name = tmpname;
610 } 626 }
611 627
@@ -624,12 +640,15 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
624 if (IS_ERR(profile->xmatch)) { 640 if (IS_ERR(profile->xmatch)) {
625 error = PTR_ERR(profile->xmatch); 641 error = PTR_ERR(profile->xmatch);
626 profile->xmatch = NULL; 642 profile->xmatch = NULL;
643 info = "bad xmatch";
627 goto fail; 644 goto fail;
628 } 645 }
629 /* xmatch_len is not optional if xmatch is set */ 646 /* xmatch_len is not optional if xmatch is set */
630 if (profile->xmatch) { 647 if (profile->xmatch) {
631 if (!unpack_u32(e, &tmp, NULL)) 648 if (!unpack_u32(e, &tmp, NULL)) {
649 info = "missing xmatch len";
632 goto fail; 650 goto fail;
651 }
633 profile->xmatch_len = tmp; 652 profile->xmatch_len = tmp;
634 } 653 }
635 654
@@ -637,8 +656,11 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
637 (void) unpack_str(e, &profile->disconnected, "disconnected"); 656 (void) unpack_str(e, &profile->disconnected, "disconnected");
638 657
639 /* per profile debug flags (complain, audit) */ 658 /* per profile debug flags (complain, audit) */
640 if (!unpack_nameX(e, AA_STRUCT, "flags")) 659 if (!unpack_nameX(e, AA_STRUCT, "flags")) {
660 info = "profile missing flags";
641 goto fail; 661 goto fail;
662 }
663 info = "failed to unpack profile flags";
642 if (!unpack_u32(e, &tmp, NULL)) 664 if (!unpack_u32(e, &tmp, NULL))
643 goto fail; 665 goto fail;
644 if (tmp & PACKED_FLAG_HAT) 666 if (tmp & PACKED_FLAG_HAT)
@@ -667,6 +689,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
667 /* set a default value if path_flags field is not present */ 689 /* set a default value if path_flags field is not present */
668 profile->path_flags = PATH_MEDIATE_DELETED; 690 profile->path_flags = PATH_MEDIATE_DELETED;
669 691
692 info = "failed to unpack profile capabilities";
670 if (!unpack_u32(e, &(profile->caps.allow.cap[0]), NULL)) 693 if (!unpack_u32(e, &(profile->caps.allow.cap[0]), NULL))
671 goto fail; 694 goto fail;
672 if (!unpack_u32(e, &(profile->caps.audit.cap[0]), NULL)) 695 if (!unpack_u32(e, &(profile->caps.audit.cap[0]), NULL))
@@ -676,6 +699,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
676 if (!unpack_u32(e, &tmpcap.cap[0], NULL)) 699 if (!unpack_u32(e, &tmpcap.cap[0], NULL))
677 goto fail; 700 goto fail;
678 701
702 info = "failed to unpack upper profile capabilities";
679 if (unpack_nameX(e, AA_STRUCT, "caps64")) { 703 if (unpack_nameX(e, AA_STRUCT, "caps64")) {
680 /* optional upper half of 64 bit caps */ 704 /* optional upper half of 64 bit caps */
681 if (!unpack_u32(e, &(profile->caps.allow.cap[1]), NULL)) 705 if (!unpack_u32(e, &(profile->caps.allow.cap[1]), NULL))
@@ -690,6 +714,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
690 goto fail; 714 goto fail;
691 } 715 }
692 716
717 info = "failed to unpack extended profile capabilities";
693 if (unpack_nameX(e, AA_STRUCT, "capsx")) { 718 if (unpack_nameX(e, AA_STRUCT, "capsx")) {
694 /* optional extended caps mediation mask */ 719 /* optional extended caps mediation mask */
695 if (!unpack_u32(e, &(profile->caps.extended.cap[0]), NULL)) 720 if (!unpack_u32(e, &(profile->caps.extended.cap[0]), NULL))
@@ -700,11 +725,46 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
700 goto fail; 725 goto fail;
701 } 726 }
702 727
703 if (!unpack_rlimits(e, profile)) 728 if (!unpack_rlimits(e, profile)) {
729 info = "failed to unpack profile rlimits";
704 goto fail; 730 goto fail;
731 }
732
733 size = unpack_array(e, "net_allowed_af");
734 if (size) {
735
736 for (i = 0; i < size; i++) {
737 /* discard extraneous rules that this kernel will
738 * never request
739 */
740 if (i >= AF_MAX) {
741 u16 tmp;
742
743 if (!unpack_u16(e, &tmp, NULL) ||
744 !unpack_u16(e, &tmp, NULL) ||
745 !unpack_u16(e, &tmp, NULL))
746 goto fail;
747 continue;
748 }
749 if (!unpack_u16(e, &profile->net.allow[i], NULL))
750 goto fail;
751 if (!unpack_u16(e, &profile->net.audit[i], NULL))
752 goto fail;
753 if (!unpack_u16(e, &profile->net.quiet[i], NULL))
754 goto fail;
755 }
756 if (!unpack_nameX(e, AA_ARRAYEND, NULL))
757 goto fail;
758 }
759 if (VERSION_LT(e->version, v7)) {
760 /* pre v7 policy always allowed these */
761 profile->net.allow[AF_UNIX] = 0xffff;
762 profile->net.allow[AF_NETLINK] = 0xffff;
763 }
705 764
706 if (unpack_nameX(e, AA_STRUCT, "policydb")) { 765 if (unpack_nameX(e, AA_STRUCT, "policydb")) {
707 /* generic policy dfa - optional and may be NULL */ 766 /* generic policy dfa - optional and may be NULL */
767 info = "failed to unpack policydb";
708 profile->policy.dfa = unpack_dfa(e); 768 profile->policy.dfa = unpack_dfa(e);
709 if (IS_ERR(profile->policy.dfa)) { 769 if (IS_ERR(profile->policy.dfa)) {
710 error = PTR_ERR(profile->policy.dfa); 770 error = PTR_ERR(profile->policy.dfa);
@@ -734,6 +794,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
734 if (IS_ERR(profile->file.dfa)) { 794 if (IS_ERR(profile->file.dfa)) {
735 error = PTR_ERR(profile->file.dfa); 795 error = PTR_ERR(profile->file.dfa);
736 profile->file.dfa = NULL; 796 profile->file.dfa = NULL;
797 info = "failed to unpack profile file rules";
737 goto fail; 798 goto fail;
738 } else if (profile->file.dfa) { 799 } else if (profile->file.dfa) {
739 if (!unpack_u32(e, &profile->file.start, "dfa_start")) 800 if (!unpack_u32(e, &profile->file.start, "dfa_start"))
@@ -746,10 +807,13 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
746 } else 807 } else
747 profile->file.dfa = aa_get_dfa(nulldfa); 808 profile->file.dfa = aa_get_dfa(nulldfa);
748 809
749 if (!unpack_trans_table(e, profile)) 810 if (!unpack_trans_table(e, profile)) {
811 info = "failed to unpack profile transition table";
750 goto fail; 812 goto fail;
813 }
751 814
752 if (unpack_nameX(e, AA_STRUCT, "data")) { 815 if (unpack_nameX(e, AA_STRUCT, "data")) {
816 info = "out of memory";
753 profile->data = kzalloc(sizeof(*profile->data), GFP_KERNEL); 817 profile->data = kzalloc(sizeof(*profile->data), GFP_KERNEL);
754 if (!profile->data) 818 if (!profile->data)
755 goto fail; 819 goto fail;
@@ -761,8 +825,10 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
761 params.hashfn = strhash; 825 params.hashfn = strhash;
762 params.obj_cmpfn = datacmp; 826 params.obj_cmpfn = datacmp;
763 827
764 if (rhashtable_init(profile->data, &params)) 828 if (rhashtable_init(profile->data, &params)) {
829 info = "failed to init key, value hash table";
765 goto fail; 830 goto fail;
831 }
766 832
767 while (unpack_strdup(e, &key, NULL)) { 833 while (unpack_strdup(e, &key, NULL)) {
768 data = kzalloc(sizeof(*data), GFP_KERNEL); 834 data = kzalloc(sizeof(*data), GFP_KERNEL);
@@ -784,12 +850,16 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
784 profile->data->p); 850 profile->data->p);
785 } 851 }
786 852
787 if (!unpack_nameX(e, AA_STRUCTEND, NULL)) 853 if (!unpack_nameX(e, AA_STRUCTEND, NULL)) {
854 info = "failed to unpack end of key, value data table";
788 goto fail; 855 goto fail;
856 }
789 } 857 }
790 858
791 if (!unpack_nameX(e, AA_STRUCTEND, NULL)) 859 if (!unpack_nameX(e, AA_STRUCTEND, NULL)) {
860 info = "failed to unpack end of profile";
792 goto fail; 861 goto fail;
862 }
793 863
794 return profile; 864 return profile;
795 865
@@ -798,8 +868,7 @@ fail:
798 name = NULL; 868 name = NULL;
799 else if (!name) 869 else if (!name)
800 name = "unknown"; 870 name = "unknown";
801 audit_iface(profile, NULL, name, "failed to unpack profile", e, 871 audit_iface(profile, NULL, name, info, e, error);
802 error);
803 aa_free_profile(profile); 872 aa_free_profile(profile);
804 873
805 return ERR_PTR(error); 874 return ERR_PTR(error);
@@ -832,7 +901,7 @@ static int verify_header(struct aa_ext *e, int required, const char **ns)
832 * if not specified use previous version 901 * if not specified use previous version
833 * Mask off everything that is not kernel abi version 902 * Mask off everything that is not kernel abi version
834 */ 903 */
835 if (VERSION_LT(e->version, v5) && VERSION_GT(e->version, v7)) { 904 if (VERSION_LT(e->version, v5) || VERSION_GT(e->version, v7)) {
836 audit_iface(NULL, NULL, NULL, "unsupported interface version", 905 audit_iface(NULL, NULL, NULL, "unsupported interface version",
837 e, error); 906 e, error);
838 return error; 907 return error;