• 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 security_context_t ctx,security_id_t * sid)69 int avc_context_to_sid(const security_context_t ctx, security_id_t * sid)
70 {
71 	int rc;
72 	avc_get_lock(avc_lock);
73 	rc = sidtab_context_to_sid(&avc_sidtab, ctx, sid);
74 	avc_release_lock(avc_lock);
75 	return rc;
76 }
77 
avc_sid_to_context(security_id_t sid,security_context_t * ctx)78 int avc_sid_to_context(security_id_t sid, security_context_t * ctx)
79 {
80 	int rc;
81 	*ctx = NULL;
82 	avc_get_lock(avc_lock);
83 	*ctx = strdup(sid->ctx);	/* caller must free via freecon */
84 	rc = *ctx ? 0 : -1;
85 	avc_release_lock(avc_lock);
86 	return rc;
87 }
88 
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 	security_context_t con;
93 
94 	rc = security_get_initial_context(name, &con);
95 	if (rc < 0)
96 		return rc;
97 	rc = avc_context_to_sid(con, sid);
98 
99 	freecon(con);
100 
101 	return rc;
102 }
103 
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 	ae->ssid = ae->tsid = ae->create_sid = NULL;
291 	ae->tclass = 0;
292 	ae->avd.allowed = ae->avd.decided = 0;
293 	ae->avd.auditallow = ae->avd.auditdeny = 0;
294 	ae->used = 0;
295 }
296 
avc_claim_node(security_id_t ssid,security_id_t tsid,security_class_t tclass)297 static inline struct avc_node *avc_claim_node(security_id_t ssid,
298 					      security_id_t tsid,
299 					      security_class_t tclass)
300 {
301 	struct avc_node *new;
302 	int hvalue;
303 
304 	if (!avc_node_freelist)
305 		avc_cleanup();
306 
307 	if (avc_node_freelist) {
308 		new = avc_node_freelist;
309 		avc_node_freelist = avc_node_freelist->next;
310 		avc_cache.active_nodes++;
311 	} else {
312 		new = avc_reclaim_node();
313 		if (!new)
314 			goto out;
315 	}
316 
317 	hvalue = avc_hash(ssid, tsid, tclass);
318 	avc_clear_avc_entry(&new->ae);
319 	new->ae.used = 1;
320 	new->ae.ssid = ssid;
321 	new->ae.tsid = tsid;
322 	new->ae.tclass = tclass;
323 	new->next = avc_cache.slots[hvalue];
324 	avc_cache.slots[hvalue] = new;
325 
326       out:
327 	return new;
328 }
329 
avc_search_node(security_id_t ssid,security_id_t tsid,security_class_t tclass,int * probes)330 static inline struct avc_node *avc_search_node(security_id_t ssid,
331 					       security_id_t tsid,
332 					       security_class_t tclass,
333 					       int *probes)
334 {
335 	struct avc_node *cur;
336 	int hvalue;
337 	int tprobes = 1;
338 
339 	hvalue = avc_hash(ssid, tsid, tclass);
340 	cur = avc_cache.slots[hvalue];
341 	while (cur != NULL &&
342 	       (ssid != cur->ae.ssid ||
343 		tclass != cur->ae.tclass || tsid != cur->ae.tsid)) {
344 		tprobes++;
345 		cur = cur->next;
346 	}
347 
348 	if (cur == NULL) {
349 		/* cache miss */
350 		goto out;
351 	}
352 
353 	/* cache hit */
354 	if (probes)
355 		*probes = tprobes;
356 
357 	cur->ae.used = 1;
358 
359       out:
360 	return cur;
361 }
362 
363 /**
364  * avc_lookup - Look up an AVC entry.
365  * @ssid: source security identifier
366  * @tsid: target security identifier
367  * @tclass: target security class
368  * @requested: requested permissions, interpreted based on @tclass
369  * @aeref:  AVC entry reference
370  *
371  * Look up an AVC entry that is valid for the
372  * @requested permissions between the SID pair
373  * (@ssid, @tsid), interpreting the permissions
374  * based on @tclass.  If a valid AVC entry exists,
375  * then this function updates @aeref to refer to the
376  * entry and returns %0.  Otherwise, -1 is returned.
377  */
avc_lookup(security_id_t ssid,security_id_t tsid,security_class_t tclass,access_vector_t requested,struct avc_entry_ref * aeref)378 static int avc_lookup(security_id_t ssid, security_id_t tsid,
379 		      security_class_t tclass,
380 		      access_vector_t requested, struct avc_entry_ref *aeref)
381 {
382 	struct avc_node *node;
383 	int probes, rc = 0;
384 
385 	avc_cache_stats_incr(cav_lookups);
386 	node = avc_search_node(ssid, tsid, tclass, &probes);
387 
388 	if (node && ((node->ae.avd.decided & requested) == requested)) {
389 		avc_cache_stats_incr(cav_hits);
390 		avc_cache_stats_add(cav_probes, probes);
391 		aeref->ae = &node->ae;
392 		goto out;
393 	}
394 
395 	avc_cache_stats_incr(cav_misses);
396 	rc = -1;
397       out:
398 	return rc;
399 }
400 
401 /**
402  * avc_insert - Insert an AVC entry.
403  * @ssid: source security identifier
404  * @tsid: target security identifier
405  * @tclass: target security class
406  * @ae: AVC entry
407  * @aeref:  AVC entry reference
408  *
409  * Insert an AVC entry for the SID pair
410  * (@ssid, @tsid) and class @tclass.
411  * The access vectors and the sequence number are
412  * normally provided by the security server in
413  * response to a security_compute_av() call.  If the
414  * sequence number @ae->avd.seqno is not less than the latest
415  * revocation notification, then the function copies
416  * the access vectors into a cache entry, updates
417  * @aeref to refer to the entry, and returns %0.
418  * Otherwise, this function returns -%1 with @errno set to %EAGAIN.
419  */
avc_insert(security_id_t ssid,security_id_t tsid,security_class_t tclass,struct avc_entry * ae,struct avc_entry_ref * aeref)420 static int avc_insert(security_id_t ssid, security_id_t tsid,
421 		      security_class_t tclass,
422 		      struct avc_entry *ae, struct avc_entry_ref *aeref)
423 {
424 	struct avc_node *node;
425 	int rc = 0;
426 
427 	if (ae->avd.seqno < avc_cache.latest_notif) {
428 		avc_log(SELINUX_WARNING,
429 			"%s:  seqno %d < latest_notif %d\n", avc_prefix,
430 			ae->avd.seqno, avc_cache.latest_notif);
431 		errno = EAGAIN;
432 		rc = -1;
433 		goto out;
434 	}
435 
436 	node = avc_claim_node(ssid, tsid, tclass);
437 	if (!node) {
438 		rc = -1;
439 		goto out;
440 	}
441 
442 	node->ae.avd.allowed = ae->avd.allowed;
443 	node->ae.avd.decided = ae->avd.decided;
444 	node->ae.avd.auditallow = ae->avd.auditallow;
445 	node->ae.avd.auditdeny = ae->avd.auditdeny;
446 	node->ae.avd.seqno = ae->avd.seqno;
447 	aeref->ae = &node->ae;
448       out:
449 	return rc;
450 }
451 
avc_cleanup(void)452 void avc_cleanup(void)
453 {
454 }
455 
hidden_def(avc_cleanup)456 hidden_def(avc_cleanup)
457 
458 int avc_reset(void)
459 {
460 	struct avc_callback_node *c;
461 	int i, ret, rc = 0, errsave = 0;
462 	struct avc_node *node, *tmp;
463 	errno = 0;
464 
465 	if (!avc_running)
466 		return 0;
467 
468 	avc_get_lock(avc_lock);
469 
470 	for (i = 0; i < AVC_CACHE_SLOTS; i++) {
471 		node = avc_cache.slots[i];
472 		while (node) {
473 			tmp = node;
474 			node = node->next;
475 			avc_clear_avc_entry(&tmp->ae);
476 			tmp->next = avc_node_freelist;
477 			avc_node_freelist = tmp;
478 			avc_cache.active_nodes--;
479 		}
480 		avc_cache.slots[i] = 0;
481 	}
482 	avc_cache.lru_hint = 0;
483 
484 	avc_release_lock(avc_lock);
485 
486 	memset(&cache_stats, 0, sizeof(cache_stats));
487 
488 	for (c = avc_callbacks; c; c = c->next) {
489 		if (c->events & AVC_CALLBACK_RESET) {
490 			ret = c->callback(AVC_CALLBACK_RESET, 0, 0, 0, 0, 0);
491 			if (ret && !rc) {
492 				rc = ret;
493 				errsave = errno;
494 			}
495 		}
496 	}
497 	errno = errsave;
498 	return rc;
499 }
500 
hidden_def(avc_reset)501 hidden_def(avc_reset)
502 
503 void avc_destroy(void)
504 {
505 	struct avc_callback_node *c;
506 	struct avc_node *node, *tmp;
507 	int i;
508 
509 	avc_get_lock(avc_lock);
510 
511 	if (avc_using_threads)
512 		avc_stop_thread(avc_netlink_thread);
513 	avc_netlink_close();
514 
515 	for (i = 0; i < AVC_CACHE_SLOTS; i++) {
516 		node = avc_cache.slots[i];
517 		while (node) {
518 			tmp = node;
519 			node = node->next;
520 			avc_free(tmp);
521 		}
522 	}
523 	while (avc_node_freelist) {
524 		tmp = avc_node_freelist;
525 		avc_node_freelist = tmp->next;
526 		avc_free(tmp);
527 	}
528 	avc_release_lock(avc_lock);
529 
530 	while (avc_callbacks) {
531 		c = avc_callbacks;
532 		avc_callbacks = c->next;
533 		avc_free(c);
534 	}
535 	sidtab_destroy(&avc_sidtab);
536 	avc_free_lock(avc_lock);
537 	avc_free_lock(avc_log_lock);
538 	avc_free(avc_audit_buf);
539 	avc_running = 0;
540 }
541 
542 /* ratelimit stuff put aside for now --EFW */
543 #if 0
544 /*
545  * Copied from net/core/utils.c:net_ratelimit and modified for
546  * use by the AVC audit facility.
547  */
548 #define AVC_MSG_COST	5*HZ
549 #define AVC_MSG_BURST	10*5*HZ
550 
551 /*
552  * This enforces a rate limit: not more than one kernel message
553  * every 5secs to make a denial-of-service attack impossible.
554  */
555 static int avc_ratelimit(void)
556 {
557 	static unsigned long toks = 10 * 5 * HZ;
558 	static unsigned long last_msg;
559 	static int missed, rc = 0;
560 	unsigned long now = jiffies;
561 	void *ratelimit_lock = avc_alloc_lock();
562 
563 	avc_get_lock(ratelimit_lock);
564 	toks += now - last_msg;
565 	last_msg = now;
566 	if (toks > AVC_MSG_BURST)
567 		toks = AVC_MSG_BURST;
568 	if (toks >= AVC_MSG_COST) {
569 		int lost = missed;
570 		missed = 0;
571 		toks -= AVC_MSG_COST;
572 		avc_release_lock(ratelimit_lock);
573 		if (lost) {
574 			avc_log(SELINUX_WARNING,
575 				"%s:  %d messages suppressed.\n", avc_prefix,
576 				lost);
577 		}
578 		rc = 1;
579 		goto out;
580 	}
581 	missed++;
582 	avc_release_lock(ratelimit_lock);
583       out:
584 	avc_free_lock(ratelimit_lock);
585 	return rc;
586 }
587 
588 static inline int check_avc_ratelimit(void)
589 {
590 	if (avc_enforcing)
591 		return avc_ratelimit();
592 	else {
593 		/* If permissive, then never suppress messages. */
594 		return 1;
595 	}
596 }
597 #endif				/* ratelimit stuff */
598 
599 /**
600  * avc_dump_av - Display an access vector in human-readable form.
601  * @tclass: target security class
602  * @av: access vector
603  */
avc_dump_av(security_class_t tclass,access_vector_t av)604 static void avc_dump_av(security_class_t tclass, access_vector_t av)
605 {
606 	const char *permstr;
607 	access_vector_t bit = 1;
608 
609 	if (av == 0) {
610 		log_append(avc_audit_buf, " null");
611 		return;
612 	}
613 
614 	log_append(avc_audit_buf, " {");
615 
616 	while (av) {
617 		if (av & bit) {
618 			permstr = security_av_perm_to_string(tclass, bit);
619 			if (!permstr)
620 				break;
621 			log_append(avc_audit_buf, " %s", permstr);
622 			av &= ~bit;
623 		}
624 		bit <<= 1;
625 	}
626 
627 	if (av)
628 		log_append(avc_audit_buf, " 0x%x", av);
629 	log_append(avc_audit_buf, " }");
630 }
631 
632 /**
633  * avc_dump_query - Display a SID pair and a class in human-readable form.
634  * @ssid: source security identifier
635  * @tsid: target security identifier
636  * @tclass: target security class
637  */
avc_dump_query(security_id_t ssid,security_id_t tsid,security_class_t tclass)638 static void avc_dump_query(security_id_t ssid, security_id_t tsid,
639 			   security_class_t tclass)
640 {
641 	avc_get_lock(avc_lock);
642 
643 	log_append(avc_audit_buf, "scontext=%s tcontext=%s",
644 		   ssid->ctx, tsid->ctx);
645 
646 	avc_release_lock(avc_lock);
647 	log_append(avc_audit_buf, " tclass=%s",
648 		   security_class_to_string(tclass));
649 }
650 
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)651 void avc_audit(security_id_t ssid, security_id_t tsid,
652 	       security_class_t tclass, access_vector_t requested,
653 	       struct av_decision *avd, int result, void *a)
654 {
655 	access_vector_t denied, audited;
656 
657 	denied = requested & ~avd->allowed;
658 	if (denied)
659 		audited = denied & avd->auditdeny;
660 	else if (!requested || result)
661 		audited = denied = requested;
662 	else
663 		audited = requested & avd->auditallow;
664 	if (!audited)
665 		return;
666 #if 0
667 	if (!check_avc_ratelimit())
668 		return;
669 #endif
670 	/* prevent overlapping buffer writes */
671 	avc_get_lock(avc_log_lock);
672 	snprintf(avc_audit_buf, AVC_AUDIT_BUFSIZE,
673 		 "%s:  %s ", avc_prefix, (denied || !requested) ? "denied" : "granted");
674 	avc_dump_av(tclass, audited);
675 	log_append(avc_audit_buf, " for ");
676 
677 	/* get any extra information printed by the callback */
678 	avc_suppl_audit(a, tclass, avc_audit_buf + strlen(avc_audit_buf),
679 			AVC_AUDIT_BUFSIZE - strlen(avc_audit_buf));
680 
681 	log_append(avc_audit_buf, " ");
682 	avc_dump_query(ssid, tsid, tclass);
683 	log_append(avc_audit_buf, "\n");
684 	avc_log(SELINUX_AVC, "%s", avc_audit_buf);
685 
686 	avc_release_lock(avc_log_lock);
687 }
688 
hidden_def(avc_audit)689 hidden_def(avc_audit)
690 
691 int avc_has_perm_noaudit(security_id_t ssid,
692 			 security_id_t tsid,
693 			 security_class_t tclass,
694 			 access_vector_t requested,
695 			 struct avc_entry_ref *aeref, struct av_decision *avd)
696 {
697 	struct avc_entry *ae;
698 	int rc = 0;
699 	struct avc_entry entry;
700 	access_vector_t denied;
701 	struct avc_entry_ref ref;
702 
703 	if (!avc_using_threads && !avc_app_main_loop) {
704 		(void)avc_netlink_check_nb();
705 	}
706 
707 	if (!aeref) {
708 		avc_entry_ref_init(&ref);
709 		aeref = &ref;
710 	}
711 
712 	avc_get_lock(avc_lock);
713 	avc_cache_stats_incr(entry_lookups);
714 	ae = aeref->ae;
715 	if (ae) {
716 		if (ae->ssid == ssid &&
717 		    ae->tsid == tsid &&
718 		    ae->tclass == tclass &&
719 		    ((ae->avd.decided & requested) == requested)) {
720 			avc_cache_stats_incr(entry_hits);
721 			ae->used = 1;
722 		} else {
723 			avc_cache_stats_incr(entry_discards);
724 			ae = 0;
725 		}
726 	}
727 
728 	if (!ae) {
729 		avc_cache_stats_incr(entry_misses);
730 		rc = avc_lookup(ssid, tsid, tclass, requested, aeref);
731 		if (rc) {
732 			rc = security_compute_av(ssid->ctx, tsid->ctx,
733 						 tclass, requested,
734 						 &entry.avd);
735 			if (rc)
736 				goto out;
737 			rc = avc_insert(ssid, tsid, tclass, &entry, aeref);
738 			if (rc)
739 				goto out;
740 		}
741 		ae = aeref->ae;
742 	}
743 
744 	if (avd)
745 		memcpy(avd, &ae->avd, sizeof(*avd));
746 
747 	denied = requested & ~(ae->avd.allowed);
748 
749 	if (!requested || denied) {
750 		if (!avc_enforcing ||
751 		    (ae->avd.flags & SELINUX_AVD_FLAGS_PERMISSIVE))
752 			ae->avd.allowed |= requested;
753 		else {
754 			errno = EACCES;
755 			rc = -1;
756 		}
757 	}
758 
759       out:
760 	avc_release_lock(avc_lock);
761 	return rc;
762 }
763 
hidden_def(avc_has_perm_noaudit)764 hidden_def(avc_has_perm_noaudit)
765 
766 int avc_has_perm(security_id_t ssid, security_id_t tsid,
767 		 security_class_t tclass, access_vector_t requested,
768 		 struct avc_entry_ref *aeref, void *auditdata)
769 {
770 	struct av_decision avd;
771 	int errsave, rc;
772 
773 	memset(&avd, 0, sizeof(avd));
774 
775 	rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, aeref, &avd);
776 	errsave = errno;
777 	avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata);
778 	errno = errsave;
779 	return rc;
780 }
781 
avc_compute_create(security_id_t ssid,security_id_t tsid,security_class_t tclass,security_id_t * newsid)782 int avc_compute_create(security_id_t ssid,  security_id_t tsid,
783 		       security_class_t tclass, security_id_t *newsid)
784 {
785 	int rc;
786 	struct avc_entry_ref aeref;
787 	struct avc_entry entry;
788 	security_context_t ctx;
789 
790 	*newsid = NULL;
791 	avc_entry_ref_init(&aeref);
792 
793 	avc_get_lock(avc_lock);
794 
795 	/* check for a cached entry */
796 	rc = avc_lookup(ssid, tsid, tclass, 0, &aeref);
797 	if (rc) {
798 		/* need to make a cache entry for this tuple */
799 		rc = security_compute_av(ssid->ctx, tsid->ctx,
800 					 tclass, 0, &entry.avd);
801 		if (rc)
802 			goto out;
803 		rc = avc_insert(ssid, tsid, tclass, &entry, &aeref);
804 		if (rc)
805 			goto out;
806 	}
807 
808 	/* check for a saved compute_create value */
809 	if (!aeref.ae->create_sid) {
810 		/* need to query the kernel policy */
811 		rc = security_compute_create(ssid->ctx, tsid->ctx, tclass,
812 						 &ctx);
813 		if (rc)
814 			goto out;
815 		rc = sidtab_context_to_sid(&avc_sidtab, ctx, newsid);
816 		freecon(ctx);
817 		if (rc)
818 			goto out;
819 
820 		aeref.ae->create_sid = *newsid;
821 	} else {
822 		/* found saved value */
823 		*newsid = aeref.ae->create_sid;
824 	}
825 
826 	rc = 0;
827 out:
828 	avc_release_lock(avc_lock);
829 	return rc;
830 }
831 
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)832 int avc_add_callback(int (*callback) (uint32_t event, security_id_t ssid,
833 				      security_id_t tsid,
834 				      security_class_t tclass,
835 				      access_vector_t perms,
836 				      access_vector_t * out_retained),
837 		     uint32_t events, security_id_t ssid,
838 		     security_id_t tsid,
839 		     security_class_t tclass, access_vector_t perms)
840 {
841 	struct avc_callback_node *c;
842 	int rc = 0;
843 
844 	c = avc_malloc(sizeof(*c));
845 	if (!c) {
846 		rc = -1;
847 		goto out;
848 	}
849 
850 	c->callback = callback;
851 	c->events = events;
852 	c->ssid = ssid;
853 	c->tsid = tsid;
854 	c->tclass = tclass;
855 	c->perms = perms;
856 	c->next = avc_callbacks;
857 	avc_callbacks = c;
858       out:
859 	return rc;
860 }
861 
avc_sidcmp(security_id_t x,security_id_t y)862 static inline int avc_sidcmp(security_id_t x, security_id_t y)
863 {
864 	return (x == y || x == SECSID_WILD || y == SECSID_WILD);
865 }
866 
avc_update_node(uint32_t event,struct avc_node * node,access_vector_t perms)867 static inline void avc_update_node(uint32_t event, struct avc_node *node,
868 				   access_vector_t perms)
869 {
870 	switch (event) {
871 	case AVC_CALLBACK_GRANT:
872 		node->ae.avd.allowed |= perms;
873 		break;
874 	case AVC_CALLBACK_TRY_REVOKE:
875 	case AVC_CALLBACK_REVOKE:
876 		node->ae.avd.allowed &= ~perms;
877 		break;
878 	case AVC_CALLBACK_AUDITALLOW_ENABLE:
879 		node->ae.avd.auditallow |= perms;
880 		break;
881 	case AVC_CALLBACK_AUDITALLOW_DISABLE:
882 		node->ae.avd.auditallow &= ~perms;
883 		break;
884 	case AVC_CALLBACK_AUDITDENY_ENABLE:
885 		node->ae.avd.auditdeny |= perms;
886 		break;
887 	case AVC_CALLBACK_AUDITDENY_DISABLE:
888 		node->ae.avd.auditdeny &= ~perms;
889 		break;
890 	}
891 }
892 
avc_update_cache(uint32_t event,security_id_t ssid,security_id_t tsid,security_class_t tclass,access_vector_t perms)893 static int avc_update_cache(uint32_t event, security_id_t ssid,
894 			    security_id_t tsid, security_class_t tclass,
895 			    access_vector_t perms)
896 {
897 	struct avc_node *node;
898 	int i;
899 
900 	avc_get_lock(avc_lock);
901 
902 	if (ssid == SECSID_WILD || tsid == SECSID_WILD) {
903 		/* apply to all matching nodes */
904 		for (i = 0; i < AVC_CACHE_SLOTS; i++) {
905 			for (node = avc_cache.slots[i]; node; node = node->next) {
906 				if (avc_sidcmp(ssid, node->ae.ssid) &&
907 				    avc_sidcmp(tsid, node->ae.tsid) &&
908 				    tclass == node->ae.tclass) {
909 					avc_update_node(event, node, perms);
910 				}
911 			}
912 		}
913 	} else {
914 		/* apply to one node */
915 		node = avc_search_node(ssid, tsid, tclass, 0);
916 		if (node) {
917 			avc_update_node(event, node, perms);
918 		}
919 	}
920 
921 	avc_release_lock(avc_lock);
922 
923 	return 0;
924 }
925 
926 /* avc_control - update cache and call callbacks
927  *
928  * This should not be called directly; use the individual event
929  * functions instead.
930  */
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)931 static int avc_control(uint32_t event, security_id_t ssid,
932 		       security_id_t tsid, security_class_t tclass,
933 		       access_vector_t perms,
934 		       uint32_t seqno, access_vector_t * out_retained)
935 {
936 	struct avc_callback_node *c;
937 	access_vector_t tretained = 0, cretained = 0;
938 	int ret, rc = 0, errsave = 0;
939 	errno = 0;
940 
941 	/*
942 	 * try_revoke only removes permissions from the cache
943 	 * state if they are not retained by the object manager.
944 	 * Hence, try_revoke must wait until after the callbacks have
945 	 * been invoked to update the cache state.
946 	 */
947 	if (event != AVC_CALLBACK_TRY_REVOKE)
948 		avc_update_cache(event, ssid, tsid, tclass, perms);
949 
950 	for (c = avc_callbacks; c; c = c->next) {
951 		if ((c->events & event) &&
952 		    avc_sidcmp(c->ssid, ssid) &&
953 		    avc_sidcmp(c->tsid, tsid) &&
954 		    c->tclass == tclass && (c->perms & perms)) {
955 			cretained = 0;
956 			ret = c->callback(event, ssid, tsid, tclass,
957 					  (c->perms & perms), &cretained);
958 			if (ret && !rc) {
959 				rc = ret;
960 				errsave = errno;
961 			}
962 			if (!ret)
963 				tretained |= cretained;
964 		}
965 	}
966 
967 	if (event == AVC_CALLBACK_TRY_REVOKE) {
968 		/* revoke any unretained permissions */
969 		perms &= ~tretained;
970 		avc_update_cache(event, ssid, tsid, tclass, perms);
971 		*out_retained = tretained;
972 	}
973 
974 	avc_get_lock(avc_lock);
975 	if (seqno > avc_cache.latest_notif)
976 		avc_cache.latest_notif = seqno;
977 	avc_release_lock(avc_lock);
978 
979 	errno = errsave;
980 	return rc;
981 }
982 
983 /**
984  * avc_ss_grant - Grant previously denied permissions.
985  * @ssid: source security identifier or %SECSID_WILD
986  * @tsid: target security identifier or %SECSID_WILD
987  * @tclass: target security class
988  * @perms: permissions to grant
989  * @seqno: policy sequence number
990  */
avc_ss_grant(security_id_t ssid,security_id_t tsid,security_class_t tclass,access_vector_t perms,uint32_t seqno)991 int avc_ss_grant(security_id_t ssid, security_id_t tsid,
992 		 security_class_t tclass, access_vector_t perms,
993 		 uint32_t seqno)
994 {
995 	return avc_control(AVC_CALLBACK_GRANT,
996 			   ssid, tsid, tclass, perms, seqno, 0);
997 }
998 
999 /**
1000  * avc_ss_try_revoke - Try to revoke previously granted permissions.
1001  * @ssid: source security identifier or %SECSID_WILD
1002  * @tsid: target security identifier or %SECSID_WILD
1003  * @tclass: target security class
1004  * @perms: permissions to grant
1005  * @seqno: policy sequence number
1006  * @out_retained: subset of @perms that are retained
1007  *
1008  * Try to revoke previously granted permissions, but
1009  * only if they are not retained as migrated permissions.
1010  * Return the subset of permissions that are retained via @out_retained.
1011  */
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)1012 int avc_ss_try_revoke(security_id_t ssid, security_id_t tsid,
1013 		      security_class_t tclass,
1014 		      access_vector_t perms, uint32_t seqno,
1015 		      access_vector_t * out_retained)
1016 {
1017 	return avc_control(AVC_CALLBACK_TRY_REVOKE,
1018 			   ssid, tsid, tclass, perms, seqno, out_retained);
1019 }
1020 
1021 /**
1022  * avc_ss_revoke - Revoke previously granted permissions.
1023  * @ssid: source security identifier or %SECSID_WILD
1024  * @tsid: target security identifier or %SECSID_WILD
1025  * @tclass: target security class
1026  * @perms: permissions to grant
1027  * @seqno: policy sequence number
1028  *
1029  * Revoke previously granted permissions, even if
1030  * they are retained as migrated permissions.
1031  */
avc_ss_revoke(security_id_t ssid,security_id_t tsid,security_class_t tclass,access_vector_t perms,uint32_t seqno)1032 int avc_ss_revoke(security_id_t ssid, security_id_t tsid,
1033 		  security_class_t tclass, access_vector_t perms,
1034 		  uint32_t seqno)
1035 {
1036 	return avc_control(AVC_CALLBACK_REVOKE,
1037 			   ssid, tsid, tclass, perms, seqno, 0);
1038 }
1039 
1040 /**
1041  * avc_ss_reset - Flush the cache and revalidate migrated permissions.
1042  * @seqno: policy sequence number
1043  */
avc_ss_reset(uint32_t seqno)1044 int avc_ss_reset(uint32_t seqno)
1045 {
1046 	int rc;
1047 
1048 	rc = avc_reset();
1049 
1050 	avc_get_lock(avc_lock);
1051 	if (seqno > avc_cache.latest_notif)
1052 		avc_cache.latest_notif = seqno;
1053 	avc_release_lock(avc_lock);
1054 
1055 	return rc;
1056 }
1057 
1058 /**
1059  * avc_ss_set_auditallow - Enable or disable auditing of granted permissions.
1060  * @ssid: source security identifier or %SECSID_WILD
1061  * @tsid: target security identifier or %SECSID_WILD
1062  * @tclass: target security class
1063  * @perms: permissions to grant
1064  * @seqno: policy sequence number
1065  * @enable: enable flag.
1066  */
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)1067 int avc_ss_set_auditallow(security_id_t ssid, security_id_t tsid,
1068 			  security_class_t tclass, access_vector_t perms,
1069 			  uint32_t seqno, uint32_t enable)
1070 {
1071 	if (enable)
1072 		return avc_control(AVC_CALLBACK_AUDITALLOW_ENABLE,
1073 				   ssid, tsid, tclass, perms, seqno, 0);
1074 	else
1075 		return avc_control(AVC_CALLBACK_AUDITALLOW_DISABLE,
1076 				   ssid, tsid, tclass, perms, seqno, 0);
1077 }
1078 
1079 /**
1080  * avc_ss_set_auditdeny - Enable or disable auditing of denied permissions.
1081  * @ssid: source security identifier or %SECSID_WILD
1082  * @tsid: target security identifier or %SECSID_WILD
1083  * @tclass: target security class
1084  * @perms: permissions to grant
1085  * @seqno: policy sequence number
1086  * @enable: enable flag.
1087  */
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)1088 int avc_ss_set_auditdeny(security_id_t ssid, security_id_t tsid,
1089 			 security_class_t tclass, access_vector_t perms,
1090 			 uint32_t seqno, uint32_t enable)
1091 {
1092 	if (enable)
1093 		return avc_control(AVC_CALLBACK_AUDITDENY_ENABLE,
1094 				   ssid, tsid, tclass, perms, seqno, 0);
1095 	else
1096 		return avc_control(AVC_CALLBACK_AUDITDENY_DISABLE,
1097 				   ssid, tsid, tclass, perms, seqno, 0);
1098 }
1099