linux/security/selinux/avc.c
<<
>>
Prefs
   1/*
   2 * Implementation of the kernel access vector cache (AVC).
   3 *
   4 * Authors:  Stephen Smalley, <sds@epoch.ncsc.mil>
   5 *           James Morris <jmorris@redhat.com>
   6 *
   7 * Update:   KaiGai, Kohei <kaigai@ak.jp.nec.com>
   8 *      Replaced the avc_lock spinlock by RCU.
   9 *
  10 * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
  11 *
  12 *      This program is free software; you can redistribute it and/or modify
  13 *      it under the terms of the GNU General Public License version 2,
  14 *      as published by the Free Software Foundation.
  15 */
  16#include <linux/types.h>
  17#include <linux/stddef.h>
  18#include <linux/kernel.h>
  19#include <linux/slab.h>
  20#include <linux/fs.h>
  21#include <linux/dcache.h>
  22#include <linux/init.h>
  23#include <linux/skbuff.h>
  24#include <linux/percpu.h>
  25#include <net/sock.h>
  26#include <linux/un.h>
  27#include <net/af_unix.h>
  28#include <linux/ip.h>
  29#include <linux/audit.h>
  30#include <linux/ipv6.h>
  31#include <net/ipv6.h>
  32#include "avc.h"
  33#include "avc_ss.h"
  34#include "classmap.h"
  35
  36#define AVC_CACHE_SLOTS                 512
  37#define AVC_DEF_CACHE_THRESHOLD         512
  38#define AVC_CACHE_RECLAIM               16
  39
  40#ifdef CONFIG_SECURITY_SELINUX_AVC_STATS
  41#define avc_cache_stats_incr(field)     this_cpu_inc(avc_cache_stats.field)
  42#else
  43#define avc_cache_stats_incr(field)     do {} while (0)
  44#endif
  45
  46struct avc_entry {
  47        u32                     ssid;
  48        u32                     tsid;
  49        u16                     tclass;
  50        struct av_decision      avd;
  51};
  52
  53struct avc_node {
  54        struct avc_entry        ae;
  55        struct hlist_node       list; /* anchored in avc_cache->slots[i] */
  56        struct rcu_head         rhead;
  57};
  58
  59struct avc_cache {
  60        struct hlist_head       slots[AVC_CACHE_SLOTS]; /* head for avc_node->list */
  61        spinlock_t              slots_lock[AVC_CACHE_SLOTS]; /* lock for writes */
  62        atomic_t                lru_hint;       /* LRU hint for reclaim scan */
  63        atomic_t                active_nodes;
  64        u32                     latest_notif;   /* latest revocation notification */
  65};
  66
  67struct avc_callback_node {
  68        int (*callback) (u32 event, u32 ssid, u32 tsid,
  69                         u16 tclass, u32 perms,
  70                         u32 *out_retained);
  71        u32 events;
  72        u32 ssid;
  73        u32 tsid;
  74        u16 tclass;
  75        u32 perms;
  76        struct avc_callback_node *next;
  77};
  78
  79/* Exported via selinufs */
  80unsigned int avc_cache_threshold = AVC_DEF_CACHE_THRESHOLD;
  81
  82#ifdef CONFIG_SECURITY_SELINUX_AVC_STATS
  83DEFINE_PER_CPU(struct avc_cache_stats, avc_cache_stats) = { 0 };
  84#endif
  85
  86static struct avc_cache avc_cache;
  87static struct avc_callback_node *avc_callbacks;
  88static struct kmem_cache *avc_node_cachep;
  89
  90static inline int avc_hash(u32 ssid, u32 tsid, u16 tclass)
  91{
  92        return (ssid ^ (tsid<<2) ^ (tclass<<4)) & (AVC_CACHE_SLOTS - 1);
  93}
  94
  95/**
  96 * avc_dump_av - Display an access vector in human-readable form.
  97 * @tclass: target security class
  98 * @av: access vector
  99 */
 100static void avc_dump_av(struct audit_buffer *ab, u16 tclass, u32 av)
 101{
 102        const char **perms;
 103        int i, perm;
 104
 105        if (av == 0) {
 106                audit_log_format(ab, " null");
 107                return;
 108        }
 109
 110        perms = secclass_map[tclass-1].perms;
 111
 112        audit_log_format(ab, " {");
 113        i = 0;
 114        perm = 1;
 115        while (i < (sizeof(av) * 8)) {
 116                if ((perm & av) && perms[i]) {
 117                        audit_log_format(ab, " %s", perms[i]);
 118                        av &= ~perm;
 119                }
 120                i++;
 121                perm <<= 1;
 122        }
 123
 124        if (av)
 125                audit_log_format(ab, " 0x%x", av);
 126
 127        audit_log_format(ab, " }");
 128}
 129
 130/**
 131 * avc_dump_query - Display a SID pair and a class in human-readable form.
 132 * @ssid: source security identifier
 133 * @tsid: target security identifier
 134 * @tclass: target security class
 135 */
 136static void avc_dump_query(struct audit_buffer *ab, u32 ssid, u32 tsid, u16 tclass)
 137{
 138        int rc;
 139        char *scontext;
 140        u32 scontext_len;
 141
 142        rc = security_sid_to_context(ssid, &scontext, &scontext_len);
 143        if (rc)
 144                audit_log_format(ab, "ssid=%d", ssid);
 145        else {
 146                audit_log_format(ab, "scontext=%s", scontext);
 147                kfree(scontext);
 148        }
 149
 150        rc = security_sid_to_context(tsid, &scontext, &scontext_len);
 151        if (rc)
 152                audit_log_format(ab, " tsid=%d", tsid);
 153        else {
 154                audit_log_format(ab, " tcontext=%s", scontext);
 155                kfree(scontext);
 156        }
 157
 158        BUG_ON(tclass >= ARRAY_SIZE(secclass_map));
 159        audit_log_format(ab, " tclass=%s", secclass_map[tclass-1].name);
 160}
 161
 162/**
 163 * avc_init - Initialize the AVC.
 164 *
 165 * Initialize the access vector cache.
 166 */
 167void __init avc_init(void)
 168{
 169        int i;
 170
 171        for (i = 0; i < AVC_CACHE_SLOTS; i++) {
 172                INIT_HLIST_HEAD(&avc_cache.slots[i]);
 173                spin_lock_init(&avc_cache.slots_lock[i]);
 174        }
 175        atomic_set(&avc_cache.active_nodes, 0);
 176        atomic_set(&avc_cache.lru_hint, 0);
 177
 178        avc_node_cachep = kmem_cache_create("avc_node", sizeof(struct avc_node),
 179                                             0, SLAB_PANIC, NULL);
 180
 181        audit_log(current->audit_context, GFP_KERNEL, AUDIT_KERNEL, "AVC INITIALIZED\n");
 182}
 183
 184int avc_get_hash_stats(char *page)
 185{
 186        int i, chain_len, max_chain_len, slots_used;
 187        struct avc_node *node;
 188        struct hlist_head *head;
 189
 190        rcu_read_lock();
 191
 192        slots_used = 0;
 193        max_chain_len = 0;
 194        for (i = 0; i < AVC_CACHE_SLOTS; i++) {
 195                head = &avc_cache.slots[i];
 196                if (!hlist_empty(head)) {
 197                        struct hlist_node *next;
 198
 199                        slots_used++;
 200                        chain_len = 0;
 201                        hlist_for_each_entry_rcu(node, next, head, list)
 202                                chain_len++;
 203                        if (chain_len > max_chain_len)
 204                                max_chain_len = chain_len;
 205                }
 206        }
 207
 208        rcu_read_unlock();
 209
 210        return scnprintf(page, PAGE_SIZE, "entries: %d\nbuckets used: %d/%d\n"
 211                         "longest chain: %d\n",
 212                         atomic_read(&avc_cache.active_nodes),
 213                         slots_used, AVC_CACHE_SLOTS, max_chain_len);
 214}
 215
 216static void avc_node_free(struct rcu_head *rhead)
 217{
 218        struct avc_node *node = container_of(rhead, struct avc_node, rhead);
 219        kmem_cache_free(avc_node_cachep, node);
 220        avc_cache_stats_incr(frees);
 221}
 222
 223static void avc_node_delete(struct avc_node *node)
 224{
 225        hlist_del_rcu(&node->list);
 226        call_rcu(&node->rhead, avc_node_free);
 227        atomic_dec(&avc_cache.active_nodes);
 228}
 229
 230static void avc_node_kill(struct avc_node *node)
 231{
 232        kmem_cache_free(avc_node_cachep, node);
 233        avc_cache_stats_incr(frees);
 234        atomic_dec(&avc_cache.active_nodes);
 235}
 236
 237static void avc_node_replace(struct avc_node *new, struct avc_node *old)
 238{
 239        hlist_replace_rcu(&old->list, &new->list);
 240        call_rcu(&old->rhead, avc_node_free);
 241        atomic_dec(&avc_cache.active_nodes);
 242}
 243
 244static inline int avc_reclaim_node(void)
 245{
 246        struct avc_node *node;
 247        int hvalue, try, ecx;
 248        unsigned long flags;
 249        struct hlist_head *head;
 250        struct hlist_node *next;
 251        spinlock_t *lock;
 252
 253        for (try = 0, ecx = 0; try < AVC_CACHE_SLOTS; try++) {
 254                hvalue = atomic_inc_return(&avc_cache.lru_hint) & (AVC_CACHE_SLOTS - 1);
 255                head = &avc_cache.slots[hvalue];
 256                lock = &avc_cache.slots_lock[hvalue];
 257
 258                if (!spin_trylock_irqsave(lock, flags))
 259                        continue;
 260
 261                rcu_read_lock();
 262                hlist_for_each_entry(node, next, head, list) {
 263                        avc_node_delete(node);
 264                        avc_cache_stats_incr(reclaims);
 265                        ecx++;
 266                        if (ecx >= AVC_CACHE_RECLAIM) {
 267                                rcu_read_unlock();
 268                                spin_unlock_irqrestore(lock, flags);
 269                                goto out;
 270                        }
 271                }
 272                rcu_read_unlock();
 273                spin_unlock_irqrestore(lock, flags);
 274        }
 275out:
 276        return ecx;
 277}
 278
 279static struct avc_node *avc_alloc_node(void)
 280{
 281        struct avc_node *node;
 282
 283        node = kmem_cache_zalloc(avc_node_cachep, GFP_ATOMIC);
 284        if (!node)
 285                goto out;
 286
 287        INIT_HLIST_NODE(&node->list);
 288        avc_cache_stats_incr(allocations);
 289
 290        if (atomic_inc_return(&avc_cache.active_nodes) > avc_cache_threshold)
 291                avc_reclaim_node();
 292
 293out:
 294        return node;
 295}
 296
 297static void avc_node_populate(struct avc_node *node, u32 ssid, u32 tsid, u16 tclass, struct av_decision *avd)
 298{
 299        node->ae.ssid = ssid;
 300        node->ae.tsid = tsid;
 301        node->ae.tclass = tclass;
 302        memcpy(&node->ae.avd, avd, sizeof(node->ae.avd));
 303}
 304
 305static inline struct avc_node *avc_search_node(u32 ssid, u32 tsid, u16 tclass)
 306{
 307        struct avc_node *node, *ret = NULL;
 308        int hvalue;
 309        struct hlist_head *head;
 310        struct hlist_node *next;
 311
 312        hvalue = avc_hash(ssid, tsid, tclass);
 313        head = &avc_cache.slots[hvalue];
 314        hlist_for_each_entry_rcu(node, next, head, list) {
 315                if (ssid == node->ae.ssid &&
 316                    tclass == node->ae.tclass &&
 317                    tsid == node->ae.tsid) {
 318                        ret = node;
 319                        break;
 320                }
 321        }
 322
 323        return ret;
 324}
 325
 326/**
 327 * avc_lookup - Look up an AVC entry.
 328 * @ssid: source security identifier
 329 * @tsid: target security identifier
 330 * @tclass: target security class
 331 *
 332 * Look up an AVC entry that is valid for the
 333 * (@ssid, @tsid), interpreting the permissions
 334 * based on @tclass.  If a valid AVC entry exists,
 335 * then this function returns the avc_node.
 336 * Otherwise, this function returns NULL.
 337 */
 338static struct avc_node *avc_lookup(u32 ssid, u32 tsid, u16 tclass)
 339{
 340        struct avc_node *node;
 341
 342        avc_cache_stats_incr(lookups);
 343        node = avc_search_node(ssid, tsid, tclass);
 344
 345        if (node)
 346                return node;
 347
 348        avc_cache_stats_incr(misses);
 349        return NULL;
 350}
 351
 352static int avc_latest_notif_update(int seqno, int is_insert)
 353{
 354        int ret = 0;
 355        static DEFINE_SPINLOCK(notif_lock);
 356        unsigned long flag;
 357
 358        spin_lock_irqsave(&notif_lock, flag);
 359        if (is_insert) {
 360                if (seqno < avc_cache.latest_notif) {
 361                        printk(KERN_WARNING "SELinux: avc:  seqno %d < latest_notif %d\n",
 362                               seqno, avc_cache.latest_notif);
 363                        ret = -EAGAIN;
 364                }
 365        } else {
 366                if (seqno > avc_cache.latest_notif)
 367                        avc_cache.latest_notif = seqno;
 368        }
 369        spin_unlock_irqrestore(&notif_lock, flag);
 370
 371        return ret;
 372}
 373
 374/**
 375 * avc_insert - Insert an AVC entry.
 376 * @ssid: source security identifier
 377 * @tsid: target security identifier
 378 * @tclass: target security class
 379 * @avd: resulting av decision
 380 *
 381 * Insert an AVC entry for the SID pair
 382 * (@ssid, @tsid) and class @tclass.
 383 * The access vectors and the sequence number are
 384 * normally provided by the security server in
 385 * response to a security_compute_av() call.  If the
 386 * sequence number @avd->seqno is not less than the latest
 387 * revocation notification, then the function copies
 388 * the access vectors into a cache entry, returns
 389 * avc_node inserted. Otherwise, this function returns NULL.
 390 */
 391static struct avc_node *avc_insert(u32 ssid, u32 tsid, u16 tclass, struct av_decision *avd)
 392{
 393        struct avc_node *pos, *node = NULL;
 394        int hvalue;
 395        unsigned long flag;
 396
 397        if (avc_latest_notif_update(avd->seqno, 1))
 398                goto out;
 399
 400        node = avc_alloc_node();
 401        if (node) {
 402                struct hlist_head *head;
 403                struct hlist_node *next;
 404                spinlock_t *lock;
 405
 406                hvalue = avc_hash(ssid, tsid, tclass);
 407                avc_node_populate(node, ssid, tsid, tclass, avd);
 408
 409                head = &avc_cache.slots[hvalue];
 410                lock = &avc_cache.slots_lock[hvalue];
 411
 412                spin_lock_irqsave(lock, flag);
 413                hlist_for_each_entry(pos, next, head, list) {
 414                        if (pos->ae.ssid == ssid &&
 415                            pos->ae.tsid == tsid &&
 416                            pos->ae.tclass == tclass) {
 417                                avc_node_replace(node, pos);
 418                                goto found;
 419                        }
 420                }
 421                hlist_add_head_rcu(&node->list, head);
 422found:
 423                spin_unlock_irqrestore(lock, flag);
 424        }
 425out:
 426        return node;
 427}
 428
 429/**
 430 * avc_audit_pre_callback - SELinux specific information
 431 * will be called by generic audit code
 432 * @ab: the audit buffer
 433 * @a: audit_data
 434 */
 435static void avc_audit_pre_callback(struct audit_buffer *ab, void *a)
 436{
 437        struct common_audit_data *ad = a;
 438        audit_log_format(ab, "avc:  %s ",
 439                         ad->selinux_audit_data.denied ? "denied" : "granted");
 440        avc_dump_av(ab, ad->selinux_audit_data.tclass,
 441                        ad->selinux_audit_data.audited);
 442        audit_log_format(ab, " for ");
 443}
 444
 445/**
 446 * avc_audit_post_callback - SELinux specific information
 447 * will be called by generic audit code
 448 * @ab: the audit buffer
 449 * @a: audit_data
 450 */
 451static void avc_audit_post_callback(struct audit_buffer *ab, void *a)
 452{
 453        struct common_audit_data *ad = a;
 454        audit_log_format(ab, " ");
 455        avc_dump_query(ab, ad->selinux_audit_data.ssid,
 456                           ad->selinux_audit_data.tsid,
 457                           ad->selinux_audit_data.tclass);
 458}
 459
 460/**
 461 * avc_audit - Audit the granting or denial of permissions.
 462 * @ssid: source security identifier
 463 * @tsid: target security identifier
 464 * @tclass: target security class
 465 * @requested: requested permissions
 466 * @avd: access vector decisions
 467 * @result: result from avc_has_perm_noaudit
 468 * @a:  auxiliary audit data
 469 * @flags: VFS walk flags
 470 *
 471 * Audit the granting or denial of permissions in accordance
 472 * with the policy.  This function is typically called by
 473 * avc_has_perm() after a permission check, but can also be
 474 * called directly by callers who use avc_has_perm_noaudit()
 475 * in order to separate the permission check from the auditing.
 476 * For example, this separation is useful when the permission check must
 477 * be performed under a lock, to allow the lock to be released
 478 * before calling the auditing code.
 479 */
 480int avc_audit(u32 ssid, u32 tsid,
 481               u16 tclass, u32 requested,
 482               struct av_decision *avd, int result, struct common_audit_data *a,
 483               unsigned flags)
 484{
 485        struct common_audit_data stack_data;
 486        u32 denied, audited;
 487        denied = requested & ~avd->allowed;
 488        if (denied) {
 489                audited = denied & avd->auditdeny;
 490                /*
 491                 * a->selinux_audit_data.auditdeny is TRICKY!  Setting a bit in
 492                 * this field means that ANY denials should NOT be audited if
 493                 * the policy contains an explicit dontaudit rule for that
 494                 * permission.  Take notice that this is unrelated to the
 495                 * actual permissions that were denied.  As an example lets
 496                 * assume:
 497                 *
 498                 * denied == READ
 499                 * avd.auditdeny & ACCESS == 0 (not set means explicit rule)
 500                 * selinux_audit_data.auditdeny & ACCESS == 1
 501                 *
 502                 * We will NOT audit the denial even though the denied
 503                 * permission was READ and the auditdeny checks were for
 504                 * ACCESS
 505                 */
 506                if (a &&
 507                    a->selinux_audit_data.auditdeny &&
 508                    !(a->selinux_audit_data.auditdeny & avd->auditdeny))
 509                        audited = 0;
 510        } else if (result)
 511                audited = denied = requested;
 512        else
 513                audited = requested & avd->auditallow;
 514        if (!audited)
 515                return 0;
 516
 517        if (!a) {
 518                a = &stack_data;
 519                COMMON_AUDIT_DATA_INIT(a, NONE);
 520        }
 521
 522        /*
 523         * When in a RCU walk do the audit on the RCU retry.  This is because
 524         * the collection of the dname in an inode audit message is not RCU
 525         * safe.  Note this may drop some audits when the situation changes
 526         * during retry. However this is logically just as if the operation
 527         * happened a little later.
 528         */
 529        if ((a->type == LSM_AUDIT_DATA_INODE) &&
 530            (flags & MAY_NOT_BLOCK))
 531                return -ECHILD;
 532
 533        a->selinux_audit_data.tclass = tclass;
 534        a->selinux_audit_data.requested = requested;
 535        a->selinux_audit_data.ssid = ssid;
 536        a->selinux_audit_data.tsid = tsid;
 537        a->selinux_audit_data.audited = audited;
 538        a->selinux_audit_data.denied = denied;
 539        a->lsm_pre_audit = avc_audit_pre_callback;
 540        a->lsm_post_audit = avc_audit_post_callback;
 541        common_lsm_audit(a);
 542        return 0;
 543}
 544
 545/**
 546 * avc_add_callback - Register a callback for security events.
 547 * @callback: callback function
 548 * @events: security events
 549 * @ssid: source security identifier or %SECSID_WILD
 550 * @tsid: target security identifier or %SECSID_WILD
 551 * @tclass: target security class
 552 * @perms: permissions
 553 *
 554 * Register a callback function for events in the set @events
 555 * related to the SID pair (@ssid, @tsid) 
 556 * and the permissions @perms, interpreting
 557 * @perms based on @tclass.  Returns %0 on success or
 558 * -%ENOMEM if insufficient memory exists to add the callback.
 559 */
 560int avc_add_callback(int (*callback)(u32 event, u32 ssid, u32 tsid,
 561                                     u16 tclass, u32 perms,
 562                                     u32 *out_retained),
 563                     u32 events, u32 ssid, u32 tsid,
 564                     u16 tclass, u32 perms)
 565{
 566        struct avc_callback_node *c;
 567        int rc = 0;
 568
 569        c = kmalloc(sizeof(*c), GFP_ATOMIC);
 570        if (!c) {
 571                rc = -ENOMEM;
 572                goto out;
 573        }
 574
 575        c->callback = callback;
 576        c->events = events;
 577        c->ssid = ssid;
 578        c->tsid = tsid;
 579        c->perms = perms;
 580        c->next = avc_callbacks;
 581        avc_callbacks = c;
 582out:
 583        return rc;
 584}
 585
 586static inline int avc_sidcmp(u32 x, u32 y)
 587{
 588        return (x == y || x == SECSID_WILD || y == SECSID_WILD);
 589}
 590
 591/**
 592 * avc_update_node Update an AVC entry
 593 * @event : Updating event
 594 * @perms : Permission mask bits
 595 * @ssid,@tsid,@tclass : identifier of an AVC entry
 596 * @seqno : sequence number when decision was made
 597 *
 598 * if a valid AVC entry doesn't exist,this function returns -ENOENT.
 599 * if kmalloc() called internal returns NULL, this function returns -ENOMEM.
 600 * otherwise, this function updates the AVC entry. The original AVC-entry object
 601 * will release later by RCU.
 602 */
 603static int avc_update_node(u32 event, u32 perms, u32 ssid, u32 tsid, u16 tclass,
 604                           u32 seqno)
 605{
 606        int hvalue, rc = 0;
 607        unsigned long flag;
 608        struct avc_node *pos, *node, *orig = NULL;
 609        struct hlist_head *head;
 610        struct hlist_node *next;
 611        spinlock_t *lock;
 612
 613        node = avc_alloc_node();
 614        if (!node) {
 615                rc = -ENOMEM;
 616                goto out;
 617        }
 618
 619        /* Lock the target slot */
 620        hvalue = avc_hash(ssid, tsid, tclass);
 621
 622        head = &avc_cache.slots[hvalue];
 623        lock = &avc_cache.slots_lock[hvalue];
 624
 625        spin_lock_irqsave(lock, flag);
 626
 627        hlist_for_each_entry(pos, next, head, list) {
 628                if (ssid == pos->ae.ssid &&
 629                    tsid == pos->ae.tsid &&
 630                    tclass == pos->ae.tclass &&
 631                    seqno == pos->ae.avd.seqno){
 632                        orig = pos;
 633                        break;
 634                }
 635        }
 636
 637        if (!orig) {
 638                rc = -ENOENT;
 639                avc_node_kill(node);
 640                goto out_unlock;
 641        }
 642
 643        /*
 644         * Copy and replace original node.
 645         */
 646
 647        avc_node_populate(node, ssid, tsid, tclass, &orig->ae.avd);
 648
 649        switch (event) {
 650        case AVC_CALLBACK_GRANT:
 651                node->ae.avd.allowed |= perms;
 652                break;
 653        case AVC_CALLBACK_TRY_REVOKE:
 654        case AVC_CALLBACK_REVOKE:
 655                node->ae.avd.allowed &= ~perms;
 656                break;
 657        case AVC_CALLBACK_AUDITALLOW_ENABLE:
 658                node->ae.avd.auditallow |= perms;
 659                break;
 660        case AVC_CALLBACK_AUDITALLOW_DISABLE:
 661                node->ae.avd.auditallow &= ~perms;
 662                break;
 663        case AVC_CALLBACK_AUDITDENY_ENABLE:
 664                node->ae.avd.auditdeny |= perms;
 665                break;
 666        case AVC_CALLBACK_AUDITDENY_DISABLE:
 667                node->ae.avd.auditdeny &= ~perms;
 668                break;
 669        }
 670        avc_node_replace(node, orig);
 671out_unlock:
 672        spin_unlock_irqrestore(lock, flag);
 673out:
 674        return rc;
 675}
 676
 677/**
 678 * avc_flush - Flush the cache
 679 */
 680static void avc_flush(void)
 681{
 682        struct hlist_head *head;
 683        struct hlist_node *next;
 684        struct avc_node *node;
 685        spinlock_t *lock;
 686        unsigned long flag;
 687        int i;
 688
 689        for (i = 0; i < AVC_CACHE_SLOTS; i++) {
 690                head = &avc_cache.slots[i];
 691                lock = &avc_cache.slots_lock[i];
 692
 693                spin_lock_irqsave(lock, flag);
 694                /*
 695                 * With preemptable RCU, the outer spinlock does not
 696                 * prevent RCU grace periods from ending.
 697                 */
 698                rcu_read_lock();
 699                hlist_for_each_entry(node, next, head, list)
 700                        avc_node_delete(node);
 701                rcu_read_unlock();
 702                spin_unlock_irqrestore(lock, flag);
 703        }
 704}
 705
 706/**
 707 * avc_ss_reset - Flush the cache and revalidate migrated permissions.
 708 * @seqno: policy sequence number
 709 */
 710int avc_ss_reset(u32 seqno)
 711{
 712        struct avc_callback_node *c;
 713        int rc = 0, tmprc;
 714
 715        avc_flush();
 716
 717        for (c = avc_callbacks; c; c = c->next) {
 718                if (c->events & AVC_CALLBACK_RESET) {
 719                        tmprc = c->callback(AVC_CALLBACK_RESET,
 720                                            0, 0, 0, 0, NULL);
 721                        /* save the first error encountered for the return
 722                           value and continue processing the callbacks */
 723                        if (!rc)
 724                                rc = tmprc;
 725                }
 726        }
 727
 728        avc_latest_notif_update(seqno, 0);
 729        return rc;
 730}
 731
 732/**
 733 * avc_has_perm_noaudit - Check permissions but perform no auditing.
 734 * @ssid: source security identifier
 735 * @tsid: target security identifier
 736 * @tclass: target security class
 737 * @requested: requested permissions, interpreted based on @tclass
 738 * @flags:  AVC_STRICT or 0
 739 * @avd: access vector decisions
 740 *
 741 * Check the AVC to determine whether the @requested permissions are granted
 742 * for the SID pair (@ssid, @tsid), interpreting the permissions
 743 * based on @tclass, and call the security server on a cache miss to obtain
 744 * a new decision and add it to the cache.  Return a copy of the decisions
 745 * in @avd.  Return %0 if all @requested permissions are granted,
 746 * -%EACCES if any permissions are denied, or another -errno upon
 747 * other errors.  This function is typically called by avc_has_perm(),
 748 * but may also be called directly to separate permission checking from
 749 * auditing, e.g. in cases where a lock must be held for the check but
 750 * should be released for the auditing.
 751 */
 752int avc_has_perm_noaudit(u32 ssid, u32 tsid,
 753                         u16 tclass, u32 requested,
 754                         unsigned flags,
 755                         struct av_decision *avd)
 756{
 757        struct avc_node *node;
 758        int rc = 0;
 759        u32 denied;
 760
 761        BUG_ON(!requested);
 762
 763        rcu_read_lock();
 764
 765        node = avc_lookup(ssid, tsid, tclass);
 766        if (unlikely(!node)) {
 767                rcu_read_unlock();
 768                security_compute_av(ssid, tsid, tclass, avd);
 769                rcu_read_lock();
 770                node = avc_insert(ssid, tsid, tclass, avd);
 771        } else {
 772                memcpy(avd, &node->ae.avd, sizeof(*avd));
 773                avd = &node->ae.avd;
 774        }
 775
 776        denied = requested & ~(avd->allowed);
 777
 778        if (denied) {
 779                if (flags & AVC_STRICT)
 780                        rc = -EACCES;
 781                else if (!selinux_enforcing || (avd->flags & AVD_FLAGS_PERMISSIVE))
 782                        avc_update_node(AVC_CALLBACK_GRANT, requested, ssid,
 783                                        tsid, tclass, avd->seqno);
 784                else
 785                        rc = -EACCES;
 786        }
 787
 788        rcu_read_unlock();
 789        return rc;
 790}
 791
 792/**
 793 * avc_has_perm - Check permissions and perform any appropriate auditing.
 794 * @ssid: source security identifier
 795 * @tsid: target security identifier
 796 * @tclass: target security class
 797 * @requested: requested permissions, interpreted based on @tclass
 798 * @auditdata: auxiliary audit data
 799 * @flags: VFS walk flags
 800 *
 801 * Check the AVC to determine whether the @requested permissions are granted
 802 * for the SID pair (@ssid, @tsid), interpreting the permissions
 803 * based on @tclass, and call the security server on a cache miss to obtain
 804 * a new decision and add it to the cache.  Audit the granting or denial of
 805 * permissions in accordance with the policy.  Return %0 if all @requested
 806 * permissions are granted, -%EACCES if any permissions are denied, or
 807 * another -errno upon other errors.
 808 */
 809int avc_has_perm_flags(u32 ssid, u32 tsid, u16 tclass,
 810                       u32 requested, struct common_audit_data *auditdata,
 811                       unsigned flags)
 812{
 813        struct av_decision avd;
 814        int rc, rc2;
 815
 816        rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, 0, &avd);
 817
 818        rc2 = avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata,
 819                        flags);
 820        if (rc2)
 821                return rc2;
 822        return rc;
 823}
 824
 825u32 avc_policy_seqno(void)
 826{
 827        return avc_cache.latest_notif;
 828}
 829
 830void avc_disable(void)
 831{
 832        /*
 833         * If you are looking at this because you have realized that we are
 834         * not destroying the avc_node_cachep it might be easy to fix, but
 835         * I don't know the memory barrier semantics well enough to know.  It's
 836         * possible that some other task dereferenced security_ops when
 837         * it still pointed to selinux operations.  If that is the case it's
 838         * possible that it is about to use the avc and is about to need the
 839         * avc_node_cachep.  I know I could wrap the security.c security_ops call
 840         * in an rcu_lock, but seriously, it's not worth it.  Instead I just flush
 841         * the cache and get that memory back.
 842         */
 843        if (avc_node_cachep) {
 844                avc_flush();
 845                /* kmem_cache_destroy(avc_node_cachep); */
 846        }
 847}
 848
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.