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