LCOV - code coverage report
Current view: top level - security/selinux - avc.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 160 519 30.8 %
Date: 2022-04-01 14:58:12 Functions: 14 37 37.8 %
Branches: 47 270 17.4 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-only
       2                 :            : /*
       3                 :            :  * Implementation of the kernel access vector cache (AVC).
       4                 :            :  *
       5                 :            :  * Authors:  Stephen Smalley, <sds@tycho.nsa.gov>
       6                 :            :  *           James Morris <jmorris@redhat.com>
       7                 :            :  *
       8                 :            :  * Update:   KaiGai, Kohei <kaigai@ak.jp.nec.com>
       9                 :            :  *      Replaced the avc_lock spinlock by RCU.
      10                 :            :  *
      11                 :            :  * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
      12                 :            :  */
      13                 :            : #include <linux/types.h>
      14                 :            : #include <linux/stddef.h>
      15                 :            : #include <linux/kernel.h>
      16                 :            : #include <linux/slab.h>
      17                 :            : #include <linux/fs.h>
      18                 :            : #include <linux/dcache.h>
      19                 :            : #include <linux/init.h>
      20                 :            : #include <linux/skbuff.h>
      21                 :            : #include <linux/percpu.h>
      22                 :            : #include <linux/list.h>
      23                 :            : #include <net/sock.h>
      24                 :            : #include <linux/un.h>
      25                 :            : #include <net/af_unix.h>
      26                 :            : #include <linux/ip.h>
      27                 :            : #include <linux/audit.h>
      28                 :            : #include <linux/ipv6.h>
      29                 :            : #include <net/ipv6.h>
      30                 :            : #include "avc.h"
      31                 :            : #include "avc_ss.h"
      32                 :            : #include "classmap.h"
      33                 :            : 
      34                 :            : #define AVC_CACHE_SLOTS                 512
      35                 :            : #define AVC_DEF_CACHE_THRESHOLD         512
      36                 :            : #define AVC_CACHE_RECLAIM               16
      37                 :            : 
      38                 :            : #ifdef CONFIG_SECURITY_SELINUX_AVC_STATS
      39                 :            : #define avc_cache_stats_incr(field)     this_cpu_inc(avc_cache_stats.field)
      40                 :            : #else
      41                 :            : #define avc_cache_stats_incr(field)     do {} while (0)
      42                 :            : #endif
      43                 :            : 
      44                 :            : struct avc_entry {
      45                 :            :         u32                     ssid;
      46                 :            :         u32                     tsid;
      47                 :            :         u16                     tclass;
      48                 :            :         struct av_decision      avd;
      49                 :            :         struct avc_xperms_node  *xp_node;
      50                 :            : };
      51                 :            : 
      52                 :            : struct avc_node {
      53                 :            :         struct avc_entry        ae;
      54                 :            :         struct hlist_node       list; /* anchored in avc_cache->slots[i] */
      55                 :            :         struct rcu_head         rhead;
      56                 :            : };
      57                 :            : 
      58                 :            : struct avc_xperms_decision_node {
      59                 :            :         struct extended_perms_decision xpd;
      60                 :            :         struct list_head xpd_list; /* list of extended_perms_decision */
      61                 :            : };
      62                 :            : 
      63                 :            : struct avc_xperms_node {
      64                 :            :         struct extended_perms xp;
      65                 :            :         struct list_head xpd_head; /* list head of extended_perms_decision */
      66                 :            : };
      67                 :            : 
      68                 :            : struct avc_cache {
      69                 :            :         struct hlist_head       slots[AVC_CACHE_SLOTS]; /* head for avc_node->list */
      70                 :            :         spinlock_t              slots_lock[AVC_CACHE_SLOTS]; /* lock for writes */
      71                 :            :         atomic_t                lru_hint;       /* LRU hint for reclaim scan */
      72                 :            :         atomic_t                active_nodes;
      73                 :            :         u32                     latest_notif;   /* latest revocation notification */
      74                 :            : };
      75                 :            : 
      76                 :            : struct avc_callback_node {
      77                 :            :         int (*callback) (u32 event);
      78                 :            :         u32 events;
      79                 :            :         struct avc_callback_node *next;
      80                 :            : };
      81                 :            : 
      82                 :            : #ifdef CONFIG_SECURITY_SELINUX_AVC_STATS
      83                 :            : DEFINE_PER_CPU(struct avc_cache_stats, avc_cache_stats) = { 0 };
      84                 :            : #endif
      85                 :            : 
      86                 :            : struct selinux_avc {
      87                 :            :         unsigned int avc_cache_threshold;
      88                 :            :         struct avc_cache avc_cache;
      89                 :            : };
      90                 :            : 
      91                 :            : static struct selinux_avc selinux_avc;
      92                 :            : 
      93                 :          3 : void selinux_avc_init(struct selinux_avc **avc)
      94                 :            : {
      95                 :          3 :         int i;
      96                 :            : 
      97                 :          3 :         selinux_avc.avc_cache_threshold = AVC_DEF_CACHE_THRESHOLD;
      98         [ +  + ]:       1539 :         for (i = 0; i < AVC_CACHE_SLOTS; i++) {
      99                 :       1536 :                 INIT_HLIST_HEAD(&selinux_avc.avc_cache.slots[i]);
     100                 :       1536 :                 spin_lock_init(&selinux_avc.avc_cache.slots_lock[i]);
     101                 :            :         }
     102                 :          3 :         atomic_set(&selinux_avc.avc_cache.active_nodes, 0);
     103                 :          3 :         atomic_set(&selinux_avc.avc_cache.lru_hint, 0);
     104                 :          3 :         *avc = &selinux_avc;
     105                 :          3 : }
     106                 :            : 
     107                 :          0 : unsigned int avc_get_cache_threshold(struct selinux_avc *avc)
     108                 :            : {
     109                 :          0 :         return avc->avc_cache_threshold;
     110                 :            : }
     111                 :            : 
     112                 :          0 : void avc_set_cache_threshold(struct selinux_avc *avc,
     113                 :            :                              unsigned int cache_threshold)
     114                 :            : {
     115                 :          0 :         avc->avc_cache_threshold = cache_threshold;
     116                 :          0 : }
     117                 :            : 
     118                 :            : static struct avc_callback_node *avc_callbacks;
     119                 :            : static struct kmem_cache *avc_node_cachep;
     120                 :            : static struct kmem_cache *avc_xperms_data_cachep;
     121                 :            : static struct kmem_cache *avc_xperms_decision_cachep;
     122                 :            : static struct kmem_cache *avc_xperms_cachep;
     123                 :            : 
     124                 :    1675546 : static inline int avc_hash(u32 ssid, u32 tsid, u16 tclass)
     125                 :            : {
     126                 :    1675546 :         return (ssid ^ (tsid<<2) ^ (tclass<<4)) & (AVC_CACHE_SLOTS - 1);
     127                 :            : }
     128                 :            : 
     129                 :            : /**
     130                 :            :  * avc_init - Initialize the AVC.
     131                 :            :  *
     132                 :            :  * Initialize the access vector cache.
     133                 :            :  */
     134                 :          3 : void __init avc_init(void)
     135                 :            : {
     136                 :          3 :         avc_node_cachep = kmem_cache_create("avc_node", sizeof(struct avc_node),
     137                 :            :                                         0, SLAB_PANIC, NULL);
     138                 :          3 :         avc_xperms_cachep = kmem_cache_create("avc_xperms_node",
     139                 :            :                                         sizeof(struct avc_xperms_node),
     140                 :            :                                         0, SLAB_PANIC, NULL);
     141                 :          3 :         avc_xperms_decision_cachep = kmem_cache_create(
     142                 :            :                                         "avc_xperms_decision_node",
     143                 :            :                                         sizeof(struct avc_xperms_decision_node),
     144                 :            :                                         0, SLAB_PANIC, NULL);
     145                 :          3 :         avc_xperms_data_cachep = kmem_cache_create("avc_xperms_data",
     146                 :            :                                         sizeof(struct extended_perms_data),
     147                 :            :                                         0, SLAB_PANIC, NULL);
     148                 :          3 : }
     149                 :            : 
     150                 :          0 : int avc_get_hash_stats(struct selinux_avc *avc, char *page)
     151                 :            : {
     152                 :          0 :         int i, chain_len, max_chain_len, slots_used;
     153                 :          0 :         struct avc_node *node;
     154                 :          0 :         struct hlist_head *head;
     155                 :            : 
     156                 :          0 :         rcu_read_lock();
     157                 :            : 
     158                 :          0 :         slots_used = 0;
     159                 :          0 :         max_chain_len = 0;
     160         [ #  # ]:          0 :         for (i = 0; i < AVC_CACHE_SLOTS; i++) {
     161                 :          0 :                 head = &avc->avc_cache.slots[i];
     162         [ #  # ]:          0 :                 if (!hlist_empty(head)) {
     163                 :          0 :                         slots_used++;
     164                 :          0 :                         chain_len = 0;
     165   [ #  #  #  # ]:          0 :                         hlist_for_each_entry_rcu(node, head, list)
     166         [ #  # ]:          0 :                                 chain_len++;
     167                 :          0 :                         if (chain_len > max_chain_len)
     168                 :            :                                 max_chain_len = chain_len;
     169                 :            :                 }
     170                 :            :         }
     171                 :            : 
     172                 :          0 :         rcu_read_unlock();
     173                 :            : 
     174                 :          0 :         return scnprintf(page, PAGE_SIZE, "entries: %d\nbuckets used: %d/%d\n"
     175                 :            :                          "longest chain: %d\n",
     176                 :          0 :                          atomic_read(&avc->avc_cache.active_nodes),
     177                 :            :                          slots_used, AVC_CACHE_SLOTS, max_chain_len);
     178                 :            : }
     179                 :            : 
     180                 :            : /*
     181                 :            :  * using a linked list for extended_perms_decision lookup because the list is
     182                 :            :  * always small. i.e. less than 5, typically 1
     183                 :            :  */
     184                 :          0 : static struct extended_perms_decision *avc_xperms_decision_lookup(u8 driver,
     185                 :            :                                         struct avc_xperms_node *xp_node)
     186                 :            : {
     187                 :          0 :         struct avc_xperms_decision_node *xpd_node;
     188                 :            : 
     189   [ #  #  #  # ]:          0 :         list_for_each_entry(xpd_node, &xp_node->xpd_head, xpd_list) {
     190   [ #  #  #  # ]:          0 :                 if (xpd_node->xpd.driver == driver)
     191                 :          0 :                         return &xpd_node->xpd;
     192                 :            :         }
     193                 :            :         return NULL;
     194                 :            : }
     195                 :            : 
     196                 :            : static inline unsigned int
     197                 :          0 : avc_xperms_has_perm(struct extended_perms_decision *xpd,
     198                 :            :                                         u8 perm, u8 which)
     199                 :            : {
     200                 :          0 :         unsigned int rc = 0;
     201                 :            : 
     202         [ #  # ]:          0 :         if ((which == XPERMS_ALLOWED) &&
     203         [ #  # ]:          0 :                         (xpd->used & XPERMS_ALLOWED))
     204                 :          0 :                 rc = security_xperm_test(xpd->allowed->p, perm);
     205         [ #  # ]:          0 :         else if ((which == XPERMS_AUDITALLOW) &&
     206         [ #  # ]:          0 :                         (xpd->used & XPERMS_AUDITALLOW))
     207                 :          0 :                 rc = security_xperm_test(xpd->auditallow->p, perm);
     208         [ #  # ]:          0 :         else if ((which == XPERMS_DONTAUDIT) &&
     209         [ #  # ]:          0 :                         (xpd->used & XPERMS_DONTAUDIT))
     210                 :          0 :                 rc = security_xperm_test(xpd->dontaudit->p, perm);
     211                 :          0 :         return rc;
     212                 :            : }
     213                 :            : 
     214                 :          0 : static void avc_xperms_allow_perm(struct avc_xperms_node *xp_node,
     215                 :            :                                 u8 driver, u8 perm)
     216                 :            : {
     217                 :          0 :         struct extended_perms_decision *xpd;
     218                 :          0 :         security_xperm_set(xp_node->xp.drivers.p, driver);
     219                 :          0 :         xpd = avc_xperms_decision_lookup(driver, xp_node);
     220   [ #  #  #  # ]:          0 :         if (xpd && xpd->allowed)
     221                 :          0 :                 security_xperm_set(xpd->allowed->p, perm);
     222                 :          0 : }
     223                 :            : 
     224                 :          0 : static void avc_xperms_decision_free(struct avc_xperms_decision_node *xpd_node)
     225                 :            : {
     226                 :          0 :         struct extended_perms_decision *xpd;
     227                 :            : 
     228                 :          0 :         xpd = &xpd_node->xpd;
     229         [ #  # ]:          0 :         if (xpd->allowed)
     230                 :          0 :                 kmem_cache_free(avc_xperms_data_cachep, xpd->allowed);
     231         [ #  # ]:          0 :         if (xpd->auditallow)
     232                 :          0 :                 kmem_cache_free(avc_xperms_data_cachep, xpd->auditallow);
     233         [ #  # ]:          0 :         if (xpd->dontaudit)
     234                 :          0 :                 kmem_cache_free(avc_xperms_data_cachep, xpd->dontaudit);
     235                 :          0 :         kmem_cache_free(avc_xperms_decision_cachep, xpd_node);
     236                 :          0 : }
     237                 :            : 
     238                 :          0 : static void avc_xperms_free(struct avc_xperms_node *xp_node)
     239                 :            : {
     240                 :          0 :         struct avc_xperms_decision_node *xpd_node, *tmp;
     241                 :            : 
     242         [ #  # ]:          0 :         if (!xp_node)
     243                 :            :                 return;
     244                 :            : 
     245         [ #  # ]:          0 :         list_for_each_entry_safe(xpd_node, tmp, &xp_node->xpd_head, xpd_list) {
     246                 :          0 :                 list_del(&xpd_node->xpd_list);
     247                 :          0 :                 avc_xperms_decision_free(xpd_node);
     248                 :            :         }
     249                 :          0 :         kmem_cache_free(avc_xperms_cachep, xp_node);
     250                 :            : }
     251                 :            : 
     252                 :          0 : static void avc_copy_xperms_decision(struct extended_perms_decision *dest,
     253                 :            :                                         struct extended_perms_decision *src)
     254                 :            : {
     255                 :          0 :         dest->driver = src->driver;
     256                 :          0 :         dest->used = src->used;
     257         [ #  # ]:          0 :         if (dest->used & XPERMS_ALLOWED)
     258                 :          0 :                 memcpy(dest->allowed->p, src->allowed->p,
     259                 :            :                                 sizeof(src->allowed->p));
     260         [ #  # ]:          0 :         if (dest->used & XPERMS_AUDITALLOW)
     261                 :          0 :                 memcpy(dest->auditallow->p, src->auditallow->p,
     262                 :            :                                 sizeof(src->auditallow->p));
     263         [ #  # ]:          0 :         if (dest->used & XPERMS_DONTAUDIT)
     264                 :          0 :                 memcpy(dest->dontaudit->p, src->dontaudit->p,
     265                 :            :                                 sizeof(src->dontaudit->p));
     266                 :          0 : }
     267                 :            : 
     268                 :            : /*
     269                 :            :  * similar to avc_copy_xperms_decision, but only copy decision
     270                 :            :  * information relevant to this perm
     271                 :            :  */
     272                 :          0 : static inline void avc_quick_copy_xperms_decision(u8 perm,
     273                 :            :                         struct extended_perms_decision *dest,
     274                 :            :                         struct extended_perms_decision *src)
     275                 :            : {
     276                 :            :         /*
     277                 :            :          * compute index of the u32 of the 256 bits (8 u32s) that contain this
     278                 :            :          * command permission
     279                 :            :          */
     280                 :          0 :         u8 i = perm >> 5;
     281                 :            : 
     282                 :          0 :         dest->used = src->used;
     283         [ #  # ]:          0 :         if (dest->used & XPERMS_ALLOWED)
     284                 :          0 :                 dest->allowed->p[i] = src->allowed->p[i];
     285         [ #  # ]:          0 :         if (dest->used & XPERMS_AUDITALLOW)
     286                 :          0 :                 dest->auditallow->p[i] = src->auditallow->p[i];
     287         [ #  # ]:          0 :         if (dest->used & XPERMS_DONTAUDIT)
     288                 :          0 :                 dest->dontaudit->p[i] = src->dontaudit->p[i];
     289                 :          0 : }
     290                 :            : 
     291                 :            : static struct avc_xperms_decision_node
     292                 :          0 :                 *avc_xperms_decision_alloc(u8 which)
     293                 :            : {
     294                 :          0 :         struct avc_xperms_decision_node *xpd_node;
     295                 :          0 :         struct extended_perms_decision *xpd;
     296                 :            : 
     297                 :          0 :         xpd_node = kmem_cache_zalloc(avc_xperms_decision_cachep, GFP_NOWAIT);
     298         [ #  # ]:          0 :         if (!xpd_node)
     299                 :            :                 return NULL;
     300                 :            : 
     301                 :          0 :         xpd = &xpd_node->xpd;
     302         [ #  # ]:          0 :         if (which & XPERMS_ALLOWED) {
     303                 :          0 :                 xpd->allowed = kmem_cache_zalloc(avc_xperms_data_cachep,
     304                 :            :                                                 GFP_NOWAIT);
     305         [ #  # ]:          0 :                 if (!xpd->allowed)
     306                 :          0 :                         goto error;
     307                 :            :         }
     308         [ #  # ]:          0 :         if (which & XPERMS_AUDITALLOW) {
     309                 :          0 :                 xpd->auditallow = kmem_cache_zalloc(avc_xperms_data_cachep,
     310                 :            :                                                 GFP_NOWAIT);
     311         [ #  # ]:          0 :                 if (!xpd->auditallow)
     312                 :          0 :                         goto error;
     313                 :            :         }
     314         [ #  # ]:          0 :         if (which & XPERMS_DONTAUDIT) {
     315                 :          0 :                 xpd->dontaudit = kmem_cache_zalloc(avc_xperms_data_cachep,
     316                 :            :                                                 GFP_NOWAIT);
     317         [ #  # ]:          0 :                 if (!xpd->dontaudit)
     318                 :          0 :                         goto error;
     319                 :            :         }
     320                 :            :         return xpd_node;
     321                 :          0 : error:
     322                 :          0 :         avc_xperms_decision_free(xpd_node);
     323                 :          0 :         return NULL;
     324                 :            : }
     325                 :            : 
     326                 :            : static int avc_add_xperms_decision(struct avc_node *node,
     327                 :            :                         struct extended_perms_decision *src)
     328                 :            : {
     329                 :            :         struct avc_xperms_decision_node *dest_xpd;
     330                 :            : 
     331                 :            :         node->ae.xp_node->xp.len++;
     332                 :            :         dest_xpd = avc_xperms_decision_alloc(src->used);
     333                 :            :         if (!dest_xpd)
     334                 :            :                 return -ENOMEM;
     335                 :            :         avc_copy_xperms_decision(&dest_xpd->xpd, src);
     336                 :            :         list_add(&dest_xpd->xpd_list, &node->ae.xp_node->xpd_head);
     337                 :            :         return 0;
     338                 :            : }
     339                 :            : 
     340                 :            : static struct avc_xperms_node *avc_xperms_alloc(void)
     341                 :            : {
     342                 :            :         struct avc_xperms_node *xp_node;
     343                 :            : 
     344                 :            :         xp_node = kmem_cache_zalloc(avc_xperms_cachep, GFP_NOWAIT);
     345                 :            :         if (!xp_node)
     346                 :            :                 return xp_node;
     347                 :            :         INIT_LIST_HEAD(&xp_node->xpd_head);
     348                 :            :         return xp_node;
     349                 :            : }
     350                 :            : 
     351                 :            : static int avc_xperms_populate(struct avc_node *node,
     352                 :            :                                 struct avc_xperms_node *src)
     353                 :            : {
     354                 :            :         struct avc_xperms_node *dest;
     355                 :            :         struct avc_xperms_decision_node *dest_xpd;
     356                 :            :         struct avc_xperms_decision_node *src_xpd;
     357                 :            : 
     358                 :            :         if (src->xp.len == 0)
     359                 :            :                 return 0;
     360                 :            :         dest = avc_xperms_alloc();
     361                 :            :         if (!dest)
     362                 :            :                 return -ENOMEM;
     363                 :            : 
     364                 :            :         memcpy(dest->xp.drivers.p, src->xp.drivers.p, sizeof(dest->xp.drivers.p));
     365                 :            :         dest->xp.len = src->xp.len;
     366                 :            : 
     367                 :            :         /* for each source xpd allocate a destination xpd and copy */
     368                 :            :         list_for_each_entry(src_xpd, &src->xpd_head, xpd_list) {
     369                 :            :                 dest_xpd = avc_xperms_decision_alloc(src_xpd->xpd.used);
     370                 :            :                 if (!dest_xpd)
     371                 :            :                         goto error;
     372                 :            :                 avc_copy_xperms_decision(&dest_xpd->xpd, &src_xpd->xpd);
     373                 :            :                 list_add(&dest_xpd->xpd_list, &dest->xpd_head);
     374                 :            :         }
     375                 :            :         node->ae.xp_node = dest;
     376                 :            :         return 0;
     377                 :            : error:
     378                 :            :         avc_xperms_free(dest);
     379                 :            :         return -ENOMEM;
     380                 :            : 
     381                 :            : }
     382                 :            : 
     383                 :       1167 : static inline u32 avc_xperms_audit_required(u32 requested,
     384                 :            :                                         struct av_decision *avd,
     385                 :            :                                         struct extended_perms_decision *xpd,
     386                 :            :                                         u8 perm,
     387                 :            :                                         int result,
     388                 :            :                                         u32 *deniedp)
     389                 :            : {
     390                 :       1167 :         u32 denied, audited;
     391                 :            : 
     392                 :       1167 :         denied = requested & ~avd->allowed;
     393         [ -  + ]:       1167 :         if (unlikely(denied)) {
     394                 :          0 :                 audited = denied & avd->auditdeny;
     395         [ #  # ]:          0 :                 if (audited && xpd) {
     396         [ #  # ]:          0 :                         if (avc_xperms_has_perm(xpd, perm, XPERMS_DONTAUDIT))
     397                 :          0 :                                 audited &= ~requested;
     398                 :            :                 }
     399         [ +  - ]:       1167 :         } else if (result) {
     400                 :            :                 audited = denied = requested;
     401                 :            :         } else {
     402                 :       1167 :                 audited = requested & avd->auditallow;
     403         [ -  + ]:       1167 :                 if (audited && xpd) {
     404         [ #  # ]:          0 :                         if (!avc_xperms_has_perm(xpd, perm, XPERMS_AUDITALLOW))
     405                 :          0 :                                 audited &= ~requested;
     406                 :            :                 }
     407                 :            :         }
     408                 :            : 
     409                 :       1167 :         *deniedp = denied;
     410                 :       1167 :         return audited;
     411                 :            : }
     412                 :            : 
     413                 :       1167 : static inline int avc_xperms_audit(struct selinux_state *state,
     414                 :            :                                    u32 ssid, u32 tsid, u16 tclass,
     415                 :            :                                    u32 requested, struct av_decision *avd,
     416                 :            :                                    struct extended_perms_decision *xpd,
     417                 :            :                                    u8 perm, int result,
     418                 :            :                                    struct common_audit_data *ad)
     419                 :            : {
     420                 :       1167 :         u32 audited, denied;
     421                 :            : 
     422                 :       1167 :         audited = avc_xperms_audit_required(
     423                 :            :                         requested, avd, xpd, perm, result, &denied);
     424         [ -  + ]:       1167 :         if (likely(!audited))
     425                 :            :                 return 0;
     426                 :          0 :         return slow_avc_audit(state, ssid, tsid, tclass, requested,
     427                 :            :                         audited, denied, result, ad);
     428                 :            : }
     429                 :            : 
     430                 :          0 : static void avc_node_free(struct rcu_head *rhead)
     431                 :            : {
     432                 :          0 :         struct avc_node *node = container_of(rhead, struct avc_node, rhead);
     433                 :          0 :         avc_xperms_free(node->ae.xp_node);
     434                 :          0 :         kmem_cache_free(avc_node_cachep, node);
     435                 :          0 :         avc_cache_stats_incr(frees);
     436                 :          0 : }
     437                 :            : 
     438                 :          0 : static void avc_node_delete(struct selinux_avc *avc, struct avc_node *node)
     439                 :            : {
     440         [ #  # ]:          0 :         hlist_del_rcu(&node->list);
     441                 :          0 :         call_rcu(&node->rhead, avc_node_free);
     442                 :          0 :         atomic_dec(&avc->avc_cache.active_nodes);
     443                 :          0 : }
     444                 :            : 
     445                 :          0 : static void avc_node_kill(struct selinux_avc *avc, struct avc_node *node)
     446                 :            : {
     447                 :          0 :         avc_xperms_free(node->ae.xp_node);
     448                 :          0 :         kmem_cache_free(avc_node_cachep, node);
     449                 :          0 :         avc_cache_stats_incr(frees);
     450                 :          0 :         atomic_dec(&avc->avc_cache.active_nodes);
     451                 :          0 : }
     452                 :            : 
     453                 :          0 : static void avc_node_replace(struct selinux_avc *avc,
     454                 :            :                              struct avc_node *new, struct avc_node *old)
     455                 :            : {
     456                 :          0 :         hlist_replace_rcu(&old->list, &new->list);
     457                 :          0 :         call_rcu(&old->rhead, avc_node_free);
     458                 :          0 :         atomic_dec(&avc->avc_cache.active_nodes);
     459                 :          0 : }
     460                 :            : 
     461                 :          0 : static inline int avc_reclaim_node(struct selinux_avc *avc)
     462                 :            : {
     463                 :          0 :         struct avc_node *node;
     464                 :          0 :         int hvalue, try, ecx;
     465                 :          0 :         unsigned long flags;
     466                 :          0 :         struct hlist_head *head;
     467                 :          0 :         spinlock_t *lock;
     468                 :            : 
     469         [ #  # ]:          0 :         for (try = 0, ecx = 0; try < AVC_CACHE_SLOTS; try++) {
     470                 :          0 :                 hvalue = atomic_inc_return(&avc->avc_cache.lru_hint) &
     471                 :            :                         (AVC_CACHE_SLOTS - 1);
     472                 :          0 :                 head = &avc->avc_cache.slots[hvalue];
     473                 :          0 :                 lock = &avc->avc_cache.slots_lock[hvalue];
     474                 :            : 
     475         [ #  # ]:          0 :                 if (!spin_trylock_irqsave(lock, flags))
     476                 :          0 :                         continue;
     477                 :            : 
     478                 :          0 :                 rcu_read_lock();
     479   [ #  #  #  #  :          0 :                 hlist_for_each_entry(node, head, list) {
                   #  # ]
     480                 :          0 :                         avc_node_delete(avc, node);
     481                 :          0 :                         avc_cache_stats_incr(reclaims);
     482                 :          0 :                         ecx++;
     483         [ #  # ]:          0 :                         if (ecx >= AVC_CACHE_RECLAIM) {
     484                 :          0 :                                 rcu_read_unlock();
     485                 :          0 :                                 spin_unlock_irqrestore(lock, flags);
     486                 :          0 :                                 goto out;
     487                 :            :                         }
     488                 :            :                 }
     489                 :          0 :                 rcu_read_unlock();
     490                 :          0 :                 spin_unlock_irqrestore(lock, flags);
     491                 :            :         }
     492                 :          0 : out:
     493                 :          0 :         return ecx;
     494                 :            : }
     495                 :            : 
     496                 :         84 : static struct avc_node *avc_alloc_node(struct selinux_avc *avc)
     497                 :            : {
     498                 :         84 :         struct avc_node *node;
     499                 :            : 
     500                 :         84 :         node = kmem_cache_zalloc(avc_node_cachep, GFP_NOWAIT);
     501         [ -  + ]:         84 :         if (!node)
     502                 :          0 :                 goto out;
     503                 :            : 
     504                 :         84 :         INIT_HLIST_NODE(&node->list);
     505                 :         84 :         avc_cache_stats_incr(allocations);
     506                 :            : 
     507                 :         84 :         if (atomic_inc_return(&avc->avc_cache.active_nodes) >
     508         [ +  - ]:         84 :             avc->avc_cache_threshold)
     509                 :          0 :                 avc_reclaim_node(avc);
     510                 :            : 
     511                 :         84 : out:
     512                 :         84 :         return node;
     513                 :            : }
     514                 :            : 
     515                 :         84 : static void avc_node_populate(struct avc_node *node, u32 ssid, u32 tsid, u16 tclass, struct av_decision *avd)
     516                 :            : {
     517                 :         84 :         node->ae.ssid = ssid;
     518                 :         84 :         node->ae.tsid = tsid;
     519                 :         84 :         node->ae.tclass = tclass;
     520                 :         84 :         memcpy(&node->ae.avd, avd, sizeof(node->ae.avd));
     521                 :            : }
     522                 :            : 
     523                 :    1675462 : static inline struct avc_node *avc_search_node(struct selinux_avc *avc,
     524                 :            :                                                u32 ssid, u32 tsid, u16 tclass)
     525                 :            : {
     526                 :    1675462 :         struct avc_node *node, *ret = NULL;
     527                 :    1675462 :         int hvalue;
     528                 :    1675462 :         struct hlist_head *head;
     529                 :            : 
     530                 :    1675462 :         hvalue = avc_hash(ssid, tsid, tclass);
     531                 :    1675462 :         head = &avc->avc_cache.slots[hvalue];
     532   [ +  +  +  +  :    3505070 :         hlist_for_each_entry_rcu(node, head, list) {
                   +  + ]
     533         [ +  - ]:    1829519 :                 if (ssid == node->ae.ssid &&
     534         [ +  + ]:    1829519 :                     tclass == node->ae.tclass &&
     535         [ -  + ]:    1675378 :                     tsid == node->ae.tsid) {
     536                 :            :                         ret = node;
     537                 :            :                         break;
     538                 :            :                 }
     539                 :            :         }
     540                 :            : 
     541                 :    1675462 :         return ret;
     542                 :            : }
     543                 :            : 
     544                 :            : /**
     545                 :            :  * avc_lookup - Look up an AVC entry.
     546                 :            :  * @ssid: source security identifier
     547                 :            :  * @tsid: target security identifier
     548                 :            :  * @tclass: target security class
     549                 :            :  *
     550                 :            :  * Look up an AVC entry that is valid for the
     551                 :            :  * (@ssid, @tsid), interpreting the permissions
     552                 :            :  * based on @tclass.  If a valid AVC entry exists,
     553                 :            :  * then this function returns the avc_node.
     554                 :            :  * Otherwise, this function returns NULL.
     555                 :            :  */
     556                 :    1675462 : static struct avc_node *avc_lookup(struct selinux_avc *avc,
     557                 :            :                                    u32 ssid, u32 tsid, u16 tclass)
     558                 :            : {
     559                 :    1675462 :         struct avc_node *node;
     560                 :            : 
     561                 :    3350920 :         avc_cache_stats_incr(lookups);
     562                 :    1675462 :         node = avc_search_node(avc, ssid, tsid, tclass);
     563                 :            : 
     564   [ +  +  -  + ]:    1675462 :         if (node)
     565                 :            :                 return node;
     566                 :            : 
     567                 :         84 :         avc_cache_stats_incr(misses);
     568                 :         84 :         return NULL;
     569                 :            : }
     570                 :            : 
     571                 :            : static int avc_latest_notif_update(struct selinux_avc *avc,
     572                 :            :                                    int seqno, int is_insert)
     573                 :            : {
     574                 :            :         int ret = 0;
     575                 :            :         static DEFINE_SPINLOCK(notif_lock);
     576                 :            :         unsigned long flag;
     577                 :            : 
     578                 :            :         spin_lock_irqsave(&notif_lock, flag);
     579                 :            :         if (is_insert) {
     580                 :            :                 if (seqno < avc->avc_cache.latest_notif) {
     581                 :            :                         pr_warn("SELinux: avc:  seqno %d < latest_notif %d\n",
     582                 :            :                                seqno, avc->avc_cache.latest_notif);
     583                 :            :                         ret = -EAGAIN;
     584                 :            :                 }
     585                 :            :         } else {
     586                 :            :                 if (seqno > avc->avc_cache.latest_notif)
     587                 :            :                         avc->avc_cache.latest_notif = seqno;
     588                 :            :         }
     589                 :            :         spin_unlock_irqrestore(&notif_lock, flag);
     590                 :            : 
     591                 :            :         return ret;
     592                 :            : }
     593                 :            : 
     594                 :            : /**
     595                 :            :  * avc_insert - Insert an AVC entry.
     596                 :            :  * @ssid: source security identifier
     597                 :            :  * @tsid: target security identifier
     598                 :            :  * @tclass: target security class
     599                 :            :  * @avd: resulting av decision
     600                 :            :  * @xp_node: resulting extended permissions
     601                 :            :  *
     602                 :            :  * Insert an AVC entry for the SID pair
     603                 :            :  * (@ssid, @tsid) and class @tclass.
     604                 :            :  * The access vectors and the sequence number are
     605                 :            :  * normally provided by the security server in
     606                 :            :  * response to a security_compute_av() call.  If the
     607                 :            :  * sequence number @avd->seqno is not less than the latest
     608                 :            :  * revocation notification, then the function copies
     609                 :            :  * the access vectors into a cache entry, returns
     610                 :            :  * avc_node inserted. Otherwise, this function returns NULL.
     611                 :            :  */
     612                 :         84 : static struct avc_node *avc_insert(struct selinux_avc *avc,
     613                 :            :                                    u32 ssid, u32 tsid, u16 tclass,
     614                 :            :                                    struct av_decision *avd,
     615                 :            :                                    struct avc_xperms_node *xp_node)
     616                 :            : {
     617                 :         84 :         struct avc_node *pos, *node = NULL;
     618                 :         84 :         int hvalue;
     619                 :         84 :         unsigned long flag;
     620                 :         84 :         spinlock_t *lock;
     621                 :         84 :         struct hlist_head *head;
     622                 :            : 
     623         [ +  - ]:         84 :         if (avc_latest_notif_update(avc, avd->seqno, 1))
     624                 :            :                 return NULL;
     625                 :            : 
     626                 :         84 :         node = avc_alloc_node(avc);
     627         [ +  - ]:         84 :         if (!node)
     628                 :            :                 return NULL;
     629                 :            : 
     630                 :         84 :         avc_node_populate(node, ssid, tsid, tclass, avd);
     631         [ -  + ]:         84 :         if (avc_xperms_populate(node, xp_node)) {
     632                 :          0 :                 avc_node_kill(avc, node);
     633                 :          0 :                 return NULL;
     634                 :            :         }
     635                 :            : 
     636                 :         84 :         hvalue = avc_hash(ssid, tsid, tclass);
     637                 :         84 :         head = &avc->avc_cache.slots[hvalue];
     638                 :         84 :         lock = &avc->avc_cache.slots_lock[hvalue];
     639                 :         84 :         spin_lock_irqsave(lock, flag);
     640   [ +  +  -  +  :        174 :         hlist_for_each_entry(pos, head, list) {
                   +  + ]
     641         [ +  - ]:          6 :                 if (pos->ae.ssid == ssid &&
     642         [ +  + ]:          6 :                         pos->ae.tsid == tsid &&
     643         [ -  + ]:          3 :                         pos->ae.tclass == tclass) {
     644                 :          0 :                         avc_node_replace(avc, node, pos);
     645                 :          0 :                         goto found;
     646                 :            :                 }
     647                 :            :         }
     648                 :         84 :         hlist_add_head_rcu(&node->list, head);
     649                 :         84 : found:
     650                 :         84 :         spin_unlock_irqrestore(lock, flag);
     651                 :         84 :         return node;
     652                 :            : }
     653                 :            : 
     654                 :            : /**
     655                 :            :  * avc_audit_pre_callback - SELinux specific information
     656                 :            :  * will be called by generic audit code
     657                 :            :  * @ab: the audit buffer
     658                 :            :  * @a: audit_data
     659                 :            :  */
     660                 :          0 : static void avc_audit_pre_callback(struct audit_buffer *ab, void *a)
     661                 :            : {
     662                 :          0 :         struct common_audit_data *ad = a;
     663                 :          0 :         struct selinux_audit_data *sad = ad->selinux_audit_data;
     664                 :          0 :         u32 av = sad->audited;
     665                 :          0 :         const char **perms;
     666                 :          0 :         int i, perm;
     667                 :            : 
     668         [ #  # ]:          0 :         audit_log_format(ab, "avc:  %s ", sad->denied ? "denied" : "granted");
     669                 :            : 
     670         [ #  # ]:          0 :         if (av == 0) {
     671                 :          0 :                 audit_log_format(ab, " null");
     672                 :          0 :                 return;
     673                 :            :         }
     674                 :            : 
     675                 :          0 :         perms = secclass_map[sad->tclass-1].perms;
     676                 :            : 
     677                 :          0 :         audit_log_format(ab, " {");
     678                 :          0 :         i = 0;
     679                 :          0 :         perm = 1;
     680         [ #  # ]:          0 :         while (i < (sizeof(av) * 8)) {
     681   [ #  #  #  # ]:          0 :                 if ((perm & av) && perms[i]) {
     682                 :          0 :                         audit_log_format(ab, " %s", perms[i]);
     683                 :          0 :                         av &= ~perm;
     684                 :            :                 }
     685                 :          0 :                 i++;
     686                 :          0 :                 perm <<= 1;
     687                 :            :         }
     688                 :            : 
     689         [ #  # ]:          0 :         if (av)
     690                 :          0 :                 audit_log_format(ab, " 0x%x", av);
     691                 :            : 
     692                 :          0 :         audit_log_format(ab, " } for ");
     693                 :            : }
     694                 :            : 
     695                 :            : /**
     696                 :            :  * avc_audit_post_callback - SELinux specific information
     697                 :            :  * will be called by generic audit code
     698                 :            :  * @ab: the audit buffer
     699                 :            :  * @a: audit_data
     700                 :            :  */
     701                 :          0 : static void avc_audit_post_callback(struct audit_buffer *ab, void *a)
     702                 :            : {
     703                 :          0 :         struct common_audit_data *ad = a;
     704                 :          0 :         struct selinux_audit_data *sad = ad->selinux_audit_data;
     705                 :          0 :         char *scontext;
     706                 :          0 :         u32 scontext_len;
     707                 :          0 :         int rc;
     708                 :            : 
     709                 :          0 :         rc = security_sid_to_context(sad->state, sad->ssid, &scontext,
     710                 :            :                                      &scontext_len);
     711         [ #  # ]:          0 :         if (rc)
     712                 :          0 :                 audit_log_format(ab, " ssid=%d", sad->ssid);
     713                 :            :         else {
     714                 :          0 :                 audit_log_format(ab, " scontext=%s", scontext);
     715                 :          0 :                 kfree(scontext);
     716                 :            :         }
     717                 :            : 
     718                 :          0 :         rc = security_sid_to_context(sad->state, sad->tsid, &scontext,
     719                 :            :                                      &scontext_len);
     720         [ #  # ]:          0 :         if (rc)
     721                 :          0 :                 audit_log_format(ab, " tsid=%d", sad->tsid);
     722                 :            :         else {
     723                 :          0 :                 audit_log_format(ab, " tcontext=%s", scontext);
     724                 :          0 :                 kfree(scontext);
     725                 :            :         }
     726                 :            : 
     727                 :          0 :         audit_log_format(ab, " tclass=%s", secclass_map[sad->tclass-1].name);
     728                 :            : 
     729         [ #  # ]:          0 :         if (sad->denied)
     730                 :          0 :                 audit_log_format(ab, " permissive=%u", sad->result ? 0 : 1);
     731                 :            : 
     732                 :            :         /* in case of invalid context report also the actual context string */
     733                 :          0 :         rc = security_sid_to_context_inval(sad->state, sad->ssid, &scontext,
     734                 :            :                                            &scontext_len);
     735   [ #  #  #  # ]:          0 :         if (!rc && scontext) {
     736   [ #  #  #  # ]:          0 :                 if (scontext_len && scontext[scontext_len - 1] == '\0')
     737                 :          0 :                         scontext_len--;
     738                 :          0 :                 audit_log_format(ab, " srawcon=");
     739                 :          0 :                 audit_log_n_untrustedstring(ab, scontext, scontext_len);
     740                 :          0 :                 kfree(scontext);
     741                 :            :         }
     742                 :            : 
     743                 :          0 :         rc = security_sid_to_context_inval(sad->state, sad->tsid, &scontext,
     744                 :            :                                            &scontext_len);
     745   [ #  #  #  # ]:          0 :         if (!rc && scontext) {
     746   [ #  #  #  # ]:          0 :                 if (scontext_len && scontext[scontext_len - 1] == '\0')
     747                 :          0 :                         scontext_len--;
     748                 :          0 :                 audit_log_format(ab, " trawcon=");
     749                 :          0 :                 audit_log_n_untrustedstring(ab, scontext, scontext_len);
     750                 :          0 :                 kfree(scontext);
     751                 :            :         }
     752                 :          0 : }
     753                 :            : 
     754                 :            : /* This is the slow part of avc audit with big stack footprint */
     755                 :          0 : noinline int slow_avc_audit(struct selinux_state *state,
     756                 :            :                             u32 ssid, u32 tsid, u16 tclass,
     757                 :            :                             u32 requested, u32 audited, u32 denied, int result,
     758                 :            :                             struct common_audit_data *a)
     759                 :            : {
     760                 :          0 :         struct common_audit_data stack_data;
     761                 :          0 :         struct selinux_audit_data sad;
     762                 :            : 
     763   [ #  #  #  # ]:          0 :         if (WARN_ON(!tclass || tclass >= ARRAY_SIZE(secclass_map)))
     764                 :            :                 return -EINVAL;
     765                 :            : 
     766         [ #  # ]:          0 :         if (!a) {
     767                 :          0 :                 a = &stack_data;
     768                 :          0 :                 a->type = LSM_AUDIT_DATA_NONE;
     769                 :            :         }
     770                 :            : 
     771                 :          0 :         sad.tclass = tclass;
     772                 :          0 :         sad.requested = requested;
     773                 :          0 :         sad.ssid = ssid;
     774                 :          0 :         sad.tsid = tsid;
     775                 :          0 :         sad.audited = audited;
     776                 :          0 :         sad.denied = denied;
     777                 :          0 :         sad.result = result;
     778                 :          0 :         sad.state = state;
     779                 :            : 
     780                 :          0 :         a->selinux_audit_data = &sad;
     781                 :            : 
     782                 :          0 :         common_lsm_audit(a, avc_audit_pre_callback, avc_audit_post_callback);
     783                 :          0 :         return 0;
     784                 :            : }
     785                 :            : 
     786                 :            : /**
     787                 :            :  * avc_add_callback - Register a callback for security events.
     788                 :            :  * @callback: callback function
     789                 :            :  * @events: security events
     790                 :            :  *
     791                 :            :  * Register a callback function for events in the set @events.
     792                 :            :  * Returns %0 on success or -%ENOMEM if insufficient memory
     793                 :            :  * exists to add the callback.
     794                 :            :  */
     795                 :          9 : int __init avc_add_callback(int (*callback)(u32 event), u32 events)
     796                 :            : {
     797                 :          9 :         struct avc_callback_node *c;
     798                 :          9 :         int rc = 0;
     799                 :            : 
     800                 :          9 :         c = kmalloc(sizeof(*c), GFP_KERNEL);
     801         [ -  + ]:          9 :         if (!c) {
     802                 :          0 :                 rc = -ENOMEM;
     803                 :          0 :                 goto out;
     804                 :            :         }
     805                 :            : 
     806                 :          9 :         c->callback = callback;
     807                 :          9 :         c->events = events;
     808                 :          9 :         c->next = avc_callbacks;
     809                 :          9 :         avc_callbacks = c;
     810                 :          9 : out:
     811                 :          9 :         return rc;
     812                 :            : }
     813                 :            : 
     814                 :            : /**
     815                 :            :  * avc_update_node Update an AVC entry
     816                 :            :  * @event : Updating event
     817                 :            :  * @perms : Permission mask bits
     818                 :            :  * @ssid,@tsid,@tclass : identifier of an AVC entry
     819                 :            :  * @seqno : sequence number when decision was made
     820                 :            :  * @xpd: extended_perms_decision to be added to the node
     821                 :            :  * @flags: the AVC_* flags, e.g. AVC_NONBLOCKING, AVC_EXTENDED_PERMS, or 0.
     822                 :            :  *
     823                 :            :  * if a valid AVC entry doesn't exist,this function returns -ENOENT.
     824                 :            :  * if kmalloc() called internal returns NULL, this function returns -ENOMEM.
     825                 :            :  * otherwise, this function updates the AVC entry. The original AVC-entry object
     826                 :            :  * will release later by RCU.
     827                 :            :  */
     828                 :          0 : static int avc_update_node(struct selinux_avc *avc,
     829                 :            :                            u32 event, u32 perms, u8 driver, u8 xperm, u32 ssid,
     830                 :            :                            u32 tsid, u16 tclass, u32 seqno,
     831                 :            :                            struct extended_perms_decision *xpd,
     832                 :            :                            u32 flags)
     833                 :            : {
     834                 :          0 :         int hvalue, rc = 0;
     835                 :          0 :         unsigned long flag;
     836                 :          0 :         struct avc_node *pos, *node, *orig = NULL;
     837                 :          0 :         struct hlist_head *head;
     838                 :          0 :         spinlock_t *lock;
     839                 :            : 
     840                 :            :         /*
     841                 :            :          * If we are in a non-blocking code path, e.g. VFS RCU walk,
     842                 :            :          * then we must not add permissions to a cache entry
     843                 :            :          * because we will not audit the denial.  Otherwise,
     844                 :            :          * during the subsequent blocking retry (e.g. VFS ref walk), we
     845                 :            :          * will find the permissions already granted in the cache entry
     846                 :            :          * and won't audit anything at all, leading to silent denials in
     847                 :            :          * permissive mode that only appear when in enforcing mode.
     848                 :            :          *
     849                 :            :          * See the corresponding handling of MAY_NOT_BLOCK in avc_audit()
     850                 :            :          * and selinux_inode_permission().
     851                 :            :          */
     852         [ #  # ]:          0 :         if (flags & AVC_NONBLOCKING)
     853                 :            :                 return 0;
     854                 :            : 
     855                 :          0 :         node = avc_alloc_node(avc);
     856         [ #  # ]:          0 :         if (!node) {
     857                 :          0 :                 rc = -ENOMEM;
     858                 :          0 :                 goto out;
     859                 :            :         }
     860                 :            : 
     861                 :            :         /* Lock the target slot */
     862                 :          0 :         hvalue = avc_hash(ssid, tsid, tclass);
     863                 :            : 
     864                 :          0 :         head = &avc->avc_cache.slots[hvalue];
     865                 :          0 :         lock = &avc->avc_cache.slots_lock[hvalue];
     866                 :            : 
     867                 :          0 :         spin_lock_irqsave(lock, flag);
     868                 :            : 
     869   [ #  #  #  #  :          0 :         hlist_for_each_entry(pos, head, list) {
                   #  # ]
     870         [ #  # ]:          0 :                 if (ssid == pos->ae.ssid &&
     871         [ #  # ]:          0 :                     tsid == pos->ae.tsid &&
     872         [ #  # ]:          0 :                     tclass == pos->ae.tclass &&
     873         [ #  # ]:          0 :                     seqno == pos->ae.avd.seqno){
     874                 :            :                         orig = pos;
     875                 :            :                         break;
     876                 :            :                 }
     877                 :            :         }
     878                 :            : 
     879         [ #  # ]:          0 :         if (!orig) {
     880                 :          0 :                 rc = -ENOENT;
     881                 :          0 :                 avc_node_kill(avc, node);
     882                 :          0 :                 goto out_unlock;
     883                 :            :         }
     884                 :            : 
     885                 :            :         /*
     886                 :            :          * Copy and replace original node.
     887                 :            :          */
     888                 :            : 
     889                 :          0 :         avc_node_populate(node, ssid, tsid, tclass, &orig->ae.avd);
     890                 :            : 
     891         [ #  # ]:          0 :         if (orig->ae.xp_node) {
     892                 :          0 :                 rc = avc_xperms_populate(node, orig->ae.xp_node);
     893         [ #  # ]:          0 :                 if (rc) {
     894                 :          0 :                         avc_node_kill(avc, node);
     895                 :          0 :                         goto out_unlock;
     896                 :            :                 }
     897                 :            :         }
     898                 :            : 
     899   [ #  #  #  #  :          0 :         switch (event) {
             #  #  #  # ]
     900                 :          0 :         case AVC_CALLBACK_GRANT:
     901                 :          0 :                 node->ae.avd.allowed |= perms;
     902   [ #  #  #  # ]:          0 :                 if (node->ae.xp_node && (flags & AVC_EXTENDED_PERMS))
     903                 :          0 :                         avc_xperms_allow_perm(node->ae.xp_node, driver, xperm);
     904                 :            :                 break;
     905                 :          0 :         case AVC_CALLBACK_TRY_REVOKE:
     906                 :            :         case AVC_CALLBACK_REVOKE:
     907                 :          0 :                 node->ae.avd.allowed &= ~perms;
     908                 :          0 :                 break;
     909                 :          0 :         case AVC_CALLBACK_AUDITALLOW_ENABLE:
     910                 :          0 :                 node->ae.avd.auditallow |= perms;
     911                 :          0 :                 break;
     912                 :          0 :         case AVC_CALLBACK_AUDITALLOW_DISABLE:
     913                 :          0 :                 node->ae.avd.auditallow &= ~perms;
     914                 :          0 :                 break;
     915                 :          0 :         case AVC_CALLBACK_AUDITDENY_ENABLE:
     916                 :          0 :                 node->ae.avd.auditdeny |= perms;
     917                 :          0 :                 break;
     918                 :          0 :         case AVC_CALLBACK_AUDITDENY_DISABLE:
     919                 :          0 :                 node->ae.avd.auditdeny &= ~perms;
     920                 :          0 :                 break;
     921                 :          0 :         case AVC_CALLBACK_ADD_XPERMS:
     922                 :          0 :                 avc_add_xperms_decision(node, xpd);
     923                 :          0 :                 break;
     924                 :            :         }
     925                 :          0 :         avc_node_replace(avc, node, orig);
     926                 :          0 : out_unlock:
     927                 :          0 :         spin_unlock_irqrestore(lock, flag);
     928                 :            : out:
     929                 :            :         return rc;
     930                 :            : }
     931                 :            : 
     932                 :            : /**
     933                 :            :  * avc_flush - Flush the cache
     934                 :            :  */
     935                 :          0 : static void avc_flush(struct selinux_avc *avc)
     936                 :            : {
     937                 :          0 :         struct hlist_head *head;
     938                 :          0 :         struct avc_node *node;
     939                 :          0 :         spinlock_t *lock;
     940                 :          0 :         unsigned long flag;
     941                 :          0 :         int i;
     942                 :            : 
     943         [ #  # ]:          0 :         for (i = 0; i < AVC_CACHE_SLOTS; i++) {
     944                 :          0 :                 head = &avc->avc_cache.slots[i];
     945                 :          0 :                 lock = &avc->avc_cache.slots_lock[i];
     946                 :            : 
     947                 :          0 :                 spin_lock_irqsave(lock, flag);
     948                 :            :                 /*
     949                 :            :                  * With preemptable RCU, the outer spinlock does not
     950                 :            :                  * prevent RCU grace periods from ending.
     951                 :            :                  */
     952                 :          0 :                 rcu_read_lock();
     953   [ #  #  #  #  :          0 :                 hlist_for_each_entry(node, head, list)
                   #  # ]
     954                 :          0 :                         avc_node_delete(avc, node);
     955                 :          0 :                 rcu_read_unlock();
     956                 :          0 :                 spin_unlock_irqrestore(lock, flag);
     957                 :            :         }
     958                 :          0 : }
     959                 :            : 
     960                 :            : /**
     961                 :            :  * avc_ss_reset - Flush the cache and revalidate migrated permissions.
     962                 :            :  * @seqno: policy sequence number
     963                 :            :  */
     964                 :          0 : int avc_ss_reset(struct selinux_avc *avc, u32 seqno)
     965                 :            : {
     966                 :          0 :         struct avc_callback_node *c;
     967                 :          0 :         int rc = 0, tmprc;
     968                 :            : 
     969                 :          0 :         avc_flush(avc);
     970                 :            : 
     971         [ #  # ]:          0 :         for (c = avc_callbacks; c; c = c->next) {
     972         [ #  # ]:          0 :                 if (c->events & AVC_CALLBACK_RESET) {
     973                 :          0 :                         tmprc = c->callback(AVC_CALLBACK_RESET);
     974                 :            :                         /* save the first error encountered for the return
     975                 :            :                            value and continue processing the callbacks */
     976         [ #  # ]:          0 :                         if (!rc)
     977                 :          0 :                                 rc = tmprc;
     978                 :            :                 }
     979                 :            :         }
     980                 :            : 
     981                 :          0 :         avc_latest_notif_update(avc, seqno, 0);
     982                 :          0 :         return rc;
     983                 :            : }
     984                 :            : 
     985                 :            : /*
     986                 :            :  * Slow-path helper function for avc_has_perm_noaudit,
     987                 :            :  * when the avc_node lookup fails. We get called with
     988                 :            :  * the RCU read lock held, and need to return with it
     989                 :            :  * still held, but drop if for the security compute.
     990                 :            :  *
     991                 :            :  * Don't inline this, since it's the slow-path and just
     992                 :            :  * results in a bigger stack frame.
     993                 :            :  */
     994                 :            : static noinline
     995                 :         84 : struct avc_node *avc_compute_av(struct selinux_state *state,
     996                 :            :                                 u32 ssid, u32 tsid,
     997                 :            :                                 u16 tclass, struct av_decision *avd,
     998                 :            :                                 struct avc_xperms_node *xp_node)
     999                 :            : {
    1000                 :         84 :         rcu_read_unlock();
    1001                 :         84 :         INIT_LIST_HEAD(&xp_node->xpd_head);
    1002                 :         84 :         security_compute_av(state, ssid, tsid, tclass, avd, &xp_node->xp);
    1003                 :         84 :         rcu_read_lock();
    1004                 :         84 :         return avc_insert(state->avc, ssid, tsid, tclass, avd, xp_node);
    1005                 :            : }
    1006                 :            : 
    1007                 :          0 : static noinline int avc_denied(struct selinux_state *state,
    1008                 :            :                                u32 ssid, u32 tsid,
    1009                 :            :                                u16 tclass, u32 requested,
    1010                 :            :                                u8 driver, u8 xperm, unsigned int flags,
    1011                 :            :                                struct av_decision *avd)
    1012                 :            : {
    1013         [ #  # ]:          0 :         if (flags & AVC_STRICT)
    1014                 :            :                 return -EACCES;
    1015                 :            : 
    1016         [ #  # ]:          0 :         if (enforcing_enabled(state) &&
    1017         [ #  # ]:          0 :             !(avd->flags & AVD_FLAGS_PERMISSIVE))
    1018                 :            :                 return -EACCES;
    1019                 :            : 
    1020                 :          0 :         avc_update_node(state->avc, AVC_CALLBACK_GRANT, requested, driver,
    1021                 :            :                         xperm, ssid, tsid, tclass, avd->seqno, NULL, flags);
    1022                 :          0 :         return 0;
    1023                 :            : }
    1024                 :            : 
    1025                 :            : /*
    1026                 :            :  * The avc extended permissions logic adds an additional 256 bits of
    1027                 :            :  * permissions to an avc node when extended permissions for that node are
    1028                 :            :  * specified in the avtab. If the additional 256 permissions is not adequate,
    1029                 :            :  * as-is the case with ioctls, then multiple may be chained together and the
    1030                 :            :  * driver field is used to specify which set contains the permission.
    1031                 :            :  */
    1032                 :       1167 : int avc_has_extended_perms(struct selinux_state *state,
    1033                 :            :                            u32 ssid, u32 tsid, u16 tclass, u32 requested,
    1034                 :            :                            u8 driver, u8 xperm, struct common_audit_data *ad)
    1035                 :            : {
    1036                 :       1167 :         struct avc_node *node;
    1037                 :       1167 :         struct av_decision avd;
    1038                 :       1167 :         u32 denied;
    1039                 :       1167 :         struct extended_perms_decision local_xpd;
    1040                 :       1167 :         struct extended_perms_decision *xpd = NULL;
    1041                 :       1167 :         struct extended_perms_data allowed;
    1042                 :       1167 :         struct extended_perms_data auditallow;
    1043                 :       1167 :         struct extended_perms_data dontaudit;
    1044                 :       1167 :         struct avc_xperms_node local_xp_node;
    1045                 :       1167 :         struct avc_xperms_node *xp_node;
    1046                 :       1167 :         int rc = 0, rc2;
    1047                 :            : 
    1048                 :       1167 :         xp_node = &local_xp_node;
    1049   [ -  +  +  - ]:       1167 :         if (WARN_ON(!requested))
    1050                 :            :                 return -EACCES;
    1051                 :            : 
    1052                 :       1167 :         rcu_read_lock();
    1053                 :            : 
    1054                 :       1167 :         node = avc_lookup(state->avc, ssid, tsid, tclass);
    1055         [ -  + ]:       1167 :         if (unlikely(!node)) {
    1056                 :          0 :                 node = avc_compute_av(state, ssid, tsid, tclass, &avd, xp_node);
    1057                 :            :         } else {
    1058                 :       1167 :                 memcpy(&avd, &node->ae.avd, sizeof(avd));
    1059                 :       1167 :                 xp_node = node->ae.xp_node;
    1060                 :            :         }
    1061                 :            :         /* if extended permissions are not defined, only consider av_decision */
    1062   [ -  +  -  - ]:       1167 :         if (!xp_node || !xp_node->xp.len)
    1063                 :       1167 :                 goto decision;
    1064                 :            : 
    1065                 :          0 :         local_xpd.allowed = &allowed;
    1066                 :          0 :         local_xpd.auditallow = &auditallow;
    1067                 :          0 :         local_xpd.dontaudit = &dontaudit;
    1068                 :            : 
    1069                 :          0 :         xpd = avc_xperms_decision_lookup(driver, xp_node);
    1070         [ #  # ]:          0 :         if (unlikely(!xpd)) {
    1071                 :            :                 /*
    1072                 :            :                  * Compute the extended_perms_decision only if the driver
    1073                 :            :                  * is flagged
    1074                 :            :                  */
    1075         [ #  # ]:          0 :                 if (!security_xperm_test(xp_node->xp.drivers.p, driver)) {
    1076                 :          0 :                         avd.allowed &= ~requested;
    1077                 :          0 :                         goto decision;
    1078                 :            :                 }
    1079                 :          0 :                 rcu_read_unlock();
    1080                 :          0 :                 security_compute_xperms_decision(state, ssid, tsid, tclass,
    1081                 :            :                                                  driver, &local_xpd);
    1082                 :          0 :                 rcu_read_lock();
    1083                 :          0 :                 avc_update_node(state->avc, AVC_CALLBACK_ADD_XPERMS, requested,
    1084                 :            :                                 driver, xperm, ssid, tsid, tclass, avd.seqno,
    1085                 :            :                                 &local_xpd, 0);
    1086                 :            :         } else {
    1087                 :          0 :                 avc_quick_copy_xperms_decision(xperm, &local_xpd, xpd);
    1088                 :            :         }
    1089                 :          0 :         xpd = &local_xpd;
    1090                 :            : 
    1091         [ #  # ]:          0 :         if (!avc_xperms_has_perm(xpd, xperm, XPERMS_ALLOWED))
    1092                 :          0 :                 avd.allowed &= ~requested;
    1093                 :            : 
    1094                 :          0 : decision:
    1095                 :       1167 :         denied = requested & ~(avd.allowed);
    1096         [ -  + ]:       1167 :         if (unlikely(denied))
    1097                 :          0 :                 rc = avc_denied(state, ssid, tsid, tclass, requested,
    1098                 :            :                                 driver, xperm, AVC_EXTENDED_PERMS, &avd);
    1099                 :            : 
    1100                 :       1167 :         rcu_read_unlock();
    1101                 :            : 
    1102                 :       1167 :         rc2 = avc_xperms_audit(state, ssid, tsid, tclass, requested,
    1103                 :            :                         &avd, xpd, xperm, rc, ad);
    1104         [ -  + ]:       1167 :         if (rc2)
    1105                 :          0 :                 return rc2;
    1106                 :            :         return rc;
    1107                 :            : }
    1108                 :            : 
    1109                 :            : /**
    1110                 :            :  * avc_has_perm_noaudit - Check permissions but perform no auditing.
    1111                 :            :  * @ssid: source security identifier
    1112                 :            :  * @tsid: target security identifier
    1113                 :            :  * @tclass: target security class
    1114                 :            :  * @requested: requested permissions, interpreted based on @tclass
    1115                 :            :  * @flags:  AVC_STRICT, AVC_NONBLOCKING, or 0
    1116                 :            :  * @avd: access vector decisions
    1117                 :            :  *
    1118                 :            :  * Check the AVC to determine whether the @requested permissions are granted
    1119                 :            :  * for the SID pair (@ssid, @tsid), interpreting the permissions
    1120                 :            :  * based on @tclass, and call the security server on a cache miss to obtain
    1121                 :            :  * a new decision and add it to the cache.  Return a copy of the decisions
    1122                 :            :  * in @avd.  Return %0 if all @requested permissions are granted,
    1123                 :            :  * -%EACCES if any permissions are denied, or another -errno upon
    1124                 :            :  * other errors.  This function is typically called by avc_has_perm(),
    1125                 :            :  * but may also be called directly to separate permission checking from
    1126                 :            :  * auditing, e.g. in cases where a lock must be held for the check but
    1127                 :            :  * should be released for the auditing.
    1128                 :            :  */
    1129                 :    1674295 : inline int avc_has_perm_noaudit(struct selinux_state *state,
    1130                 :            :                                 u32 ssid, u32 tsid,
    1131                 :            :                                 u16 tclass, u32 requested,
    1132                 :            :                                 unsigned int flags,
    1133                 :            :                                 struct av_decision *avd)
    1134                 :            : {
    1135                 :    1674295 :         struct avc_node *node;
    1136                 :    1674295 :         struct avc_xperms_node xp_node;
    1137                 :    1674295 :         int rc = 0;
    1138                 :    1674295 :         u32 denied;
    1139                 :            : 
    1140   [ -  +  +  - ]:    1674295 :         if (WARN_ON(!requested))
    1141                 :            :                 return -EACCES;
    1142                 :            : 
    1143                 :    1674295 :         rcu_read_lock();
    1144                 :            : 
    1145                 :    1674295 :         node = avc_lookup(state->avc, ssid, tsid, tclass);
    1146         [ +  + ]:    1674295 :         if (unlikely(!node))
    1147                 :         84 :                 node = avc_compute_av(state, ssid, tsid, tclass, avd, &xp_node);
    1148                 :            :         else
    1149                 :    1674211 :                 memcpy(avd, &node->ae.avd, sizeof(*avd));
    1150                 :            : 
    1151                 :    1674295 :         denied = requested & ~(avd->allowed);
    1152         [ -  + ]:    1674295 :         if (unlikely(denied))
    1153                 :          0 :                 rc = avc_denied(state, ssid, tsid, tclass, requested, 0, 0,
    1154                 :            :                                 flags, avd);
    1155                 :            : 
    1156                 :    1674295 :         rcu_read_unlock();
    1157                 :    1674295 :         return rc;
    1158                 :            : }
    1159                 :            : 
    1160                 :            : /**
    1161                 :            :  * avc_has_perm - Check permissions and perform any appropriate auditing.
    1162                 :            :  * @ssid: source security identifier
    1163                 :            :  * @tsid: target security identifier
    1164                 :            :  * @tclass: target security class
    1165                 :            :  * @requested: requested permissions, interpreted based on @tclass
    1166                 :            :  * @auditdata: auxiliary audit data
    1167                 :            :  *
    1168                 :            :  * Check the AVC to determine whether the @requested permissions are granted
    1169                 :            :  * for the SID pair (@ssid, @tsid), interpreting the permissions
    1170                 :            :  * based on @tclass, and call the security server on a cache miss to obtain
    1171                 :            :  * a new decision and add it to the cache.  Audit the granting or denial of
    1172                 :            :  * permissions in accordance with the policy.  Return %0 if all @requested
    1173                 :            :  * permissions are granted, -%EACCES if any permissions are denied, or
    1174                 :            :  * another -errno upon other errors.
    1175                 :            :  */
    1176                 :     555966 : int avc_has_perm(struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass,
    1177                 :            :                  u32 requested, struct common_audit_data *auditdata)
    1178                 :            : {
    1179                 :     555966 :         struct av_decision avd;
    1180                 :     555966 :         int rc, rc2;
    1181                 :            : 
    1182                 :     555966 :         rc = avc_has_perm_noaudit(state, ssid, tsid, tclass, requested, 0,
    1183                 :            :                                   &avd);
    1184                 :            : 
    1185                 :     555966 :         rc2 = avc_audit(state, ssid, tsid, tclass, requested, &avd, rc,
    1186                 :            :                         auditdata, 0);
    1187         [ -  + ]:     555966 :         if (rc2)
    1188                 :          0 :                 return rc2;
    1189                 :            :         return rc;
    1190                 :            : }
    1191                 :            : 
    1192                 :      41634 : int avc_has_perm_flags(struct selinux_state *state,
    1193                 :            :                        u32 ssid, u32 tsid, u16 tclass, u32 requested,
    1194                 :            :                        struct common_audit_data *auditdata,
    1195                 :            :                        int flags)
    1196                 :            : {
    1197                 :      41634 :         struct av_decision avd;
    1198                 :      41634 :         int rc, rc2;
    1199                 :            : 
    1200                 :      41634 :         rc = avc_has_perm_noaudit(state, ssid, tsid, tclass, requested,
    1201                 :      41634 :                                   (flags & MAY_NOT_BLOCK) ? AVC_NONBLOCKING : 0,
    1202                 :            :                                   &avd);
    1203                 :            : 
    1204                 :      41634 :         rc2 = avc_audit(state, ssid, tsid, tclass, requested, &avd, rc,
    1205                 :            :                         auditdata, flags);
    1206         [ -  + ]:      41634 :         if (rc2)
    1207                 :          0 :                 return rc2;
    1208                 :            :         return rc;
    1209                 :            : }
    1210                 :            : 
    1211                 :     144013 : u32 avc_policy_seqno(struct selinux_state *state)
    1212                 :            : {
    1213                 :     144013 :         return state->avc->avc_cache.latest_notif;
    1214                 :            : }
    1215                 :            : 
    1216                 :          0 : void avc_disable(void)
    1217                 :            : {
    1218                 :            :         /*
    1219                 :            :          * If you are looking at this because you have realized that we are
    1220                 :            :          * not destroying the avc_node_cachep it might be easy to fix, but
    1221                 :            :          * I don't know the memory barrier semantics well enough to know.  It's
    1222                 :            :          * possible that some other task dereferenced security_ops when
    1223                 :            :          * it still pointed to selinux operations.  If that is the case it's
    1224                 :            :          * possible that it is about to use the avc and is about to need the
    1225                 :            :          * avc_node_cachep.  I know I could wrap the security.c security_ops call
    1226                 :            :          * in an rcu_lock, but seriously, it's not worth it.  Instead I just flush
    1227                 :            :          * the cache and get that memory back.
    1228                 :            :          */
    1229         [ #  # ]:          0 :         if (avc_node_cachep) {
    1230                 :          0 :                 avc_flush(selinux_state.avc);
    1231                 :            :                 /* kmem_cache_destroy(avc_node_cachep); */
    1232                 :            :         }
    1233                 :          0 : }

Generated by: LCOV version 1.14