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 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(!mutex_is_locked(&data->ns->lock)); in __aa_loaddata_update()
129 AA_BUG(data->revision > revision); in __aa_loaddata_update()
131 data->revision = revision; in __aa_loaddata_update()
132 if ((data->dents[AAFS_LOADDATA_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()
142 if (l->size != r->size) in aa_rawdata_eq()
144 if (l->compressed_size != r->compressed_size) in aa_rawdata_eq()
146 if (aa_g_hash_policy && memcmp(l->hash, r->hash, aa_hash_size()) != 0) in aa_rawdata_eq()
148 return memcmp(l->data, r->data, r->compressed_size ?: r->size) == 0; in aa_rawdata_eq()
158 struct aa_ns *ns = aa_get_ns(d->ns); in do_loaddata_free()
161 mutex_lock_nested(&ns->lock, ns->level); in do_loaddata_free()
163 mutex_unlock(&ns->lock); in do_loaddata_free()
167 kfree_sensitive(d->hash); in do_loaddata_free()
168 kfree_sensitive(d->name); in do_loaddata_free()
169 kvfree(d->data); in do_loaddata_free()
178 INIT_WORK(&d->work, do_loaddata_free); in aa_loaddata_kref()
179 schedule_work(&d->work); in aa_loaddata_kref()
183 struct aa_loaddata *aa_loaddata_alloc(size_t size) in aa_loaddata_alloc() argument
189 return ERR_PTR(-ENOMEM); in aa_loaddata_alloc()
190 d->data = kvzalloc(size, GFP_KERNEL); in aa_loaddata_alloc()
191 if (!d->data) { in aa_loaddata_alloc()
193 return ERR_PTR(-ENOMEM); in aa_loaddata_alloc()
195 kref_init(&d->count); in aa_loaddata_alloc()
196 INIT_LIST_HEAD(&d->list); in aa_loaddata_alloc()
201 /* test if read will be in packed data bounds */
202 static bool inbounds(struct aa_ext *e, size_t size) in inbounds() argument
204 return (size <= e->end - e->pos); in inbounds()
217 * unpack_u16_chunk - test and do bounds checking for a u16 size based chunk
218 * @e: serialized data read head (NOT NULL)
219 * @chunk: start address for chunk of data (NOT NULL)
221 * Returns: the size of chunk found with the read head at the end of the chunk.
225 size_t size = 0; in unpack_u16_chunk() local
226 void *pos = e->pos; in unpack_u16_chunk()
230 size = le16_to_cpu(get_unaligned((__le16 *) e->pos)); in unpack_u16_chunk()
231 e->pos += sizeof(__le16); in unpack_u16_chunk()
232 if (!inbounds(e, size)) in unpack_u16_chunk()
234 *chunk = e->pos; in unpack_u16_chunk()
235 e->pos += size; in unpack_u16_chunk()
236 return size; in unpack_u16_chunk()
239 e->pos = pos; in unpack_u16_chunk()
248 if (*(u8 *) e->pos != code) in unpack_X()
250 e->pos++; in unpack_X()
255 * unpack_nameX - check is the next element is of type X with a name of @name
256 * @e: serialized data extent information (NOT NULL)
260 * check that the next serialized data element is of type X and has a tag
275 void *pos = e->pos; in unpack_nameX()
277 * Check for presence of a tagname, and if present name size in unpack_nameX()
282 size_t size = unpack_u16_chunk(e, &tag); in unpack_nameX() local
284 if (name && (!size || tag[size-1] != '\0' || strcmp(name, tag))) in unpack_nameX()
296 e->pos = pos; in unpack_nameX()
300 static bool unpack_u8(struct aa_ext *e, u8 *data, const char *name) in unpack_u8() argument
302 void *pos = e->pos; in unpack_u8()
307 if (data) in unpack_u8()
308 *data = *((u8 *)e->pos); in unpack_u8()
309 e->pos += sizeof(u8); in unpack_u8()
314 e->pos = pos; in unpack_u8()
318 static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name) in unpack_u32() argument
320 void *pos = e->pos; in unpack_u32()
325 if (data) in unpack_u32()
326 *data = le32_to_cpu(get_unaligned((__le32 *) e->pos)); in unpack_u32()
327 e->pos += sizeof(u32); in unpack_u32()
332 e->pos = pos; in unpack_u32()
336 static bool unpack_u64(struct aa_ext *e, u64 *data, const char *name) in unpack_u64() argument
338 void *pos = e->pos; in unpack_u64()
343 if (data) in unpack_u64()
344 *data = le64_to_cpu(get_unaligned((__le64 *) e->pos)); in unpack_u64()
345 e->pos += sizeof(u64); in unpack_u64()
350 e->pos = pos; in unpack_u64()
356 void *pos = e->pos; in unpack_array()
359 int size; in unpack_array() local
362 size = (int)le16_to_cpu(get_unaligned((__le16 *) e->pos)); in unpack_array()
363 e->pos += sizeof(u16); in unpack_array()
364 return size; in unpack_array()
368 e->pos = pos; in unpack_array()
374 void *pos = e->pos; in unpack_blob()
377 u32 size; in unpack_blob() local
380 size = le32_to_cpu(get_unaligned((__le32 *) e->pos)); in unpack_blob()
381 e->pos += sizeof(u32); in unpack_blob()
382 if (inbounds(e, (size_t) size)) { in unpack_blob()
383 *blob = e->pos; in unpack_blob()
384 e->pos += size; in unpack_blob()
385 return size; in unpack_blob()
390 e->pos = pos; in unpack_blob()
397 size_t size = 0; in unpack_str() local
398 void *pos = e->pos; in unpack_str()
401 size = unpack_u16_chunk(e, &src_str); in unpack_str()
402 if (size) { in unpack_str()
403 /* strings are null terminated, length is size - 1 */ in unpack_str()
404 if (src_str[size - 1] != 0) in unpack_str()
408 return size; in unpack_str()
413 e->pos = pos; in unpack_str()
420 void *pos = e->pos; in unpack_strdup()
429 e->pos = pos; in unpack_strdup()
438 * unpack_dfa - unpack a file rule dfa
439 * @e: serialized data extent information (NOT NULL)
446 size_t size; in unpack_dfa() local
449 size = unpack_blob(e, &blob, "aadfa"); in unpack_dfa()
450 if (size) { in unpack_dfa()
456 size_t sz = blob - (char *) e->start - in unpack_dfa()
457 ((e->pos - e->start) & 7); in unpack_dfa()
458 size_t pad = ALIGN(sz, 8) - sz; in unpack_dfa()
463 dfa = aa_dfa_unpack(blob + pad, size - pad, flags); in unpack_dfa()
474 * unpack_trans_table - unpack a profile transition table
475 * @e: serialized data extent information (NOT NULL)
482 void *saved_pos = e->pos; in unpack_trans_table()
486 int i, size; in unpack_trans_table() local
488 size = unpack_array(e, NULL); in unpack_trans_table()
489 /* currently 4 exec bits and entries 0-3 are reserved iupcx */ in unpack_trans_table()
490 if (size > 16 - 4) in unpack_trans_table()
492 profile->file.trans.table = kcalloc(size, sizeof(char *), in unpack_trans_table()
494 if (!profile->file.trans.table) in unpack_trans_table()
497 profile->file.trans.size = size; in unpack_trans_table()
498 for (i = 0; i < size; i++) { in unpack_trans_table()
506 profile->file.trans.table[i] = str; in unpack_trans_table()
512 for (c = j = 0; j < size2 - 1; j++) { in unpack_trans_table()
533 /* fail - all other cases with embedded \0 */ in unpack_trans_table()
544 aa_free_domain_entries(&profile->file.trans); in unpack_trans_table()
545 e->pos = saved_pos; in unpack_trans_table()
551 void *pos = e->pos; in unpack_xattrs()
554 int i, size; in unpack_xattrs() local
556 size = unpack_array(e, NULL); in unpack_xattrs()
557 profile->xattr_count = size; in unpack_xattrs()
558 profile->xattrs = kcalloc(size, sizeof(char *), GFP_KERNEL); in unpack_xattrs()
559 if (!profile->xattrs) in unpack_xattrs()
561 for (i = 0; i < size; i++) { in unpack_xattrs()
562 if (!unpack_strdup(e, &profile->xattrs[i], NULL)) in unpack_xattrs()
574 e->pos = pos; in unpack_xattrs()
580 void *pos = e->pos; in unpack_secmark()
581 int i, size; in unpack_secmark() local
584 size = unpack_array(e, NULL); in unpack_secmark()
586 profile->secmark = kcalloc(size, sizeof(struct aa_secmark), in unpack_secmark()
588 if (!profile->secmark) in unpack_secmark()
591 profile->secmark_count = size; in unpack_secmark()
593 for (i = 0; i < size; i++) { in unpack_secmark()
594 if (!unpack_u8(e, &profile->secmark[i].audit, NULL)) in unpack_secmark()
596 if (!unpack_u8(e, &profile->secmark[i].deny, NULL)) in unpack_secmark()
598 if (!unpack_strdup(e, &profile->secmark[i].label, NULL)) in unpack_secmark()
610 if (profile->secmark) { in unpack_secmark()
611 for (i = 0; i < size; i++) in unpack_secmark()
612 kfree(profile->secmark[i].label); in unpack_secmark()
613 kfree(profile->secmark); in unpack_secmark()
614 profile->secmark_count = 0; in unpack_secmark()
615 profile->secmark = NULL; in unpack_secmark()
618 e->pos = pos; in unpack_secmark()
624 void *pos = e->pos; in unpack_rlimits()
628 int i, size; in unpack_rlimits() local
632 profile->rlimits.mask = tmp; in unpack_rlimits()
634 size = unpack_array(e, NULL); in unpack_rlimits()
635 if (size > RLIM_NLIMITS) in unpack_rlimits()
637 for (i = 0; i < size; i++) { in unpack_rlimits()
642 profile->rlimits.limits[a].rlim_max = tmp2; in unpack_rlimits()
652 e->pos = pos; in unpack_rlimits()
656 static u32 strhash(const void *data, u32 len, u32 seed) in strhash() argument
658 const char * const *key = data; in strhash()
665 const struct aa_data *data = obj; in datacmp() local
666 const char * const *key = arg->key; in datacmp()
668 return strcmp(data->key, *key); in datacmp()
672 * unpack_profile - unpack a serialized profile
673 * @e: serialized data extent information (NOT NULL)
686 struct aa_data *data; in unpack_profile() local
687 int i, error = -EPROTO; in unpack_profile()
713 return ERR_PTR(-ENOMEM); in unpack_profile()
716 (void) unpack_str(e, &profile->rename, "rename"); in unpack_profile()
719 (void) unpack_str(e, &profile->attach, "attach"); in unpack_profile()
722 profile->xmatch = unpack_dfa(e); in unpack_profile()
723 if (IS_ERR(profile->xmatch)) { in unpack_profile()
724 error = PTR_ERR(profile->xmatch); in unpack_profile()
725 profile->xmatch = NULL; in unpack_profile()
730 if (profile->xmatch) { in unpack_profile()
735 profile->xmatch_len = tmp; in unpack_profile()
739 (void) unpack_str(e, &profile->disconnected, "disconnected"); in unpack_profile()
750 profile->label.flags |= FLAG_HAT; in unpack_profile()
752 profile->label.flags |= FLAG_DEBUG1; in unpack_profile()
754 profile->label.flags |= FLAG_DEBUG2; in unpack_profile()
757 if (tmp == PACKED_MODE_COMPLAIN || (e->version & FORCE_COMPLAIN_FLAG)) { in unpack_profile()
758 profile->mode = APPARMOR_COMPLAIN; in unpack_profile()
760 profile->mode = APPARMOR_ENFORCE; in unpack_profile()
762 profile->mode = APPARMOR_KILL; in unpack_profile()
764 profile->mode = APPARMOR_UNCONFINED; in unpack_profile()
765 profile->label.flags |= FLAG_UNCONFINED; in unpack_profile()
772 profile->audit = AUDIT_ALL; in unpack_profile()
778 if (unpack_u32(e, &profile->path_flags, "path_flags")) in unpack_profile()
779 profile->path_flags |= profile->label.flags & in unpack_profile()
783 profile->path_flags = PATH_MEDIATE_DELETED; in unpack_profile()
786 if (!unpack_u32(e, &(profile->caps.allow.cap[0]), NULL)) in unpack_profile()
788 if (!unpack_u32(e, &(profile->caps.audit.cap[0]), NULL)) in unpack_profile()
790 if (!unpack_u32(e, &(profile->caps.quiet.cap[0]), NULL)) in unpack_profile()
798 if (!unpack_u32(e, &(profile->caps.allow.cap[1]), NULL)) in unpack_profile()
800 if (!unpack_u32(e, &(profile->caps.audit.cap[1]), NULL)) in unpack_profile()
802 if (!unpack_u32(e, &(profile->caps.quiet.cap[1]), NULL)) in unpack_profile()
813 if (!unpack_u32(e, &(profile->caps.extended.cap[0]), NULL)) in unpack_profile()
815 if (!unpack_u32(e, &(profile->caps.extended.cap[1]), NULL)) in unpack_profile()
837 /* generic policy dfa - optional and may be NULL */ in unpack_profile()
839 profile->policy.dfa = unpack_dfa(e); in unpack_profile()
840 if (IS_ERR(profile->policy.dfa)) { in unpack_profile()
841 error = PTR_ERR(profile->policy.dfa); in unpack_profile()
842 profile->policy.dfa = NULL; in unpack_profile()
844 } else if (!profile->policy.dfa) { in unpack_profile()
845 error = -EPROTO; in unpack_profile()
848 if (!unpack_u32(e, &profile->policy.start[0], "start")) in unpack_profile()
850 profile->policy.start[0] = DFA_START; in unpack_profile()
853 profile->policy.start[i] = in unpack_profile()
854 aa_dfa_next(profile->policy.dfa, in unpack_profile()
855 profile->policy.start[0], in unpack_profile()
861 profile->policy.dfa = aa_get_dfa(nulldfa); in unpack_profile()
864 profile->file.dfa = unpack_dfa(e); in unpack_profile()
865 if (IS_ERR(profile->file.dfa)) { in unpack_profile()
866 error = PTR_ERR(profile->file.dfa); in unpack_profile()
867 profile->file.dfa = NULL; in unpack_profile()
870 } else if (profile->file.dfa) { in unpack_profile()
871 if (!unpack_u32(e, &profile->file.start, "dfa_start")) in unpack_profile()
873 profile->file.start = DFA_START; in unpack_profile()
874 } else if (profile->policy.dfa && in unpack_profile()
875 profile->policy.start[AA_CLASS_FILE]) { in unpack_profile()
876 profile->file.dfa = aa_get_dfa(profile->policy.dfa); in unpack_profile()
877 profile->file.start = profile->policy.start[AA_CLASS_FILE]; in unpack_profile()
879 profile->file.dfa = aa_get_dfa(nulldfa); in unpack_profile()
886 if (unpack_nameX(e, AA_STRUCT, "data")) { in unpack_profile()
888 profile->data = kzalloc(sizeof(*profile->data), GFP_KERNEL); in unpack_profile()
889 if (!profile->data) in unpack_profile()
899 if (rhashtable_init(profile->data, ¶ms)) { in unpack_profile()
905 data = kzalloc(sizeof(*data), GFP_KERNEL); in unpack_profile()
906 if (!data) { in unpack_profile()
911 data->key = key; in unpack_profile()
912 data->size = unpack_blob(e, &data->data, NULL); in unpack_profile()
913 data->data = kvmemdup(data->data, data->size); in unpack_profile()
914 if (data->size && !data->data) { in unpack_profile()
915 kfree_sensitive(data->key); in unpack_profile()
916 kfree_sensitive(data); in unpack_profile()
920 rhashtable_insert_fast(profile->data, &data->head, in unpack_profile()
921 profile->data->p); in unpack_profile()
925 info = "failed to unpack end of key, value data table"; in unpack_profile()
949 * verify_header - unpack serialized stream header
950 * @e: serialized data read head (NOT NULL)
952 * @ns: Returns - namespace if one is specified else NULL (NOT NULL)
958 int error = -EPROTONOSUPPORT; in verify_header()
963 if (!unpack_u32(e, &e->version, "version")) { in verify_header()
975 if (VERSION_LT(e->version, v5) || VERSION_GT(e->version, v7)) { in verify_header()
994 return -ENOMEM; in verify_header()
1015 for (i = 0; i < dfa->tables[YYTD_ID_ACCEPT]->td_lolen; i++) { in verify_dfa_xindex()
1025 * verify_profile - Do post unpack analysis to verify profile consistency
1032 if (profile->file.dfa && in verify_profile()
1033 !verify_dfa_xindex(profile->file.dfa, in verify_profile()
1034 profile->file.trans.size)) { in verify_profile()
1036 NULL, -EPROTO); in verify_profile()
1037 return -EPROTO; in verify_profile()
1046 aa_put_profile(ent->rename); in aa_load_ent_free()
1047 aa_put_profile(ent->old); in aa_load_ent_free()
1048 aa_put_profile(ent->new); in aa_load_ent_free()
1049 kfree(ent->ns_name); in aa_load_ent_free()
1058 INIT_LIST_HEAD(&ent->list); in aa_load_ent_alloc()
1074 return -EFBIG; in deflate_compress()
1080 return -ENOMEM; in deflate_compress()
1084 error = -ENOMEM; in deflate_compress()
1090 error = -ENOMEM; in deflate_compress()
1101 error = -EINVAL; in deflate_compress()
1121 error = -ENOMEM; in deflate_compress()
1143 static int compress_loaddata(struct aa_loaddata *data) in compress_loaddata() argument
1146 AA_BUG(data->compressed_size > 0); in compress_loaddata()
1153 void *udata = data->data; in compress_loaddata()
1154 int error = deflate_compress(udata, data->size, &data->data, in compress_loaddata()
1155 &data->compressed_size); in compress_loaddata()
1159 if (udata != data->data) in compress_loaddata()
1162 data->compressed_size = data->size; in compress_loaddata()
1168 * aa_unpack - unpack packed binary profile(s) data loaded from user space
1169 * @udata: user data copied to kmem (NOT NULL)
1173 * Unpack user data and return refcounted allocated profile(s) stored in
1186 .start = udata->data, in aa_unpack()
1187 .end = udata->data + udata->size, in aa_unpack()
1188 .pos = udata->data, in aa_unpack()
1212 e.pos - start); in aa_unpack()
1218 error = -ENOMEM; in aa_unpack()
1222 ent->new = profile; in aa_unpack()
1223 ent->ns_name = ns_name; in aa_unpack()
1224 list_add_tail(&ent->list, lh); in aa_unpack()
1226 udata->abi = e.version & K_ABI_MASK; in aa_unpack()
1228 udata->hash = aa_calc_hash(udata->data, udata->size); in aa_unpack()
1229 if (IS_ERR(udata->hash)) { in aa_unpack()
1230 error = PTR_ERR(udata->hash); in aa_unpack()
1231 udata->hash = NULL; in aa_unpack()
1248 list_del_init(&ent->list); in aa_unpack()