Home | History | Annotate | Download | only in src
      1 /*
      2  * Implementation of the userspace access vector cache (AVC).
      3  *
      4  * Author : Eamon Walsh <ewalsh (at) epoch.ncsc.mil>
      5  *
      6  * Derived from the kernel AVC implementation by
      7  * Stephen Smalley <sds (at) epoch.ncsc.mil> and
      8  * James Morris <jmorris (at) redhat.com>.
      9  */
     10 #include <selinux/avc.h>
     11 #include "selinux_internal.h"
     12 #include "avc_sidtab.h"
     13 #include "avc_internal.h"
     14 
     15 #define AVC_CACHE_SLOTS		512
     16 #define AVC_CACHE_MAXNODES	410
     17 
     18 struct avc_entry {
     19 	security_id_t ssid;
     20 	security_id_t tsid;
     21 	security_class_t tclass;
     22 	struct av_decision avd;
     23 	security_id_t	create_sid;
     24 	int used;		/* used recently */
     25 };
     26 
     27 struct avc_node {
     28 	struct avc_entry ae;
     29 	struct avc_node *next;
     30 };
     31 
     32 struct avc_cache {
     33 	struct avc_node *slots[AVC_CACHE_SLOTS];
     34 	uint32_t lru_hint;	/* LRU hint for reclaim scan */
     35 	uint32_t active_nodes;
     36 	uint32_t latest_notif;	/* latest revocation notification */
     37 };
     38 
     39 struct avc_callback_node {
     40 	int (*callback) (uint32_t event, security_id_t ssid,
     41 			 security_id_t tsid,
     42 			 security_class_t tclass, access_vector_t perms,
     43 			 access_vector_t * out_retained);
     44 	uint32_t events;
     45 	security_id_t ssid;
     46 	security_id_t tsid;
     47 	security_class_t tclass;
     48 	access_vector_t perms;
     49 	struct avc_callback_node *next;
     50 };
     51 
     52 static void *avc_netlink_thread = NULL;
     53 static void *avc_lock = NULL;
     54 static void *avc_log_lock = NULL;
     55 static struct avc_node *avc_node_freelist = NULL;
     56 static struct avc_cache avc_cache;
     57 static char *avc_audit_buf = NULL;
     58 static struct avc_cache_stats cache_stats;
     59 static struct avc_callback_node *avc_callbacks = NULL;
     60 static struct sidtab avc_sidtab;
     61 
     62 static inline int avc_hash(security_id_t ssid,
     63 			   security_id_t tsid, security_class_t tclass)
     64 {
     65 	return ((uintptr_t) ssid ^ ((uintptr_t) tsid << 2) ^ tclass)
     66 	    & (AVC_CACHE_SLOTS - 1);
     67 }
     68 
     69 int avc_context_to_sid(const security_context_t ctx, security_id_t * sid)
     70 {
     71 	int rc;
     72 	avc_get_lock(avc_lock);
     73 	rc = sidtab_context_to_sid(&avc_sidtab, ctx, sid);
     74 	avc_release_lock(avc_lock);
     75 	return rc;
     76 }
     77 
     78 int avc_sid_to_context(security_id_t sid, security_context_t * ctx)
     79 {
     80 	int rc;
     81 	*ctx = NULL;
     82 	avc_get_lock(avc_lock);
     83 	*ctx = strdup(sid->ctx);	/* caller must free via freecon */
     84 	rc = *ctx ? 0 : -1;
     85 	avc_release_lock(avc_lock);
     86 	return rc;
     87 }
     88 
     89 int avc_get_initial_sid(const char * name, security_id_t * sid)
     90 {
     91 	int rc;
     92 	security_context_t con;
     93 
     94 	rc = security_get_initial_context(name, &con);
     95 	if (rc < 0)
     96 		return rc;
     97 	rc = avc_context_to_sid(con, sid);
     98 
     99 	freecon(con);
    100 
    101 	return rc;
    102 }
    103 
    104 int avc_open(struct selinux_opt *opts, unsigned nopts)
    105 {
    106 	avc_setenforce = 0;
    107 
    108 	while (nopts--)
    109 		switch(opts[nopts].type) {
    110 		case AVC_OPT_SETENFORCE:
    111 			avc_setenforce = 1;
    112 			avc_enforcing = !!opts[nopts].value;
    113 			break;
    114 		}
    115 
    116 	return avc_init("avc", NULL, NULL, NULL, NULL);
    117 }
    118 
    119 int avc_init(const char *prefix,
    120 	     const struct avc_memory_callback *mem_cb,
    121 	     const struct avc_log_callback *log_cb,
    122 	     const struct avc_thread_callback *thread_cb,
    123 	     const struct avc_lock_callback *lock_cb)
    124 {
    125 	struct avc_node *new;
    126 	int i, rc = 0;
    127 
    128 	if (prefix)
    129 		strncpy(avc_prefix, prefix, AVC_PREFIX_SIZE - 1);
    130 
    131 	set_callbacks(mem_cb, log_cb, thread_cb, lock_cb);
    132 
    133 	avc_lock = avc_alloc_lock();
    134 	avc_log_lock = avc_alloc_lock();
    135 
    136 	memset(&cache_stats, 0, sizeof(cache_stats));
    137 
    138 	for (i = 0; i < AVC_CACHE_SLOTS; i++)
    139 		avc_cache.slots[i] = 0;
    140 	avc_cache.lru_hint = 0;
    141 	avc_cache.active_nodes = 0;
    142 	avc_cache.latest_notif = 0;
    143 
    144 	rc = sidtab_init(&avc_sidtab);
    145 	if (rc) {
    146 		avc_log(SELINUX_ERROR,
    147 			"%s:  unable to initialize SID table\n",
    148 			avc_prefix);
    149 		goto out;
    150 	}
    151 
    152 	avc_audit_buf = (char *)avc_malloc(AVC_AUDIT_BUFSIZE);
    153 	if (!avc_audit_buf) {
    154 		avc_log(SELINUX_ERROR,
    155 			"%s:  unable to allocate audit buffer\n",
    156 			avc_prefix);
    157 		rc = -1;
    158 		goto out;
    159 	}
    160 
    161 	for (i = 0; i < AVC_CACHE_MAXNODES; i++) {
    162 		new = avc_malloc(sizeof(*new));
    163 		if (!new) {
    164 			avc_log(SELINUX_WARNING,
    165 				"%s:  warning: only got %d av entries\n",
    166 				avc_prefix, i);
    167 			break;
    168 		}
    169 		memset(new, 0, sizeof(*new));
    170 		new->next = avc_node_freelist;
    171 		avc_node_freelist = new;
    172 	}
    173 
    174 	if (!avc_setenforce) {
    175 		rc = security_getenforce();
    176 		if (rc < 0) {
    177 			avc_log(SELINUX_ERROR,
    178 				"%s:  could not determine enforcing mode: %s\n",
    179 				avc_prefix,
    180 				strerror(errno));
    181 			goto out;
    182 		}
    183 		avc_enforcing = rc;
    184 	}
    185 
    186 	rc = avc_netlink_open(0);
    187 	if (rc < 0) {
    188 		avc_log(SELINUX_ERROR,
    189 			"%s:  can't open netlink socket: %d (%s)\n",
    190 			avc_prefix, errno, strerror(errno));
    191 		goto out;
    192 	}
    193 	if (avc_using_threads) {
    194 		avc_netlink_thread = avc_create_thread(&avc_netlink_loop);
    195 		avc_netlink_trouble = 0;
    196 	}
    197 	avc_running = 1;
    198       out:
    199 	return rc;
    200 }
    201 
    202 void avc_cache_stats(struct avc_cache_stats *p)
    203 {
    204 	memcpy(p, &cache_stats, sizeof(cache_stats));
    205 }
    206 
    207 void avc_sid_stats(void)
    208 {
    209 	avc_get_lock(avc_log_lock);
    210 	avc_get_lock(avc_lock);
    211 	sidtab_sid_stats(&avc_sidtab, avc_audit_buf, AVC_AUDIT_BUFSIZE);
    212 	avc_release_lock(avc_lock);
    213 	avc_log(SELINUX_INFO, "%s", avc_audit_buf);
    214 	avc_release_lock(avc_log_lock);
    215 }
    216 
    217 void avc_av_stats(void)
    218 {
    219 	int i, chain_len, max_chain_len, slots_used;
    220 	struct avc_node *node;
    221 
    222 	avc_get_lock(avc_lock);
    223 
    224 	slots_used = 0;
    225 	max_chain_len = 0;
    226 	for (i = 0; i < AVC_CACHE_SLOTS; i++) {
    227 		node = avc_cache.slots[i];
    228 		if (node) {
    229 			slots_used++;
    230 			chain_len = 0;
    231 			while (node) {
    232 				chain_len++;
    233 				node = node->next;
    234 			}
    235 			if (chain_len > max_chain_len)
    236 				max_chain_len = chain_len;
    237 		}
    238 	}
    239 
    240 	avc_release_lock(avc_lock);
    241 
    242 	avc_log(SELINUX_INFO, "%s:  %d AV entries and %d/%d buckets used, "
    243 		"longest chain length %d\n", avc_prefix,
    244 		avc_cache.active_nodes,
    245 		slots_used, AVC_CACHE_SLOTS, max_chain_len);
    246 }
    247 
    248 hidden_def(avc_av_stats)
    249 
    250 static inline struct avc_node *avc_reclaim_node(void)
    251 {
    252 	struct avc_node *prev, *cur;
    253 	int try;
    254 	uint32_t hvalue;
    255 
    256 	hvalue = avc_cache.lru_hint;
    257 	for (try = 0; try < 2; try++) {
    258 		do {
    259 			prev = NULL;
    260 			cur = avc_cache.slots[hvalue];
    261 			while (cur) {
    262 				if (!cur->ae.used)
    263 					goto found;
    264 
    265 				cur->ae.used = 0;
    266 
    267 				prev = cur;
    268 				cur = cur->next;
    269 			}
    270 			hvalue = (hvalue + 1) & (AVC_CACHE_SLOTS - 1);
    271 		} while (hvalue != avc_cache.lru_hint);
    272 	}
    273 
    274 	errno = ENOMEM;		/* this was a panic in the kernel... */
    275 	return NULL;
    276 
    277       found:
    278 	avc_cache.lru_hint = hvalue;
    279 
    280 	if (prev == NULL)
    281 		avc_cache.slots[hvalue] = cur->next;
    282 	else
    283 		prev->next = cur->next;
    284 
    285 	return cur;
    286 }
    287 
    288 static inline void avc_clear_avc_entry(struct avc_entry *ae)
    289 {
    290 	memset(ae, 0, sizeof *ae);
    291 }
    292 
    293 static inline struct avc_node *avc_claim_node(security_id_t ssid,
    294 					      security_id_t tsid,
    295 					      security_class_t tclass)
    296 {
    297 	struct avc_node *new;
    298 	int hvalue;
    299 
    300 	if (!avc_node_freelist)
    301 		avc_cleanup();
    302 
    303 	if (avc_node_freelist) {
    304 		new = avc_node_freelist;
    305 		avc_node_freelist = avc_node_freelist->next;
    306 		avc_cache.active_nodes++;
    307 	} else {
    308 		new = avc_reclaim_node();
    309 		if (!new)
    310 			goto out;
    311 	}
    312 
    313 	hvalue = avc_hash(ssid, tsid, tclass);
    314 	avc_clear_avc_entry(&new->ae);
    315 	new->ae.used = 1;
    316 	new->ae.ssid = ssid;
    317 	new->ae.tsid = tsid;
    318 	new->ae.tclass = tclass;
    319 	new->next = avc_cache.slots[hvalue];
    320 	avc_cache.slots[hvalue] = new;
    321 
    322       out:
    323 	return new;
    324 }
    325 
    326 static inline struct avc_node *avc_search_node(security_id_t ssid,
    327 					       security_id_t tsid,
    328 					       security_class_t tclass,
    329 					       int *probes)
    330 {
    331 	struct avc_node *cur;
    332 	int hvalue;
    333 	int tprobes = 1;
    334 
    335 	hvalue = avc_hash(ssid, tsid, tclass);
    336 	cur = avc_cache.slots[hvalue];
    337 	while (cur != NULL &&
    338 	       (ssid != cur->ae.ssid ||
    339 		tclass != cur->ae.tclass || tsid != cur->ae.tsid)) {
    340 		tprobes++;
    341 		cur = cur->next;
    342 	}
    343 
    344 	if (cur == NULL) {
    345 		/* cache miss */
    346 		goto out;
    347 	}
    348 
    349 	/* cache hit */
    350 	if (probes)
    351 		*probes = tprobes;
    352 
    353 	cur->ae.used = 1;
    354 
    355       out:
    356 	return cur;
    357 }
    358 
    359 /**
    360  * avc_lookup - Look up an AVC entry.
    361  * @ssid: source security identifier
    362  * @tsid: target security identifier
    363  * @tclass: target security class
    364  * @requested: requested permissions, interpreted based on @tclass
    365  * @aeref:  AVC entry reference
    366  *
    367  * Look up an AVC entry that is valid for the
    368  * @requested permissions between the SID pair
    369  * (@ssid, @tsid), interpreting the permissions
    370  * based on @tclass.  If a valid AVC entry exists,
    371  * then this function updates @aeref to refer to the
    372  * entry and returns %0.  Otherwise, -1 is returned.
    373  */
    374 static int avc_lookup(security_id_t ssid, security_id_t tsid,
    375 		      security_class_t tclass,
    376 		      access_vector_t requested, struct avc_entry_ref *aeref)
    377 {
    378 	struct avc_node *node;
    379 	int probes, rc = 0;
    380 
    381 	avc_cache_stats_incr(cav_lookups);
    382 	node = avc_search_node(ssid, tsid, tclass, &probes);
    383 
    384 	if (node && ((node->ae.avd.decided & requested) == requested)) {
    385 		avc_cache_stats_incr(cav_hits);
    386 		avc_cache_stats_add(cav_probes, probes);
    387 		aeref->ae = &node->ae;
    388 		goto out;
    389 	}
    390 
    391 	avc_cache_stats_incr(cav_misses);
    392 	rc = -1;
    393       out:
    394 	return rc;
    395 }
    396 
    397 /**
    398  * avc_insert - Insert an AVC entry.
    399  * @ssid: source security identifier
    400  * @tsid: target security identifier
    401  * @tclass: target security class
    402  * @ae: AVC entry
    403  * @aeref:  AVC entry reference
    404  *
    405  * Insert an AVC entry for the SID pair
    406  * (@ssid, @tsid) and class @tclass.
    407  * The access vectors and the sequence number are
    408  * normally provided by the security server in
    409  * response to a security_compute_av() call.  If the
    410  * sequence number @ae->avd.seqno is not less than the latest
    411  * revocation notification, then the function copies
    412  * the access vectors into a cache entry, updates
    413  * @aeref to refer to the entry, and returns %0.
    414  * Otherwise, this function returns -%1 with @errno set to %EAGAIN.
    415  */
    416 static int avc_insert(security_id_t ssid, security_id_t tsid,
    417 		      security_class_t tclass,
    418 		      struct avc_entry *ae, struct avc_entry_ref *aeref)
    419 {
    420 	struct avc_node *node;
    421 	int rc = 0;
    422 
    423 	if (ae->avd.seqno < avc_cache.latest_notif) {
    424 		avc_log(SELINUX_WARNING,
    425 			"%s:  seqno %d < latest_notif %d\n", avc_prefix,
    426 			ae->avd.seqno, avc_cache.latest_notif);
    427 		errno = EAGAIN;
    428 		rc = -1;
    429 		goto out;
    430 	}
    431 
    432 	node = avc_claim_node(ssid, tsid, tclass);
    433 	if (!node) {
    434 		rc = -1;
    435 		goto out;
    436 	}
    437 
    438 	memcpy(&node->ae.avd, &ae->avd, sizeof ae->avd);
    439 	aeref->ae = &node->ae;
    440       out:
    441 	return rc;
    442 }
    443 
    444 void avc_cleanup(void)
    445 {
    446 }
    447 
    448 hidden_def(avc_cleanup)
    449 
    450 int avc_reset(void)
    451 {
    452 	struct avc_callback_node *c;
    453 	int i, ret, rc = 0, errsave = 0;
    454 	struct avc_node *node, *tmp;
    455 	errno = 0;
    456 
    457 	if (!avc_running)
    458 		return 0;
    459 
    460 	avc_get_lock(avc_lock);
    461 
    462 	for (i = 0; i < AVC_CACHE_SLOTS; i++) {
    463 		node = avc_cache.slots[i];
    464 		while (node) {
    465 			tmp = node;
    466 			node = node->next;
    467 			avc_clear_avc_entry(&tmp->ae);
    468 			tmp->next = avc_node_freelist;
    469 			avc_node_freelist = tmp;
    470 			avc_cache.active_nodes--;
    471 		}
    472 		avc_cache.slots[i] = 0;
    473 	}
    474 	avc_cache.lru_hint = 0;
    475 
    476 	avc_release_lock(avc_lock);
    477 
    478 	memset(&cache_stats, 0, sizeof(cache_stats));
    479 
    480 	for (c = avc_callbacks; c; c = c->next) {
    481 		if (c->events & AVC_CALLBACK_RESET) {
    482 			ret = c->callback(AVC_CALLBACK_RESET, 0, 0, 0, 0, 0);
    483 			if (ret && !rc) {
    484 				rc = ret;
    485 				errsave = errno;
    486 			}
    487 		}
    488 	}
    489 	errno = errsave;
    490 	return rc;
    491 }
    492 
    493 hidden_def(avc_reset)
    494 
    495 void avc_destroy(void)
    496 {
    497 	struct avc_callback_node *c;
    498 	struct avc_node *node, *tmp;
    499 	int i;
    500 
    501 	avc_get_lock(avc_lock);
    502 
    503 	if (avc_using_threads)
    504 		avc_stop_thread(avc_netlink_thread);
    505 	avc_netlink_close();
    506 
    507 	for (i = 0; i < AVC_CACHE_SLOTS; i++) {
    508 		node = avc_cache.slots[i];
    509 		while (node) {
    510 			tmp = node;
    511 			node = node->next;
    512 			avc_free(tmp);
    513 		}
    514 	}
    515 	while (avc_node_freelist) {
    516 		tmp = avc_node_freelist;
    517 		avc_node_freelist = tmp->next;
    518 		avc_free(tmp);
    519 	}
    520 	avc_release_lock(avc_lock);
    521 
    522 	while (avc_callbacks) {
    523 		c = avc_callbacks;
    524 		avc_callbacks = c->next;
    525 		avc_free(c);
    526 	}
    527 	sidtab_destroy(&avc_sidtab);
    528 	avc_free_lock(avc_lock);
    529 	avc_free_lock(avc_log_lock);
    530 	avc_free(avc_audit_buf);
    531 	avc_running = 0;
    532 }
    533 
    534 /* ratelimit stuff put aside for now --EFW */
    535 #if 0
    536 /*
    537  * Copied from net/core/utils.c:net_ratelimit and modified for
    538  * use by the AVC audit facility.
    539  */
    540 #define AVC_MSG_COST	5*HZ
    541 #define AVC_MSG_BURST	10*5*HZ
    542 
    543 /*
    544  * This enforces a rate limit: not more than one kernel message
    545  * every 5secs to make a denial-of-service attack impossible.
    546  */
    547 static int avc_ratelimit(void)
    548 {
    549 	static unsigned long toks = 10 * 5 * HZ;
    550 	static unsigned long last_msg;
    551 	static int missed, rc = 0;
    552 	unsigned long now = jiffies;
    553 	void *ratelimit_lock = avc_alloc_lock();
    554 
    555 	avc_get_lock(ratelimit_lock);
    556 	toks += now - last_msg;
    557 	last_msg = now;
    558 	if (toks > AVC_MSG_BURST)
    559 		toks = AVC_MSG_BURST;
    560 	if (toks >= AVC_MSG_COST) {
    561 		int lost = missed;
    562 		missed = 0;
    563 		toks -= AVC_MSG_COST;
    564 		avc_release_lock(ratelimit_lock);
    565 		if (lost) {
    566 			avc_log(SELINUX_WARNING,
    567 				"%s:  %d messages suppressed.\n", avc_prefix,
    568 				lost);
    569 		}
    570 		rc = 1;
    571 		goto out;
    572 	}
    573 	missed++;
    574 	avc_release_lock(ratelimit_lock);
    575       out:
    576 	avc_free_lock(ratelimit_lock);
    577 	return rc;
    578 }
    579 
    580 static inline int check_avc_ratelimit(void)
    581 {
    582 	if (avc_enforcing)
    583 		return avc_ratelimit();
    584 	else {
    585 		/* If permissive, then never suppress messages. */
    586 		return 1;
    587 	}
    588 }
    589 #endif				/* ratelimit stuff */
    590 
    591 /**
    592  * avc_dump_av - Display an access vector in human-readable form.
    593  * @tclass: target security class
    594  * @av: access vector
    595  */
    596 static void avc_dump_av(security_class_t tclass, access_vector_t av)
    597 {
    598 	const char *permstr;
    599 	access_vector_t bit = 1;
    600 
    601 	if (av == 0) {
    602 		log_append(avc_audit_buf, " null");
    603 		return;
    604 	}
    605 
    606 	log_append(avc_audit_buf, " {");
    607 
    608 	while (av) {
    609 		if (av & bit) {
    610 			permstr = security_av_perm_to_string(tclass, bit);
    611 			if (!permstr)
    612 				break;
    613 			log_append(avc_audit_buf, " %s", permstr);
    614 			av &= ~bit;
    615 		}
    616 		bit <<= 1;
    617 	}
    618 
    619 	if (av)
    620 		log_append(avc_audit_buf, " 0x%x", av);
    621 	log_append(avc_audit_buf, " }");
    622 }
    623 
    624 /**
    625  * avc_dump_query - Display a SID pair and a class in human-readable form.
    626  * @ssid: source security identifier
    627  * @tsid: target security identifier
    628  * @tclass: target security class
    629  */
    630 static void avc_dump_query(security_id_t ssid, security_id_t tsid,
    631 			   security_class_t tclass)
    632 {
    633 	avc_get_lock(avc_lock);
    634 
    635 	log_append(avc_audit_buf, "scontext=%s tcontext=%s",
    636 		   ssid->ctx, tsid->ctx);
    637 
    638 	avc_release_lock(avc_lock);
    639 	log_append(avc_audit_buf, " tclass=%s",
    640 		   security_class_to_string(tclass));
    641 }
    642 
    643 void avc_audit(security_id_t ssid, security_id_t tsid,
    644 	       security_class_t tclass, access_vector_t requested,
    645 	       struct av_decision *avd, int result, void *a)
    646 {
    647 	access_vector_t denied, audited;
    648 
    649 	denied = requested & ~avd->allowed;
    650 	if (denied)
    651 		audited = denied & avd->auditdeny;
    652 	else if (!requested || result)
    653 		audited = denied = requested;
    654 	else
    655 		audited = requested & avd->auditallow;
    656 	if (!audited)
    657 		return;
    658 #if 0
    659 	if (!check_avc_ratelimit())
    660 		return;
    661 #endif
    662 	/* prevent overlapping buffer writes */
    663 	avc_get_lock(avc_log_lock);
    664 	snprintf(avc_audit_buf, AVC_AUDIT_BUFSIZE,
    665 		 "%s:  %s ", avc_prefix, (denied || !requested) ? "denied" : "granted");
    666 	avc_dump_av(tclass, audited);
    667 	log_append(avc_audit_buf, " for ");
    668 
    669 	/* get any extra information printed by the callback */
    670 	avc_suppl_audit(a, tclass, avc_audit_buf + strlen(avc_audit_buf),
    671 			AVC_AUDIT_BUFSIZE - strlen(avc_audit_buf));
    672 
    673 	log_append(avc_audit_buf, " ");
    674 	avc_dump_query(ssid, tsid, tclass);
    675 	log_append(avc_audit_buf, "\n");
    676 	avc_log(SELINUX_AVC, "%s", avc_audit_buf);
    677 
    678 	avc_release_lock(avc_log_lock);
    679 }
    680 
    681 hidden_def(avc_audit)
    682 
    683 int avc_has_perm_noaudit(security_id_t ssid,
    684 			 security_id_t tsid,
    685 			 security_class_t tclass,
    686 			 access_vector_t requested,
    687 			 struct avc_entry_ref *aeref, struct av_decision *avd)
    688 {
    689 	struct avc_entry *ae;
    690 	int rc = 0;
    691 	struct avc_entry entry;
    692 	access_vector_t denied;
    693 	struct avc_entry_ref ref;
    694 
    695 	if (!avc_using_threads && !avc_app_main_loop) {
    696 		(void)avc_netlink_check_nb();
    697 	}
    698 
    699 	if (!aeref) {
    700 		avc_entry_ref_init(&ref);
    701 		aeref = &ref;
    702 	}
    703 
    704 	avc_get_lock(avc_lock);
    705 	avc_cache_stats_incr(entry_lookups);
    706 	ae = aeref->ae;
    707 	if (ae) {
    708 		if (ae->ssid == ssid &&
    709 		    ae->tsid == tsid &&
    710 		    ae->tclass == tclass &&
    711 		    ((ae->avd.decided & requested) == requested)) {
    712 			avc_cache_stats_incr(entry_hits);
    713 			ae->used = 1;
    714 		} else {
    715 			avc_cache_stats_incr(entry_discards);
    716 			ae = 0;
    717 		}
    718 	}
    719 
    720 	if (!ae) {
    721 		avc_cache_stats_incr(entry_misses);
    722 		rc = avc_lookup(ssid, tsid, tclass, requested, aeref);
    723 		if (rc) {
    724 			rc = security_compute_av(ssid->ctx, tsid->ctx,
    725 						 tclass, requested,
    726 						 &entry.avd);
    727 			if (rc)
    728 				goto out;
    729 			rc = avc_insert(ssid, tsid, tclass, &entry, aeref);
    730 			if (rc)
    731 				goto out;
    732 		}
    733 		ae = aeref->ae;
    734 	}
    735 
    736 	if (avd)
    737 		memcpy(avd, &ae->avd, sizeof(*avd));
    738 
    739 	denied = requested & ~(ae->avd.allowed);
    740 
    741 	if (!requested || denied) {
    742 		if (!avc_enforcing ||
    743 		    (ae->avd.flags & SELINUX_AVD_FLAGS_PERMISSIVE))
    744 			ae->avd.allowed |= requested;
    745 		else {
    746 			errno = EACCES;
    747 			rc = -1;
    748 		}
    749 	}
    750 
    751       out:
    752 	avc_release_lock(avc_lock);
    753 	return rc;
    754 }
    755 
    756 hidden_def(avc_has_perm_noaudit)
    757 
    758 int avc_has_perm(security_id_t ssid, security_id_t tsid,
    759 		 security_class_t tclass, access_vector_t requested,
    760 		 struct avc_entry_ref *aeref, void *auditdata)
    761 {
    762 	struct av_decision avd;
    763 	int errsave, rc;
    764 
    765 	memset(&avd, 0, sizeof(avd));
    766 
    767 	rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, aeref, &avd);
    768 	errsave = errno;
    769 	avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata);
    770 	errno = errsave;
    771 	return rc;
    772 }
    773 
    774 int avc_compute_create(security_id_t ssid,  security_id_t tsid,
    775 		       security_class_t tclass, security_id_t *newsid)
    776 {
    777 	int rc;
    778 	struct avc_entry_ref aeref;
    779 	struct avc_entry entry;
    780 	security_context_t ctx;
    781 
    782 	*newsid = NULL;
    783 	avc_entry_ref_init(&aeref);
    784 
    785 	avc_get_lock(avc_lock);
    786 
    787 	/* check for a cached entry */
    788 	rc = avc_lookup(ssid, tsid, tclass, 0, &aeref);
    789 	if (rc) {
    790 		/* need to make a cache entry for this tuple */
    791 		rc = security_compute_av(ssid->ctx, tsid->ctx,
    792 					 tclass, 0, &entry.avd);
    793 		if (rc)
    794 			goto out;
    795 		rc = avc_insert(ssid, tsid, tclass, &entry, &aeref);
    796 		if (rc)
    797 			goto out;
    798 	}
    799 
    800 	/* check for a saved compute_create value */
    801 	if (!aeref.ae->create_sid) {
    802 		/* need to query the kernel policy */
    803 		rc = security_compute_create(ssid->ctx, tsid->ctx, tclass,
    804 						 &ctx);
    805 		if (rc)
    806 			goto out;
    807 		rc = sidtab_context_to_sid(&avc_sidtab, ctx, newsid);
    808 		freecon(ctx);
    809 		if (rc)
    810 			goto out;
    811 
    812 		aeref.ae->create_sid = *newsid;
    813 	} else {
    814 		/* found saved value */
    815 		*newsid = aeref.ae->create_sid;
    816 	}
    817 
    818 	rc = 0;
    819 out:
    820 	avc_release_lock(avc_lock);
    821 	return rc;
    822 }
    823 
    824 int avc_add_callback(int (*callback) (uint32_t event, security_id_t ssid,
    825 				      security_id_t tsid,
    826 				      security_class_t tclass,
    827 				      access_vector_t perms,
    828 				      access_vector_t * out_retained),
    829 		     uint32_t events, security_id_t ssid,
    830 		     security_id_t tsid,
    831 		     security_class_t tclass, access_vector_t perms)
    832 {
    833 	struct avc_callback_node *c;
    834 	int rc = 0;
    835 
    836 	c = avc_malloc(sizeof(*c));
    837 	if (!c) {
    838 		rc = -1;
    839 		goto out;
    840 	}
    841 
    842 	c->callback = callback;
    843 	c->events = events;
    844 	c->ssid = ssid;
    845 	c->tsid = tsid;
    846 	c->tclass = tclass;
    847 	c->perms = perms;
    848 	c->next = avc_callbacks;
    849 	avc_callbacks = c;
    850       out:
    851 	return rc;
    852 }
    853 
    854 static inline int avc_sidcmp(security_id_t x, security_id_t y)
    855 {
    856 	return (x == y || x == SECSID_WILD || y == SECSID_WILD);
    857 }
    858 
    859 static inline void avc_update_node(uint32_t event, struct avc_node *node,
    860 				   access_vector_t perms)
    861 {
    862 	switch (event) {
    863 	case AVC_CALLBACK_GRANT:
    864 		node->ae.avd.allowed |= perms;
    865 		break;
    866 	case AVC_CALLBACK_TRY_REVOKE:
    867 	case AVC_CALLBACK_REVOKE:
    868 		node->ae.avd.allowed &= ~perms;
    869 		break;
    870 	case AVC_CALLBACK_AUDITALLOW_ENABLE:
    871 		node->ae.avd.auditallow |= perms;
    872 		break;
    873 	case AVC_CALLBACK_AUDITALLOW_DISABLE:
    874 		node->ae.avd.auditallow &= ~perms;
    875 		break;
    876 	case AVC_CALLBACK_AUDITDENY_ENABLE:
    877 		node->ae.avd.auditdeny |= perms;
    878 		break;
    879 	case AVC_CALLBACK_AUDITDENY_DISABLE:
    880 		node->ae.avd.auditdeny &= ~perms;
    881 		break;
    882 	}
    883 }
    884 
    885 static int avc_update_cache(uint32_t event, security_id_t ssid,
    886 			    security_id_t tsid, security_class_t tclass,
    887 			    access_vector_t perms)
    888 {
    889 	struct avc_node *node;
    890 	int i;
    891 
    892 	avc_get_lock(avc_lock);
    893 
    894 	if (ssid == SECSID_WILD || tsid == SECSID_WILD) {
    895 		/* apply to all matching nodes */
    896 		for (i = 0; i < AVC_CACHE_SLOTS; i++) {
    897 			for (node = avc_cache.slots[i]; node; node = node->next) {
    898 				if (avc_sidcmp(ssid, node->ae.ssid) &&
    899 				    avc_sidcmp(tsid, node->ae.tsid) &&
    900 				    tclass == node->ae.tclass) {
    901 					avc_update_node(event, node, perms);
    902 				}
    903 			}
    904 		}
    905 	} else {
    906 		/* apply to one node */
    907 		node = avc_search_node(ssid, tsid, tclass, 0);
    908 		if (node) {
    909 			avc_update_node(event, node, perms);
    910 		}
    911 	}
    912 
    913 	avc_release_lock(avc_lock);
    914 
    915 	return 0;
    916 }
    917 
    918 /* avc_control - update cache and call callbacks
    919  *
    920  * This should not be called directly; use the individual event
    921  * functions instead.
    922  */
    923 static int avc_control(uint32_t event, security_id_t ssid,
    924 		       security_id_t tsid, security_class_t tclass,
    925 		       access_vector_t perms,
    926 		       uint32_t seqno, access_vector_t * out_retained)
    927 {
    928 	struct avc_callback_node *c;
    929 	access_vector_t tretained = 0, cretained = 0;
    930 	int ret, rc = 0, errsave = 0;
    931 	errno = 0;
    932 
    933 	/*
    934 	 * try_revoke only removes permissions from the cache
    935 	 * state if they are not retained by the object manager.
    936 	 * Hence, try_revoke must wait until after the callbacks have
    937 	 * been invoked to update the cache state.
    938 	 */
    939 	if (event != AVC_CALLBACK_TRY_REVOKE)
    940 		avc_update_cache(event, ssid, tsid, tclass, perms);
    941 
    942 	for (c = avc_callbacks; c; c = c->next) {
    943 		if ((c->events & event) &&
    944 		    avc_sidcmp(c->ssid, ssid) &&
    945 		    avc_sidcmp(c->tsid, tsid) &&
    946 		    c->tclass == tclass && (c->perms & perms)) {
    947 			cretained = 0;
    948 			ret = c->callback(event, ssid, tsid, tclass,
    949 					  (c->perms & perms), &cretained);
    950 			if (ret && !rc) {
    951 				rc = ret;
    952 				errsave = errno;
    953 			}
    954 			if (!ret)
    955 				tretained |= cretained;
    956 		}
    957 	}
    958 
    959 	if (event == AVC_CALLBACK_TRY_REVOKE) {
    960 		/* revoke any unretained permissions */
    961 		perms &= ~tretained;
    962 		avc_update_cache(event, ssid, tsid, tclass, perms);
    963 		*out_retained = tretained;
    964 	}
    965 
    966 	avc_get_lock(avc_lock);
    967 	if (seqno > avc_cache.latest_notif)
    968 		avc_cache.latest_notif = seqno;
    969 	avc_release_lock(avc_lock);
    970 
    971 	errno = errsave;
    972 	return rc;
    973 }
    974 
    975 /**
    976  * avc_ss_grant - Grant previously denied permissions.
    977  * @ssid: source security identifier or %SECSID_WILD
    978  * @tsid: target security identifier or %SECSID_WILD
    979  * @tclass: target security class
    980  * @perms: permissions to grant
    981  * @seqno: policy sequence number
    982  */
    983 int avc_ss_grant(security_id_t ssid, security_id_t tsid,
    984 		 security_class_t tclass, access_vector_t perms,
    985 		 uint32_t seqno)
    986 {
    987 	return avc_control(AVC_CALLBACK_GRANT,
    988 			   ssid, tsid, tclass, perms, seqno, 0);
    989 }
    990 
    991 /**
    992  * avc_ss_try_revoke - Try to revoke previously granted permissions.
    993  * @ssid: source security identifier or %SECSID_WILD
    994  * @tsid: target security identifier or %SECSID_WILD
    995  * @tclass: target security class
    996  * @perms: permissions to grant
    997  * @seqno: policy sequence number
    998  * @out_retained: subset of @perms that are retained
    999  *
   1000  * Try to revoke previously granted permissions, but
   1001  * only if they are not retained as migrated permissions.
   1002  * Return the subset of permissions that are retained via @out_retained.
   1003  */
   1004 int avc_ss_try_revoke(security_id_t ssid, security_id_t tsid,
   1005 		      security_class_t tclass,
   1006 		      access_vector_t perms, uint32_t seqno,
   1007 		      access_vector_t * out_retained)
   1008 {
   1009 	return avc_control(AVC_CALLBACK_TRY_REVOKE,
   1010 			   ssid, tsid, tclass, perms, seqno, out_retained);
   1011 }
   1012 
   1013 /**
   1014  * avc_ss_revoke - Revoke previously granted permissions.
   1015  * @ssid: source security identifier or %SECSID_WILD
   1016  * @tsid: target security identifier or %SECSID_WILD
   1017  * @tclass: target security class
   1018  * @perms: permissions to grant
   1019  * @seqno: policy sequence number
   1020  *
   1021  * Revoke previously granted permissions, even if
   1022  * they are retained as migrated permissions.
   1023  */
   1024 int avc_ss_revoke(security_id_t ssid, security_id_t tsid,
   1025 		  security_class_t tclass, access_vector_t perms,
   1026 		  uint32_t seqno)
   1027 {
   1028 	return avc_control(AVC_CALLBACK_REVOKE,
   1029 			   ssid, tsid, tclass, perms, seqno, 0);
   1030 }
   1031 
   1032 /**
   1033  * avc_ss_reset - Flush the cache and revalidate migrated permissions.
   1034  * @seqno: policy sequence number
   1035  */
   1036 int avc_ss_reset(uint32_t seqno)
   1037 {
   1038 	int rc;
   1039 
   1040 	rc = avc_reset();
   1041 
   1042 	avc_get_lock(avc_lock);
   1043 	if (seqno > avc_cache.latest_notif)
   1044 		avc_cache.latest_notif = seqno;
   1045 	avc_release_lock(avc_lock);
   1046 
   1047 	return rc;
   1048 }
   1049 
   1050 /**
   1051  * avc_ss_set_auditallow - Enable or disable auditing of granted permissions.
   1052  * @ssid: source security identifier or %SECSID_WILD
   1053  * @tsid: target security identifier or %SECSID_WILD
   1054  * @tclass: target security class
   1055  * @perms: permissions to grant
   1056  * @seqno: policy sequence number
   1057  * @enable: enable flag.
   1058  */
   1059 int avc_ss_set_auditallow(security_id_t ssid, security_id_t tsid,
   1060 			  security_class_t tclass, access_vector_t perms,
   1061 			  uint32_t seqno, uint32_t enable)
   1062 {
   1063 	if (enable)
   1064 		return avc_control(AVC_CALLBACK_AUDITALLOW_ENABLE,
   1065 				   ssid, tsid, tclass, perms, seqno, 0);
   1066 	else
   1067 		return avc_control(AVC_CALLBACK_AUDITALLOW_DISABLE,
   1068 				   ssid, tsid, tclass, perms, seqno, 0);
   1069 }
   1070 
   1071 /**
   1072  * avc_ss_set_auditdeny - Enable or disable auditing of denied permissions.
   1073  * @ssid: source security identifier or %SECSID_WILD
   1074  * @tsid: target security identifier or %SECSID_WILD
   1075  * @tclass: target security class
   1076  * @perms: permissions to grant
   1077  * @seqno: policy sequence number
   1078  * @enable: enable flag.
   1079  */
   1080 int avc_ss_set_auditdeny(security_id_t ssid, security_id_t tsid,
   1081 			 security_class_t tclass, access_vector_t perms,
   1082 			 uint32_t seqno, uint32_t enable)
   1083 {
   1084 	if (enable)
   1085 		return avc_control(AVC_CALLBACK_AUDITDENY_ENABLE,
   1086 				   ssid, tsid, tclass, perms, seqno, 0);
   1087 	else
   1088 		return avc_control(AVC_CALLBACK_AUDITDENY_DISABLE,
   1089 				   ssid, tsid, tclass, perms, seqno, 0);
   1090 }
   1091