^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 security identifier (secid) manipulation fns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright 2009-2017 Canonical Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * AppArmor allocates a unique secid for every label used. If a label
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * is replaced it receives the secid of the label it is replacing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/idr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "include/cred.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "include/lib.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "include/secid.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "include/label.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "include/policy_ns.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * secids - do not pin labels with a refcount. They rely on the label
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * properly updating/freeing them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define AA_FIRST_SECID 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static DEFINE_IDR(aa_secids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) static DEFINE_SPINLOCK(secid_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * TODO: allow policy to reserve a secid range?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * TODO: add secid pinning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * TODO: use secid_update in label replace
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * aa_secid_update - update a secid mapping to a new label
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * @secid: secid to update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * @label: label the secid will now map to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) void aa_secid_update(u32 secid, struct aa_label *label)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) spin_lock_irqsave(&secid_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) idr_replace(&aa_secids, label, secid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) spin_unlock_irqrestore(&secid_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * see label for inverse aa_label_to_secid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct aa_label *aa_secid_to_label(u32 secid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct aa_label *label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) label = idr_find(&aa_secids, secid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) int apparmor_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /* TODO: cache secctx and ref count so we don't have to recreate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct aa_label *label = aa_secid_to_label(secid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) AA_BUG(!seclen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (!label)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (secdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) len = aa_label_asxprint(secdata, root_ns, label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) FLAG_SHOW_MODE | FLAG_VIEW_SUBNS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) FLAG_HIDDEN_UNCONFINED | FLAG_ABS_ROOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) len = aa_label_snxprint(NULL, 0, root_ns, label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) FLAG_SHOW_MODE | FLAG_VIEW_SUBNS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) FLAG_HIDDEN_UNCONFINED | FLAG_ABS_ROOT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (len < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) *seclen = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) int apparmor_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct aa_label *label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) label = aa_label_strn_parse(&root_ns->unconfined->label, secdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) seclen, GFP_KERNEL, false, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (IS_ERR(label))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return PTR_ERR(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) *secid = label->secid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) void apparmor_release_secctx(char *secdata, u32 seclen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) kfree(secdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * aa_alloc_secid - allocate a new secid for a profile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * @label: the label to allocate a secid for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * @gfp: memory allocation flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * Returns: 0 with @label->secid initialized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * <0 returns error with @label->secid set to AA_SECID_INVALID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) int aa_alloc_secid(struct aa_label *label, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) idr_preload(gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) spin_lock_irqsave(&secid_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) ret = idr_alloc(&aa_secids, label, AA_FIRST_SECID, 0, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) spin_unlock_irqrestore(&secid_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) idr_preload_end();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) label->secid = AA_SECID_INVALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) AA_BUG(ret == AA_SECID_INVALID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) label->secid = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * aa_free_secid - free a secid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * @secid: secid to free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) void aa_free_secid(u32 secid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) spin_lock_irqsave(&secid_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) idr_remove(&aa_secids, secid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) spin_unlock_irqrestore(&secid_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) void aa_secids_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) idr_init_base(&aa_secids, AA_FIRST_SECID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }