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