Lines Matching +full:data +full:- +full:size

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
41 * The AppArmor interface treats data as a type byte followed by the
42 * actual data. The interface has the notion of a a named entry
44 * the entries typecode and data. Named types allow for optional
67 * data is copied into a kernel buffer in apparmorfs and then handed off to
82 if (aad(sa)->iface.ns) { in audit_cb()
84 audit_log_untrustedstring(ab, aad(sa)->iface.ns); in audit_cb()
86 if (aad(sa)->name) { in audit_cb()
88 audit_log_untrustedstring(ab, aad(sa)->name); in audit_cb()
90 if (aad(sa)->iface.pos) in audit_cb()
91 audit_log_format(ab, " offset=%ld", aad(sa)->iface.pos); in audit_cb()
95 * audit_iface - do audit message for policy unpacking/load/replace/remove
112 aad(&sa)->iface.pos = e->pos - e->start; in audit_iface()
113 aad(&sa)->iface.ns = ns_name; in audit_iface()
115 aad(&sa)->name = new->base.hname; in audit_iface()
117 aad(&sa)->name = name; in audit_iface()
118 aad(&sa)->info = info; in audit_iface()
119 aad(&sa)->error = error; in audit_iface()
124 void __aa_loaddata_update(struct aa_loaddata *data, long revision) in __aa_loaddata_update() argument
126 AA_BUG(!data); in __aa_loaddata_update()
127 AA_BUG(!data->ns); in __aa_loaddata_update()
128 AA_BUG(!data->dents[AAFS_LOADDATA_REVISION]); in __aa_loaddata_update()
129 AA_BUG(!mutex_is_locked(&data->ns->lock)); in __aa_loaddata_update()
130 AA_BUG(data->revision > revision); in __aa_loaddata_update()
132 data->revision = revision; in __aa_loaddata_update()
133 d_inode(data->dents[AAFS_LOADDATA_DIR])->i_mtime = in __aa_loaddata_update()
134 current_time(d_inode(data->dents[AAFS_LOADDATA_DIR])); in __aa_loaddata_update()
135 d_inode(data->dents[AAFS_LOADDATA_REVISION])->i_mtime = in __aa_loaddata_update()
136 current_time(d_inode(data->dents[AAFS_LOADDATA_REVISION])); in __aa_loaddata_update()
141 if (l->size != r->size) in aa_rawdata_eq()
143 if (l->compressed_size != r->compressed_size) in aa_rawdata_eq()
145 if (aa_g_hash_policy && memcmp(l->hash, r->hash, aa_hash_size()) != 0) in aa_rawdata_eq()
147 return memcmp(l->data, r->data, r->compressed_size ?: r->size) == 0; in aa_rawdata_eq()
157 struct aa_ns *ns = aa_get_ns(d->ns); in do_loaddata_free()
160 mutex_lock_nested(&ns->lock, ns->level); in do_loaddata_free()
162 mutex_unlock(&ns->lock); in do_loaddata_free()
166 kfree_sensitive(d->hash); in do_loaddata_free()
167 kfree_sensitive(d->name); in do_loaddata_free()
168 kvfree(d->data); in do_loaddata_free()
177 INIT_WORK(&d->work, do_loaddata_free); in aa_loaddata_kref()
178 schedule_work(&d->work); in aa_loaddata_kref()
182 struct aa_loaddata *aa_loaddata_alloc(size_t size) in aa_loaddata_alloc() argument
188 return ERR_PTR(-ENOMEM); in aa_loaddata_alloc()
189 d->data = kvzalloc(size, GFP_KERNEL); in aa_loaddata_alloc()
190 if (!d->data) { in aa_loaddata_alloc()
192 return ERR_PTR(-ENOMEM); in aa_loaddata_alloc()
194 kref_init(&d->count); in aa_loaddata_alloc()
195 INIT_LIST_HEAD(&d->list); in aa_loaddata_alloc()
200 /* test if read will be in packed data bounds */
201 static bool inbounds(struct aa_ext *e, size_t size) in inbounds() argument
203 return (size <= e->end - e->pos); in inbounds()
216 * aa_u16_chunck - test and do bounds checking for a u16 size based chunk
217 * @e: serialized data read head (NOT NULL)
218 * @chunk: start address for chunk of data (NOT NULL)
220 * Returns: the size of chunk found with the read head at the end of the chunk.
224 size_t size = 0; in unpack_u16_chunk() local
225 void *pos = e->pos; in unpack_u16_chunk()
229 size = le16_to_cpu(get_unaligned((__le16 *) e->pos)); in unpack_u16_chunk()
230 e->pos += sizeof(__le16); in unpack_u16_chunk()
231 if (!inbounds(e, size)) in unpack_u16_chunk()
233 *chunk = e->pos; in unpack_u16_chunk()
234 e->pos += size; in unpack_u16_chunk()
235 return size; in unpack_u16_chunk()
238 e->pos = pos; in unpack_u16_chunk()
247 if (*(u8 *) e->pos != code) in unpack_X()
249 e->pos++; in unpack_X()
254 * unpack_nameX - check is the next element is of type X with a name of @name
255 * @e: serialized data extent information (NOT NULL)
259 * check that the next serialized data element is of type X and has a tag
274 void *pos = e->pos; in unpack_nameX()
276 * Check for presence of a tagname, and if present name size in unpack_nameX()
281 size_t size = unpack_u16_chunk(e, &tag); in unpack_nameX() local
283 if (name && (!size || tag[size-1] != '\0' || strcmp(name, tag))) in unpack_nameX()
295 e->pos = pos; in unpack_nameX()
299 static bool unpack_u8(struct aa_ext *e, u8 *data, const char *name) in unpack_u8() argument
301 void *pos = e->pos; in unpack_u8()
306 if (data) in unpack_u8()
307 *data = *((u8 *)e->pos); in unpack_u8()
308 e->pos += sizeof(u8); in unpack_u8()
313 e->pos = pos; in unpack_u8()
317 static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name) in unpack_u32() argument
319 void *pos = e->pos; in unpack_u32()
324 if (data) in unpack_u32()
325 *data = le32_to_cpu(get_unaligned((__le32 *) e->pos)); in unpack_u32()
326 e->pos += sizeof(u32); in unpack_u32()
331 e->pos = pos; in unpack_u32()
335 static bool unpack_u64(struct aa_ext *e, u64 *data, const char *name) in unpack_u64() argument
337 void *pos = e->pos; in unpack_u64()
342 if (data) in unpack_u64()
343 *data = le64_to_cpu(get_unaligned((__le64 *) e->pos)); in unpack_u64()
344 e->pos += sizeof(u64); in unpack_u64()
349 e->pos = pos; in unpack_u64()
355 void *pos = e->pos; in unpack_array()
358 int size; in unpack_array() local
361 size = (int)le16_to_cpu(get_unaligned((__le16 *) e->pos)); in unpack_array()
362 e->pos += sizeof(u16); in unpack_array()
363 return size; in unpack_array()
367 e->pos = pos; in unpack_array()
373 void *pos = e->pos; in unpack_blob()
376 u32 size; in unpack_blob() local
379 size = le32_to_cpu(get_unaligned((__le32 *) e->pos)); in unpack_blob()
380 e->pos += sizeof(u32); in unpack_blob()
381 if (inbounds(e, (size_t) size)) { in unpack_blob()
382 *blob = e->pos; in unpack_blob()
383 e->pos += size; in unpack_blob()
384 return size; in unpack_blob()
389 e->pos = pos; in unpack_blob()
396 size_t size = 0; in unpack_str() local
397 void *pos = e->pos; in unpack_str()
400 size = unpack_u16_chunk(e, &src_str); in unpack_str()
401 if (size) { in unpack_str()
402 /* strings are null terminated, length is size - 1 */ in unpack_str()
403 if (src_str[size - 1] != 0) in unpack_str()
407 return size; in unpack_str()
412 e->pos = pos; in unpack_str()
419 void *pos = e->pos; in unpack_strdup()
428 e->pos = pos; in unpack_strdup()
437 * unpack_dfa - unpack a file rule dfa
438 * @e: serialized data extent information (NOT NULL)
445 size_t size; in unpack_dfa() local
448 size = unpack_blob(e, &blob, "aadfa"); in unpack_dfa()
449 if (size) { in unpack_dfa()
455 size_t sz = blob - (char *) e->start - in unpack_dfa()
456 ((e->pos - e->start) & 7); in unpack_dfa()
457 size_t pad = ALIGN(sz, 8) - sz; in unpack_dfa()
460 dfa = aa_dfa_unpack(blob + pad, size - pad, flags); in unpack_dfa()
471 * unpack_trans_table - unpack a profile transition table
472 * @e: serialized data extent information (NOT NULL)
479 void *saved_pos = e->pos; in unpack_trans_table()
483 int i, size; in unpack_trans_table() local
485 size = unpack_array(e, NULL); in unpack_trans_table()
486 /* currently 4 exec bits and entries 0-3 are reserved iupcx */ in unpack_trans_table()
487 if (size > 16 - 4) in unpack_trans_table()
489 profile->file.trans.table = kcalloc(size, sizeof(char *), in unpack_trans_table()
491 if (!profile->file.trans.table) in unpack_trans_table()
494 profile->file.trans.size = size; in unpack_trans_table()
495 for (i = 0; i < size; i++) { in unpack_trans_table()
503 profile->file.trans.table[i] = str; in unpack_trans_table()
509 for (c = j = 0; j < size2 - 1; j++) { in unpack_trans_table()
530 /* fail - all other cases with embedded \0 */ in unpack_trans_table()
541 aa_free_domain_entries(&profile->file.trans); in unpack_trans_table()
542 e->pos = saved_pos; in unpack_trans_table()
548 void *pos = e->pos; in unpack_xattrs()
551 int i, size; in unpack_xattrs() local
553 size = unpack_array(e, NULL); in unpack_xattrs()
554 profile->xattr_count = size; in unpack_xattrs()
555 profile->xattrs = kcalloc(size, sizeof(char *), GFP_KERNEL); in unpack_xattrs()
556 if (!profile->xattrs) in unpack_xattrs()
558 for (i = 0; i < size; i++) { in unpack_xattrs()
559 if (!unpack_strdup(e, &profile->xattrs[i], NULL)) in unpack_xattrs()
571 e->pos = pos; in unpack_xattrs()
577 void *pos = e->pos; in unpack_secmark()
578 int i, size; in unpack_secmark() local
581 size = unpack_array(e, NULL); in unpack_secmark()
583 profile->secmark = kcalloc(size, sizeof(struct aa_secmark), in unpack_secmark()
585 if (!profile->secmark) in unpack_secmark()
588 profile->secmark_count = size; in unpack_secmark()
590 for (i = 0; i < size; i++) { in unpack_secmark()
591 if (!unpack_u8(e, &profile->secmark[i].audit, NULL)) in unpack_secmark()
593 if (!unpack_u8(e, &profile->secmark[i].deny, NULL)) in unpack_secmark()
595 if (!unpack_strdup(e, &profile->secmark[i].label, NULL)) in unpack_secmark()
607 if (profile->secmark) { in unpack_secmark()
608 for (i = 0; i < size; i++) in unpack_secmark()
609 kfree(profile->secmark[i].label); in unpack_secmark()
610 kfree(profile->secmark); in unpack_secmark()
611 profile->secmark_count = 0; in unpack_secmark()
612 profile->secmark = NULL; in unpack_secmark()
615 e->pos = pos; in unpack_secmark()
621 void *pos = e->pos; in unpack_rlimits()
625 int i, size; in unpack_rlimits() local
629 profile->rlimits.mask = tmp; in unpack_rlimits()
631 size = unpack_array(e, NULL); in unpack_rlimits()
632 if (size > RLIM_NLIMITS) in unpack_rlimits()
634 for (i = 0; i < size; i++) { in unpack_rlimits()
639 profile->rlimits.limits[a].rlim_max = tmp2; in unpack_rlimits()
649 e->pos = pos; in unpack_rlimits()
653 static u32 strhash(const void *data, u32 len, u32 seed) in strhash() argument
655 const char * const *key = data; in strhash()
662 const struct aa_data *data = obj; in datacmp() local
663 const char * const *key = arg->key; in datacmp()
665 return strcmp(data->key, *key); in datacmp()
669 * unpack_profile - unpack a serialized profile
670 * @e: serialized data extent information (NOT NULL)
682 struct aa_data *data; in unpack_profile() local
683 int i, error = -EPROTO; in unpack_profile()
709 return ERR_PTR(-ENOMEM); in unpack_profile()
712 (void) unpack_str(e, &profile->rename, "rename"); in unpack_profile()
715 (void) unpack_str(e, &profile->attach, "attach"); in unpack_profile()
718 profile->xmatch = unpack_dfa(e); in unpack_profile()
719 if (IS_ERR(profile->xmatch)) { in unpack_profile()
720 error = PTR_ERR(profile->xmatch); in unpack_profile()
721 profile->xmatch = NULL; in unpack_profile()
726 if (profile->xmatch) { in unpack_profile()
731 profile->xmatch_len = tmp; in unpack_profile()
735 (void) unpack_str(e, &profile->disconnected, "disconnected"); in unpack_profile()
746 profile->label.flags |= FLAG_HAT; in unpack_profile()
749 if (tmp == PACKED_MODE_COMPLAIN || (e->version & FORCE_COMPLAIN_FLAG)) in unpack_profile()
750 profile->mode = APPARMOR_COMPLAIN; in unpack_profile()
752 profile->mode = APPARMOR_ENFORCE; in unpack_profile()
754 profile->mode = APPARMOR_KILL; in unpack_profile()
756 profile->mode = APPARMOR_UNCONFINED; in unpack_profile()
762 profile->audit = AUDIT_ALL; in unpack_profile()
768 if (unpack_u32(e, &profile->path_flags, "path_flags")) in unpack_profile()
769 profile->path_flags |= profile->label.flags & in unpack_profile()
773 profile->path_flags = PATH_MEDIATE_DELETED; in unpack_profile()
776 if (!unpack_u32(e, &(profile->caps.allow.cap[0]), NULL)) in unpack_profile()
778 if (!unpack_u32(e, &(profile->caps.audit.cap[0]), NULL)) in unpack_profile()
780 if (!unpack_u32(e, &(profile->caps.quiet.cap[0]), NULL)) in unpack_profile()
788 if (!unpack_u32(e, &(profile->caps.allow.cap[1]), NULL)) in unpack_profile()
790 if (!unpack_u32(e, &(profile->caps.audit.cap[1]), NULL)) in unpack_profile()
792 if (!unpack_u32(e, &(profile->caps.quiet.cap[1]), NULL)) in unpack_profile()
803 if (!unpack_u32(e, &(profile->caps.extended.cap[0]), NULL)) in unpack_profile()
805 if (!unpack_u32(e, &(profile->caps.extended.cap[1]), NULL)) in unpack_profile()
827 /* generic policy dfa - optional and may be NULL */ in unpack_profile()
829 profile->policy.dfa = unpack_dfa(e); in unpack_profile()
830 if (IS_ERR(profile->policy.dfa)) { in unpack_profile()
831 error = PTR_ERR(profile->policy.dfa); in unpack_profile()
832 profile->policy.dfa = NULL; in unpack_profile()
834 } else if (!profile->policy.dfa) { in unpack_profile()
835 error = -EPROTO; in unpack_profile()
838 if (!unpack_u32(e, &profile->policy.start[0], "start")) in unpack_profile()
840 profile->policy.start[0] = DFA_START; in unpack_profile()
843 profile->policy.start[i] = in unpack_profile()
844 aa_dfa_next(profile->policy.dfa, in unpack_profile()
845 profile->policy.start[0], in unpack_profile()
851 profile->policy.dfa = aa_get_dfa(nulldfa); in unpack_profile()
854 profile->file.dfa = unpack_dfa(e); in unpack_profile()
855 if (IS_ERR(profile->file.dfa)) { in unpack_profile()
856 error = PTR_ERR(profile->file.dfa); in unpack_profile()
857 profile->file.dfa = NULL; in unpack_profile()
860 } else if (profile->file.dfa) { in unpack_profile()
861 if (!unpack_u32(e, &profile->file.start, "dfa_start")) in unpack_profile()
863 profile->file.start = DFA_START; in unpack_profile()
864 } else if (profile->policy.dfa && in unpack_profile()
865 profile->policy.start[AA_CLASS_FILE]) { in unpack_profile()
866 profile->file.dfa = aa_get_dfa(profile->policy.dfa); in unpack_profile()
867 profile->file.start = profile->policy.start[AA_CLASS_FILE]; in unpack_profile()
869 profile->file.dfa = aa_get_dfa(nulldfa); in unpack_profile()
876 if (unpack_nameX(e, AA_STRUCT, "data")) { in unpack_profile()
878 profile->data = kzalloc(sizeof(*profile->data), GFP_KERNEL); in unpack_profile()
879 if (!profile->data) in unpack_profile()
889 if (rhashtable_init(profile->data, &params)) { in unpack_profile()
895 data = kzalloc(sizeof(*data), GFP_KERNEL); in unpack_profile()
896 if (!data) { in unpack_profile()
901 data->key = key; in unpack_profile()
902 data->size = unpack_blob(e, &data->data, NULL); in unpack_profile()
903 data->data = kvmemdup(data->data, data->size); in unpack_profile()
904 if (data->size && !data->data) { in unpack_profile()
905 kfree_sensitive(data->key); in unpack_profile()
906 kfree_sensitive(data); in unpack_profile()
910 rhashtable_insert_fast(profile->data, &data->head, in unpack_profile()
911 profile->data->p); in unpack_profile()
915 info = "failed to unpack end of key, value data table"; in unpack_profile()
939 * verify_head - unpack serialized stream header
940 * @e: serialized data read head (NOT NULL)
942 * @ns: Returns - namespace if one is specified else NULL (NOT NULL)
948 int error = -EPROTONOSUPPORT; in verify_header()
953 if (!unpack_u32(e, &e->version, "version")) { in verify_header()
965 if (VERSION_LT(e->version, v5) || VERSION_GT(e->version, v7)) { in verify_header()
984 return -ENOMEM; in verify_header()
1005 for (i = 0; i < dfa->tables[YYTD_ID_ACCEPT]->td_lolen; i++) { in verify_dfa_xindex()
1015 * verify_profile - Do post unpack analysis to verify profile consistency
1022 if (profile->file.dfa && in verify_profile()
1023 !verify_dfa_xindex(profile->file.dfa, in verify_profile()
1024 profile->file.trans.size)) { in verify_profile()
1026 NULL, -EPROTO); in verify_profile()
1027 return -EPROTO; in verify_profile()
1036 aa_put_profile(ent->rename); in aa_load_ent_free()
1037 aa_put_profile(ent->old); in aa_load_ent_free()
1038 aa_put_profile(ent->new); in aa_load_ent_free()
1039 kfree(ent->ns_name); in aa_load_ent_free()
1048 INIT_LIST_HEAD(&ent->list); in aa_load_ent_alloc()
1063 return -EFBIG; in deflate_compress()
1069 return -ENOMEM; in deflate_compress()
1073 error = -ENOMEM; in deflate_compress()
1079 error = -ENOMEM; in deflate_compress()
1090 error = -EINVAL; in deflate_compress()
1110 error = -ENOMEM; in deflate_compress()
1128 static int compress_loaddata(struct aa_loaddata *data) in compress_loaddata() argument
1131 AA_BUG(data->compressed_size > 0); in compress_loaddata()
1138 void *udata = data->data; in compress_loaddata()
1139 int error = deflate_compress(udata, data->size, &data->data, in compress_loaddata()
1140 &data->compressed_size); in compress_loaddata()
1146 data->compressed_size = data->size; in compress_loaddata()
1152 * aa_unpack - unpack packed binary profile(s) data loaded from user space
1153 * @udata: user data copied to kmem (NOT NULL)
1157 * Unpack user data and return refcounted allocated profile(s) stored in
1170 .start = udata->data, in aa_unpack()
1171 .end = udata->data + udata->size, in aa_unpack()
1172 .pos = udata->data, in aa_unpack()
1196 e.pos - start); in aa_unpack()
1202 error = -ENOMEM; in aa_unpack()
1206 ent->new = profile; in aa_unpack()
1207 ent->ns_name = ns_name; in aa_unpack()
1208 list_add_tail(&ent->list, lh); in aa_unpack()
1210 udata->abi = e.version & K_ABI_MASK; in aa_unpack()
1212 udata->hash = aa_calc_hash(udata->data, udata->size); in aa_unpack()
1213 if (IS_ERR(udata->hash)) { in aa_unpack()
1214 error = PTR_ERR(udata->hash); in aa_unpack()
1215 udata->hash = NULL; in aa_unpack()
1229 list_del_init(&ent->list); in aa_unpack()