2 * Implementation of the kernel access vector cache (AVC).
4 * Authors: Stephen Smalley, <sds@epoch.ncsc.mil>
5 * James Morris <jmorris@redhat.com>
7 * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2,
11 * as published by the Free Software Foundation.
13 #include <linux/types.h>
14 #include <linux/stddef.h>
15 #include <linux/kernel.h>
16 #include <linux/slab.h>
18 #include <linux/dcache.h>
19 #include <linux/init.h>
20 #include <linux/skbuff.h>
23 #include <net/af_unix.h>
25 #include <linux/audit.h>
26 #include <linux/ipv6.h>
31 #include "class_to_string.h"
33 #include "common_perm_to_string.h"
34 #include "av_inherit.h"
35 #include "av_perm_to_string.h"
38 #define AVC_CACHE_SLOTS 512
39 #define AVC_CACHE_MAXNODES 410
45 struct av_decision avd;
46 int used; /* used recently */
51 struct avc_node *next;
55 struct avc_node *slots[AVC_CACHE_SLOTS];
56 u32 lru_hint; /* LRU hint for reclaim scan */
58 u32 latest_notif; /* latest revocation notification */
61 struct avc_callback_node {
62 int (*callback) (u32 event, u32 ssid, u32 tsid,
63 u16 tclass, u32 perms,
70 struct avc_callback_node *next;
73 static spinlock_t avc_lock = SPIN_LOCK_UNLOCKED;
74 static struct avc_node *avc_node_freelist = NULL;
75 static struct avc_cache avc_cache;
76 static unsigned avc_cache_stats[AVC_NSTATS];
77 static struct avc_callback_node *avc_callbacks = NULL;
79 static inline int avc_hash(u32 ssid, u32 tsid, u16 tclass)
81 return (ssid ^ (tsid<<2) ^ (tclass<<4)) & (AVC_CACHE_SLOTS - 1);
85 * avc_dump_av - Display an access vector in human-readable form.
86 * @tclass: target security class
89 void avc_dump_av(struct audit_buffer *ab, u16 tclass, u32 av)
91 char **common_pts = 0;
96 audit_log_format(ab, " null");
100 for (i = 0; i < ARRAY_SIZE(av_inherit); i++) {
101 if (av_inherit[i].tclass == tclass) {
102 common_pts = av_inherit[i].common_pts;
103 common_base = av_inherit[i].common_base;
108 audit_log_format(ab, " {");
111 while (perm < common_base) {
113 audit_log_format(ab, " %s", common_pts[i]);
118 while (i < sizeof(av) * 8) {
120 for (i2 = 0; i2 < ARRAY_SIZE(av_perm_to_string); i2++) {
121 if ((av_perm_to_string[i2].tclass == tclass) &&
122 (av_perm_to_string[i2].value == perm))
125 if (i2 < ARRAY_SIZE(av_perm_to_string))
126 audit_log_format(ab, " %s",
127 av_perm_to_string[i2].name);
133 audit_log_format(ab, " }");
137 * avc_dump_query - Display a SID pair and a class in human-readable form.
138 * @ssid: source security identifier
139 * @tsid: target security identifier
140 * @tclass: target security class
142 void avc_dump_query(struct audit_buffer *ab, u32 ssid, u32 tsid, u16 tclass)
148 rc = security_sid_to_context(ssid, &scontext, &scontext_len);
150 audit_log_format(ab, "ssid=%d", ssid);
152 audit_log_format(ab, "scontext=%s", scontext);
156 rc = security_sid_to_context(tsid, &scontext, &scontext_len);
158 audit_log_format(ab, " tsid=%d", tsid);
160 audit_log_format(ab, " tcontext=%s", scontext);
163 audit_log_format(ab, " tclass=%s", class_to_string[tclass]);
167 * avc_init - Initialize the AVC.
169 * Initialize the access vector cache.
171 void __init avc_init(void)
173 struct avc_node *new;
176 for (i = 0; i < AVC_NSTATS; i++)
177 avc_cache_stats[i] = 0;
179 for (i = 0; i < AVC_CACHE_SLOTS; i++)
180 avc_cache.slots[i] = 0;
181 avc_cache.lru_hint = 0;
182 avc_cache.active_nodes = 0;
183 avc_cache.latest_notif = 0;
185 for (i = 0; i < AVC_CACHE_MAXNODES; i++) {
186 new = kmalloc(sizeof(*new), GFP_ATOMIC);
188 printk(KERN_WARNING "avc: only able to allocate "
192 memset(new, 0, sizeof(*new));
193 new->next = avc_node_freelist;
194 avc_node_freelist = new;
197 audit_log(current->audit_context, "AVC INITIALIZED\n");
201 static void avc_hash_eval(char *tag)
203 int i, chain_len, max_chain_len, slots_used;
204 struct avc_node *node;
207 spin_lock_irqsave(&avc_lock,flags);
211 for (i = 0; i < AVC_CACHE_SLOTS; i++) {
212 node = avc_cache.slots[i];
220 if (chain_len > max_chain_len)
221 max_chain_len = chain_len;
225 spin_unlock_irqrestore(&avc_lock,flags);
227 printk(KERN_INFO "\n");
228 printk(KERN_INFO "%s avc: %d entries and %d/%d buckets used, longest "
229 "chain length %d\n", tag, avc_cache.active_nodes, slots_used,
230 AVC_CACHE_SLOTS, max_chain_len);
233 static inline void avc_hash_eval(char *tag)
237 static inline struct avc_node *avc_reclaim_node(void)
239 struct avc_node *prev, *cur;
242 hvalue = avc_cache.lru_hint;
243 for (try = 0; try < 2; try++) {
246 cur = avc_cache.slots[hvalue];
256 hvalue = (hvalue + 1) & (AVC_CACHE_SLOTS - 1);
257 } while (hvalue != avc_cache.lru_hint);
260 panic("avc_reclaim_node");
263 avc_cache.lru_hint = hvalue;
266 avc_cache.slots[hvalue] = cur->next;
268 prev->next = cur->next;
273 static inline struct avc_node *avc_claim_node(u32 ssid,
274 u32 tsid, u16 tclass)
276 struct avc_node *new;
279 hvalue = avc_hash(ssid, tsid, tclass);
280 if (avc_node_freelist) {
281 new = avc_node_freelist;
282 avc_node_freelist = avc_node_freelist->next;
283 avc_cache.active_nodes++;
285 new = avc_reclaim_node();
293 new->ae.tclass = tclass;
294 new->next = avc_cache.slots[hvalue];
295 avc_cache.slots[hvalue] = new;
301 static inline struct avc_node *avc_search_node(u32 ssid, u32 tsid,
302 u16 tclass, int *probes)
304 struct avc_node *cur;
308 hvalue = avc_hash(ssid, tsid, tclass);
309 cur = avc_cache.slots[hvalue];
310 while (cur != NULL &&
311 (ssid != cur->ae.ssid ||
312 tclass != cur->ae.tclass ||
313 tsid != cur->ae.tsid)) {
334 * avc_lookup - Look up an AVC entry.
335 * @ssid: source security identifier
336 * @tsid: target security identifier
337 * @tclass: target security class
338 * @requested: requested permissions, interpreted based on @tclass
339 * @aeref: AVC entry reference
341 * Look up an AVC entry that is valid for the
342 * @requested permissions between the SID pair
343 * (@ssid, @tsid), interpreting the permissions
344 * based on @tclass. If a valid AVC entry exists,
345 * then this function updates @aeref to refer to the
346 * entry and returns %0. Otherwise, this function
349 int avc_lookup(u32 ssid, u32 tsid, u16 tclass,
350 u32 requested, struct avc_entry_ref *aeref)
352 struct avc_node *node;
355 avc_cache_stats_incr(AVC_CAV_LOOKUPS);
356 node = avc_search_node(ssid, tsid, tclass,&probes);
358 if (node && ((node->ae.avd.decided & requested) == requested)) {
359 avc_cache_stats_incr(AVC_CAV_HITS);
360 avc_cache_stats_add(AVC_CAV_PROBES,probes);
361 aeref->ae = &node->ae;
365 avc_cache_stats_incr(AVC_CAV_MISSES);
372 * avc_insert - Insert an AVC entry.
373 * @ssid: source security identifier
374 * @tsid: target security identifier
375 * @tclass: target security class
377 * @aeref: AVC entry reference
379 * Insert an AVC entry for the SID pair
380 * (@ssid, @tsid) and class @tclass.
381 * The access vectors and the sequence number are
382 * normally provided by the security server in
383 * response to a security_compute_av() call. If the
384 * sequence number @ae->avd.seqno is not less than the latest
385 * revocation notification, then the function copies
386 * the access vectors into a cache entry, updates
387 * @aeref to refer to the entry, and returns %0.
388 * Otherwise, this function returns -%EAGAIN.
390 int avc_insert(u32 ssid, u32 tsid, u16 tclass,
391 struct avc_entry *ae, struct avc_entry_ref *aeref)
393 struct avc_node *node;
396 if (ae->avd.seqno < avc_cache.latest_notif) {
397 printk(KERN_WARNING "avc: seqno %d < latest_notif %d\n",
398 ae->avd.seqno, avc_cache.latest_notif);
403 node = avc_claim_node(ssid, tsid, tclass);
409 node->ae.avd.allowed = ae->avd.allowed;
410 node->ae.avd.decided = ae->avd.decided;
411 node->ae.avd.auditallow = ae->avd.auditallow;
412 node->ae.avd.auditdeny = ae->avd.auditdeny;
413 node->ae.avd.seqno = ae->avd.seqno;
414 aeref->ae = &node->ae;
419 static inline void avc_print_ipv6_addr(struct audit_buffer *ab,
420 struct in6_addr *addr, u16 port,
421 char *name1, char *name2)
423 if (!ipv6_addr_any(addr))
424 audit_log_format(ab, " %s=%04x:%04x:%04x:%04x:%04x:"
425 "%04x:%04x:%04x", name1, NIP6(*addr));
427 audit_log_format(ab, " %s=%d", name2, ntohs(port));
430 static inline void avc_print_ipv4_addr(struct audit_buffer *ab, u32 addr,
431 u16 port, char *name1, char *name2)
434 audit_log_format(ab, " %s=%d.%d.%d.%d", name1, NIPQUAD(addr));
436 audit_log_format(ab, " %s=%d", name2, ntohs(port));
440 * avc_audit - Audit the granting or denial of permissions.
441 * @ssid: source security identifier
442 * @tsid: target security identifier
443 * @tclass: target security class
444 * @requested: requested permissions
445 * @avd: access vector decisions
446 * @result: result from avc_has_perm_noaudit
447 * @a: auxiliary audit data
449 * Audit the granting or denial of permissions in accordance
450 * with the policy. This function is typically called by
451 * avc_has_perm() after a permission check, but can also be
452 * called directly by callers who use avc_has_perm_noaudit()
453 * in order to separate the permission check from the auditing.
454 * For example, this separation is useful when the permission check must
455 * be performed under a lock, to allow the lock to be released
456 * before calling the auditing code.
458 void avc_audit(u32 ssid, u32 tsid,
459 u16 tclass, u32 requested,
460 struct av_decision *avd, int result, struct avc_audit_data *a)
462 struct task_struct *tsk = current;
463 struct inode *inode = NULL;
465 struct audit_buffer *ab;
467 denied = requested & ~avd->allowed;
470 if (!(audited & avd->auditdeny))
473 audited = denied = requested;
476 if (!(audited & avd->auditallow))
480 ab = audit_log_start(current->audit_context);
482 return; /* audit_panic has been called */
483 audit_log_format(ab, "avc: %s ", denied ? "denied" : "granted");
484 avc_dump_av(ab, tclass,audited);
485 audit_log_format(ab, " for ");
488 if (tsk && tsk->pid) {
489 struct mm_struct *mm;
490 struct vm_area_struct *vma;
491 audit_log_format(ab, " pid=%d", tsk->pid);
495 mm = get_task_mm(tsk);
497 if (down_read_trylock(&mm->mmap_sem)) {
500 if ((vma->vm_flags & VM_EXECUTABLE) &&
502 audit_log_d_path(ab, "exe=",
503 vma->vm_file->f_dentry,
504 vma->vm_file->f_vfsmnt);
509 up_read(&mm->mmap_sem);
514 audit_log_format(ab, " comm=%s", tsk->comm);
519 case AVC_AUDIT_DATA_IPC:
520 audit_log_format(ab, " key=%d", a->u.ipc_id);
522 case AVC_AUDIT_DATA_CAP:
523 audit_log_format(ab, " capability=%d", a->u.cap);
525 case AVC_AUDIT_DATA_FS:
526 if (a->u.fs.dentry) {
527 struct dentry *dentry = a->u.fs.dentry;
529 audit_log_d_path(ab, "path=", dentry,
532 audit_log_format(ab, " name=%s",
533 dentry->d_name.name);
535 inode = dentry->d_inode;
536 } else if (a->u.fs.inode) {
537 struct dentry *dentry;
538 inode = a->u.fs.inode;
539 dentry = d_find_alias(inode);
541 audit_log_format(ab, " name=%s",
542 dentry->d_name.name);
547 audit_log_format(ab, " dev=%s ino=%ld",
551 case AVC_AUDIT_DATA_NET:
553 struct sock *sk = a->u.net.sk;
558 switch (sk->sk_family) {
560 struct inet_opt *inet = inet_sk(sk);
562 avc_print_ipv4_addr(ab, inet->rcv_saddr,
565 avc_print_ipv4_addr(ab, inet->daddr,
571 struct inet_opt *inet = inet_sk(sk);
572 struct ipv6_pinfo *inet6 = inet6_sk(sk);
574 avc_print_ipv6_addr(ab, &inet6->rcv_saddr,
577 avc_print_ipv6_addr(ab, &inet6->daddr,
585 audit_log_d_path(ab, "path=",
591 len = u->addr->len-sizeof(short);
592 p = &u->addr->name->sun_path[0];
599 "path=@%*.*s", len-1,
605 switch (a->u.net.family) {
607 avc_print_ipv4_addr(ab, a->u.net.v4info.saddr,
610 avc_print_ipv4_addr(ab, a->u.net.v4info.daddr,
615 avc_print_ipv6_addr(ab, &a->u.net.v6info.saddr,
618 avc_print_ipv6_addr(ab, &a->u.net.v6info.daddr,
624 audit_log_format(ab, " netif=%s",
629 audit_log_format(ab, " ");
630 avc_dump_query(ab, ssid, tsid, tclass);
635 * avc_add_callback - Register a callback for security events.
636 * @callback: callback function
637 * @events: security events
638 * @ssid: source security identifier or %SECSID_WILD
639 * @tsid: target security identifier or %SECSID_WILD
640 * @tclass: target security class
641 * @perms: permissions
643 * Register a callback function for events in the set @events
644 * related to the SID pair (@ssid, @tsid) and
645 * and the permissions @perms, interpreting
646 * @perms based on @tclass. Returns %0 on success or
647 * -%ENOMEM if insufficient memory exists to add the callback.
649 int avc_add_callback(int (*callback)(u32 event, u32 ssid, u32 tsid,
650 u16 tclass, u32 perms,
652 u32 events, u32 ssid, u32 tsid,
653 u16 tclass, u32 perms)
655 struct avc_callback_node *c;
658 c = kmalloc(sizeof(*c), GFP_ATOMIC);
664 c->callback = callback;
669 c->next = avc_callbacks;
675 static inline int avc_sidcmp(u32 x, u32 y)
677 return (x == y || x == SECSID_WILD || y == SECSID_WILD);
680 static inline void avc_update_node(u32 event, struct avc_node *node, u32 perms)
683 case AVC_CALLBACK_GRANT:
684 node->ae.avd.allowed |= perms;
686 case AVC_CALLBACK_TRY_REVOKE:
687 case AVC_CALLBACK_REVOKE:
688 node->ae.avd.allowed &= ~perms;
690 case AVC_CALLBACK_AUDITALLOW_ENABLE:
691 node->ae.avd.auditallow |= perms;
693 case AVC_CALLBACK_AUDITALLOW_DISABLE:
694 node->ae.avd.auditallow &= ~perms;
696 case AVC_CALLBACK_AUDITDENY_ENABLE:
697 node->ae.avd.auditdeny |= perms;
699 case AVC_CALLBACK_AUDITDENY_DISABLE:
700 node->ae.avd.auditdeny &= ~perms;
705 static int avc_update_cache(u32 event, u32 ssid, u32 tsid,
706 u16 tclass, u32 perms)
708 struct avc_node *node;
712 spin_lock_irqsave(&avc_lock,flags);
714 if (ssid == SECSID_WILD || tsid == SECSID_WILD) {
715 /* apply to all matching nodes */
716 for (i = 0; i < AVC_CACHE_SLOTS; i++) {
717 for (node = avc_cache.slots[i]; node;
719 if (avc_sidcmp(ssid, node->ae.ssid) &&
720 avc_sidcmp(tsid, node->ae.tsid) &&
721 tclass == node->ae.tclass) {
722 avc_update_node(event,node,perms);
727 /* apply to one node */
728 node = avc_search_node(ssid, tsid, tclass, 0);
730 avc_update_node(event,node,perms);
734 spin_unlock_irqrestore(&avc_lock,flags);
739 static int avc_control(u32 event, u32 ssid, u32 tsid,
740 u16 tclass, u32 perms,
741 u32 seqno, u32 *out_retained)
743 struct avc_callback_node *c;
744 u32 tretained = 0, cretained = 0;
749 * try_revoke only removes permissions from the cache
750 * state if they are not retained by the object manager.
751 * Hence, try_revoke must wait until after the callbacks have
752 * been invoked to update the cache state.
754 if (event != AVC_CALLBACK_TRY_REVOKE)
755 avc_update_cache(event,ssid,tsid,tclass,perms);
757 for (c = avc_callbacks; c; c = c->next)
759 if ((c->events & event) &&
760 avc_sidcmp(c->ssid, ssid) &&
761 avc_sidcmp(c->tsid, tsid) &&
762 c->tclass == tclass &&
763 (c->perms & perms)) {
765 rc = c->callback(event, ssid, tsid, tclass,
770 tretained |= cretained;
774 if (event == AVC_CALLBACK_TRY_REVOKE) {
775 /* revoke any unretained permissions */
777 avc_update_cache(event,ssid,tsid,tclass,perms);
778 *out_retained = tretained;
781 spin_lock_irqsave(&avc_lock,flags);
782 if (seqno > avc_cache.latest_notif)
783 avc_cache.latest_notif = seqno;
784 spin_unlock_irqrestore(&avc_lock,flags);
791 * avc_ss_grant - Grant previously denied permissions.
792 * @ssid: source security identifier or %SECSID_WILD
793 * @tsid: target security identifier or %SECSID_WILD
794 * @tclass: target security class
795 * @perms: permissions to grant
796 * @seqno: policy sequence number
798 int avc_ss_grant(u32 ssid, u32 tsid, u16 tclass,
799 u32 perms, u32 seqno)
801 return avc_control(AVC_CALLBACK_GRANT,
802 ssid, tsid, tclass, perms, seqno, 0);
806 * avc_ss_try_revoke - Try to revoke previously granted permissions.
807 * @ssid: source security identifier or %SECSID_WILD
808 * @tsid: target security identifier or %SECSID_WILD
809 * @tclass: target security class
810 * @perms: permissions to grant
811 * @seqno: policy sequence number
812 * @out_retained: subset of @perms that are retained
814 * Try to revoke previously granted permissions, but
815 * only if they are not retained as migrated permissions.
816 * Return the subset of permissions that are retained via @out_retained.
818 int avc_ss_try_revoke(u32 ssid, u32 tsid, u16 tclass,
819 u32 perms, u32 seqno, u32 *out_retained)
821 return avc_control(AVC_CALLBACK_TRY_REVOKE,
822 ssid, tsid, tclass, perms, seqno, out_retained);
826 * avc_ss_revoke - Revoke previously granted permissions.
827 * @ssid: source security identifier or %SECSID_WILD
828 * @tsid: target security identifier or %SECSID_WILD
829 * @tclass: target security class
830 * @perms: permissions to grant
831 * @seqno: policy sequence number
833 * Revoke previously granted permissions, even if
834 * they are retained as migrated permissions.
836 int avc_ss_revoke(u32 ssid, u32 tsid, u16 tclass,
837 u32 perms, u32 seqno)
839 return avc_control(AVC_CALLBACK_REVOKE,
840 ssid, tsid, tclass, perms, seqno, 0);
844 * avc_ss_reset - Flush the cache and revalidate migrated permissions.
845 * @seqno: policy sequence number
847 int avc_ss_reset(u32 seqno)
849 struct avc_callback_node *c;
851 struct avc_node *node, *tmp;
854 avc_hash_eval("reset");
856 spin_lock_irqsave(&avc_lock,flags);
858 for (i = 0; i < AVC_CACHE_SLOTS; i++) {
859 node = avc_cache.slots[i];
863 tmp->ae.ssid = tmp->ae.tsid = SECSID_NULL;
864 tmp->ae.tclass = SECCLASS_NULL;
865 tmp->ae.avd.allowed = tmp->ae.avd.decided = 0;
866 tmp->ae.avd.auditallow = tmp->ae.avd.auditdeny = 0;
868 tmp->next = avc_node_freelist;
869 avc_node_freelist = tmp;
870 avc_cache.active_nodes--;
872 avc_cache.slots[i] = 0;
874 avc_cache.lru_hint = 0;
876 spin_unlock_irqrestore(&avc_lock,flags);
878 for (i = 0; i < AVC_NSTATS; i++)
879 avc_cache_stats[i] = 0;
881 for (c = avc_callbacks; c; c = c->next) {
882 if (c->events & AVC_CALLBACK_RESET) {
883 rc = c->callback(AVC_CALLBACK_RESET,
890 spin_lock_irqsave(&avc_lock,flags);
891 if (seqno > avc_cache.latest_notif)
892 avc_cache.latest_notif = seqno;
893 spin_unlock_irqrestore(&avc_lock,flags);
899 * avc_ss_set_auditallow - Enable or disable auditing of granted permissions.
900 * @ssid: source security identifier or %SECSID_WILD
901 * @tsid: target security identifier or %SECSID_WILD
902 * @tclass: target security class
903 * @perms: permissions to grant
904 * @seqno: policy sequence number
905 * @enable: enable flag.
907 int avc_ss_set_auditallow(u32 ssid, u32 tsid, u16 tclass,
908 u32 perms, u32 seqno, u32 enable)
911 return avc_control(AVC_CALLBACK_AUDITALLOW_ENABLE,
912 ssid, tsid, tclass, perms, seqno, 0);
914 return avc_control(AVC_CALLBACK_AUDITALLOW_DISABLE,
915 ssid, tsid, tclass, perms, seqno, 0);
919 * avc_ss_set_auditdeny - Enable or disable auditing of denied permissions.
920 * @ssid: source security identifier or %SECSID_WILD
921 * @tsid: target security identifier or %SECSID_WILD
922 * @tclass: target security class
923 * @perms: permissions to grant
924 * @seqno: policy sequence number
925 * @enable: enable flag.
927 int avc_ss_set_auditdeny(u32 ssid, u32 tsid, u16 tclass,
928 u32 perms, u32 seqno, u32 enable)
931 return avc_control(AVC_CALLBACK_AUDITDENY_ENABLE,
932 ssid, tsid, tclass, perms, seqno, 0);
934 return avc_control(AVC_CALLBACK_AUDITDENY_DISABLE,
935 ssid, tsid, tclass, perms, seqno, 0);
939 * avc_has_perm_noaudit - Check permissions but perform no auditing.
940 * @ssid: source security identifier
941 * @tsid: target security identifier
942 * @tclass: target security class
943 * @requested: requested permissions, interpreted based on @tclass
944 * @aeref: AVC entry reference
945 * @avd: access vector decisions
947 * Check the AVC to determine whether the @requested permissions are granted
948 * for the SID pair (@ssid, @tsid), interpreting the permissions
949 * based on @tclass, and call the security server on a cache miss to obtain
950 * a new decision and add it to the cache. Update @aeref to refer to an AVC
951 * entry with the resulting decisions, and return a copy of the decisions
952 * in @avd. Return %0 if all @requested permissions are granted,
953 * -%EACCES if any permissions are denied, or another -errno upon
954 * other errors. This function is typically called by avc_has_perm(),
955 * but may also be called directly to separate permission checking from
956 * auditing, e.g. in cases where a lock must be held for the check but
957 * should be released for the auditing.
959 int avc_has_perm_noaudit(u32 ssid, u32 tsid,
960 u16 tclass, u32 requested,
961 struct avc_entry_ref *aeref, struct av_decision *avd)
963 struct avc_entry *ae;
966 struct avc_entry entry;
968 struct avc_entry_ref ref;
971 avc_entry_ref_init(&ref);
975 spin_lock_irqsave(&avc_lock, flags);
976 avc_cache_stats_incr(AVC_ENTRY_LOOKUPS);
979 if (ae->ssid == ssid &&
981 ae->tclass == tclass &&
982 ((ae->avd.decided & requested) == requested)) {
983 avc_cache_stats_incr(AVC_ENTRY_HITS);
986 avc_cache_stats_incr(AVC_ENTRY_DISCARDS);
992 avc_cache_stats_incr(AVC_ENTRY_MISSES);
993 rc = avc_lookup(ssid, tsid, tclass, requested, aeref);
995 spin_unlock_irqrestore(&avc_lock,flags);
996 rc = security_compute_av(ssid,tsid,tclass,requested,&entry.avd);
999 spin_lock_irqsave(&avc_lock, flags);
1000 rc = avc_insert(ssid,tsid,tclass,&entry,aeref);
1002 spin_unlock_irqrestore(&avc_lock,flags);
1010 memcpy(avd, &ae->avd, sizeof(*avd));
1012 denied = requested & ~(ae->avd.allowed);
1014 if (!requested || denied) {
1015 if (selinux_enforcing) {
1016 spin_unlock_irqrestore(&avc_lock,flags);
1020 ae->avd.allowed |= requested;
1021 spin_unlock_irqrestore(&avc_lock,flags);
1026 spin_unlock_irqrestore(&avc_lock,flags);
1032 * avc_has_perm - Check permissions and perform any appropriate auditing.
1033 * @ssid: source security identifier
1034 * @tsid: target security identifier
1035 * @tclass: target security class
1036 * @requested: requested permissions, interpreted based on @tclass
1037 * @aeref: AVC entry reference
1038 * @auditdata: auxiliary audit data
1040 * Check the AVC to determine whether the @requested permissions are granted
1041 * for the SID pair (@ssid, @tsid), interpreting the permissions
1042 * based on @tclass, and call the security server on a cache miss to obtain
1043 * a new decision and add it to the cache. Update @aeref to refer to an AVC
1044 * entry with the resulting decisions. Audit the granting or denial of
1045 * permissions in accordance with the policy. Return %0 if all @requested
1046 * permissions are granted, -%EACCES if any permissions are denied, or
1047 * another -errno upon other errors.
1049 int avc_has_perm(u32 ssid, u32 tsid, u16 tclass,
1050 u32 requested, struct avc_entry_ref *aeref,
1051 struct avc_audit_data *auditdata)
1053 struct av_decision avd;
1056 rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, aeref, &avd);
1057 avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata);