^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * AppArmor security module
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * This file contains AppArmor functions for unpacking policy loaded from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * userspace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 1998-2008 Novell/SUSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright 2009-2010 Canonical Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * AppArmor uses a serialized binary format for loading policy. To find
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * policy format documentation see Documentation/admin-guide/LSM/apparmor.rst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * All policy is validated before it is used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/zlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "include/apparmor.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "include/audit.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "include/cred.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "include/crypto.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "include/match.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "include/path.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "include/policy.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include "include/policy_unpack.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define K_ABI_MASK 0x3ff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define FORCE_COMPLAIN_FLAG 0x800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define VERSION_LT(X, Y) (((X) & K_ABI_MASK) < ((Y) & K_ABI_MASK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define VERSION_GT(X, Y) (((X) & K_ABI_MASK) > ((Y) & K_ABI_MASK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define v5 5 /* base version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define v6 6 /* per entry policydb mediation check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define v7 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define v8 8 /* full network masking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * The AppArmor interface treats data as a type byte followed by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * actual data. The interface has the notion of a a named entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * which has a name (AA_NAME typecode followed by name string) followed by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * the entries typecode and data. Named types allow for optional
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * elements and extensions to be added and tested for without breaking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * backwards compatibility.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) enum aa_code {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) AA_U8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) AA_U16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) AA_U32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) AA_U64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) AA_NAME, /* same as string except it is items name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) AA_STRING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) AA_BLOB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) AA_STRUCT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) AA_STRUCTEND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) AA_LIST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) AA_LISTEND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) AA_ARRAY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) AA_ARRAYEND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * aa_ext is the read of the buffer containing the serialized profile. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * data is copied into a kernel buffer in apparmorfs and then handed off to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * the unpack routines.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct aa_ext {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) void *start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) void *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) void *pos; /* pointer to current position in the buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) u32 version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* audit callback for unpack fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static void audit_cb(struct audit_buffer *ab, void *va)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct common_audit_data *sa = va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (aad(sa)->iface.ns) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) audit_log_format(ab, " ns=");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) audit_log_untrustedstring(ab, aad(sa)->iface.ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (aad(sa)->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) audit_log_format(ab, " name=");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) audit_log_untrustedstring(ab, aad(sa)->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (aad(sa)->iface.pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) audit_log_format(ab, " offset=%ld", aad(sa)->iface.pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * audit_iface - do audit message for policy unpacking/load/replace/remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * @new: profile if it has been allocated (MAYBE NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * @ns_name: name of the ns the profile is to be loaded to (MAY BE NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * @name: name of the profile being manipulated (MAYBE NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * @info: any extra info about the failure (MAYBE NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * @e: buffer position info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * @error: error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * Returns: %0 or error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static int audit_iface(struct aa_profile *new, const char *ns_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) const char *name, const char *info, struct aa_ext *e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) int error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct aa_profile *profile = labels_profile(aa_current_raw_label());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) aad(&sa)->iface.pos = e->pos - e->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) aad(&sa)->iface.ns = ns_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) aad(&sa)->name = new->base.hname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) aad(&sa)->name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) aad(&sa)->info = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) aad(&sa)->error = error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return aa_audit(AUDIT_APPARMOR_STATUS, profile, &sa, audit_cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) void __aa_loaddata_update(struct aa_loaddata *data, long revision)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) AA_BUG(!data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) AA_BUG(!data->ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) AA_BUG(!data->dents[AAFS_LOADDATA_REVISION]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) AA_BUG(!mutex_is_locked(&data->ns->lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) AA_BUG(data->revision > revision);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) data->revision = revision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) d_inode(data->dents[AAFS_LOADDATA_DIR])->i_mtime =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) current_time(d_inode(data->dents[AAFS_LOADDATA_DIR]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) d_inode(data->dents[AAFS_LOADDATA_REVISION])->i_mtime =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) current_time(d_inode(data->dents[AAFS_LOADDATA_REVISION]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) bool aa_rawdata_eq(struct aa_loaddata *l, struct aa_loaddata *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (l->size != r->size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (l->compressed_size != r->compressed_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (aa_g_hash_policy && memcmp(l->hash, r->hash, aa_hash_size()) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return memcmp(l->data, r->data, r->compressed_size ?: r->size) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * need to take the ns mutex lock which is NOT safe most places that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * put_loaddata is called, so we have to delay freeing it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static void do_loaddata_free(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct aa_loaddata *d = container_of(work, struct aa_loaddata, work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) struct aa_ns *ns = aa_get_ns(d->ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (ns) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) mutex_lock_nested(&ns->lock, ns->level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) __aa_fs_remove_rawdata(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) mutex_unlock(&ns->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) aa_put_ns(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) kfree_sensitive(d->hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) kfree_sensitive(d->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) kvfree(d->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) kfree_sensitive(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) void aa_loaddata_kref(struct kref *kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) struct aa_loaddata *d = container_of(kref, struct aa_loaddata, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (d) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) INIT_WORK(&d->work, do_loaddata_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) schedule_work(&d->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct aa_loaddata *aa_loaddata_alloc(size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct aa_loaddata *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) d = kzalloc(sizeof(*d), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (d == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) d->data = kvzalloc(size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (!d->data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) kfree(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) kref_init(&d->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) INIT_LIST_HEAD(&d->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) /* test if read will be in packed data bounds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static bool inbounds(struct aa_ext *e, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return (size <= e->end - e->pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) static void *kvmemdup(const void *src, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) void *p = kvmalloc(len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) memcpy(p, src, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * aa_u16_chunck - test and do bounds checking for a u16 size based chunk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * @e: serialized data read head (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * @chunk: start address for chunk of data (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * Returns: the size of chunk found with the read head at the end of the chunk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static size_t unpack_u16_chunk(struct aa_ext *e, char **chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) size_t size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) void *pos = e->pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (!inbounds(e, sizeof(u16)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) size = le16_to_cpu(get_unaligned((__le16 *) e->pos));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) e->pos += sizeof(__le16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (!inbounds(e, size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) *chunk = e->pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) e->pos += size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) e->pos = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /* unpack control byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static bool unpack_X(struct aa_ext *e, enum aa_code code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (!inbounds(e, 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (*(u8 *) e->pos != code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) e->pos++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * unpack_nameX - check is the next element is of type X with a name of @name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * @e: serialized data extent information (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * @code: type code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * @name: name to match to the serialized element. (MAYBE NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * check that the next serialized data element is of type X and has a tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * name @name. If @name is specified then there must be a matching
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * name element in the stream. If @name is NULL any name element will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * skipped and only the typecode will be tested.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * Returns true on success (both type code and name tests match) and the read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * head is advanced past the headers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * Returns: false if either match fails, the read head does not move
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static bool unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * May need to reset pos if name or type doesn't match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) void *pos = e->pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * Check for presence of a tagname, and if present name size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * AA_NAME tag value is a u16.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (unpack_X(e, AA_NAME)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) char *tag = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) size_t size = unpack_u16_chunk(e, &tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) /* if a name is specified it must match. otherwise skip tag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (name && (!size || tag[size-1] != '\0' || strcmp(name, tag)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) } else if (name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /* if a name is specified and there is no name tag fail */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) /* now check if type code matches */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (unpack_X(e, code))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) e->pos = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) static bool unpack_u8(struct aa_ext *e, u8 *data, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) void *pos = e->pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (unpack_nameX(e, AA_U8, name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (!inbounds(e, sizeof(u8)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if (data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) *data = get_unaligned((u8 *)e->pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) e->pos += sizeof(u8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) e->pos = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) void *pos = e->pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (unpack_nameX(e, AA_U32, name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (!inbounds(e, sizeof(u32)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) *data = le32_to_cpu(get_unaligned((__le32 *) e->pos));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) e->pos += sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) e->pos = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) static bool unpack_u64(struct aa_ext *e, u64 *data, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) void *pos = e->pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (unpack_nameX(e, AA_U64, name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (!inbounds(e, sizeof(u64)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) *data = le64_to_cpu(get_unaligned((__le64 *) e->pos));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) e->pos += sizeof(u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) e->pos = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) static size_t unpack_array(struct aa_ext *e, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) void *pos = e->pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (unpack_nameX(e, AA_ARRAY, name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (!inbounds(e, sizeof(u16)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) size = (int)le16_to_cpu(get_unaligned((__le16 *) e->pos));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) e->pos += sizeof(u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) e->pos = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) static size_t unpack_blob(struct aa_ext *e, char **blob, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) void *pos = e->pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (unpack_nameX(e, AA_BLOB, name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) u32 size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (!inbounds(e, sizeof(u32)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) size = le32_to_cpu(get_unaligned((__le32 *) e->pos));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) e->pos += sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (inbounds(e, (size_t) size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) *blob = e->pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) e->pos += size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) e->pos = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) static int unpack_str(struct aa_ext *e, const char **string, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) char *src_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) size_t size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) void *pos = e->pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) *string = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (unpack_nameX(e, AA_STRING, name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) size = unpack_u16_chunk(e, &src_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) /* strings are null terminated, length is size - 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (src_str[size - 1] != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) *string = src_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) e->pos = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) static int unpack_strdup(struct aa_ext *e, char **string, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) const char *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) void *pos = e->pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) int res = unpack_str(e, &tmp, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) *string = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (!res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) *string = kmemdup(tmp, res, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (!*string) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) e->pos = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) * unpack_dfa - unpack a file rule dfa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) * @e: serialized data extent information (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) * returns dfa or ERR_PTR or NULL if no dfa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) static struct aa_dfa *unpack_dfa(struct aa_ext *e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) char *blob = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) size_t size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) struct aa_dfa *dfa = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) size = unpack_blob(e, &blob, "aadfa");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) * The dfa is aligned with in the blob to 8 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * from the beginning of the stream.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) * alignment adjust needed by dfa unpack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) size_t sz = blob - (char *) e->start -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) ((e->pos - e->start) & 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) size_t pad = ALIGN(sz, 8) - sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) int flags = TO_ACCEPT1_FLAG(YYTD_DATA32) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) TO_ACCEPT2_FLAG(YYTD_DATA32) | DFA_FLAG_VERIFY_STATES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) dfa = aa_dfa_unpack(blob + pad, size - pad, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (IS_ERR(dfa))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) return dfa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return dfa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) * unpack_trans_table - unpack a profile transition table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) * @e: serialized data extent information (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) * @profile: profile to add the accept table to (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) * Returns: true if table successfully unpacked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) void *saved_pos = e->pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) /* exec table is optional */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (unpack_nameX(e, AA_STRUCT, "xtable")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) int i, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) size = unpack_array(e, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /* currently 4 exec bits and entries 0-3 are reserved iupcx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (size > 16 - 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) profile->file.trans.table = kcalloc(size, sizeof(char *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (!profile->file.trans.table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) profile->file.trans.size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) for (i = 0; i < size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) char *str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) int c, j, pos, size2 = unpack_strdup(e, &str, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) /* unpack_strdup verifies that the last character is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) * null termination byte.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (!size2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) profile->file.trans.table[i] = str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) /* verify that name doesn't start with space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (isspace(*str))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) /* count internal # of internal \0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) for (c = j = 0; j < size2 - 1; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (!str[j]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) pos = j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) c++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (*str == ':') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) /* first character after : must be valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (!str[1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) /* beginning with : requires an embedded \0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) * verify that exactly 1 internal \0 exists
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) * trailing \0 already verified by unpack_strdup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) * convert \0 back to : for label_parse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (c == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) str[pos] = ':';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) else if (c > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) } else if (c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) /* fail - all other cases with embedded \0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (!unpack_nameX(e, AA_ARRAYEND, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (!unpack_nameX(e, AA_STRUCTEND, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) aa_free_domain_entries(&profile->file.trans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) e->pos = saved_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) static bool unpack_xattrs(struct aa_ext *e, struct aa_profile *profile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) void *pos = e->pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (unpack_nameX(e, AA_STRUCT, "xattrs")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) int i, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) size = unpack_array(e, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) profile->xattr_count = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) profile->xattrs = kcalloc(size, sizeof(char *), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (!profile->xattrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) for (i = 0; i < size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) if (!unpack_strdup(e, &profile->xattrs[i], NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (!unpack_nameX(e, AA_ARRAYEND, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) if (!unpack_nameX(e, AA_STRUCTEND, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) e->pos = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) static bool unpack_secmark(struct aa_ext *e, struct aa_profile *profile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) void *pos = e->pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) int i, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (unpack_nameX(e, AA_STRUCT, "secmark")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) size = unpack_array(e, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) profile->secmark = kcalloc(size, sizeof(struct aa_secmark),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) if (!profile->secmark)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) profile->secmark_count = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) for (i = 0; i < size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) if (!unpack_u8(e, &profile->secmark[i].audit, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) if (!unpack_u8(e, &profile->secmark[i].deny, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if (!unpack_strdup(e, &profile->secmark[i].label, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (!unpack_nameX(e, AA_ARRAYEND, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) if (!unpack_nameX(e, AA_STRUCTEND, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (profile->secmark) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) for (i = 0; i < size; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) kfree(profile->secmark[i].label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) kfree(profile->secmark);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) profile->secmark_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) profile->secmark = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) e->pos = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) static bool unpack_rlimits(struct aa_ext *e, struct aa_profile *profile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) void *pos = e->pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) /* rlimits are optional */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if (unpack_nameX(e, AA_STRUCT, "rlimits")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) int i, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) u32 tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) if (!unpack_u32(e, &tmp, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) profile->rlimits.mask = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) size = unpack_array(e, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (size > RLIM_NLIMITS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) for (i = 0; i < size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) u64 tmp2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) int a = aa_map_resource(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) if (!unpack_u64(e, &tmp2, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) profile->rlimits.limits[a].rlim_max = tmp2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) if (!unpack_nameX(e, AA_ARRAYEND, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) if (!unpack_nameX(e, AA_STRUCTEND, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) e->pos = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) static u32 strhash(const void *data, u32 len, u32 seed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) const char * const *key = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) return jhash(*key, strlen(*key), seed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) static int datacmp(struct rhashtable_compare_arg *arg, const void *obj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) const struct aa_data *data = obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) const char * const *key = arg->key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) return strcmp(data->key, *key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) * unpack_profile - unpack a serialized profile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) * @e: serialized data extent information (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) * NOTE: unpack profile sets audit struct if there is a failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) struct aa_profile *profile = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) const char *tmpname, *tmpns = NULL, *name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) const char *info = "failed to unpack profile";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) size_t ns_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) struct rhashtable_params params = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) char *key = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) struct aa_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) int i, error = -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) kernel_cap_t tmpcap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) *ns_name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) /* check that we have the right struct being passed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) if (!unpack_nameX(e, AA_STRUCT, "profile"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) if (!unpack_str(e, &name, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) if (*name == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) tmpname = aa_splitn_fqname(name, strlen(name), &tmpns, &ns_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) if (tmpns) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) *ns_name = kstrndup(tmpns, ns_len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (!*ns_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) info = "out of memory";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) name = tmpname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) profile = aa_alloc_profile(name, NULL, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) if (!profile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) /* profile renaming is optional */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) (void) unpack_str(e, &profile->rename, "rename");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) /* attachment string is optional */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) (void) unpack_str(e, &profile->attach, "attach");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) /* xmatch is optional and may be NULL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) profile->xmatch = unpack_dfa(e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) if (IS_ERR(profile->xmatch)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) error = PTR_ERR(profile->xmatch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) profile->xmatch = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) info = "bad xmatch";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) /* xmatch_len is not optional if xmatch is set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if (profile->xmatch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (!unpack_u32(e, &tmp, NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) info = "missing xmatch len";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) profile->xmatch_len = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) /* disconnected attachment string is optional */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) (void) unpack_str(e, &profile->disconnected, "disconnected");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) /* per profile debug flags (complain, audit) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) if (!unpack_nameX(e, AA_STRUCT, "flags")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) info = "profile missing flags";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) info = "failed to unpack profile flags";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (!unpack_u32(e, &tmp, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) if (tmp & PACKED_FLAG_HAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) profile->label.flags |= FLAG_HAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (!unpack_u32(e, &tmp, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (tmp == PACKED_MODE_COMPLAIN || (e->version & FORCE_COMPLAIN_FLAG))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) profile->mode = APPARMOR_COMPLAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) else if (tmp == PACKED_MODE_ENFORCE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) profile->mode = APPARMOR_ENFORCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) else if (tmp == PACKED_MODE_KILL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) profile->mode = APPARMOR_KILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) else if (tmp == PACKED_MODE_UNCONFINED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) profile->mode = APPARMOR_UNCONFINED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (!unpack_u32(e, &tmp, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if (tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) profile->audit = AUDIT_ALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) if (!unpack_nameX(e, AA_STRUCTEND, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) /* path_flags is optional */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (unpack_u32(e, &profile->path_flags, "path_flags"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) profile->path_flags |= profile->label.flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) PATH_MEDIATE_DELETED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) /* set a default value if path_flags field is not present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) profile->path_flags = PATH_MEDIATE_DELETED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) info = "failed to unpack profile capabilities";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (!unpack_u32(e, &(profile->caps.allow.cap[0]), NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if (!unpack_u32(e, &(profile->caps.audit.cap[0]), NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) if (!unpack_u32(e, &(profile->caps.quiet.cap[0]), NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) if (!unpack_u32(e, &tmpcap.cap[0], NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) info = "failed to unpack upper profile capabilities";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) if (unpack_nameX(e, AA_STRUCT, "caps64")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) /* optional upper half of 64 bit caps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) if (!unpack_u32(e, &(profile->caps.allow.cap[1]), NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) if (!unpack_u32(e, &(profile->caps.audit.cap[1]), NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) if (!unpack_u32(e, &(profile->caps.quiet.cap[1]), NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if (!unpack_u32(e, &(tmpcap.cap[1]), NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) if (!unpack_nameX(e, AA_STRUCTEND, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) info = "failed to unpack extended profile capabilities";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (unpack_nameX(e, AA_STRUCT, "capsx")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) /* optional extended caps mediation mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) if (!unpack_u32(e, &(profile->caps.extended.cap[0]), NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) if (!unpack_u32(e, &(profile->caps.extended.cap[1]), NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) if (!unpack_nameX(e, AA_STRUCTEND, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) if (!unpack_xattrs(e, profile)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) info = "failed to unpack profile xattrs";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) if (!unpack_rlimits(e, profile)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) info = "failed to unpack profile rlimits";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) if (!unpack_secmark(e, profile)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) info = "failed to unpack profile secmark rules";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) if (unpack_nameX(e, AA_STRUCT, "policydb")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) /* generic policy dfa - optional and may be NULL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) info = "failed to unpack policydb";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) profile->policy.dfa = unpack_dfa(e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) if (IS_ERR(profile->policy.dfa)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) error = PTR_ERR(profile->policy.dfa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) profile->policy.dfa = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) } else if (!profile->policy.dfa) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) error = -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) if (!unpack_u32(e, &profile->policy.start[0], "start"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) /* default start state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) profile->policy.start[0] = DFA_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) /* setup class index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) for (i = AA_CLASS_FILE; i <= AA_CLASS_LAST; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) profile->policy.start[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) aa_dfa_next(profile->policy.dfa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) profile->policy.start[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) if (!unpack_nameX(e, AA_STRUCTEND, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) profile->policy.dfa = aa_get_dfa(nulldfa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) /* get file rules */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) profile->file.dfa = unpack_dfa(e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) if (IS_ERR(profile->file.dfa)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) error = PTR_ERR(profile->file.dfa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) profile->file.dfa = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) info = "failed to unpack profile file rules";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) } else if (profile->file.dfa) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if (!unpack_u32(e, &profile->file.start, "dfa_start"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) /* default start state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) profile->file.start = DFA_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) } else if (profile->policy.dfa &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) profile->policy.start[AA_CLASS_FILE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) profile->file.dfa = aa_get_dfa(profile->policy.dfa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) profile->file.start = profile->policy.start[AA_CLASS_FILE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) profile->file.dfa = aa_get_dfa(nulldfa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) if (!unpack_trans_table(e, profile)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) info = "failed to unpack profile transition table";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) if (unpack_nameX(e, AA_STRUCT, "data")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) info = "out of memory";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) profile->data = kzalloc(sizeof(*profile->data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) if (!profile->data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) params.nelem_hint = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) params.key_len = sizeof(void *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) params.key_offset = offsetof(struct aa_data, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) params.head_offset = offsetof(struct aa_data, head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) params.hashfn = strhash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) params.obj_cmpfn = datacmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) if (rhashtable_init(profile->data, ¶ms)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) info = "failed to init key, value hash table";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) while (unpack_strdup(e, &key, NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) data = kzalloc(sizeof(*data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) if (!data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) kfree_sensitive(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) data->key = key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) data->size = unpack_blob(e, &data->data, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) data->data = kvmemdup(data->data, data->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) if (data->size && !data->data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) kfree_sensitive(data->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) kfree_sensitive(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) rhashtable_insert_fast(profile->data, &data->head,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) profile->data->p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) if (!unpack_nameX(e, AA_STRUCTEND, NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) info = "failed to unpack end of key, value data table";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) if (!unpack_nameX(e, AA_STRUCTEND, NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) info = "failed to unpack end of profile";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) return profile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) if (profile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) else if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) name = "unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) audit_iface(profile, NULL, name, info, e, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) aa_free_profile(profile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) return ERR_PTR(error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) * verify_head - unpack serialized stream header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) * @e: serialized data read head (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) * @required: whether the header is required or optional
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) * @ns: Returns - namespace if one is specified else NULL (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) * Returns: error or 0 if header is good
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) static int verify_header(struct aa_ext *e, int required, const char **ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) int error = -EPROTONOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) const char *name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) *ns = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) /* get the interface version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) if (!unpack_u32(e, &e->version, "version")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) if (required) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) audit_iface(NULL, NULL, NULL, "invalid profile format",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) e, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) /* Check that the interface version is currently supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) * if not specified use previous version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) * Mask off everything that is not kernel abi version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) if (VERSION_LT(e->version, v5) || VERSION_GT(e->version, v7)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) audit_iface(NULL, NULL, NULL, "unsupported interface version",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) e, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) /* read the namespace if present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) if (unpack_str(e, &name, "namespace")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) if (*name == '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) audit_iface(NULL, NULL, NULL, "invalid namespace name",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) e, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) if (*ns && strcmp(*ns, name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) audit_iface(NULL, NULL, NULL, "invalid ns change", e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) } else if (!*ns) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) *ns = kstrdup(name, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) if (!*ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) static bool verify_xindex(int xindex, int table_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) int index, xtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) xtype = xindex & AA_X_TYPE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) index = xindex & AA_X_INDEX_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if (xtype == AA_X_TABLE && index >= table_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) /* verify dfa xindexes are in range of transition tables */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) static bool verify_dfa_xindex(struct aa_dfa *dfa, int table_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) for (i = 0; i < dfa->tables[YYTD_ID_ACCEPT]->td_lolen; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) if (!verify_xindex(dfa_user_xindex(dfa, i), table_size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) if (!verify_xindex(dfa_other_xindex(dfa, i), table_size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) * verify_profile - Do post unpack analysis to verify profile consistency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) * @profile: profile to verify (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) * Returns: 0 if passes verification else error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) static int verify_profile(struct aa_profile *profile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) if (profile->file.dfa &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) !verify_dfa_xindex(profile->file.dfa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) profile->file.trans.size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) audit_iface(profile, NULL, NULL, "Invalid named transition",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) NULL, -EPROTO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) void aa_load_ent_free(struct aa_load_ent *ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) if (ent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) aa_put_profile(ent->rename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) aa_put_profile(ent->old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) aa_put_profile(ent->new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) kfree(ent->ns_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) kfree_sensitive(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) struct aa_load_ent *aa_load_ent_alloc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) struct aa_load_ent *ent = kzalloc(sizeof(*ent), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) if (ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) INIT_LIST_HEAD(&ent->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) return ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) static int deflate_compress(const char *src, size_t slen, char **dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) size_t *dlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) struct z_stream_s strm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) void *stgbuf, *dstbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) size_t stglen = deflateBound(slen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) memset(&strm, 0, sizeof(strm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) if (stglen < slen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) return -EFBIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) strm.workspace = kvzalloc(zlib_deflate_workspacesize(MAX_WBITS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) MAX_MEM_LEVEL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) if (!strm.workspace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) error = zlib_deflateInit(&strm, aa_g_rawdata_compression_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) if (error != Z_OK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) goto fail_deflate_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) stgbuf = kvzalloc(stglen, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) if (!stgbuf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) goto fail_stg_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) strm.next_in = src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) strm.avail_in = slen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) strm.next_out = stgbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) strm.avail_out = stglen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) error = zlib_deflate(&strm, Z_FINISH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) if (error != Z_STREAM_END) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) goto fail_deflate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) if (is_vmalloc_addr(stgbuf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) dstbuf = kvzalloc(strm.total_out, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) if (dstbuf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) memcpy(dstbuf, stgbuf, strm.total_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) kvfree(stgbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) * If the staging buffer was kmalloc'd, then using krealloc is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) * probably going to be faster. The destination buffer will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) * always be smaller, so it's just shrunk, avoiding a memcpy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) dstbuf = krealloc(stgbuf, strm.total_out, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) if (!dstbuf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) goto fail_deflate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) *dst = dstbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) *dlen = strm.total_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) fail_stg_alloc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) zlib_deflateEnd(&strm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) fail_deflate_init:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) kvfree(strm.workspace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) fail_deflate:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) kvfree(stgbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) goto fail_stg_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) static int compress_loaddata(struct aa_loaddata *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) AA_BUG(data->compressed_size > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) * Shortcut the no compression case, else we increase the amount of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) * storage required by a small amount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) if (aa_g_rawdata_compression_level != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) void *udata = data->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) int error = deflate_compress(udata, data->size, &data->data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) &data->compressed_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) kvfree(udata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) data->compressed_size = data->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) * aa_unpack - unpack packed binary profile(s) data loaded from user space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) * @udata: user data copied to kmem (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) * @lh: list to place unpacked profiles in a aa_repl_ws
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) * @ns: Returns namespace profile is in if specified else NULL (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) * Unpack user data and return refcounted allocated profile(s) stored in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) * @lh in order of discovery, with the list chain stored in base.list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) * or error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) * Returns: profile(s) on @lh else error pointer if fails to unpack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) int aa_unpack(struct aa_loaddata *udata, struct list_head *lh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) const char **ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) struct aa_load_ent *tmp, *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) struct aa_profile *profile = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) struct aa_ext e = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) .start = udata->data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) .end = udata->data + udata->size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) .pos = udata->data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) *ns = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) while (e.pos < e.end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) char *ns_name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) void *start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) error = verify_header(&e, e.pos == e.start, ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) start = e.pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) profile = unpack_profile(&e, &ns_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) if (IS_ERR(profile)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) error = PTR_ERR(profile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) error = verify_profile(profile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) goto fail_profile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) if (aa_g_hash_policy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) error = aa_calc_profile_hash(profile, e.version, start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) e.pos - start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) goto fail_profile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) ent = aa_load_ent_alloc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) if (!ent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) goto fail_profile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) ent->new = profile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) ent->ns_name = ns_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) list_add_tail(&ent->list, lh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) udata->abi = e.version & K_ABI_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) if (aa_g_hash_policy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) udata->hash = aa_calc_hash(udata->data, udata->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) if (IS_ERR(udata->hash)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) error = PTR_ERR(udata->hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) udata->hash = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) error = compress_loaddata(udata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) fail_profile:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) aa_put_profile(profile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) list_for_each_entry_safe(ent, tmp, lh, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) list_del_init(&ent->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) aa_load_ent_free(ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) #ifdef CONFIG_SECURITY_APPARMOR_KUNIT_TEST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) #include "policy_unpack_test.c"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) #endif /* CONFIG_SECURITY_APPARMOR_KUNIT_TEST */