File Index
Files and directories
Sign in
FILE

policy_unpack.c

File preview with syntax highlighting.

linux-6.19.14/security/apparmor/policy_unpack.c C
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * AppArmor security module
   4 *
   5 * This file contains AppArmor functions for unpacking policy loaded from
   6 * userspace.
   7 *
   8 * Copyright (C) 1998-2008 Novell/SUSE
   9 * Copyright 2009-2010 Canonical Ltd.
  10 *
  11 * AppArmor uses a serialized binary format for loading policy. To find
  12 * policy format documentation see Documentation/admin-guide/LSM/apparmor.rst
  13 * All policy is validated before it is used.
  14 */
  15
  16#include <linux/unaligned.h>
  17#include <kunit/visibility.h>
  18#include <linux/ctype.h>
  19#include <linux/errno.h>
  20#include <linux/zstd.h>
  21
  22#include "include/apparmor.h"
  23#include "include/audit.h"
  24#include "include/cred.h"
  25#include "include/crypto.h"
  26#include "include/file.h"
  27#include "include/match.h"
  28#include "include/path.h"
  29#include "include/policy.h"
  30#include "include/policy_unpack.h"
  31#include "include/policy_compat.h"
  32#include "include/signal.h"
  33
  34/* audit callback for unpack fields */
  35static void audit_cb(struct audit_buffer *ab, void *va)
  36{
  37	struct common_audit_data *sa = va;
  38	struct apparmor_audit_data *ad = aad(sa);
  39
  40	if (ad->iface.ns) {
  41		audit_log_format(ab, " ns=");
  42		audit_log_untrustedstring(ab, ad->iface.ns);
  43	}
  44	if (ad->name) {
  45		audit_log_format(ab, " name=");
  46		audit_log_untrustedstring(ab, ad->name);
  47	}
  48	if (ad->iface.pos)
  49		audit_log_format(ab, " offset=%ld", ad->iface.pos);
  50}
  51
  52/**
  53 * audit_iface - do audit message for policy unpacking/load/replace/remove
  54 * @new: profile if it has been allocated (MAYBE NULL)
  55 * @ns_name: name of the ns the profile is to be loaded to (MAY BE NULL)
  56 * @name: name of the profile being manipulated (MAYBE NULL)
  57 * @info: any extra info about the failure (MAYBE NULL)
  58 * @e: buffer position info
  59 * @error: error code
  60 *
  61 * Returns: %0 or error
  62 */
  63static int audit_iface(struct aa_profile *new, const char *ns_name,
  64		       const char *name, const char *info, struct aa_ext *e,
  65		       int error)
  66{
  67	struct aa_profile *profile = labels_profile(aa_current_raw_label());
  68	DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_NONE, AA_CLASS_NONE, NULL);
  69	if (e)
  70		ad.iface.pos = e->pos - e->start;
  71	ad.iface.ns = ns_name;
  72	if (new)
  73		ad.name = new->base.hname;
  74	else
  75		ad.name = name;
  76	ad.info = info;
  77	ad.error = error;
  78
  79	return aa_audit(AUDIT_APPARMOR_STATUS, profile, &ad, audit_cb);
  80}
  81
  82void __aa_loaddata_update(struct aa_loaddata *data, long revision)
  83{
  84	AA_BUG(!data);
  85	AA_BUG(!data->ns);
  86	AA_BUG(!mutex_is_locked(&data->ns->lock));
  87	AA_BUG(data->revision > revision);
  88
  89	data->revision = revision;
  90	if ((data->dents[AAFS_LOADDATA_REVISION])) {
  91		struct inode *inode;
  92
  93		inode = d_inode(data->dents[AAFS_LOADDATA_DIR]);
  94		inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
  95
  96		inode = d_inode(data->dents[AAFS_LOADDATA_REVISION]);
  97		inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
  98	}
  99}
 100
 101bool aa_rawdata_eq(struct aa_loaddata *l, struct aa_loaddata *r)
 102{
 103	if (l->size != r->size)
 104		return false;
 105	if (l->compressed_size != r->compressed_size)
 106		return false;
 107	if (aa_g_hash_policy && memcmp(l->hash, r->hash, aa_hash_size()) != 0)
 108		return false;
 109	return memcmp(l->data, r->data, r->compressed_size ?: r->size) == 0;
 110}
 111
 112static void do_loaddata_free(struct aa_loaddata *d)
 113{
 114	kfree_sensitive(d->hash);
 115	kfree_sensitive(d->name);
 116	kvfree(d->data);
 117	kfree_sensitive(d);
 118}
 119
 120void aa_loaddata_kref(struct kref *kref)
 121{
 122	struct aa_loaddata *d = container_of(kref, struct aa_loaddata,
 123					     count.count);
 124
 125	do_loaddata_free(d);
 126}
 127
 128/*
 129 * need to take the ns mutex lock which is NOT safe most places that
 130 * put_loaddata is called, so we have to delay freeing it
 131 */
 132static void do_ploaddata_rmfs(struct work_struct *work)
 133{
 134	struct aa_loaddata *d = container_of(work, struct aa_loaddata, work);
 135	struct aa_ns *ns = aa_get_ns(d->ns);
 136
 137	if (ns) {
 138		mutex_lock_nested(&ns->lock, ns->level);
 139		/* remove fs ref to loaddata */
 140		__aa_fs_remove_rawdata(d);
 141		mutex_unlock(&ns->lock);
 142		aa_put_ns(ns);
 143	}
 144	/* called by dropping last pcount, so drop its associated icount */
 145	aa_put_i_loaddata(d);
 146}
 147
 148void aa_ploaddata_kref(struct kref *kref)
 149{
 150	struct aa_loaddata *d = container_of(kref, struct aa_loaddata, pcount);
 151
 152	if (d) {
 153		INIT_WORK(&d->work, do_ploaddata_rmfs);
 154		schedule_work(&d->work);
 155	}
 156}
 157
 158struct aa_loaddata *aa_loaddata_alloc(size_t size)
 159{
 160	struct aa_loaddata *d;
 161
 162	d = kzalloc(sizeof(*d), GFP_KERNEL);
 163	if (d == NULL)
 164		return ERR_PTR(-ENOMEM);
 165	d->data = kvzalloc(size, GFP_KERNEL);
 166	if (!d->data) {
 167		kfree(d);
 168		return ERR_PTR(-ENOMEM);
 169	}
 170	kref_init(&d->count.count);
 171	d->count.reftype = REF_RAWDATA;
 172	kref_init(&d->pcount);
 173	INIT_LIST_HEAD(&d->list);
 174
 175	return d;
 176}
 177
 178/* test if read will be in packed data bounds */
 179VISIBLE_IF_KUNIT bool aa_inbounds(struct aa_ext *e, size_t size)
 180{
 181	return (size <= e->end - e->pos);
 182}
 183EXPORT_SYMBOL_IF_KUNIT(aa_inbounds);
 184
 185/**
 186 * aa_unpack_u16_chunk - test and do bounds checking for a u16 size based chunk
 187 * @e: serialized data read head (NOT NULL)
 188 * @chunk: start address for chunk of data (NOT NULL)
 189 *
 190 * Returns: the size of chunk found with the read head at the end of the chunk.
 191 */
 192VISIBLE_IF_KUNIT size_t aa_unpack_u16_chunk(struct aa_ext *e, char **chunk)
 193{
 194	size_t size = 0;
 195	void *pos = e->pos;
 196
 197	if (!aa_inbounds(e, sizeof(u16)))
 198		goto fail;
 199	size = le16_to_cpu(get_unaligned((__le16 *) e->pos));
 200	e->pos += sizeof(__le16);
 201	if (!aa_inbounds(e, size))
 202		goto fail;
 203	*chunk = e->pos;
 204	e->pos += size;
 205	return size;
 206
 207fail:
 208	e->pos = pos;
 209	return 0;
 210}
 211EXPORT_SYMBOL_IF_KUNIT(aa_unpack_u16_chunk);
 212
 213/* unpack control byte */
 214VISIBLE_IF_KUNIT bool aa_unpack_X(struct aa_ext *e, enum aa_code code)
 215{
 216	if (!aa_inbounds(e, 1))
 217		return false;
 218	if (*(u8 *) e->pos != code)
 219		return false;
 220	e->pos++;
 221	return true;
 222}
 223EXPORT_SYMBOL_IF_KUNIT(aa_unpack_X);
 224
 225/**
 226 * aa_unpack_nameX - check is the next element is of type X with a name of @name
 227 * @e: serialized data extent information  (NOT NULL)
 228 * @code: type code
 229 * @name: name to match to the serialized element.  (MAYBE NULL)
 230 *
 231 * check that the next serialized data element is of type X and has a tag
 232 * name @name.  If @name is specified then there must be a matching
 233 * name element in the stream.  If @name is NULL any name element will be
 234 * skipped and only the typecode will be tested.
 235 *
 236 * Returns true on success (both type code and name tests match) and the read
 237 * head is advanced past the headers
 238 *
 239 * Returns: false if either match fails, the read head does not move
 240 */
 241VISIBLE_IF_KUNIT bool aa_unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name)
 242{
 243	/*
 244	 * May need to reset pos if name or type doesn't match
 245	 */
 246	void *pos = e->pos;
 247	/*
 248	 * Check for presence of a tagname, and if present name size
 249	 * AA_NAME tag value is a u16.
 250	 */
 251	if (aa_unpack_X(e, AA_NAME)) {
 252		char *tag = NULL;
 253		size_t size = aa_unpack_u16_chunk(e, &tag);
 254		/* if a name is specified it must match. otherwise skip tag */
 255		if (name && (!size || tag[size-1] != '\0' || strcmp(name, tag)))
 256			goto fail;
 257	} else if (name) {
 258		/* if a name is specified and there is no name tag fail */
 259		goto fail;
 260	}
 261
 262	/* now check if type code matches */
 263	if (aa_unpack_X(e, code))
 264		return true;
 265
 266fail:
 267	e->pos = pos;
 268	return false;
 269}
 270EXPORT_SYMBOL_IF_KUNIT(aa_unpack_nameX);
 271
 272static bool unpack_u8(struct aa_ext *e, u8 *data, const char *name)
 273{
 274	void *pos = e->pos;
 275
 276	if (aa_unpack_nameX(e, AA_U8, name)) {
 277		if (!aa_inbounds(e, sizeof(u8)))
 278			goto fail;
 279		if (data)
 280			*data = *((u8 *)e->pos);
 281		e->pos += sizeof(u8);
 282		return true;
 283	}
 284
 285fail:
 286	e->pos = pos;
 287	return false;
 288}
 289
 290VISIBLE_IF_KUNIT bool aa_unpack_u32(struct aa_ext *e, u32 *data, const char *name)
 291{
 292	void *pos = e->pos;
 293
 294	if (aa_unpack_nameX(e, AA_U32, name)) {
 295		if (!aa_inbounds(e, sizeof(u32)))
 296			goto fail;
 297		if (data)
 298			*data = le32_to_cpu(get_unaligned((__le32 *) e->pos));
 299		e->pos += sizeof(u32);
 300		return true;
 301	}
 302
 303fail:
 304	e->pos = pos;
 305	return false;
 306}
 307EXPORT_SYMBOL_IF_KUNIT(aa_unpack_u32);
 308
 309VISIBLE_IF_KUNIT bool aa_unpack_u64(struct aa_ext *e, u64 *data, const char *name)
 310{
 311	void *pos = e->pos;
 312
 313	if (aa_unpack_nameX(e, AA_U64, name)) {
 314		if (!aa_inbounds(e, sizeof(u64)))
 315			goto fail;
 316		if (data)
 317			*data = le64_to_cpu(get_unaligned((__le64 *) e->pos));
 318		e->pos += sizeof(u64);
 319		return true;
 320	}
 321
 322fail:
 323	e->pos = pos;
 324	return false;
 325}
 326EXPORT_SYMBOL_IF_KUNIT(aa_unpack_u64);
 327
 328static bool aa_unpack_cap_low(struct aa_ext *e, kernel_cap_t *data, const char *name)
 329{
 330	u32 val;
 331
 332	if (!aa_unpack_u32(e, &val, name))
 333		return false;
 334	data->val = val;
 335	return true;
 336}
 337
 338static bool aa_unpack_cap_high(struct aa_ext *e, kernel_cap_t *data, const char *name)
 339{
 340	u32 val;
 341
 342	if (!aa_unpack_u32(e, &val, name))
 343		return false;
 344	data->val = (u32)data->val | ((u64)val << 32);
 345	return true;
 346}
 347
 348VISIBLE_IF_KUNIT bool aa_unpack_array(struct aa_ext *e, const char *name, u16 *size)
 349{
 350	void *pos = e->pos;
 351
 352	if (aa_unpack_nameX(e, AA_ARRAY, name)) {
 353		if (!aa_inbounds(e, sizeof(u16)))
 354			goto fail;
 355		*size = le16_to_cpu(get_unaligned((__le16 *) e->pos));
 356		e->pos += sizeof(u16);
 357		return true;
 358	}
 359
 360fail:
 361	e->pos = pos;
 362	return false;
 363}
 364EXPORT_SYMBOL_IF_KUNIT(aa_unpack_array);
 365
 366VISIBLE_IF_KUNIT size_t aa_unpack_blob(struct aa_ext *e, char **blob, const char *name)
 367{
 368	void *pos = e->pos;
 369
 370	if (aa_unpack_nameX(e, AA_BLOB, name)) {
 371		u32 size;
 372		if (!aa_inbounds(e, sizeof(u32)))
 373			goto fail;
 374		size = le32_to_cpu(get_unaligned((__le32 *) e->pos));
 375		e->pos += sizeof(u32);
 376		if (aa_inbounds(e, (size_t) size)) {
 377			*blob = e->pos;
 378			e->pos += size;
 379			return size;
 380		}
 381	}
 382
 383fail:
 384	e->pos = pos;
 385	return 0;
 386}
 387EXPORT_SYMBOL_IF_KUNIT(aa_unpack_blob);
 388
 389VISIBLE_IF_KUNIT int aa_unpack_str(struct aa_ext *e, const char **string, const char *name)
 390{
 391	char *src_str;
 392	size_t size = 0;
 393	void *pos = e->pos;
 394	*string = NULL;
 395	if (aa_unpack_nameX(e, AA_STRING, name)) {
 396		size = aa_unpack_u16_chunk(e, &src_str);
 397		if (size) {
 398			/* strings are null terminated, length is size - 1 */
 399			if (src_str[size - 1] != 0)
 400				goto fail;
 401			*string = src_str;
 402
 403			return size;
 404		}
 405	}
 406
 407fail:
 408	e->pos = pos;
 409	return 0;
 410}
 411EXPORT_SYMBOL_IF_KUNIT(aa_unpack_str);
 412
 413VISIBLE_IF_KUNIT int aa_unpack_strdup(struct aa_ext *e, char **string, const char *name)
 414{
 415	const char *tmp;
 416	void *pos = e->pos;
 417	int res = aa_unpack_str(e, &tmp, name);
 418	*string = NULL;
 419
 420	if (!res)
 421		return 0;
 422
 423	*string = kmemdup(tmp, res, GFP_KERNEL);
 424	if (!*string) {
 425		e->pos = pos;
 426		return 0;
 427	}
 428
 429	return res;
 430}
 431EXPORT_SYMBOL_IF_KUNIT(aa_unpack_strdup);
 432
 433
 434/**
 435 * unpack_dfa - unpack a file rule dfa
 436 * @e: serialized data extent information (NOT NULL)
 437 * @flags: dfa flags to check
 438 *
 439 * returns dfa or ERR_PTR or NULL if no dfa
 440 */
 441static struct aa_dfa *unpack_dfa(struct aa_ext *e, int flags)
 442{
 443	char *blob = NULL;
 444	size_t size;
 445	struct aa_dfa *dfa = NULL;
 446
 447	size = aa_unpack_blob(e, &blob, "aadfa");
 448	if (size) {
 449		/*
 450		 * The dfa is aligned with in the blob to 8 bytes
 451		 * from the beginning of the stream.
 452		 * alignment adjust needed by dfa unpack
 453		 */
 454		size_t sz = blob - (char *) e->start -
 455			((e->pos - e->start) & 7);
 456		size_t pad = ALIGN(sz, 8) - sz;
 457		if (aa_g_paranoid_load)
 458			flags |= DFA_FLAG_VERIFY_STATES;
 459		dfa = aa_dfa_unpack(blob + pad, size - pad, flags);
 460
 461		if (IS_ERR(dfa))
 462			return dfa;
 463
 464	}
 465
 466	return dfa;
 467}
 468
 469/**
 470 * unpack_trans_table - unpack a profile transition table
 471 * @e: serialized data extent information  (NOT NULL)
 472 * @strs: str table to unpack to (NOT NULL)
 473 *
 474 * Returns: true if table successfully unpacked or not present
 475 */
 476static bool unpack_trans_table(struct aa_ext *e, struct aa_str_table *strs)
 477{
 478	void *saved_pos = e->pos;
 479	char **table = NULL;
 480
 481	/* exec table is optional */
 482	if (aa_unpack_nameX(e, AA_STRUCT, "xtable")) {
 483		u16 size;
 484		int i;
 485
 486		if (!aa_unpack_array(e, NULL, &size))
 487			/*
 488			 * Note: index into trans table array is a max
 489			 * of 2^24, but unpack array can only unpack
 490			 * an array of 2^16 in size atm so no need
 491			 * for size check here
 492			 */
 493			goto fail;
 494		table = kcalloc(size, sizeof(char *), GFP_KERNEL);
 495		if (!table)
 496			goto fail;
 497
 498		strs->table = table;
 499		strs->size = size;
 500		for (i = 0; i < size; i++) {
 501			char *str;
 502			int c, j, pos, size2 = aa_unpack_strdup(e, &str, NULL);
 503			/* aa_unpack_strdup verifies that the last character is
 504			 * null termination byte.
 505			 */
 506			if (!size2)
 507				goto fail;
 508			table[i] = str;
 509			/* verify that name doesn't start with space */
 510			if (isspace(*str))
 511				goto fail;
 512
 513			/* count internal #  of internal \0 */
 514			for (c = j = 0; j < size2 - 1; j++) {
 515				if (!str[j]) {
 516					pos = j;
 517					c++;
 518				}
 519			}
 520			if (*str == ':') {
 521				/* first character after : must be valid */
 522				if (!str[1])
 523					goto fail;
 524				/* beginning with : requires an embedded \0,
 525				 * verify that exactly 1 internal \0 exists
 526				 * trailing \0 already verified by aa_unpack_strdup
 527				 *
 528				 * convert \0 back to : for label_parse
 529				 */
 530				if (c == 1)
 531					str[pos] = ':';
 532				else if (c > 1)
 533					goto fail;
 534			} else if (c)
 535				/* fail - all other cases with embedded \0 */
 536				goto fail;
 537		}
 538		if (!aa_unpack_nameX(e, AA_ARRAYEND, NULL))
 539			goto fail;
 540		if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL))
 541			goto fail;
 542	}
 543	return true;
 544
 545fail:
 546	aa_free_str_table(strs);
 547	e->pos = saved_pos;
 548	return false;
 549}
 550
 551static bool unpack_xattrs(struct aa_ext *e, struct aa_profile *profile)
 552{
 553	void *pos = e->pos;
 554
 555	if (aa_unpack_nameX(e, AA_STRUCT, "xattrs")) {
 556		u16 size;
 557		int i;
 558
 559		if (!aa_unpack_array(e, NULL, &size))
 560			goto fail;
 561		profile->attach.xattr_count = size;
 562		profile->attach.xattrs = kcalloc(size, sizeof(char *), GFP_KERNEL);
 563		if (!profile->attach.xattrs)
 564			goto fail;
 565		for (i = 0; i < size; i++) {
 566			if (!aa_unpack_strdup(e, &profile->attach.xattrs[i], NULL))
 567				goto fail;
 568		}
 569		if (!aa_unpack_nameX(e, AA_ARRAYEND, NULL))
 570			goto fail;
 571		if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL))
 572			goto fail;
 573	}
 574
 575	return true;
 576
 577fail:
 578	e->pos = pos;
 579	return false;
 580}
 581
 582static bool unpack_secmark(struct aa_ext *e, struct aa_ruleset *rules)
 583{
 584	void *pos = e->pos;
 585	u16 size;
 586	int i;
 587
 588	if (aa_unpack_nameX(e, AA_STRUCT, "secmark")) {
 589		if (!aa_unpack_array(e, NULL, &size))
 590			goto fail;
 591
 592		rules->secmark = kcalloc(size, sizeof(struct aa_secmark),
 593					   GFP_KERNEL);
 594		if (!rules->secmark)
 595			goto fail;
 596
 597		rules->secmark_count = size;
 598
 599		for (i = 0; i < size; i++) {
 600			if (!unpack_u8(e, &rules->secmark[i].audit, NULL))
 601				goto fail;
 602			if (!unpack_u8(e, &rules->secmark[i].deny, NULL))
 603				goto fail;
 604			if (!aa_unpack_strdup(e, &rules->secmark[i].label, NULL))
 605				goto fail;
 606		}
 607		if (!aa_unpack_nameX(e, AA_ARRAYEND, NULL))
 608			goto fail;
 609		if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL))
 610			goto fail;
 611	}
 612
 613	return true;
 614
 615fail:
 616	if (rules->secmark) {
 617		for (i = 0; i < size; i++)
 618			kfree_sensitive(rules->secmark[i].label);
 619		kfree_sensitive(rules->secmark);
 620		rules->secmark_count = 0;
 621		rules->secmark = NULL;
 622	}
 623
 624	e->pos = pos;
 625	return false;
 626}
 627
 628static bool unpack_rlimits(struct aa_ext *e, struct aa_ruleset *rules)
 629{
 630	void *pos = e->pos;
 631
 632	/* rlimits are optional */
 633	if (aa_unpack_nameX(e, AA_STRUCT, "rlimits")) {
 634		u16 size;
 635		int i;
 636		u32 tmp = 0;
 637		if (!aa_unpack_u32(e, &tmp, NULL))
 638			goto fail;
 639		rules->rlimits.mask = tmp;
 640
 641		if (!aa_unpack_array(e, NULL, &size) ||
 642		    size > RLIM_NLIMITS)
 643			goto fail;
 644		for (i = 0; i < size; i++) {
 645			u64 tmp2 = 0;
 646			int a = aa_map_resource(i);
 647			if (!aa_unpack_u64(e, &tmp2, NULL))
 648				goto fail;
 649			rules->rlimits.limits[a].rlim_max = tmp2;
 650		}
 651		if (!aa_unpack_nameX(e, AA_ARRAYEND, NULL))
 652			goto fail;
 653		if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL))
 654			goto fail;
 655	}
 656	return true;
 657
 658fail:
 659	e->pos = pos;
 660	return false;
 661}
 662
 663static bool unpack_perm(struct aa_ext *e, u32 version, struct aa_perms *perm)
 664{
 665	u32 reserved;
 666
 667	if (version != 1)
 668		return false;
 669
 670	/* reserved entry is for later expansion, discard for now */
 671	return	aa_unpack_u32(e, &reserved, NULL) &&
 672		aa_unpack_u32(e, &perm->allow, NULL) &&
 673		aa_unpack_u32(e, &perm->deny, NULL) &&
 674		aa_unpack_u32(e, &perm->subtree, NULL) &&
 675		aa_unpack_u32(e, &perm->cond, NULL) &&
 676		aa_unpack_u32(e, &perm->kill, NULL) &&
 677		aa_unpack_u32(e, &perm->complain, NULL) &&
 678		aa_unpack_u32(e, &perm->prompt, NULL) &&
 679		aa_unpack_u32(e, &perm->audit, NULL) &&
 680		aa_unpack_u32(e, &perm->quiet, NULL) &&
 681		aa_unpack_u32(e, &perm->hide, NULL) &&
 682		aa_unpack_u32(e, &perm->xindex, NULL) &&
 683		aa_unpack_u32(e, &perm->tag, NULL) &&
 684		aa_unpack_u32(e, &perm->label, NULL);
 685}
 686
 687static ssize_t unpack_perms_table(struct aa_ext *e, struct aa_perms **perms)
 688{
 689	void *pos = e->pos;
 690	u16 size = 0;
 691
 692	AA_BUG(!perms);
 693	/*
 694	 * policy perms are optional, in which case perms are embedded
 695	 * in the dfa accept table
 696	 */
 697	if (aa_unpack_nameX(e, AA_STRUCT, "perms")) {
 698		int i;
 699		u32 version;
 700
 701		if (!aa_unpack_u32(e, &version, "version"))
 702			goto fail_reset;
 703		if (!aa_unpack_array(e, NULL, &size))
 704			goto fail_reset;
 705		*perms = kcalloc(size, sizeof(struct aa_perms), GFP_KERNEL);
 706		if (!*perms) {
 707			e->pos = pos;
 708			return -ENOMEM;
 709		}
 710		for (i = 0; i < size; i++) {
 711			if (!unpack_perm(e, version, &(*perms)[i]))
 712				goto fail;
 713		}
 714		if (!aa_unpack_nameX(e, AA_ARRAYEND, NULL))
 715			goto fail;
 716		if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL))
 717			goto fail;
 718	} else
 719		*perms = NULL;
 720
 721	return size;
 722
 723fail:
 724	kfree(*perms);
 725fail_reset:
 726	e->pos = pos;
 727	return -EPROTO;
 728}
 729
 730static int unpack_pdb(struct aa_ext *e, struct aa_policydb **policy,
 731		      bool required_dfa, bool required_trans,
 732		      const char **info)
 733{
 734	struct aa_policydb *pdb;
 735	void *pos = e->pos;
 736	int i, flags, error = -EPROTO;
 737	ssize_t size;
 738	u32 version = 0;
 739
 740	pdb = aa_alloc_pdb(GFP_KERNEL);
 741	if (!pdb)
 742		return -ENOMEM;
 743
 744	size = unpack_perms_table(e, &pdb->perms);
 745	if (size < 0) {
 746		error = size;
 747		pdb->perms = NULL;
 748		*info = "failed to unpack - perms";
 749		goto fail;
 750	}
 751	pdb->size = size;
 752
 753	if (pdb->perms) {
 754		/* perms table present accept is index */
 755		flags = TO_ACCEPT1_FLAG(YYTD_DATA32);
 756		if (aa_unpack_u32(e, &version, "permsv") && version > 2)
 757			/* accept2 used for dfa flags */
 758			flags |= TO_ACCEPT2_FLAG(YYTD_DATA32);
 759	} else {
 760		/* packed perms in accept1 and accept2 */
 761		flags = TO_ACCEPT1_FLAG(YYTD_DATA32) |
 762			TO_ACCEPT2_FLAG(YYTD_DATA32);
 763	}
 764
 765	pdb->dfa = unpack_dfa(e, flags);
 766	if (IS_ERR(pdb->dfa)) {
 767		error = PTR_ERR(pdb->dfa);
 768		pdb->dfa = NULL;
 769		*info = "failed to unpack - dfa";
 770		goto fail;
 771	} else if (!pdb->dfa) {
 772		if (required_dfa) {
 773			*info = "missing required dfa";
 774			goto fail;
 775		}
 776	} else {
 777		/*
 778		 * only unpack the following if a dfa is present
 779		 *
 780		 * sadly start was given different names for file and policydb
 781		 * but since it is optional we can try both
 782		 */
 783		if (!aa_unpack_u32(e, &pdb->start[0], "start"))
 784			/* default start state */
 785			pdb->start[0] = DFA_START;
 786		if (!aa_unpack_u32(e, &pdb->start[AA_CLASS_FILE], "dfa_start")) {
 787			/* default start state for xmatch and file dfa */
 788			pdb->start[AA_CLASS_FILE] = DFA_START;
 789		}
 790
 791		size_t state_count = pdb->dfa->tables[YYTD_ID_BASE]->td_lolen;
 792
 793		if (pdb->start[0] >= state_count ||
 794		    pdb->start[AA_CLASS_FILE] >= state_count) {
 795			*info = "invalid dfa start state";
 796			goto fail;
 797		}
 798
 799		/* setup class index */
 800		for (i = AA_CLASS_FILE + 1; i <= AA_CLASS_LAST; i++) {
 801			pdb->start[i] = aa_dfa_next(pdb->dfa, pdb->start[0],
 802						    i);
 803		}
 804	}
 805
 806	/* accept2 is in some cases being allocated, even with perms */
 807	if (pdb->perms && !pdb->dfa->tables[YYTD_ID_ACCEPT2]) {
 808		/* add dfa flags table missing in v2 */
 809		u32 noents = pdb->dfa->tables[YYTD_ID_ACCEPT]->td_lolen;
 810		u16 tdflags = pdb->dfa->tables[YYTD_ID_ACCEPT]->td_flags;
 811		size_t tsize = table_size(noents, tdflags);
 812
 813		pdb->dfa->tables[YYTD_ID_ACCEPT2] = kvzalloc(tsize, GFP_KERNEL);
 814		if (!pdb->dfa->tables[YYTD_ID_ACCEPT2]) {
 815			*info = "failed to alloc dfa flags table";
 816			goto out;
 817		}
 818		pdb->dfa->tables[YYTD_ID_ACCEPT2]->td_lolen = noents;
 819		pdb->dfa->tables[YYTD_ID_ACCEPT2]->td_flags = tdflags;
 820	}
 821	/*
 822	 * Unfortunately due to a bug in earlier userspaces, a
 823	 * transition table may be present even when the dfa is
 824	 * not. For compatibility reasons unpack and discard.
 825	 */
 826	if (!unpack_trans_table(e, &pdb->trans) && required_trans) {
 827		*info = "failed to unpack profile transition table";
 828		goto fail;
 829	}
 830
 831	if (!pdb->dfa && pdb->trans.table)
 832		aa_free_str_table(&pdb->trans);
 833
 834	/* TODO:
 835	 * - move compat mapping here, requires dfa merging first
 836	 * - move verify here, it has to be done after compat mappings
 837	 * - move free of unneeded trans table here, has to be done
 838	 *   after perm mapping.
 839	 */
 840out:
 841	*policy = pdb;
 842	return 0;
 843
 844fail:
 845	aa_put_pdb(pdb);
 846	e->pos = pos;
 847	return error;
 848}
 849
 850static u32 strhash(const void *data, u32 len, u32 seed)
 851{
 852	const char * const *key = data;
 853
 854	return jhash(*key, strlen(*key), seed);
 855}
 856
 857static int datacmp(struct rhashtable_compare_arg *arg, const void *obj)
 858{
 859	const struct aa_data *data = obj;
 860	const char * const *key = arg->key;
 861
 862	return strcmp(data->key, *key);
 863}
 864
 865/**
 866 * unpack_profile - unpack a serialized profile
 867 * @e: serialized data extent information (NOT NULL)
 868 * @ns_name: pointer of newly allocated copy of %NULL in case of error
 869 *
 870 * NOTE: unpack profile sets audit struct if there is a failure
 871 */
 872static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
 873{
 874	struct aa_ruleset *rules;
 875	struct aa_profile *profile = NULL;
 876	const char *tmpname, *tmpns = NULL, *name = NULL;
 877	const char *info = "failed to unpack profile";
 878	size_t ns_len;
 879	struct rhashtable_params params = { 0 };
 880	char *key = NULL, *disconnected = NULL;
 881	struct aa_data *data;
 882	int error = -EPROTO;
 883	kernel_cap_t tmpcap;
 884	u32 tmp;
 885
 886	*ns_name = NULL;
 887
 888	/* check that we have the right struct being passed */
 889	if (!aa_unpack_nameX(e, AA_STRUCT, "profile"))
 890		goto fail;
 891	if (!aa_unpack_str(e, &name, NULL))
 892		goto fail;
 893	if (*name == '\0')
 894		goto fail;
 895
 896	tmpname = aa_splitn_fqname(name, strlen(name), &tmpns, &ns_len);
 897	if (tmpns) {
 898		if (!tmpname) {
 899			info = "empty profile name";
 900			goto fail;
 901		}
 902		*ns_name = kstrndup(tmpns, ns_len, GFP_KERNEL);
 903		if (!*ns_name) {
 904			info = "out of memory";
 905			error = -ENOMEM;
 906			goto fail;
 907		}
 908		name = tmpname;
 909	}
 910
 911	profile = aa_alloc_profile(name, NULL, GFP_KERNEL);
 912	if (!profile) {
 913		info = "out of memory";
 914		error = -ENOMEM;
 915		goto fail;
 916	}
 917	rules = profile->label.rules[0];
 918
 919	/* profile renaming is optional */
 920	(void) aa_unpack_str(e, &profile->rename, "rename");
 921
 922	/* attachment string is optional */
 923	(void) aa_unpack_str(e, &profile->attach.xmatch_str, "attach");
 924
 925	/* xmatch is optional and may be NULL */
 926	error = unpack_pdb(e, &profile->attach.xmatch, false, false, &info);
 927	if (error) {
 928		info = "bad xmatch";
 929		goto fail;
 930	}
 931
 932	/* neither xmatch_len not xmatch_perms are optional if xmatch is set */
 933	if (profile->attach.xmatch->dfa) {
 934		if (!aa_unpack_u32(e, &tmp, NULL)) {
 935			info = "missing xmatch len";
 936			goto fail;
 937		}
 938		profile->attach.xmatch_len = tmp;
 939		profile->attach.xmatch->start[AA_CLASS_XMATCH] = DFA_START;
 940		if (!profile->attach.xmatch->perms) {
 941			error = aa_compat_map_xmatch(profile->attach.xmatch);
 942			if (error) {
 943				info = "failed to convert xmatch permission table";
 944				goto fail;
 945			}
 946		}
 947	}
 948
 949	/* disconnected attachment string is optional */
 950	(void) aa_unpack_strdup(e, &disconnected, "disconnected");
 951	profile->disconnected = disconnected;
 952
 953	/* optional */
 954	(void) aa_unpack_u32(e, &profile->signal, "kill");
 955	if (profile->signal < 1 || profile->signal > MAXMAPPED_SIG) {
 956		info = "profile kill.signal invalid value";
 957		goto fail;
 958	}
 959	/* per profile debug flags (complain, audit) */
 960	if (!aa_unpack_nameX(e, AA_STRUCT, "flags")) {
 961		info = "profile missing flags";
 962		goto fail;
 963	}
 964	info = "failed to unpack profile flags";
 965	if (!aa_unpack_u32(e, &tmp, NULL))
 966		goto fail;
 967	if (tmp & PACKED_FLAG_HAT)
 968		profile->label.flags |= FLAG_HAT;
 969	if (tmp & PACKED_FLAG_DEBUG1)
 970		profile->label.flags |= FLAG_DEBUG1;
 971	if (tmp & PACKED_FLAG_DEBUG2)
 972		profile->label.flags |= FLAG_DEBUG2;
 973	if (!aa_unpack_u32(e, &tmp, NULL))
 974		goto fail;
 975	if (tmp == PACKED_MODE_COMPLAIN || (e->version & FORCE_COMPLAIN_FLAG)) {
 976		profile->mode = APPARMOR_COMPLAIN;
 977	} else if (tmp == PACKED_MODE_ENFORCE) {
 978		profile->mode = APPARMOR_ENFORCE;
 979	} else if (tmp == PACKED_MODE_KILL) {
 980		profile->mode = APPARMOR_KILL;
 981	} else if (tmp == PACKED_MODE_UNCONFINED) {
 982		profile->mode = APPARMOR_UNCONFINED;
 983		profile->label.flags |= FLAG_UNCONFINED;
 984	} else if (tmp == PACKED_MODE_USER) {
 985		profile->mode = APPARMOR_USER;
 986	} else {
 987		goto fail;
 988	}
 989	if (!aa_unpack_u32(e, &tmp, NULL))
 990		goto fail;
 991	if (tmp)
 992		profile->audit = AUDIT_ALL;
 993
 994	if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL))
 995		goto fail;
 996
 997	/* path_flags is optional */
 998	if (aa_unpack_u32(e, &profile->path_flags, "path_flags"))
 999		profile->path_flags |= profile->label.flags &
