• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Implementation of the userspace access vector cache (AVC).
3  *
4  * Author : Eamon Walsh <ewalsh@epoch.ncsc.mil>
5  *
6  * Derived from the kernel AVC implementation by
7  * Stephen Smalley <sds@epoch.ncsc.mil> and
8  * James Morris <jmorris@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 
avc_hash(security_id_t ssid,security_id_t tsid,security_class_t tclass)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 
avc_context_to_sid(const char * ctx,security_id_t * sid)69 int avc_context_to_sid(const char * 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 
avc_sid_to_context(security_id_t sid,char ** ctx)78 int avc_sid_to_context(security_id_t sid, char ** 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 
avc_get_initial_sid(const char * name,security_id_t * sid)89 int avc_get_initial_sid(const char * name, security_id_t * sid)
90 {
91 	int rc;
92 	char * 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 
avc_open(struct selinux_opt * opts,unsigned nopts)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 
avc_init(const char * prefix,const struct avc_memory_callback * mem_cb,const struct avc_log_callback * log_cb,const struct avc_thread_callback * thread_cb,const struct avc_lock_callback * lock_cb)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 
avc_cache_stats(struct avc_cache_stats * p)202 void avc_cache_stats(struct avc_cache_stats *p)
203 {
204 	memcpy(p, &cache_stats, sizeof(cache_stats));
205 }
206 
avc_sid_stats(void)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 
avc_av_stats(void)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 
hidden_def(avc_av_stats)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 
avc_clear_avc_entry(struct avc_entry * ae)288 static inline void avc_clear_avc_entry(struct avc_entry *ae)
289 {
290 	memset(ae, 0, sizeof *ae);
291 }
292 
avc_claim_node(security_id_t ssid,security_id_t tsid,security_class_t tclass)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 
avc_search_node(security_id_t ssid,security_id_t tsid,security_class_t tclass,int * probes)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  */
avc_lookup(security_id_t ssid,security_id_t tsid,security_class_t tclass,access_vector_t requested,struct avc_entry_ref * aeref)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  */
avc_insert(security_id_t ssid,security_id_t tsid,security_class_t tclass,struct avc_entry * ae,struct avc_entry_ref * aeref)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 
avc_cleanup(void)444 void avc_cleanup(void)
445 {
446 }
447 
hidden_def(avc_cleanup)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 
hidden_def(avc_reset)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  */
avc_dump_av(security_class_t tclass,access_vector_t av)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  */
avc_dump_query(security_id_t ssid,security_id_t tsid,security_class_t tclass)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 
avc_audit(security_id_t ssid,security_id_t tsid,security_class_t tclass,access_vector_t requested,struct av_decision * avd,int result,void * a)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 
hidden_def(avc_audit)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 
hidden_def(avc_has_perm_noaudit)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 
avc_compute_create(security_id_t ssid,security_id_t tsid,security_class_t tclass,security_id_t * newsid)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 	char * 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 
avc_add_callback(int (* callback)(uint32_t event,security_id_t ssid,security_id_t tsid,security_class_t tclass,access_vector_t perms,access_vector_t * out_retained),uint32_t events,security_id_t ssid,security_id_t tsid,security_class_t tclass,access_vector_t perms)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 
avc_sidcmp(security_id_t x,security_id_t y)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 
avc_update_node(uint32_t event,struct avc_node * node,access_vector_t perms)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 
avc_update_cache(uint32_t event,security_id_t ssid,security_id_t tsid,security_class_t tclass,access_vector_t perms)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  */
avc_control(uint32_t event,security_id_t ssid,security_id_t tsid,security_class_t tclass,access_vector_t perms,uint32_t seqno,access_vector_t * out_retained)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  */
avc_ss_grant(security_id_t ssid,security_id_t tsid,security_class_t tclass,access_vector_t perms,uint32_t seqno)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  */
avc_ss_try_revoke(security_id_t ssid,security_id_t tsid,security_class_t tclass,access_vector_t perms,uint32_t seqno,access_vector_t * out_retained)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  */
avc_ss_revoke(security_id_t ssid,security_id_t tsid,security_class_t tclass,access_vector_t perms,uint32_t seqno)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  */
avc_ss_reset(uint32_t seqno)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  */
avc_ss_set_auditallow(security_id_t ssid,security_id_t tsid,security_class_t tclass,access_vector_t perms,uint32_t seqno,uint32_t enable)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  */
avc_ss_set_auditdeny(security_id_t ssid,security_id_t tsid,security_class_t tclass,access_vector_t perms,uint32_t seqno,uint32_t enable)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