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