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