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