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 19struct 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 28struct avc_node { 29 struct avc_entry ae; 30 struct avc_node *next; 31}; 32 33struct 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 40struct 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 53static void *avc_netlink_thread = NULL; 54static void *avc_lock = NULL; 55static void *avc_log_lock = NULL; 56static struct avc_node *avc_node_freelist = NULL; 57static struct avc_cache avc_cache; 58static char *avc_audit_buf = NULL; 59static struct avc_cache_stats cache_stats; 60static struct avc_callback_node *avc_callbacks = NULL; 61static struct sidtab avc_sidtab; 62 63static 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 70int 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 82int 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 93int 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 108int 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 123int 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 209void avc_cache_stats(struct avc_cache_stats *p) 210{ 211 memcpy(p, &cache_stats, sizeof(cache_stats)); 212} 213 214void 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 226void 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 257hidden_def(avc_av_stats) 258 259static 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 297static inline void avc_clear_avc_entry(struct avc_entry *ae) 298{ 299 memset(ae, 0, sizeof(*ae)); 300} 301 302static 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 335static 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 */ 383static 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 */ 425static 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 453void avc_cleanup(void) 454{ 455} 456 457hidden_def(avc_cleanup) 458 459int 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 502hidden_def(avc_reset) 503 504void 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 */ 558static 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 591static 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 */ 607static 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 */ 641static 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 654void 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 697hidden_def(avc_audit) 698 699 700static 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 709int 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 789hidden_def(avc_has_perm_noaudit) 790 791int 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 805int 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; 850out: 851 avc_release_lock(avc_lock); 852 return rc; 853} 854 855int 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 885static 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 890static 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 916static 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 */ 954static 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 */ 1014int 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 */ 1035int 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 */ 1055int 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 */ 1067int 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 */ 1090int 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 */ 1111int 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