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