1000			PATH_MEDIATE_DELETED;
1001	else
1002		/* set a default value if path_flags field is not present */
1003		profile->path_flags = PATH_MEDIATE_DELETED;
1004
1005	info = "failed to unpack profile capabilities";
1006	if (!aa_unpack_cap_low(e, &rules->caps.allow, NULL))
1007		goto fail;
1008	if (!aa_unpack_cap_low(e, &rules->caps.audit, NULL))
1009		goto fail;
1010	if (!aa_unpack_cap_low(e, &rules->caps.quiet, NULL))
1011		goto fail;
1012	if (!aa_unpack_cap_low(e, &tmpcap, NULL))
1013		goto fail;
1014
1015	info = "failed to unpack upper profile capabilities";
1016	if (aa_unpack_nameX(e, AA_STRUCT, "caps64")) {
1017		/* optional upper half of 64 bit caps */
1018		if (!aa_unpack_cap_high(e, &rules->caps.allow, NULL))
1019			goto fail;
1020		if (!aa_unpack_cap_high(e, &rules->caps.audit, NULL))
1021			goto fail;
1022		if (!aa_unpack_cap_high(e, &rules->caps.quiet, NULL))
1023			goto fail;
1024		if (!aa_unpack_cap_high(e, &tmpcap, NULL))
1025			goto fail;
1026		if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL))
1027			goto fail;
1028	}
1029
1030	info = "failed to unpack extended profile capabilities";
1031	if (aa_unpack_nameX(e, AA_STRUCT, "capsx")) {
1032		/* optional extended caps mediation mask */
1033		if (!aa_unpack_cap_low(e, &rules->caps.extended, NULL))
1034			goto fail;
1035		if (!aa_unpack_cap_high(e, &rules->caps.extended, NULL))
1036			goto fail;
1037		if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL))
1038			goto fail;
1039	}
1040
1041	if (!unpack_xattrs(e, profile)) {
1042		info = "failed to unpack profile xattrs";
1043		goto fail;
1044	}
1045
1046	if (!unpack_rlimits(e, rules)) {
1047		info = "failed to unpack profile rlimits";
1048		goto fail;
1049	}
1050
1051	if (!unpack_secmark(e, rules)) {
1052		info = "failed to unpack profile secmark rules";
1053		goto fail;
1054	}
1055
1056	if (aa_unpack_nameX(e, AA_STRUCT, "policydb")) {
1057		/* generic policy dfa - optional and may be NULL */
1058		info = "failed to unpack policydb";
1059		error = unpack_pdb(e, &rules->policy, true, false,
1060				   &info);
1061		if (error)
1062			goto fail;
1063		/* Fixup: drop when we get rid of start array */
1064		if (aa_dfa_next(rules->policy->dfa, rules->policy->start[0],
1065				AA_CLASS_FILE))
1066			rules->policy->start[AA_CLASS_FILE] =
1067			  aa_dfa_next(rules->policy->dfa,
1068				      rules->policy->start[0],
1069				      AA_CLASS_FILE);
1070		if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL))
1071			goto fail;
1072		if (!rules->policy->perms) {
1073			error = aa_compat_map_policy(rules->policy,
1074						     e->version);
1075			if (error) {
1076				info = "failed to remap policydb permission table";
1077				goto fail;
1078			}
1079		}
1080	} else {
1081		rules->policy = aa_get_pdb(nullpdb);
1082	}
1083	/* get file rules */
1084	error = unpack_pdb(e, &rules->file, false, true, &info);
1085	if (error) {
1086		goto fail;
1087	} else if (rules->file->dfa) {
1088		if (!rules->file->perms) {
1089			error = aa_compat_map_file(rules->file);
1090			if (error) {
1091				info = "failed to remap file permission table";
1092				goto fail;
1093			}
1094		}
1095	} else if (rules->policy->dfa &&
1096		   rules->policy->start[AA_CLASS_FILE]) {
1097		aa_put_pdb(rules->file);
1098		rules->file = aa_get_pdb(rules->policy);
1099	} else {
1100		aa_put_pdb(rules->file);
1101		rules->file = aa_get_pdb(nullpdb);
1102	}
1103	error = -EPROTO;
1104	if (aa_unpack_nameX(e, AA_STRUCT, "data")) {
1105		info = "out of memory";
1106		profile->data = kzalloc(sizeof(*profile->data), GFP_KERNEL);
1107		if (!profile->data) {
1108			error = -ENOMEM;
1109			goto fail;
1110		}
1111		params.nelem_hint = 3;
1112		params.key_len = sizeof(void *);
1113		params.key_offset = offsetof(struct aa_data, key);
1114		params.head_offset = offsetof(struct aa_data, head);
1115		params.hashfn = strhash;
1116		params.obj_cmpfn = datacmp;
1117
1118		if (rhashtable_init(profile->data, &params)) {
1119			info = "failed to init key, value hash table";
1120			goto fail;
1121		}
1122
1123		while (aa_unpack_strdup(e, &key, NULL)) {
1124			data = kzalloc(sizeof(*data), GFP_KERNEL);
1125			if (!data) {
1126				kfree_sensitive(key);
1127				error = -ENOMEM;
1128				goto fail;
1129			}
1130
1131			data->key = key;
1132			data->size = aa_unpack_blob(e, &data->data, NULL);
1133			data->data = kvmemdup(data->data, data->size, GFP_KERNEL);
1134			if (data->size && !data->data) {
1135				kfree_sensitive(data->key);
1136				kfree_sensitive(data);
1137				error = -ENOMEM;
1138				goto fail;
1139			}
1140
1141			if (rhashtable_insert_fast(profile->data, &data->head,
1142						   profile->data->p)) {
1143				kvfree_sensitive(data->data, data->size);
1144				kfree_sensitive(data->key);
1145				kfree_sensitive(data);
1146				info = "failed to insert data to table";
1147				goto fail;
1148			}
1149		}
1150
1151		if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) {
1152			info = "failed to unpack end of key, value data table";
1153			goto fail;
1154		}
1155	}
1156
1157	if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) {
1158		info = "failed to unpack end of profile";
1159		goto fail;
1160	}
1161
1162	aa_compute_profile_mediates(profile);
1163
1164	return profile;
1165
1166fail:
1167	if (error == 0)
1168		/* default error covers most cases */
1169		error = -EPROTO;
1170	if (*ns_name) {
1171		kfree(*ns_name);
1172		*ns_name = NULL;
1173	}
1174	if (profile)
1175		name = NULL;
1176	else if (!name)
1177		name = "unknown";
1178	audit_iface(profile, NULL, name, info, e, error);
1179	aa_free_profile(profile);
1180
1181	return ERR_PTR(error);
1182}
1183
1184/**
1185 * verify_header - unpack serialized stream header
1186 * @e: serialized data read head (NOT NULL)
1187 * @required: whether the header is required or optional
1188 * @ns: Returns - namespace if one is specified else NULL (NOT NULL)
1189 *
1190 * Returns: error or 0 if header is good
1191 */
1192static int verify_header(struct aa_ext *e, int required, const char **ns)
1193{
1194	int error = -EPROTONOSUPPORT;
1195	const char *name = NULL;
1196
1197	/* get the interface version */
1198	if (!aa_unpack_u32(e, &e->version, "version")) {
1199		if (required) {
1200			audit_iface(NULL, NULL, NULL, "invalid profile format",
1201				    e, error);
1202			return error;
1203		}
1204	}
1205
1206	/* Check that the interface version is currently supported.
1207	 * if not specified use previous version
1208	 * Mask off everything that is not kernel abi version
1209	 */
1210	if (VERSION_LT(e->version, v5) || VERSION_GT(e->version, v9)) {
1211		audit_iface(NULL, NULL, NULL, "unsupported interface version",
1212			    e, error);
1213		return error;
1214	}
1215
1216	/* read the namespace if present */
1217	if (aa_unpack_str(e, &name, "namespace")) {
1218		if (*name == '\0') {
1219			audit_iface(NULL, NULL, NULL, "invalid namespace name",
1220				    e, error);
1221			return error;
1222		}
1223		if (*ns && strcmp(*ns, name)) {
1224			audit_iface(NULL, NULL, NULL, "invalid ns change", e,
1225				    error);
1226		} else if (!*ns) {
1227			*ns = kstrdup(name, GFP_KERNEL);
1228			if (!*ns)
1229				return -ENOMEM;
1230		}
1231	}
1232
1233	return 0;
1234}
1235
1236/**
1237 * verify_dfa_accept_index - verify accept indexes are in range of perms table
1238 * @dfa: the dfa to check accept indexes are in range
1239 * @table_size: the permission table size the indexes should be within
1240 */
1241static bool verify_dfa_accept_index(struct aa_dfa *dfa, int table_size)
1242{
1243	int i;
1244	for (i = 0; i < dfa->tables[YYTD_ID_ACCEPT]->td_lolen; i++) {
1245		if (ACCEPT_TABLE(dfa)[i] >= table_size)
1246			return false;
1247	}
1248	return true;
1249}
1250
1251static bool verify_perm(struct aa_perms *perm)
1252{
1253	/* TODO: allow option to just force the perms into a valid state */
1254	if (perm->allow & perm->deny)
1255		return false;
1256	if (perm->subtree & ~perm->allow)
1257		return false;
1258	if (perm->cond & (perm->allow | perm->deny))
1259		return false;
1260	if (perm->kill & perm->allow)
1261		return false;
1262	if (perm->complain & (perm->allow | perm->deny))
1263		return false;
1264	if (perm->prompt & (perm->allow | perm->deny))
1265		return false;
1266	if (perm->complain & perm->prompt)
1267		return false;
1268	if (perm->hide & perm->allow)
1269		return false;
1270
1271	return true;
1272}
1273
1274static bool verify_perms(struct aa_policydb *pdb)
1275{
1276	int i;
1277	int xidx, xmax = -1;
1278
1279	for (i = 0; i < pdb->size; i++) {
1280		if (!verify_perm(&pdb->perms[i]))
1281			return false;
1282		/* verify indexes into str table */
1283		if ((pdb->perms[i].xindex & AA_X_TYPE_MASK) == AA_X_TABLE) {
1284			xidx = pdb->perms[i].xindex & AA_X_INDEX_MASK;
1285			if (xidx >= pdb->trans.size)
1286				return false;
1287			if (xmax < xidx)
1288				xmax = xidx;
1289		}
1290		if (pdb->perms[i].tag && pdb->perms[i].tag >= pdb->trans.size)
1291			return false;
1292		if (pdb->perms[i].label &&
1293		    pdb->perms[i].label >= pdb->trans.size)
1294			return false;
1295	}
1296	/* deal with incorrectly constructed string tables */
1297	if (xmax == -1) {
1298		aa_free_str_table(&pdb->trans);
1299	} else if (pdb->trans.size > xmax + 1) {
1300		if (!aa_resize_str_table(&pdb->trans, xmax + 1, GFP_KERNEL))
1301			return false;
1302	}
1303	return true;
1304}
1305
1306/**
1307 * verify_profile - Do post unpack analysis to verify profile consistency
1308 * @profile: profile to verify (NOT NULL)
1309 *
1310 * Returns: 0 if passes verification else error
1311 *
1312 * This verification is post any unpack mapping or changes
1313 */
1314static int verify_profile(struct aa_profile *profile)
1315{
1316	struct aa_ruleset *rules = profile->label.rules[0];
1317
1318	if (!rules)
1319		return 0;
1320
1321	if (rules->file->dfa && !verify_dfa_accept_index(rules->file->dfa,
1322							rules->file->size)) {
1323		audit_iface(profile, NULL, NULL,
1324			    "Unpack: file Invalid named transition", NULL,
1325			    -EPROTO);
1326		return -EPROTO;
1327	}
1328	if (rules->policy->dfa &&
1329	    !verify_dfa_accept_index(rules->policy->dfa, rules->policy->size)) {
1330		audit_iface(profile, NULL, NULL,
1331			    "Unpack: policy Invalid named transition", NULL,
1332			    -EPROTO);
1333		return -EPROTO;
1334	}
1335
1336	if (!verify_perms(rules->file)) {
1337		audit_iface(profile, NULL, NULL,
1338			    "Unpack: Invalid perm index", NULL, -EPROTO);
1339		return -EPROTO;
1340	}
1341	if (!verify_perms(rules->policy)) {
1342		audit_iface(profile, NULL, NULL,
1343			    "Unpack: Invalid perm index", NULL, -EPROTO);
1344		return -EPROTO;
1345	}
1346	if (!verify_perms(profile->attach.xmatch)) {
1347		audit_iface(profile, NULL, NULL,
1348			    "Unpack: Invalid perm index", NULL, -EPROTO);
1349		return -EPROTO;
1350	}
1351
1352	return 0;
1353}
1354
1355void aa_load_ent_free(struct aa_load_ent *ent)
1356{
1357	if (ent) {
1358		aa_put_profile(ent->rename);
1359		aa_put_profile(ent->old);
1360		aa_put_profile(ent->new);
1361		kfree(ent->ns_name);
1362		kfree_sensitive(ent);
1363	}
1364}
1365
1366struct aa_load_ent *aa_load_ent_alloc(void)
1367{
1368	struct aa_load_ent *ent = kzalloc(sizeof(*ent), GFP_KERNEL);
1369	if (ent)
1370		INIT_LIST_HEAD(&ent->list);
1371	return ent;
1372}
1373
1374static int compress_zstd(const char *src, size_t slen, char **dst, size_t *dlen)
1375{
1376#ifdef CONFIG_SECURITY_APPARMOR_EXPORT_BINARY
1377	const zstd_parameters params =
1378		zstd_get_params(aa_g_rawdata_compression_level, slen);
1379	const size_t wksp_len = zstd_cctx_workspace_bound(&params.cParams);
1380	void *wksp = NULL;
1381	zstd_cctx *ctx = NULL;
1382	size_t out_len = zstd_compress_bound(slen);
1383	void *out = NULL;
1384	int ret = 0;
1385
1386	out = kvzalloc(out_len, GFP_KERNEL);
1387	if (!out) {
1388		ret = -ENOMEM;
1389		goto cleanup;
1390	}
1391
1392	wksp = kvzalloc(wksp_len, GFP_KERNEL);
1393	if (!wksp) {
1394		ret = -ENOMEM;
1395		goto cleanup;
1396	}
1397
1398	ctx = zstd_init_cctx(wksp, wksp_len);
1399	if (!ctx) {
1400		ret = -EINVAL;
1401		goto cleanup;
1402	}
1403
1404	out_len = zstd_compress_cctx(ctx, out, out_len, src, slen, &params);
1405	if (zstd_is_error(out_len) || out_len >= slen) {
1406		ret = -EINVAL;
1407		goto cleanup;
1408	}
1409
1410	if (is_vmalloc_addr(out)) {
1411		*dst = kvzalloc(out_len, GFP_KERNEL);
1412		if (*dst) {
1413			memcpy(*dst, out, out_len);
1414			kvfree(out);
1415			out = NULL;
1416		}
1417	} else {
1418		/*
1419		 * If the staging buffer was kmalloc'd, then using krealloc is
1420		 * probably going to be faster. The destination buffer will
1421		 * always be smaller, so it's just shrunk, avoiding a memcpy
1422		 */
1423		*dst = krealloc(out, out_len, GFP_KERNEL);
1424	}
1425
1426	if (!*dst) {
1427		ret = -ENOMEM;
1428		goto cleanup;
1429	}
1430
1431	*dlen = out_len;
1432
1433cleanup:
1434	if (ret) {
1435		kvfree(out);
1436		*dst = NULL;
1437	}
1438
1439	kvfree(wksp);
1440	return ret;
1441#else
1442	*dlen = slen;
1443	return 0;
1444#endif
1445}
1446
1447static int compress_loaddata(struct aa_loaddata *data)
1448{
1449	AA_BUG(data->compressed_size > 0);
1450
1451	/*
1452	 * Shortcut the no compression case, else we increase the amount of
1453	 * storage required by a small amount
1454	 */
1455	if (aa_g_rawdata_compression_level != 0) {
1456		void *udata = data->data;
1457		int error = compress_zstd(udata, data->size, &data->data,
1458					  &data->compressed_size);
1459		if (error) {
1460			data->compressed_size = data->size;
1461			return error;
1462		}
1463		if (udata != data->data)
1464			kvfree(udata);
1465	} else
1466		data->compressed_size = data->size;
1467
1468	return 0;
1469}
1470
1471/**
1472 * aa_unpack - unpack packed binary profile(s) data loaded from user space
1473 * @udata: user data copied to kmem  (NOT NULL)
1474 * @lh: list to place unpacked profiles in a aa_repl_ws
1475 * @ns: Returns namespace profile is in if specified else NULL (NOT NULL)
1476 *
1477 * Unpack user data and return refcounted allocated profile(s) stored in
1478 * @lh in order of discovery, with the list chain stored in base.list
1479 * or error
1480 *
1481 * Returns: profile(s) on @lh else error pointer if fails to unpack
1482 */
1483int aa_unpack(struct aa_loaddata *udata, struct list_head *lh,
1484	      const char **ns)
1485{
1486	struct aa_load_ent *tmp, *ent;
1487	struct aa_profile *profile = NULL;
1488	char *ns_name = NULL;
1489	int error;
1490	struct aa_ext e = {
1491		.start = udata->data,
1492		.end = udata->data + udata->size,
1493		.pos = udata->data,
1494	};
1495
1496	*ns = NULL;
1497	while (e.pos < e.end) {
1498		void *start;
1499		error = verify_header(&e, e.pos == e.start, ns);
1500		if (error)
1501			goto fail;
1502
1503		start = e.pos;
1504		profile = unpack_profile(&e, &ns_name);
1505		if (IS_ERR(profile)) {
1506			error = PTR_ERR(profile);
1507			goto fail;
1508		}
1509
1510		error = verify_profile(profile);
1511		if (error)
1512			goto fail_profile;
1513
1514		if (aa_g_hash_policy)
1515			error = aa_calc_profile_hash(profile, e.version, start,
1516						     e.pos - start);
1517		if (error)
1518			goto fail_profile;
1519
1520		ent = aa_load_ent_alloc();
1521		if (!ent) {
1522			error = -ENOMEM;
1523			goto fail_profile;
1524		}
1525
1526		ent->new = profile;
1527		ent->ns_name = ns_name;
1528		ns_name = NULL;
1529		list_add_tail(&ent->list, lh);
1530	}
1531	udata->abi = e.version & K_ABI_MASK;
1532	if (aa_g_hash_policy) {
1533		udata->hash = aa_calc_hash(udata->data, udata->size);
1534		if (IS_ERR(udata->hash)) {
1535			error = PTR_ERR(udata->hash);
1536			udata->hash = NULL;
1537			goto fail;
1538		}
1539	}
1540
1541	if (aa_g_export_binary) {
1542		error = compress_loaddata(udata);
1543		if (error)
1544			goto fail;
1545	}
1546	return 0;
1547
1548fail_profile:
1549	kfree(ns_name);
1550	aa_put_profile(profile);
1551
1552fail:
1553	list_for_each_entry_safe(ent, tmp, lh, list) {
1554		list_del_init(&ent->list);
1555		aa_load_ent_free(ent);
1556	}
1557
1558	return error;
1559}
~/ Read-only file preview.