root/security/apparmor/secid.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. aa_secid_update
  2. aa_secid_to_label
  3. apparmor_secid_to_secctx
  4. apparmor_secctx_to_secid
  5. apparmor_release_secctx
  6. aa_alloc_secid
  7. aa_free_secid
  8. aa_secids_init

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

/* [<][>][^][v][top][bottom][index][help] */