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 <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 
avc_hash(security_id_t ssid,security_id_t tsid,security_class_t tclass)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 
avc_context_to_sid(const char * ctx,security_id_t * sid)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 
avc_sid_to_context(security_id_t sid,char ** ctx)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 
avc_get_initial_sid(const char * name,security_id_t * sid)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 
avc_open(struct selinux_opt * opts,unsigned nopts)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 
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)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 
avc_cache_stats(struct avc_cache_stats * p)209 void avc_cache_stats(struct avc_cache_stats *p)
210 {
211 	memcpy(p, &cache_stats, sizeof(cache_stats));
212 }
213 
avc_sid_stats(void)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 
avc_av_stats(void)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 
hidden_def(avc_av_stats)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 
avc_clear_avc_entry(struct avc_entry * ae)297 static inline void avc_clear_avc_entry(struct avc_entry *ae)
298 {
299 	memset(ae, 0, sizeof(*ae));
300 }
301 
avc_claim_node(security_id_t ssid,security_id_t tsid,security_class_t tclass)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 
avc_search_node(security_id_t ssid,security_id_t tsid,security_class_t tclass,int * probes)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  */
avc_lookup(security_id_t ssid,security_id_t tsid,security_class_t tclass,access_vector_t requested,struct avc_entry_ref * aeref)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  */
avc_insert(security_id_t ssid,security_id_t tsid,security_class_t tclass,struct avc_entry * ae,struct avc_entry_ref * aeref)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 
avc_cleanup(void)453 void avc_cleanup(void)
454 {
455 }
456 
hidden_def(avc_cleanup)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 
hidden_def(avc_reset)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  */
avc_dump_av(security_class_t tclass,access_vector_t av)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  */
avc_dump_query(security_id_t ssid,security_id_t tsid,security_class_t tclass)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 
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)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 
hidden_def(avc_audit)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 
avc_has_perm_noaudit(security_id_t ssid,security_id_t tsid,security_class_t tclass,access_vector_t requested,struct avc_entry_ref * aeref,struct av_decision * avd)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 
hidden_def(avc_has_perm_noaudit)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 
avc_compute_create(security_id_t ssid,security_id_t tsid,security_class_t tclass,security_id_t * newsid)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 
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)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 
avc_sidcmp(security_id_t x,security_id_t y)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 
avc_update_node(uint32_t event,struct avc_node * node,access_vector_t perms)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 
avc_update_cache(uint32_t event,security_id_t ssid,security_id_t tsid,security_class_t tclass,access_vector_t perms)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  */
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)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  */
avc_ss_grant(security_id_t ssid,security_id_t tsid,security_class_t tclass,access_vector_t perms,uint32_t seqno)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  */
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)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  */
avc_ss_revoke(security_id_t ssid,security_id_t tsid,security_class_t tclass,access_vector_t perms,uint32_t seqno)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  */
avc_ss_reset(uint32_t seqno)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  */
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)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  */
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)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