Lines Matching +full:- +full:e

1 // SPDX-License-Identifier: GPL-2.0-only
8 * Copyright (C) 1998-2008 Novell/SUSE
9 * Copyright 2009-2010 Canonical Ltd.
12 * policy format documentation see Documentation/admin-guide/LSM/apparmor.rst
38 if (aad(sa)->iface.ns) { in audit_cb()
40 audit_log_untrustedstring(ab, aad(sa)->iface.ns); in audit_cb()
42 if (aad(sa)->name) { in audit_cb()
44 audit_log_untrustedstring(ab, aad(sa)->name); in audit_cb()
46 if (aad(sa)->iface.pos) in audit_cb()
47 audit_log_format(ab, " offset=%ld", aad(sa)->iface.pos); in audit_cb()
51 * audit_iface - do audit message for policy unpacking/load/replace/remove
56 * @e: buffer position info
62 const char *name, const char *info, struct aa_ext *e, in audit_iface() argument
67 if (e) in audit_iface()
68 aad(&sa)->iface.pos = e->pos - e->start; in audit_iface()
69 aad(&sa)->iface.ns = ns_name; in audit_iface()
71 aad(&sa)->name = new->base.hname; in audit_iface()
73 aad(&sa)->name = name; in audit_iface()
74 aad(&sa)->info = info; in audit_iface()
75 aad(&sa)->error = error; in audit_iface()
83 AA_BUG(!data->ns); in __aa_loaddata_update()
84 AA_BUG(!mutex_is_locked(&data->ns->lock)); in __aa_loaddata_update()
85 AA_BUG(data->revision > revision); in __aa_loaddata_update()
87 data->revision = revision; in __aa_loaddata_update()
88 if ((data->dents[AAFS_LOADDATA_REVISION])) { in __aa_loaddata_update()
91 inode = d_inode(data->dents[AAFS_LOADDATA_DIR]); in __aa_loaddata_update()
92 inode->i_mtime = inode_set_ctime_current(inode); in __aa_loaddata_update()
94 inode = d_inode(data->dents[AAFS_LOADDATA_REVISION]); in __aa_loaddata_update()
95 inode->i_mtime = inode_set_ctime_current(inode); in __aa_loaddata_update()
101 if (l->size != r->size) in aa_rawdata_eq()
103 if (l->compressed_size != r->compressed_size) in aa_rawdata_eq()
105 if (aa_g_hash_policy && memcmp(l->hash, r->hash, aa_hash_size()) != 0) in aa_rawdata_eq()
107 return memcmp(l->data, r->data, r->compressed_size ?: r->size) == 0; in aa_rawdata_eq()
117 struct aa_ns *ns = aa_get_ns(d->ns); in do_loaddata_free()
120 mutex_lock_nested(&ns->lock, ns->level); in do_loaddata_free()
122 mutex_unlock(&ns->lock); in do_loaddata_free()
126 kfree_sensitive(d->hash); in do_loaddata_free()
127 kfree_sensitive(d->name); in do_loaddata_free()
128 kvfree(d->data); in do_loaddata_free()
137 INIT_WORK(&d->work, do_loaddata_free); in aa_loaddata_kref()
138 schedule_work(&d->work); in aa_loaddata_kref()
148 return ERR_PTR(-ENOMEM); in aa_loaddata_alloc()
149 d->data = kvzalloc(size, GFP_KERNEL); in aa_loaddata_alloc()
150 if (!d->data) { in aa_loaddata_alloc()
152 return ERR_PTR(-ENOMEM); in aa_loaddata_alloc()
154 kref_init(&d->count); in aa_loaddata_alloc()
155 INIT_LIST_HEAD(&d->list); in aa_loaddata_alloc()
161 VISIBLE_IF_KUNIT bool aa_inbounds(struct aa_ext *e, size_t size) in aa_inbounds() argument
163 return (size <= e->end - e->pos); in aa_inbounds()
168 * aa_unpack_u16_chunk - test and do bounds checking for a u16 size based chunk
169 * @e: serialized data read head (NOT NULL)
174 VISIBLE_IF_KUNIT size_t aa_unpack_u16_chunk(struct aa_ext *e, char **chunk) in aa_unpack_u16_chunk() argument
177 void *pos = e->pos; in aa_unpack_u16_chunk()
179 if (!aa_inbounds(e, sizeof(u16))) in aa_unpack_u16_chunk()
181 size = le16_to_cpu(get_unaligned((__le16 *) e->pos)); in aa_unpack_u16_chunk()
182 e->pos += sizeof(__le16); in aa_unpack_u16_chunk()
183 if (!aa_inbounds(e, size)) in aa_unpack_u16_chunk()
185 *chunk = e->pos; in aa_unpack_u16_chunk()
186 e->pos += size; in aa_unpack_u16_chunk()
190 e->pos = pos; in aa_unpack_u16_chunk()
196 VISIBLE_IF_KUNIT bool aa_unpack_X(struct aa_ext *e, enum aa_code code) in aa_unpack_X() argument
198 if (!aa_inbounds(e, 1)) in aa_unpack_X()
200 if (*(u8 *) e->pos != code) in aa_unpack_X()
202 e->pos++; in aa_unpack_X()
208 * aa_unpack_nameX - check is the next element is of type X with a name of @name
209 * @e: serialized data extent information (NOT NULL)
223 VISIBLE_IF_KUNIT bool aa_unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name) in aa_unpack_nameX() argument
228 void *pos = e->pos; in aa_unpack_nameX()
233 if (aa_unpack_X(e, AA_NAME)) { in aa_unpack_nameX()
235 size_t size = aa_unpack_u16_chunk(e, &tag); in aa_unpack_nameX()
237 if (name && (!size || tag[size-1] != '\0' || strcmp(name, tag))) in aa_unpack_nameX()
245 if (aa_unpack_X(e, code)) in aa_unpack_nameX()
249 e->pos = pos; in aa_unpack_nameX()
254 static bool unpack_u8(struct aa_ext *e, u8 *data, const char *name) in unpack_u8() argument
256 void *pos = e->pos; in unpack_u8()
258 if (aa_unpack_nameX(e, AA_U8, name)) { in unpack_u8()
259 if (!aa_inbounds(e, sizeof(u8))) in unpack_u8()
262 *data = *((u8 *)e->pos); in unpack_u8()
263 e->pos += sizeof(u8); in unpack_u8()
268 e->pos = pos; in unpack_u8()
272 VISIBLE_IF_KUNIT bool aa_unpack_u32(struct aa_ext *e, u32 *data, const char *name) in aa_unpack_u32() argument
274 void *pos = e->pos; in aa_unpack_u32()
276 if (aa_unpack_nameX(e, AA_U32, name)) { in aa_unpack_u32()
277 if (!aa_inbounds(e, sizeof(u32))) in aa_unpack_u32()
280 *data = le32_to_cpu(get_unaligned((__le32 *) e->pos)); in aa_unpack_u32()
281 e->pos += sizeof(u32); in aa_unpack_u32()
286 e->pos = pos; in aa_unpack_u32()
291 VISIBLE_IF_KUNIT bool aa_unpack_u64(struct aa_ext *e, u64 *data, const char *name) in aa_unpack_u64() argument
293 void *pos = e->pos; in aa_unpack_u64()
295 if (aa_unpack_nameX(e, AA_U64, name)) { in aa_unpack_u64()
296 if (!aa_inbounds(e, sizeof(u64))) in aa_unpack_u64()
299 *data = le64_to_cpu(get_unaligned((__le64 *) e->pos)); in aa_unpack_u64()
300 e->pos += sizeof(u64); in aa_unpack_u64()
305 e->pos = pos; in aa_unpack_u64()
310 static bool aa_unpack_cap_low(struct aa_ext *e, kernel_cap_t *data, const char *name) in aa_unpack_cap_low() argument
314 if (!aa_unpack_u32(e, &val, name)) in aa_unpack_cap_low()
316 data->val = val; in aa_unpack_cap_low()
320 static bool aa_unpack_cap_high(struct aa_ext *e, kernel_cap_t *data, const char *name) in aa_unpack_cap_high() argument
324 if (!aa_unpack_u32(e, &val, name)) in aa_unpack_cap_high()
326 data->val = (u32)data->val | ((u64)val << 32); in aa_unpack_cap_high()
330 VISIBLE_IF_KUNIT bool aa_unpack_array(struct aa_ext *e, const char *name, u16 *size) in aa_unpack_array() argument
332 void *pos = e->pos; in aa_unpack_array()
334 if (aa_unpack_nameX(e, AA_ARRAY, name)) { in aa_unpack_array()
335 if (!aa_inbounds(e, sizeof(u16))) in aa_unpack_array()
337 *size = le16_to_cpu(get_unaligned((__le16 *) e->pos)); in aa_unpack_array()
338 e->pos += sizeof(u16); in aa_unpack_array()
343 e->pos = pos; in aa_unpack_array()
348 VISIBLE_IF_KUNIT size_t aa_unpack_blob(struct aa_ext *e, char **blob, const char *name) in aa_unpack_blob() argument
350 void *pos = e->pos; in aa_unpack_blob()
352 if (aa_unpack_nameX(e, AA_BLOB, name)) { in aa_unpack_blob()
354 if (!aa_inbounds(e, sizeof(u32))) in aa_unpack_blob()
356 size = le32_to_cpu(get_unaligned((__le32 *) e->pos)); in aa_unpack_blob()
357 e->pos += sizeof(u32); in aa_unpack_blob()
358 if (aa_inbounds(e, (size_t) size)) { in aa_unpack_blob()
359 *blob = e->pos; in aa_unpack_blob()
360 e->pos += size; in aa_unpack_blob()
366 e->pos = pos; in aa_unpack_blob()
371 VISIBLE_IF_KUNIT int aa_unpack_str(struct aa_ext *e, const char **string, const char *name) in aa_unpack_str() argument
375 void *pos = e->pos; in aa_unpack_str()
377 if (aa_unpack_nameX(e, AA_STRING, name)) { in aa_unpack_str()
378 size = aa_unpack_u16_chunk(e, &src_str); in aa_unpack_str()
380 /* strings are null terminated, length is size - 1 */ in aa_unpack_str()
381 if (src_str[size - 1] != 0) in aa_unpack_str()
390 e->pos = pos; in aa_unpack_str()
395 VISIBLE_IF_KUNIT int aa_unpack_strdup(struct aa_ext *e, char **string, const char *name) in aa_unpack_strdup() argument
398 void *pos = e->pos; in aa_unpack_strdup()
399 int res = aa_unpack_str(e, &tmp, name); in aa_unpack_strdup()
407 e->pos = pos; in aa_unpack_strdup()
417 * unpack_dfa - unpack a file rule dfa
418 * @e: serialized data extent information (NOT NULL)
423 static struct aa_dfa *unpack_dfa(struct aa_ext *e, int flags) in unpack_dfa() argument
429 size = aa_unpack_blob(e, &blob, "aadfa"); in unpack_dfa()
436 size_t sz = blob - (char *) e->start - in unpack_dfa()
437 ((e->pos - e->start) & 7); in unpack_dfa()
438 size_t pad = ALIGN(sz, 8) - sz; in unpack_dfa()
441 dfa = aa_dfa_unpack(blob + pad, size - pad, flags); in unpack_dfa()
452 * unpack_trans_table - unpack a profile transition table
453 * @e: serialized data extent information (NOT NULL)
458 static bool unpack_trans_table(struct aa_ext *e, struct aa_str_table *strs) in unpack_trans_table() argument
460 void *saved_pos = e->pos; in unpack_trans_table()
464 if (aa_unpack_nameX(e, AA_STRUCT, "xtable")) { in unpack_trans_table()
468 if (!aa_unpack_array(e, NULL, &size)) in unpack_trans_table()
482 int c, j, pos, size2 = aa_unpack_strdup(e, &str, NULL); in unpack_trans_table()
494 for (c = j = 0; j < size2 - 1; j++) { in unpack_trans_table()
515 /* fail - all other cases with embedded \0 */ in unpack_trans_table()
518 if (!aa_unpack_nameX(e, AA_ARRAYEND, NULL)) in unpack_trans_table()
520 if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) in unpack_trans_table()
523 strs->table = table; in unpack_trans_table()
524 strs->size = size; in unpack_trans_table()
530 e->pos = saved_pos; in unpack_trans_table()
534 static bool unpack_xattrs(struct aa_ext *e, struct aa_profile *profile) in unpack_xattrs() argument
536 void *pos = e->pos; in unpack_xattrs()
538 if (aa_unpack_nameX(e, AA_STRUCT, "xattrs")) { in unpack_xattrs()
542 if (!aa_unpack_array(e, NULL, &size)) in unpack_xattrs()
544 profile->attach.xattr_count = size; in unpack_xattrs()
545 profile->attach.xattrs = kcalloc(size, sizeof(char *), GFP_KERNEL); in unpack_xattrs()
546 if (!profile->attach.xattrs) in unpack_xattrs()
549 if (!aa_unpack_strdup(e, &profile->attach.xattrs[i], NULL)) in unpack_xattrs()
552 if (!aa_unpack_nameX(e, AA_ARRAYEND, NULL)) in unpack_xattrs()
554 if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) in unpack_xattrs()
561 e->pos = pos; in unpack_xattrs()
565 static bool unpack_secmark(struct aa_ext *e, struct aa_ruleset *rules) in unpack_secmark() argument
567 void *pos = e->pos; in unpack_secmark()
571 if (aa_unpack_nameX(e, AA_STRUCT, "secmark")) { in unpack_secmark()
572 if (!aa_unpack_array(e, NULL, &size)) in unpack_secmark()
575 rules->secmark = kcalloc(size, sizeof(struct aa_secmark), in unpack_secmark()
577 if (!rules->secmark) in unpack_secmark()
580 rules->secmark_count = size; in unpack_secmark()
583 if (!unpack_u8(e, &rules->secmark[i].audit, NULL)) in unpack_secmark()
585 if (!unpack_u8(e, &rules->secmark[i].deny, NULL)) in unpack_secmark()
587 if (!aa_unpack_strdup(e, &rules->secmark[i].label, NULL)) in unpack_secmark()
590 if (!aa_unpack_nameX(e, AA_ARRAYEND, NULL)) in unpack_secmark()
592 if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) in unpack_secmark()
599 if (rules->secmark) { in unpack_secmark()
601 kfree(rules->secmark[i].label); in unpack_secmark()
602 kfree(rules->secmark); in unpack_secmark()
603 rules->secmark_count = 0; in unpack_secmark()
604 rules->secmark = NULL; in unpack_secmark()
607 e->pos = pos; in unpack_secmark()
611 static bool unpack_rlimits(struct aa_ext *e, struct aa_ruleset *rules) in unpack_rlimits() argument
613 void *pos = e->pos; in unpack_rlimits()
616 if (aa_unpack_nameX(e, AA_STRUCT, "rlimits")) { in unpack_rlimits()
620 if (!aa_unpack_u32(e, &tmp, NULL)) in unpack_rlimits()
622 rules->rlimits.mask = tmp; in unpack_rlimits()
624 if (!aa_unpack_array(e, NULL, &size) || in unpack_rlimits()
630 if (!aa_unpack_u64(e, &tmp2, NULL)) in unpack_rlimits()
632 rules->rlimits.limits[a].rlim_max = tmp2; in unpack_rlimits()
634 if (!aa_unpack_nameX(e, AA_ARRAYEND, NULL)) in unpack_rlimits()
636 if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) in unpack_rlimits()
642 e->pos = pos; in unpack_rlimits()
646 static bool unpack_perm(struct aa_ext *e, u32 version, struct aa_perms *perm) in unpack_perm() argument
651 return aa_unpack_u32(e, &perm->allow, NULL) && in unpack_perm()
652 aa_unpack_u32(e, &perm->allow, NULL) && in unpack_perm()
653 aa_unpack_u32(e, &perm->deny, NULL) && in unpack_perm()
654 aa_unpack_u32(e, &perm->subtree, NULL) && in unpack_perm()
655 aa_unpack_u32(e, &perm->cond, NULL) && in unpack_perm()
656 aa_unpack_u32(e, &perm->kill, NULL) && in unpack_perm()
657 aa_unpack_u32(e, &perm->complain, NULL) && in unpack_perm()
658 aa_unpack_u32(e, &perm->prompt, NULL) && in unpack_perm()
659 aa_unpack_u32(e, &perm->audit, NULL) && in unpack_perm()
660 aa_unpack_u32(e, &perm->quiet, NULL) && in unpack_perm()
661 aa_unpack_u32(e, &perm->hide, NULL) && in unpack_perm()
662 aa_unpack_u32(e, &perm->xindex, NULL) && in unpack_perm()
663 aa_unpack_u32(e, &perm->tag, NULL) && in unpack_perm()
664 aa_unpack_u32(e, &perm->label, NULL); in unpack_perm()
667 static ssize_t unpack_perms_table(struct aa_ext *e, struct aa_perms **perms) in unpack_perms_table() argument
669 void *pos = e->pos; in unpack_perms_table()
677 if (aa_unpack_nameX(e, AA_STRUCT, "perms")) { in unpack_perms_table()
681 if (!aa_unpack_u32(e, &version, "version")) in unpack_perms_table()
683 if (!aa_unpack_array(e, NULL, &size)) in unpack_perms_table()
689 if (!unpack_perm(e, version, &(*perms)[i])) in unpack_perms_table()
692 if (!aa_unpack_nameX(e, AA_ARRAYEND, NULL)) in unpack_perms_table()
694 if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) in unpack_perms_table()
704 e->pos = pos; in unpack_perms_table()
705 return -EPROTO; in unpack_perms_table()
708 static int unpack_pdb(struct aa_ext *e, struct aa_policydb *policy, in unpack_pdb() argument
712 void *pos = e->pos; in unpack_pdb()
713 int i, flags, error = -EPROTO; in unpack_pdb()
716 size = unpack_perms_table(e, &policy->perms); in unpack_pdb()
719 policy->perms = NULL; in unpack_pdb()
720 *info = "failed to unpack - perms"; in unpack_pdb()
723 policy->size = size; in unpack_pdb()
725 if (policy->perms) { in unpack_pdb()
734 policy->dfa = unpack_dfa(e, flags); in unpack_pdb()
735 if (IS_ERR(policy->dfa)) { in unpack_pdb()
736 error = PTR_ERR(policy->dfa); in unpack_pdb()
737 policy->dfa = NULL; in unpack_pdb()
738 *info = "failed to unpack - dfa"; in unpack_pdb()
740 } else if (!policy->dfa) { in unpack_pdb()
754 if (!aa_unpack_u32(e, &policy->start[0], "start")) in unpack_pdb()
756 policy->start[0] = DFA_START; in unpack_pdb()
757 if (!aa_unpack_u32(e, &policy->start[AA_CLASS_FILE], "dfa_start")) { in unpack_pdb()
759 policy->start[AA_CLASS_FILE] = DFA_START; in unpack_pdb()
762 policy->start[i] = aa_dfa_next(policy->dfa, policy->start[0], in unpack_pdb()
765 if (!unpack_trans_table(e, &policy->trans) && required_trans) { in unpack_pdb()
776 e->pos = pos; in unpack_pdb()
790 const char * const *key = arg->key; in datacmp()
792 return strcmp(data->key, *key); in datacmp()
796 * unpack_profile - unpack a serialized profile
797 * @e: serialized data extent information (NOT NULL)
802 static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) in unpack_profile() argument
812 int error = -EPROTO; in unpack_profile()
819 if (!aa_unpack_nameX(e, AA_STRUCT, "profile")) in unpack_profile()
821 if (!aa_unpack_str(e, &name, NULL)) in unpack_profile()
831 error = -ENOMEM; in unpack_profile()
840 error = -ENOMEM; in unpack_profile()
843 rules = list_first_entry(&profile->rules, typeof(*rules), list); in unpack_profile()
846 (void) aa_unpack_str(e, &profile->rename, "rename"); in unpack_profile()
849 (void) aa_unpack_str(e, &profile->attach.xmatch_str, "attach"); in unpack_profile()
852 error = unpack_pdb(e, &profile->attach.xmatch, false, false, &info); in unpack_profile()
859 if (profile->attach.xmatch.dfa) { in unpack_profile()
860 if (!aa_unpack_u32(e, &tmp, NULL)) { in unpack_profile()
864 profile->attach.xmatch_len = tmp; in unpack_profile()
865 profile->attach.xmatch.start[AA_CLASS_XMATCH] = DFA_START; in unpack_profile()
866 if (!profile->attach.xmatch.perms) { in unpack_profile()
867 error = aa_compat_map_xmatch(&profile->attach.xmatch); in unpack_profile()
876 (void) aa_unpack_str(e, &profile->disconnected, "disconnected"); in unpack_profile()
879 if (!aa_unpack_nameX(e, AA_STRUCT, "flags")) { in unpack_profile()
884 if (!aa_unpack_u32(e, &tmp, NULL)) in unpack_profile()
887 profile->label.flags |= FLAG_HAT; in unpack_profile()
889 profile->label.flags |= FLAG_DEBUG1; in unpack_profile()
891 profile->label.flags |= FLAG_DEBUG2; in unpack_profile()
892 if (!aa_unpack_u32(e, &tmp, NULL)) in unpack_profile()
894 if (tmp == PACKED_MODE_COMPLAIN || (e->version & FORCE_COMPLAIN_FLAG)) { in unpack_profile()
895 profile->mode = APPARMOR_COMPLAIN; in unpack_profile()
897 profile->mode = APPARMOR_ENFORCE; in unpack_profile()
899 profile->mode = APPARMOR_KILL; in unpack_profile()
901 profile->mode = APPARMOR_UNCONFINED; in unpack_profile()
902 profile->label.flags |= FLAG_UNCONFINED; in unpack_profile()
904 profile->mode = APPARMOR_USER; in unpack_profile()
908 if (!aa_unpack_u32(e, &tmp, NULL)) in unpack_profile()
911 profile->audit = AUDIT_ALL; in unpack_profile()
913 if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) in unpack_profile()
917 if (aa_unpack_u32(e, &profile->path_flags, "path_flags")) in unpack_profile()
918 profile->path_flags |= profile->label.flags & in unpack_profile()
922 profile->path_flags = PATH_MEDIATE_DELETED; in unpack_profile()
925 if (!aa_unpack_cap_low(e, &rules->caps.allow, NULL)) in unpack_profile()
927 if (!aa_unpack_cap_low(e, &rules->caps.audit, NULL)) in unpack_profile()
929 if (!aa_unpack_cap_low(e, &rules->caps.quiet, NULL)) in unpack_profile()
931 if (!aa_unpack_cap_low(e, &tmpcap, NULL)) in unpack_profile()
935 if (aa_unpack_nameX(e, AA_STRUCT, "caps64")) { in unpack_profile()
937 if (!aa_unpack_cap_high(e, &rules->caps.allow, NULL)) in unpack_profile()
939 if (!aa_unpack_cap_high(e, &rules->caps.audit, NULL)) in unpack_profile()
941 if (!aa_unpack_cap_high(e, &rules->caps.quiet, NULL)) in unpack_profile()
943 if (!aa_unpack_cap_high(e, &tmpcap, NULL)) in unpack_profile()
945 if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) in unpack_profile()
950 if (aa_unpack_nameX(e, AA_STRUCT, "capsx")) { in unpack_profile()
952 if (!aa_unpack_cap_low(e, &rules->caps.extended, NULL)) in unpack_profile()
954 if (!aa_unpack_cap_high(e, &rules->caps.extended, NULL)) in unpack_profile()
956 if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) in unpack_profile()
960 if (!unpack_xattrs(e, profile)) { in unpack_profile()
965 if (!unpack_rlimits(e, rules)) { in unpack_profile()
970 if (!unpack_secmark(e, rules)) { in unpack_profile()
975 if (aa_unpack_nameX(e, AA_STRUCT, "policydb")) { in unpack_profile()
976 /* generic policy dfa - optional and may be NULL */ in unpack_profile()
978 error = unpack_pdb(e, &rules->policy, true, false, in unpack_profile()
983 if (aa_dfa_next(rules->policy.dfa, rules->policy.start[0], in unpack_profile()
985 rules->policy.start[AA_CLASS_FILE] = in unpack_profile()
986 aa_dfa_next(rules->policy.dfa, in unpack_profile()
987 rules->policy.start[0], in unpack_profile()
989 if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) in unpack_profile()
991 if (!rules->policy.perms) { in unpack_profile()
992 error = aa_compat_map_policy(&rules->policy, in unpack_profile()
993 e->version); in unpack_profile()
1000 rules->policy.dfa = aa_get_dfa(nulldfa); in unpack_profile()
1001 rules->policy.perms = kcalloc(2, sizeof(struct aa_perms), in unpack_profile()
1003 if (!rules->policy.perms) in unpack_profile()
1005 rules->policy.size = 2; in unpack_profile()
1008 error = unpack_pdb(e, &rules->file, false, true, &info); in unpack_profile()
1011 } else if (rules->file.dfa) { in unpack_profile()
1012 if (!rules->file.perms) { in unpack_profile()
1013 error = aa_compat_map_file(&rules->file); in unpack_profile()
1019 } else if (rules->policy.dfa && in unpack_profile()
1020 rules->policy.start[AA_CLASS_FILE]) { in unpack_profile()
1021 rules->file.dfa = aa_get_dfa(rules->policy.dfa); in unpack_profile()
1022 rules->file.start[AA_CLASS_FILE] = rules->policy.start[AA_CLASS_FILE]; in unpack_profile()
1023 rules->file.perms = kcalloc(rules->policy.size, in unpack_profile()
1026 if (!rules->file.perms) in unpack_profile()
1028 memcpy(rules->file.perms, rules->policy.perms, in unpack_profile()
1029 rules->policy.size * sizeof(struct aa_perms)); in unpack_profile()
1030 rules->file.size = rules->policy.size; in unpack_profile()
1032 rules->file.dfa = aa_get_dfa(nulldfa); in unpack_profile()
1033 rules->file.perms = kcalloc(2, sizeof(struct aa_perms), in unpack_profile()
1035 if (!rules->file.perms) in unpack_profile()
1037 rules->file.size = 2; in unpack_profile()
1039 error = -EPROTO; in unpack_profile()
1040 if (aa_unpack_nameX(e, AA_STRUCT, "data")) { in unpack_profile()
1042 profile->data = kzalloc(sizeof(*profile->data), GFP_KERNEL); in unpack_profile()
1043 if (!profile->data) { in unpack_profile()
1044 error = -ENOMEM; in unpack_profile()
1054 if (rhashtable_init(profile->data, &params)) { in unpack_profile()
1059 while (aa_unpack_strdup(e, &key, NULL)) { in unpack_profile()
1063 error = -ENOMEM; in unpack_profile()
1067 data->key = key; in unpack_profile()
1068 data->size = aa_unpack_blob(e, &data->data, NULL); in unpack_profile()
1069 data->data = kvmemdup(data->data, data->size, GFP_KERNEL); in unpack_profile()
1070 if (data->size && !data->data) { in unpack_profile()
1071 kfree_sensitive(data->key); in unpack_profile()
1073 error = -ENOMEM; in unpack_profile()
1077 if (rhashtable_insert_fast(profile->data, &data->head, in unpack_profile()
1078 profile->data->p)) { in unpack_profile()
1079 kfree_sensitive(data->key); in unpack_profile()
1086 if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) { in unpack_profile()
1092 if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) { in unpack_profile()
1102 error = -EPROTO; in unpack_profile()
1111 audit_iface(profile, NULL, name, info, e, error); in unpack_profile()
1118 * verify_header - unpack serialized stream header
1119 * @e: serialized data read head (NOT NULL)
1121 * @ns: Returns - namespace if one is specified else NULL (NOT NULL)
1125 static int verify_header(struct aa_ext *e, int required, const char **ns) in verify_header() argument
1127 int error = -EPROTONOSUPPORT; in verify_header()
1132 if (!aa_unpack_u32(e, &e->version, "version")) { in verify_header()
1135 e, error); in verify_header()
1144 if (VERSION_LT(e->version, v5) || VERSION_GT(e->version, v9)) { in verify_header()
1146 e, error); in verify_header()
1151 if (aa_unpack_str(e, &name, "namespace")) { in verify_header()
1154 e, error); in verify_header()
1158 audit_iface(NULL, NULL, NULL, "invalid ns change", e, in verify_header()
1163 return -ENOMEM; in verify_header()
1171 * verify_dfa_accept_index - verify accept indexes are in range of perms table
1178 for (i = 0; i < dfa->tables[YYTD_ID_ACCEPT]->td_lolen; i++) { in verify_dfa_accept_index()
1188 if (perm->allow & perm->deny) in verify_perm()
1190 if (perm->subtree & ~perm->allow) in verify_perm()
1192 if (perm->cond & (perm->allow | perm->deny)) in verify_perm()
1194 if (perm->kill & perm->allow) in verify_perm()
1196 if (perm->complain & (perm->allow | perm->deny)) in verify_perm()
1198 if (perm->prompt & (perm->allow | perm->deny)) in verify_perm()
1200 if (perm->complain & perm->prompt) in verify_perm()
1202 if (perm->hide & perm->allow) in verify_perm()
1212 for (i = 0; i < pdb->size; i++) { in verify_perms()
1213 if (!verify_perm(&pdb->perms[i])) in verify_perms()
1216 if ((pdb->perms[i].xindex & AA_X_TYPE_MASK) == AA_X_TABLE && in verify_perms()
1217 (pdb->perms[i].xindex & AA_X_INDEX_MASK) >= pdb->trans.size) in verify_perms()
1219 if (pdb->perms[i].tag && pdb->perms[i].tag >= pdb->trans.size) in verify_perms()
1221 if (pdb->perms[i].label && in verify_perms()
1222 pdb->perms[i].label >= pdb->trans.size) in verify_perms()
1230 * verify_profile - Do post unpack analysis to verify profile consistency
1239 struct aa_ruleset *rules = list_first_entry(&profile->rules, in verify_profile()
1244 if ((rules->file.dfa && !verify_dfa_accept_index(rules->file.dfa, in verify_profile()
1245 rules->file.size)) || in verify_profile()
1246 (rules->policy.dfa && in verify_profile()
1247 !verify_dfa_accept_index(rules->policy.dfa, rules->policy.size))) { in verify_profile()
1249 "Unpack: Invalid named transition", NULL, -EPROTO); in verify_profile()
1250 return -EPROTO; in verify_profile()
1253 if (!verify_perms(&rules->file)) { in verify_profile()
1255 "Unpack: Invalid perm index", NULL, -EPROTO); in verify_profile()
1256 return -EPROTO; in verify_profile()
1258 if (!verify_perms(&rules->policy)) { in verify_profile()
1260 "Unpack: Invalid perm index", NULL, -EPROTO); in verify_profile()
1261 return -EPROTO; in verify_profile()
1263 if (!verify_perms(&profile->attach.xmatch)) { in verify_profile()
1265 "Unpack: Invalid perm index", NULL, -EPROTO); in verify_profile()
1266 return -EPROTO; in verify_profile()
1275 aa_put_profile(ent->rename); in aa_load_ent_free()
1276 aa_put_profile(ent->old); in aa_load_ent_free()
1277 aa_put_profile(ent->new); in aa_load_ent_free()
1278 kfree(ent->ns_name); in aa_load_ent_free()
1287 INIT_LIST_HEAD(&ent->list); in aa_load_ent_alloc()
1305 ret = -ENOMEM; in compress_zstd()
1311 ret = -ENOMEM; in compress_zstd()
1317 ret = -EINVAL; in compress_zstd()
1323 ret = -EINVAL; in compress_zstd()
1344 ret = -ENOMEM; in compress_zstd()
1366 AA_BUG(data->compressed_size > 0); in compress_loaddata()
1373 void *udata = data->data; in compress_loaddata()
1374 int error = compress_zstd(udata, data->size, &data->data, in compress_loaddata()
1375 &data->compressed_size); in compress_loaddata()
1377 data->compressed_size = data->size; in compress_loaddata()
1380 if (udata != data->data) in compress_loaddata()
1383 data->compressed_size = data->size; in compress_loaddata()
1389 * aa_unpack - unpack packed binary profile(s) data loaded from user space
1407 struct aa_ext e = { in aa_unpack() local
1408 .start = udata->data, in aa_unpack()
1409 .end = udata->data + udata->size, in aa_unpack()
1410 .pos = udata->data, in aa_unpack()
1414 while (e.pos < e.end) { in aa_unpack()
1416 error = verify_header(&e, e.pos == e.start, ns); in aa_unpack()
1420 start = e.pos; in aa_unpack()
1421 profile = unpack_profile(&e, &ns_name); in aa_unpack()
1432 error = aa_calc_profile_hash(profile, e.version, start, in aa_unpack()
1433 e.pos - start); in aa_unpack()
1439 error = -ENOMEM; in aa_unpack()
1443 ent->new = profile; in aa_unpack()
1444 ent->ns_name = ns_name; in aa_unpack()
1446 list_add_tail(&ent->list, lh); in aa_unpack()
1448 udata->abi = e.version & K_ABI_MASK; in aa_unpack()
1450 udata->hash = aa_calc_hash(udata->data, udata->size); in aa_unpack()
1451 if (IS_ERR(udata->hash)) { in aa_unpack()
1452 error = PTR_ERR(udata->hash); in aa_unpack()
1453 udata->hash = NULL; in aa_unpack()
1471 list_del_init(&ent->list); in aa_unpack()