LCOV - code coverage report
Current view: top level - security/apparmor - secid.c (source / functions) Hit Total Coverage
Test: Real Lines: 0 39 0.0 %
Date: 2020-10-17 15:46:16 Functions: 0 8 0.0 %
Legend: Neither, QEMU, Real, Both Branches: 0 0 -

           Branch data     Line data    Source code
       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                 :          0 : void aa_secid_update(u32 secid, struct aa_label *label)
      47                 :            : {
      48                 :            :         unsigned long flags;
      49                 :            : 
      50                 :          0 :         spin_lock_irqsave(&secid_lock, flags);
      51                 :          0 :         idr_replace(&aa_secids, label, secid);
      52                 :            :         spin_unlock_irqrestore(&secid_lock, flags);
      53                 :          0 : }
      54                 :            : 
      55                 :            : /**
      56                 :            :  *
      57                 :            :  * see label for inverse aa_label_to_secid
      58                 :            :  */
      59                 :          0 : struct aa_label *aa_secid_to_label(u32 secid)
      60                 :            : {
      61                 :            :         struct aa_label *label;
      62                 :            : 
      63                 :            :         rcu_read_lock();
      64                 :          0 :         label = idr_find(&aa_secids, secid);
      65                 :            :         rcu_read_unlock();
      66                 :            : 
      67                 :          0 :         return label;
      68                 :            : }
      69                 :            : 
      70                 :          0 : 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                 :          0 :         if (!label)
      79                 :            :                 return -EINVAL;
      80                 :            : 
      81                 :          0 :         if (secdata)
      82                 :          0 :                 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                 :          0 :                 len = aa_label_snxprint(NULL, 0, root_ns, label,
      88                 :            :                                         FLAG_SHOW_MODE | FLAG_VIEW_SUBNS |
      89                 :            :                                         FLAG_HIDDEN_UNCONFINED | FLAG_ABS_ROOT);
      90                 :          0 :         if (len < 0)
      91                 :            :                 return -ENOMEM;
      92                 :            : 
      93                 :          0 :         *seclen = len;
      94                 :            : 
      95                 :          0 :         return 0;
      96                 :            : }
      97                 :            : 
      98                 :          0 : int apparmor_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
      99                 :            : {
     100                 :            :         struct aa_label *label;
     101                 :            : 
     102                 :          0 :         label = aa_label_strn_parse(&root_ns->unconfined->label, secdata,
     103                 :            :                                     seclen, GFP_KERNEL, false, false);
     104                 :          0 :         if (IS_ERR(label))
     105                 :          0 :                 return PTR_ERR(label);
     106                 :          0 :         *secid = label->secid;
     107                 :            : 
     108                 :          0 :         return 0;
     109                 :            : }
     110                 :            : 
     111                 :          0 : void apparmor_release_secctx(char *secdata, u32 seclen)
     112                 :            : {
     113                 :          0 :         kfree(secdata);
     114                 :          0 : }
     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                 :          0 : int aa_alloc_secid(struct aa_label *label, gfp_t gfp)
     125                 :            : {
     126                 :            :         unsigned long flags;
     127                 :            :         int ret;
     128                 :            : 
     129                 :          0 :         idr_preload(gfp);
     130                 :          0 :         spin_lock_irqsave(&secid_lock, flags);
     131                 :          0 :         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                 :          0 :         if (ret < 0) {
     136                 :          0 :                 label->secid = AA_SECID_INVALID;
     137                 :          0 :                 return ret;
     138                 :            :         }
     139                 :            : 
     140                 :            :         AA_BUG(ret == AA_SECID_INVALID);
     141                 :          0 :         label->secid = ret;
     142                 :          0 :         return 0;
     143                 :            : }
     144                 :            : 
     145                 :            : /**
     146                 :            :  * aa_free_secid - free a secid
     147                 :            :  * @secid: secid to free
     148                 :            :  */
     149                 :          0 : void aa_free_secid(u32 secid)
     150                 :            : {
     151                 :            :         unsigned long flags;
     152                 :            : 
     153                 :          0 :         spin_lock_irqsave(&secid_lock, flags);
     154                 :          0 :         idr_remove(&aa_secids, secid);
     155                 :            :         spin_unlock_irqrestore(&secid_lock, flags);
     156                 :          0 : }
     157                 :            : 
     158                 :          0 : void aa_secids_init(void)
     159                 :            : {
     160                 :            :         idr_init_base(&aa_secids, AA_FIRST_SECID);
     161                 :          0 : }
    

Generated by: LCOV version 1.14