avc.c (e5a5ca96a42ca7eee19cf8694377308771350950) | avc.c (6b6bc6205d98796361962ee282a063f18ba8dc57) |
---|---|
1/* 2 * Implementation of the kernel access vector cache (AVC). 3 * 4 * Authors: Stephen Smalley, <sds@tycho.nsa.gov> 5 * James Morris <jmorris@redhat.com> 6 * 7 * Update: KaiGai, Kohei <kaigai@ak.jp.nec.com> 8 * Replaced the avc_lock spinlock by RCU. --- 68 unchanged lines hidden (view full) --- 77}; 78 79struct avc_callback_node { 80 int (*callback) (u32 event); 81 u32 events; 82 struct avc_callback_node *next; 83}; 84 | 1/* 2 * Implementation of the kernel access vector cache (AVC). 3 * 4 * Authors: Stephen Smalley, <sds@tycho.nsa.gov> 5 * James Morris <jmorris@redhat.com> 6 * 7 * Update: KaiGai, Kohei <kaigai@ak.jp.nec.com> 8 * Replaced the avc_lock spinlock by RCU. --- 68 unchanged lines hidden (view full) --- 77}; 78 79struct avc_callback_node { 80 int (*callback) (u32 event); 81 u32 events; 82 struct avc_callback_node *next; 83}; 84 |
85/* Exported via selinufs */ 86unsigned int avc_cache_threshold = AVC_DEF_CACHE_THRESHOLD; 87 | |
88#ifdef CONFIG_SECURITY_SELINUX_AVC_STATS 89DEFINE_PER_CPU(struct avc_cache_stats, avc_cache_stats) = { 0 }; 90#endif 91 | 85#ifdef CONFIG_SECURITY_SELINUX_AVC_STATS 86DEFINE_PER_CPU(struct avc_cache_stats, avc_cache_stats) = { 0 }; 87#endif 88 |
92static struct avc_cache avc_cache; | 89struct selinux_avc { 90 unsigned int avc_cache_threshold; 91 struct avc_cache avc_cache; 92}; 93 94static struct selinux_avc selinux_avc; 95 96void selinux_avc_init(struct selinux_avc **avc) 97{ 98 int i; 99 100 selinux_avc.avc_cache_threshold = AVC_DEF_CACHE_THRESHOLD; 101 for (i = 0; i < AVC_CACHE_SLOTS; i++) { 102 INIT_HLIST_HEAD(&selinux_avc.avc_cache.slots[i]); 103 spin_lock_init(&selinux_avc.avc_cache.slots_lock[i]); 104 } 105 atomic_set(&selinux_avc.avc_cache.active_nodes, 0); 106 atomic_set(&selinux_avc.avc_cache.lru_hint, 0); 107 *avc = &selinux_avc; 108} 109 110unsigned int avc_get_cache_threshold(struct selinux_avc *avc) 111{ 112 return avc->avc_cache_threshold; 113} 114 115void avc_set_cache_threshold(struct selinux_avc *avc, 116 unsigned int cache_threshold) 117{ 118 avc->avc_cache_threshold = cache_threshold; 119} 120 |
93static struct avc_callback_node *avc_callbacks; 94static struct kmem_cache *avc_node_cachep; 95static struct kmem_cache *avc_xperms_data_cachep; 96static struct kmem_cache *avc_xperms_decision_cachep; 97static struct kmem_cache *avc_xperms_cachep; 98 99static inline int avc_hash(u32 ssid, u32 tsid, u16 tclass) 100{ --- 37 unchanged lines hidden (view full) --- 138} 139 140/** 141 * avc_dump_query - Display a SID pair and a class in human-readable form. 142 * @ssid: source security identifier 143 * @tsid: target security identifier 144 * @tclass: target security class 145 */ | 121static struct avc_callback_node *avc_callbacks; 122static struct kmem_cache *avc_node_cachep; 123static struct kmem_cache *avc_xperms_data_cachep; 124static struct kmem_cache *avc_xperms_decision_cachep; 125static struct kmem_cache *avc_xperms_cachep; 126 127static inline int avc_hash(u32 ssid, u32 tsid, u16 tclass) 128{ --- 37 unchanged lines hidden (view full) --- 166} 167 168/** 169 * avc_dump_query - Display a SID pair and a class in human-readable form. 170 * @ssid: source security identifier 171 * @tsid: target security identifier 172 * @tclass: target security class 173 */ |
146static void avc_dump_query(struct audit_buffer *ab, u32 ssid, u32 tsid, u16 tclass) | 174static void avc_dump_query(struct audit_buffer *ab, struct selinux_state *state, 175 u32 ssid, u32 tsid, u16 tclass) |
147{ 148 int rc; 149 char *scontext; 150 u32 scontext_len; 151 | 176{ 177 int rc; 178 char *scontext; 179 u32 scontext_len; 180 |
152 rc = security_sid_to_context(&selinux_state, ssid, 153 &scontext, &scontext_len); | 181 rc = security_sid_to_context(state, ssid, &scontext, &scontext_len); |
154 if (rc) 155 audit_log_format(ab, "ssid=%d", ssid); 156 else { 157 audit_log_format(ab, "scontext=%s", scontext); 158 kfree(scontext); 159 } 160 | 182 if (rc) 183 audit_log_format(ab, "ssid=%d", ssid); 184 else { 185 audit_log_format(ab, "scontext=%s", scontext); 186 kfree(scontext); 187 } 188 |
161 rc = security_sid_to_context(&selinux_state, tsid, 162 &scontext, &scontext_len); | 189 rc = security_sid_to_context(state, tsid, &scontext, &scontext_len); |
163 if (rc) 164 audit_log_format(ab, " tsid=%d", tsid); 165 else { 166 audit_log_format(ab, " tcontext=%s", scontext); 167 kfree(scontext); 168 } 169 170 BUG_ON(!tclass || tclass >= ARRAY_SIZE(secclass_map)); 171 audit_log_format(ab, " tclass=%s", secclass_map[tclass-1].name); 172} 173 174/** 175 * avc_init - Initialize the AVC. 176 * 177 * Initialize the access vector cache. 178 */ 179void __init avc_init(void) 180{ | 190 if (rc) 191 audit_log_format(ab, " tsid=%d", tsid); 192 else { 193 audit_log_format(ab, " tcontext=%s", scontext); 194 kfree(scontext); 195 } 196 197 BUG_ON(!tclass || tclass >= ARRAY_SIZE(secclass_map)); 198 audit_log_format(ab, " tclass=%s", secclass_map[tclass-1].name); 199} 200 201/** 202 * avc_init - Initialize the AVC. 203 * 204 * Initialize the access vector cache. 205 */ 206void __init avc_init(void) 207{ |
181 int i; 182 183 for (i = 0; i < AVC_CACHE_SLOTS; i++) { 184 INIT_HLIST_HEAD(&avc_cache.slots[i]); 185 spin_lock_init(&avc_cache.slots_lock[i]); 186 } 187 atomic_set(&avc_cache.active_nodes, 0); 188 atomic_set(&avc_cache.lru_hint, 0); 189 | |
190 avc_node_cachep = kmem_cache_create("avc_node", sizeof(struct avc_node), 191 0, SLAB_PANIC, NULL); 192 avc_xperms_cachep = kmem_cache_create("avc_xperms_node", 193 sizeof(struct avc_xperms_node), 194 0, SLAB_PANIC, NULL); 195 avc_xperms_decision_cachep = kmem_cache_create( 196 "avc_xperms_decision_node", 197 sizeof(struct avc_xperms_decision_node), 198 0, SLAB_PANIC, NULL); 199 avc_xperms_data_cachep = kmem_cache_create("avc_xperms_data", 200 sizeof(struct extended_perms_data), 201 0, SLAB_PANIC, NULL); 202} 203 | 208 avc_node_cachep = kmem_cache_create("avc_node", sizeof(struct avc_node), 209 0, SLAB_PANIC, NULL); 210 avc_xperms_cachep = kmem_cache_create("avc_xperms_node", 211 sizeof(struct avc_xperms_node), 212 0, SLAB_PANIC, NULL); 213 avc_xperms_decision_cachep = kmem_cache_create( 214 "avc_xperms_decision_node", 215 sizeof(struct avc_xperms_decision_node), 216 0, SLAB_PANIC, NULL); 217 avc_xperms_data_cachep = kmem_cache_create("avc_xperms_data", 218 sizeof(struct extended_perms_data), 219 0, SLAB_PANIC, NULL); 220} 221 |
204int avc_get_hash_stats(char *page) | 222int avc_get_hash_stats(struct selinux_avc *avc, char *page) |
205{ 206 int i, chain_len, max_chain_len, slots_used; 207 struct avc_node *node; 208 struct hlist_head *head; 209 210 rcu_read_lock(); 211 212 slots_used = 0; 213 max_chain_len = 0; 214 for (i = 0; i < AVC_CACHE_SLOTS; i++) { | 223{ 224 int i, chain_len, max_chain_len, slots_used; 225 struct avc_node *node; 226 struct hlist_head *head; 227 228 rcu_read_lock(); 229 230 slots_used = 0; 231 max_chain_len = 0; 232 for (i = 0; i < AVC_CACHE_SLOTS; i++) { |
215 head = &avc_cache.slots[i]; | 233 head = &avc->avc_cache.slots[i]; |
216 if (!hlist_empty(head)) { 217 slots_used++; 218 chain_len = 0; 219 hlist_for_each_entry_rcu(node, head, list) 220 chain_len++; 221 if (chain_len > max_chain_len) 222 max_chain_len = chain_len; 223 } 224 } 225 226 rcu_read_unlock(); 227 228 return scnprintf(page, PAGE_SIZE, "entries: %d\nbuckets used: %d/%d\n" 229 "longest chain: %d\n", | 234 if (!hlist_empty(head)) { 235 slots_used++; 236 chain_len = 0; 237 hlist_for_each_entry_rcu(node, head, list) 238 chain_len++; 239 if (chain_len > max_chain_len) 240 max_chain_len = chain_len; 241 } 242 } 243 244 rcu_read_unlock(); 245 246 return scnprintf(page, PAGE_SIZE, "entries: %d\nbuckets used: %d/%d\n" 247 "longest chain: %d\n", |
230 atomic_read(&avc_cache.active_nodes), | 248 atomic_read(&avc->avc_cache.active_nodes), |
231 slots_used, AVC_CACHE_SLOTS, max_chain_len); 232} 233 234/* 235 * using a linked list for extended_perms_decision lookup because the list is 236 * always small. i.e. less than 5, typically 1 237 */ 238static struct extended_perms_decision *avc_xperms_decision_lookup(u8 driver, --- 220 unchanged lines hidden (view full) --- 459 audited &= ~requested; 460 } 461 } 462 463 *deniedp = denied; 464 return audited; 465} 466 | 249 slots_used, AVC_CACHE_SLOTS, max_chain_len); 250} 251 252/* 253 * using a linked list for extended_perms_decision lookup because the list is 254 * always small. i.e. less than 5, typically 1 255 */ 256static struct extended_perms_decision *avc_xperms_decision_lookup(u8 driver, --- 220 unchanged lines hidden (view full) --- 477 audited &= ~requested; 478 } 479 } 480 481 *deniedp = denied; 482 return audited; 483} 484 |
467static inline int avc_xperms_audit(u32 ssid, u32 tsid, u16 tclass, 468 u32 requested, struct av_decision *avd, 469 struct extended_perms_decision *xpd, 470 u8 perm, int result, 471 struct common_audit_data *ad) | 485static inline int avc_xperms_audit(struct selinux_state *state, 486 u32 ssid, u32 tsid, u16 tclass, 487 u32 requested, struct av_decision *avd, 488 struct extended_perms_decision *xpd, 489 u8 perm, int result, 490 struct common_audit_data *ad) |
472{ 473 u32 audited, denied; 474 475 audited = avc_xperms_audit_required( 476 requested, avd, xpd, perm, result, &denied); 477 if (likely(!audited)) 478 return 0; | 491{ 492 u32 audited, denied; 493 494 audited = avc_xperms_audit_required( 495 requested, avd, xpd, perm, result, &denied); 496 if (likely(!audited)) 497 return 0; |
479 return slow_avc_audit(ssid, tsid, tclass, requested, | 498 return slow_avc_audit(state, ssid, tsid, tclass, requested, |
480 audited, denied, result, ad, 0); 481} 482 483static void avc_node_free(struct rcu_head *rhead) 484{ 485 struct avc_node *node = container_of(rhead, struct avc_node, rhead); 486 avc_xperms_free(node->ae.xp_node); 487 kmem_cache_free(avc_node_cachep, node); 488 avc_cache_stats_incr(frees); 489} 490 | 499 audited, denied, result, ad, 0); 500} 501 502static void avc_node_free(struct rcu_head *rhead) 503{ 504 struct avc_node *node = container_of(rhead, struct avc_node, rhead); 505 avc_xperms_free(node->ae.xp_node); 506 kmem_cache_free(avc_node_cachep, node); 507 avc_cache_stats_incr(frees); 508} 509 |
491static void avc_node_delete(struct avc_node *node) | 510static void avc_node_delete(struct selinux_avc *avc, struct avc_node *node) |
492{ 493 hlist_del_rcu(&node->list); 494 call_rcu(&node->rhead, avc_node_free); | 511{ 512 hlist_del_rcu(&node->list); 513 call_rcu(&node->rhead, avc_node_free); |
495 atomic_dec(&avc_cache.active_nodes); | 514 atomic_dec(&avc->avc_cache.active_nodes); |
496} 497 | 515} 516 |
498static void avc_node_kill(struct avc_node *node) | 517static void avc_node_kill(struct selinux_avc *avc, struct avc_node *node) |
499{ 500 avc_xperms_free(node->ae.xp_node); 501 kmem_cache_free(avc_node_cachep, node); 502 avc_cache_stats_incr(frees); | 518{ 519 avc_xperms_free(node->ae.xp_node); 520 kmem_cache_free(avc_node_cachep, node); 521 avc_cache_stats_incr(frees); |
503 atomic_dec(&avc_cache.active_nodes); | 522 atomic_dec(&avc->avc_cache.active_nodes); |
504} 505 | 523} 524 |
506static void avc_node_replace(struct avc_node *new, struct avc_node *old) | 525static void avc_node_replace(struct selinux_avc *avc, 526 struct avc_node *new, struct avc_node *old) |
507{ 508 hlist_replace_rcu(&old->list, &new->list); 509 call_rcu(&old->rhead, avc_node_free); | 527{ 528 hlist_replace_rcu(&old->list, &new->list); 529 call_rcu(&old->rhead, avc_node_free); |
510 atomic_dec(&avc_cache.active_nodes); | 530 atomic_dec(&avc->avc_cache.active_nodes); |
511} 512 | 531} 532 |
513static inline int avc_reclaim_node(void) | 533static inline int avc_reclaim_node(struct selinux_avc *avc) |
514{ 515 struct avc_node *node; 516 int hvalue, try, ecx; 517 unsigned long flags; 518 struct hlist_head *head; 519 spinlock_t *lock; 520 521 for (try = 0, ecx = 0; try < AVC_CACHE_SLOTS; try++) { | 534{ 535 struct avc_node *node; 536 int hvalue, try, ecx; 537 unsigned long flags; 538 struct hlist_head *head; 539 spinlock_t *lock; 540 541 for (try = 0, ecx = 0; try < AVC_CACHE_SLOTS; try++) { |
522 hvalue = atomic_inc_return(&avc_cache.lru_hint) & (AVC_CACHE_SLOTS - 1); 523 head = &avc_cache.slots[hvalue]; 524 lock = &avc_cache.slots_lock[hvalue]; | 542 hvalue = atomic_inc_return(&avc->avc_cache.lru_hint) & 543 (AVC_CACHE_SLOTS - 1); 544 head = &avc->avc_cache.slots[hvalue]; 545 lock = &avc->avc_cache.slots_lock[hvalue]; |
525 526 if (!spin_trylock_irqsave(lock, flags)) 527 continue; 528 529 rcu_read_lock(); 530 hlist_for_each_entry(node, head, list) { | 546 547 if (!spin_trylock_irqsave(lock, flags)) 548 continue; 549 550 rcu_read_lock(); 551 hlist_for_each_entry(node, head, list) { |
531 avc_node_delete(node); | 552 avc_node_delete(avc, node); |
532 avc_cache_stats_incr(reclaims); 533 ecx++; 534 if (ecx >= AVC_CACHE_RECLAIM) { 535 rcu_read_unlock(); 536 spin_unlock_irqrestore(lock, flags); 537 goto out; 538 } 539 } 540 rcu_read_unlock(); 541 spin_unlock_irqrestore(lock, flags); 542 } 543out: 544 return ecx; 545} 546 | 553 avc_cache_stats_incr(reclaims); 554 ecx++; 555 if (ecx >= AVC_CACHE_RECLAIM) { 556 rcu_read_unlock(); 557 spin_unlock_irqrestore(lock, flags); 558 goto out; 559 } 560 } 561 rcu_read_unlock(); 562 spin_unlock_irqrestore(lock, flags); 563 } 564out: 565 return ecx; 566} 567 |
547static struct avc_node *avc_alloc_node(void) | 568static struct avc_node *avc_alloc_node(struct selinux_avc *avc) |
548{ 549 struct avc_node *node; 550 551 node = kmem_cache_zalloc(avc_node_cachep, GFP_NOWAIT); 552 if (!node) 553 goto out; 554 555 INIT_HLIST_NODE(&node->list); 556 avc_cache_stats_incr(allocations); 557 | 569{ 570 struct avc_node *node; 571 572 node = kmem_cache_zalloc(avc_node_cachep, GFP_NOWAIT); 573 if (!node) 574 goto out; 575 576 INIT_HLIST_NODE(&node->list); 577 avc_cache_stats_incr(allocations); 578 |
558 if (atomic_inc_return(&avc_cache.active_nodes) > avc_cache_threshold) 559 avc_reclaim_node(); | 579 if (atomic_inc_return(&avc->avc_cache.active_nodes) > 580 avc->avc_cache_threshold) 581 avc_reclaim_node(avc); |
560 561out: 562 return node; 563} 564 565static void avc_node_populate(struct avc_node *node, u32 ssid, u32 tsid, u16 tclass, struct av_decision *avd) 566{ 567 node->ae.ssid = ssid; 568 node->ae.tsid = tsid; 569 node->ae.tclass = tclass; 570 memcpy(&node->ae.avd, avd, sizeof(node->ae.avd)); 571} 572 | 582 583out: 584 return node; 585} 586 587static void avc_node_populate(struct avc_node *node, u32 ssid, u32 tsid, u16 tclass, struct av_decision *avd) 588{ 589 node->ae.ssid = ssid; 590 node->ae.tsid = tsid; 591 node->ae.tclass = tclass; 592 memcpy(&node->ae.avd, avd, sizeof(node->ae.avd)); 593} 594 |
573static inline struct avc_node *avc_search_node(u32 ssid, u32 tsid, u16 tclass) | 595static inline struct avc_node *avc_search_node(struct selinux_avc *avc, 596 u32 ssid, u32 tsid, u16 tclass) |
574{ 575 struct avc_node *node, *ret = NULL; 576 int hvalue; 577 struct hlist_head *head; 578 579 hvalue = avc_hash(ssid, tsid, tclass); | 597{ 598 struct avc_node *node, *ret = NULL; 599 int hvalue; 600 struct hlist_head *head; 601 602 hvalue = avc_hash(ssid, tsid, tclass); |
580 head = &avc_cache.slots[hvalue]; | 603 head = &avc->avc_cache.slots[hvalue]; |
581 hlist_for_each_entry_rcu(node, head, list) { 582 if (ssid == node->ae.ssid && 583 tclass == node->ae.tclass && 584 tsid == node->ae.tsid) { 585 ret = node; 586 break; 587 } 588 } --- 8 unchanged lines hidden (view full) --- 597 * @tclass: target security class 598 * 599 * Look up an AVC entry that is valid for the 600 * (@ssid, @tsid), interpreting the permissions 601 * based on @tclass. If a valid AVC entry exists, 602 * then this function returns the avc_node. 603 * Otherwise, this function returns NULL. 604 */ | 604 hlist_for_each_entry_rcu(node, head, list) { 605 if (ssid == node->ae.ssid && 606 tclass == node->ae.tclass && 607 tsid == node->ae.tsid) { 608 ret = node; 609 break; 610 } 611 } --- 8 unchanged lines hidden (view full) --- 620 * @tclass: target security class 621 * 622 * Look up an AVC entry that is valid for the 623 * (@ssid, @tsid), interpreting the permissions 624 * based on @tclass. If a valid AVC entry exists, 625 * then this function returns the avc_node. 626 * Otherwise, this function returns NULL. 627 */ |
605static struct avc_node *avc_lookup(u32 ssid, u32 tsid, u16 tclass) | 628static struct avc_node *avc_lookup(struct selinux_avc *avc, 629 u32 ssid, u32 tsid, u16 tclass) |
606{ 607 struct avc_node *node; 608 609 avc_cache_stats_incr(lookups); | 630{ 631 struct avc_node *node; 632 633 avc_cache_stats_incr(lookups); |
610 node = avc_search_node(ssid, tsid, tclass); | 634 node = avc_search_node(avc, ssid, tsid, tclass); |
611 612 if (node) 613 return node; 614 615 avc_cache_stats_incr(misses); 616 return NULL; 617} 618 | 635 636 if (node) 637 return node; 638 639 avc_cache_stats_incr(misses); 640 return NULL; 641} 642 |
619static int avc_latest_notif_update(int seqno, int is_insert) | 643static int avc_latest_notif_update(struct selinux_avc *avc, 644 int seqno, int is_insert) |
620{ 621 int ret = 0; 622 static DEFINE_SPINLOCK(notif_lock); 623 unsigned long flag; 624 625 spin_lock_irqsave(¬if_lock, flag); 626 if (is_insert) { | 645{ 646 int ret = 0; 647 static DEFINE_SPINLOCK(notif_lock); 648 unsigned long flag; 649 650 spin_lock_irqsave(¬if_lock, flag); 651 if (is_insert) { |
627 if (seqno < avc_cache.latest_notif) { | 652 if (seqno < avc->avc_cache.latest_notif) { |
628 printk(KERN_WARNING "SELinux: avc: seqno %d < latest_notif %d\n", | 653 printk(KERN_WARNING "SELinux: avc: seqno %d < latest_notif %d\n", |
629 seqno, avc_cache.latest_notif); | 654 seqno, avc->avc_cache.latest_notif); |
630 ret = -EAGAIN; 631 } 632 } else { | 655 ret = -EAGAIN; 656 } 657 } else { |
633 if (seqno > avc_cache.latest_notif) 634 avc_cache.latest_notif = seqno; | 658 if (seqno > avc->avc_cache.latest_notif) 659 avc->avc_cache.latest_notif = seqno; |
635 } 636 spin_unlock_irqrestore(¬if_lock, flag); 637 638 return ret; 639} 640 641/** 642 * avc_insert - Insert an AVC entry. --- 8 unchanged lines hidden (view full) --- 651 * The access vectors and the sequence number are 652 * normally provided by the security server in 653 * response to a security_compute_av() call. If the 654 * sequence number @avd->seqno is not less than the latest 655 * revocation notification, then the function copies 656 * the access vectors into a cache entry, returns 657 * avc_node inserted. Otherwise, this function returns NULL. 658 */ | 660 } 661 spin_unlock_irqrestore(¬if_lock, flag); 662 663 return ret; 664} 665 666/** 667 * avc_insert - Insert an AVC entry. --- 8 unchanged lines hidden (view full) --- 676 * The access vectors and the sequence number are 677 * normally provided by the security server in 678 * response to a security_compute_av() call. If the 679 * sequence number @avd->seqno is not less than the latest 680 * revocation notification, then the function copies 681 * the access vectors into a cache entry, returns 682 * avc_node inserted. Otherwise, this function returns NULL. 683 */ |
659static struct avc_node *avc_insert(u32 ssid, u32 tsid, u16 tclass, 660 struct av_decision *avd, 661 struct avc_xperms_node *xp_node) | 684static struct avc_node *avc_insert(struct selinux_avc *avc, 685 u32 ssid, u32 tsid, u16 tclass, 686 struct av_decision *avd, 687 struct avc_xperms_node *xp_node) |
662{ 663 struct avc_node *pos, *node = NULL; 664 int hvalue; 665 unsigned long flag; 666 | 688{ 689 struct avc_node *pos, *node = NULL; 690 int hvalue; 691 unsigned long flag; 692 |
667 if (avc_latest_notif_update(avd->seqno, 1)) | 693 if (avc_latest_notif_update(avc, avd->seqno, 1)) |
668 goto out; 669 | 694 goto out; 695 |
670 node = avc_alloc_node(); | 696 node = avc_alloc_node(avc); |
671 if (node) { 672 struct hlist_head *head; 673 spinlock_t *lock; 674 int rc = 0; 675 676 hvalue = avc_hash(ssid, tsid, tclass); 677 avc_node_populate(node, ssid, tsid, tclass, avd); 678 rc = avc_xperms_populate(node, xp_node); 679 if (rc) { 680 kmem_cache_free(avc_node_cachep, node); 681 return NULL; 682 } | 697 if (node) { 698 struct hlist_head *head; 699 spinlock_t *lock; 700 int rc = 0; 701 702 hvalue = avc_hash(ssid, tsid, tclass); 703 avc_node_populate(node, ssid, tsid, tclass, avd); 704 rc = avc_xperms_populate(node, xp_node); 705 if (rc) { 706 kmem_cache_free(avc_node_cachep, node); 707 return NULL; 708 } |
683 head = &avc_cache.slots[hvalue]; 684 lock = &avc_cache.slots_lock[hvalue]; | 709 head = &avc->avc_cache.slots[hvalue]; 710 lock = &avc->avc_cache.slots_lock[hvalue]; |
685 686 spin_lock_irqsave(lock, flag); 687 hlist_for_each_entry(pos, head, list) { 688 if (pos->ae.ssid == ssid && 689 pos->ae.tsid == tsid && 690 pos->ae.tclass == tclass) { | 711 712 spin_lock_irqsave(lock, flag); 713 hlist_for_each_entry(pos, head, list) { 714 if (pos->ae.ssid == ssid && 715 pos->ae.tsid == tsid && 716 pos->ae.tclass == tclass) { |
691 avc_node_replace(node, pos); | 717 avc_node_replace(avc, node, pos); |
692 goto found; 693 } 694 } 695 hlist_add_head_rcu(&node->list, head); 696found: 697 spin_unlock_irqrestore(lock, flag); 698 } 699out: --- 21 unchanged lines hidden (view full) --- 721 * will be called by generic audit code 722 * @ab: the audit buffer 723 * @a: audit_data 724 */ 725static void avc_audit_post_callback(struct audit_buffer *ab, void *a) 726{ 727 struct common_audit_data *ad = a; 728 audit_log_format(ab, " "); | 718 goto found; 719 } 720 } 721 hlist_add_head_rcu(&node->list, head); 722found: 723 spin_unlock_irqrestore(lock, flag); 724 } 725out: --- 21 unchanged lines hidden (view full) --- 747 * will be called by generic audit code 748 * @ab: the audit buffer 749 * @a: audit_data 750 */ 751static void avc_audit_post_callback(struct audit_buffer *ab, void *a) 752{ 753 struct common_audit_data *ad = a; 754 audit_log_format(ab, " "); |
729 avc_dump_query(ab, ad->selinux_audit_data->ssid, 730 ad->selinux_audit_data->tsid, 731 ad->selinux_audit_data->tclass); | 755 avc_dump_query(ab, ad->selinux_audit_data->state, 756 ad->selinux_audit_data->ssid, 757 ad->selinux_audit_data->tsid, 758 ad->selinux_audit_data->tclass); |
732 if (ad->selinux_audit_data->denied) { 733 audit_log_format(ab, " permissive=%u", 734 ad->selinux_audit_data->result ? 0 : 1); 735 } 736} 737 738/* This is the slow part of avc audit with big stack footprint */ | 759 if (ad->selinux_audit_data->denied) { 760 audit_log_format(ab, " permissive=%u", 761 ad->selinux_audit_data->result ? 0 : 1); 762 } 763} 764 765/* This is the slow part of avc audit with big stack footprint */ |
739noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, 740 u32 requested, u32 audited, u32 denied, int result, 741 struct common_audit_data *a, 742 unsigned flags) | 766noinline int slow_avc_audit(struct selinux_state *state, 767 u32 ssid, u32 tsid, u16 tclass, 768 u32 requested, u32 audited, u32 denied, int result, 769 struct common_audit_data *a, 770 unsigned int flags) |
743{ 744 struct common_audit_data stack_data; 745 struct selinux_audit_data sad; 746 747 if (!a) { 748 a = &stack_data; 749 a->type = LSM_AUDIT_DATA_NONE; 750 } --- 11 unchanged lines hidden (view full) --- 762 763 sad.tclass = tclass; 764 sad.requested = requested; 765 sad.ssid = ssid; 766 sad.tsid = tsid; 767 sad.audited = audited; 768 sad.denied = denied; 769 sad.result = result; | 771{ 772 struct common_audit_data stack_data; 773 struct selinux_audit_data sad; 774 775 if (!a) { 776 a = &stack_data; 777 a->type = LSM_AUDIT_DATA_NONE; 778 } --- 11 unchanged lines hidden (view full) --- 790 791 sad.tclass = tclass; 792 sad.requested = requested; 793 sad.ssid = ssid; 794 sad.tsid = tsid; 795 sad.audited = audited; 796 sad.denied = denied; 797 sad.result = result; |
798 sad.state = state; |
|
770 771 a->selinux_audit_data = &sad; 772 773 common_lsm_audit(a, avc_audit_pre_callback, avc_audit_post_callback); 774 return 0; 775} 776 777/** --- 32 unchanged lines hidden (view full) --- 810 * @seqno : sequence number when decision was made 811 * @xpd: extended_perms_decision to be added to the node 812 * 813 * if a valid AVC entry doesn't exist,this function returns -ENOENT. 814 * if kmalloc() called internal returns NULL, this function returns -ENOMEM. 815 * otherwise, this function updates the AVC entry. The original AVC-entry object 816 * will release later by RCU. 817 */ | 799 800 a->selinux_audit_data = &sad; 801 802 common_lsm_audit(a, avc_audit_pre_callback, avc_audit_post_callback); 803 return 0; 804} 805 806/** --- 32 unchanged lines hidden (view full) --- 839 * @seqno : sequence number when decision was made 840 * @xpd: extended_perms_decision to be added to the node 841 * 842 * if a valid AVC entry doesn't exist,this function returns -ENOENT. 843 * if kmalloc() called internal returns NULL, this function returns -ENOMEM. 844 * otherwise, this function updates the AVC entry. The original AVC-entry object 845 * will release later by RCU. 846 */ |
818static int avc_update_node(u32 event, u32 perms, u8 driver, u8 xperm, u32 ssid, 819 u32 tsid, u16 tclass, u32 seqno, 820 struct extended_perms_decision *xpd, 821 u32 flags) | 847static int avc_update_node(struct selinux_avc *avc, 848 u32 event, u32 perms, u8 driver, u8 xperm, u32 ssid, 849 u32 tsid, u16 tclass, u32 seqno, 850 struct extended_perms_decision *xpd, 851 u32 flags) |
822{ 823 int hvalue, rc = 0; 824 unsigned long flag; 825 struct avc_node *pos, *node, *orig = NULL; 826 struct hlist_head *head; 827 spinlock_t *lock; 828 | 852{ 853 int hvalue, rc = 0; 854 unsigned long flag; 855 struct avc_node *pos, *node, *orig = NULL; 856 struct hlist_head *head; 857 spinlock_t *lock; 858 |
829 node = avc_alloc_node(); | 859 node = avc_alloc_node(avc); |
830 if (!node) { 831 rc = -ENOMEM; 832 goto out; 833 } 834 835 /* Lock the target slot */ 836 hvalue = avc_hash(ssid, tsid, tclass); 837 | 860 if (!node) { 861 rc = -ENOMEM; 862 goto out; 863 } 864 865 /* Lock the target slot */ 866 hvalue = avc_hash(ssid, tsid, tclass); 867 |
838 head = &avc_cache.slots[hvalue]; 839 lock = &avc_cache.slots_lock[hvalue]; | 868 head = &avc->avc_cache.slots[hvalue]; 869 lock = &avc->avc_cache.slots_lock[hvalue]; |
840 841 spin_lock_irqsave(lock, flag); 842 843 hlist_for_each_entry(pos, head, list) { 844 if (ssid == pos->ae.ssid && 845 tsid == pos->ae.tsid && 846 tclass == pos->ae.tclass && 847 seqno == pos->ae.avd.seqno){ 848 orig = pos; 849 break; 850 } 851 } 852 853 if (!orig) { 854 rc = -ENOENT; | 870 871 spin_lock_irqsave(lock, flag); 872 873 hlist_for_each_entry(pos, head, list) { 874 if (ssid == pos->ae.ssid && 875 tsid == pos->ae.tsid && 876 tclass == pos->ae.tclass && 877 seqno == pos->ae.avd.seqno){ 878 orig = pos; 879 break; 880 } 881 } 882 883 if (!orig) { 884 rc = -ENOENT; |
855 avc_node_kill(node); | 885 avc_node_kill(avc, node); |
856 goto out_unlock; 857 } 858 859 /* 860 * Copy and replace original node. 861 */ 862 863 avc_node_populate(node, ssid, tsid, tclass, &orig->ae.avd); --- 27 unchanged lines hidden (view full) --- 891 break; 892 case AVC_CALLBACK_AUDITDENY_DISABLE: 893 node->ae.avd.auditdeny &= ~perms; 894 break; 895 case AVC_CALLBACK_ADD_XPERMS: 896 avc_add_xperms_decision(node, xpd); 897 break; 898 } | 886 goto out_unlock; 887 } 888 889 /* 890 * Copy and replace original node. 891 */ 892 893 avc_node_populate(node, ssid, tsid, tclass, &orig->ae.avd); --- 27 unchanged lines hidden (view full) --- 921 break; 922 case AVC_CALLBACK_AUDITDENY_DISABLE: 923 node->ae.avd.auditdeny &= ~perms; 924 break; 925 case AVC_CALLBACK_ADD_XPERMS: 926 avc_add_xperms_decision(node, xpd); 927 break; 928 } |
899 avc_node_replace(node, orig); | 929 avc_node_replace(avc, node, orig); |
900out_unlock: 901 spin_unlock_irqrestore(lock, flag); 902out: 903 return rc; 904} 905 906/** 907 * avc_flush - Flush the cache 908 */ | 930out_unlock: 931 spin_unlock_irqrestore(lock, flag); 932out: 933 return rc; 934} 935 936/** 937 * avc_flush - Flush the cache 938 */ |
909static void avc_flush(void) | 939static void avc_flush(struct selinux_avc *avc) |
910{ 911 struct hlist_head *head; 912 struct avc_node *node; 913 spinlock_t *lock; 914 unsigned long flag; 915 int i; 916 917 for (i = 0; i < AVC_CACHE_SLOTS; i++) { | 940{ 941 struct hlist_head *head; 942 struct avc_node *node; 943 spinlock_t *lock; 944 unsigned long flag; 945 int i; 946 947 for (i = 0; i < AVC_CACHE_SLOTS; i++) { |
918 head = &avc_cache.slots[i]; 919 lock = &avc_cache.slots_lock[i]; | 948 head = &avc->avc_cache.slots[i]; 949 lock = &avc->avc_cache.slots_lock[i]; |
920 921 spin_lock_irqsave(lock, flag); 922 /* 923 * With preemptable RCU, the outer spinlock does not 924 * prevent RCU grace periods from ending. 925 */ 926 rcu_read_lock(); 927 hlist_for_each_entry(node, head, list) | 950 951 spin_lock_irqsave(lock, flag); 952 /* 953 * With preemptable RCU, the outer spinlock does not 954 * prevent RCU grace periods from ending. 955 */ 956 rcu_read_lock(); 957 hlist_for_each_entry(node, head, list) |
928 avc_node_delete(node); | 958 avc_node_delete(avc, node); |
929 rcu_read_unlock(); 930 spin_unlock_irqrestore(lock, flag); 931 } 932} 933 934/** 935 * avc_ss_reset - Flush the cache and revalidate migrated permissions. 936 * @seqno: policy sequence number 937 */ | 959 rcu_read_unlock(); 960 spin_unlock_irqrestore(lock, flag); 961 } 962} 963 964/** 965 * avc_ss_reset - Flush the cache and revalidate migrated permissions. 966 * @seqno: policy sequence number 967 */ |
938int avc_ss_reset(u32 seqno) | 968int avc_ss_reset(struct selinux_avc *avc, u32 seqno) |
939{ 940 struct avc_callback_node *c; 941 int rc = 0, tmprc; 942 | 969{ 970 struct avc_callback_node *c; 971 int rc = 0, tmprc; 972 |
943 avc_flush(); | 973 avc_flush(avc); |
944 945 for (c = avc_callbacks; c; c = c->next) { 946 if (c->events & AVC_CALLBACK_RESET) { 947 tmprc = c->callback(AVC_CALLBACK_RESET); 948 /* save the first error encountered for the return 949 value and continue processing the callbacks */ 950 if (!rc) 951 rc = tmprc; 952 } 953 } 954 | 974 975 for (c = avc_callbacks; c; c = c->next) { 976 if (c->events & AVC_CALLBACK_RESET) { 977 tmprc = c->callback(AVC_CALLBACK_RESET); 978 /* save the first error encountered for the return 979 value and continue processing the callbacks */ 980 if (!rc) 981 rc = tmprc; 982 } 983 } 984 |
955 avc_latest_notif_update(seqno, 0); | 985 avc_latest_notif_update(avc, seqno, 0); |
956 return rc; 957} 958 959/* 960 * Slow-path helper function for avc_has_perm_noaudit, 961 * when the avc_node lookup fails. We get called with 962 * the RCU read lock held, and need to return with it 963 * still held, but drop if for the security compute. 964 * 965 * Don't inline this, since it's the slow-path and just 966 * results in a bigger stack frame. 967 */ | 986 return rc; 987} 988 989/* 990 * Slow-path helper function for avc_has_perm_noaudit, 991 * when the avc_node lookup fails. We get called with 992 * the RCU read lock held, and need to return with it 993 * still held, but drop if for the security compute. 994 * 995 * Don't inline this, since it's the slow-path and just 996 * results in a bigger stack frame. 997 */ |
968static noinline struct avc_node *avc_compute_av(u32 ssid, u32 tsid, 969 u16 tclass, struct av_decision *avd, 970 struct avc_xperms_node *xp_node) | 998static noinline 999struct avc_node *avc_compute_av(struct selinux_state *state, 1000 u32 ssid, u32 tsid, 1001 u16 tclass, struct av_decision *avd, 1002 struct avc_xperms_node *xp_node) |
971{ 972 rcu_read_unlock(); 973 INIT_LIST_HEAD(&xp_node->xpd_head); | 1003{ 1004 rcu_read_unlock(); 1005 INIT_LIST_HEAD(&xp_node->xpd_head); |
974 security_compute_av(&selinux_state, ssid, tsid, tclass, 975 avd, &xp_node->xp); | 1006 security_compute_av(state, ssid, tsid, tclass, avd, &xp_node->xp); |
976 rcu_read_lock(); | 1007 rcu_read_lock(); |
977 return avc_insert(ssid, tsid, tclass, avd, xp_node); | 1008 return avc_insert(state->avc, ssid, tsid, tclass, avd, xp_node); |
978} 979 | 1009} 1010 |
980static noinline int avc_denied(u32 ssid, u32 tsid, 981 u16 tclass, u32 requested, 982 u8 driver, u8 xperm, unsigned flags, 983 struct av_decision *avd) | 1011static noinline int avc_denied(struct selinux_state *state, 1012 u32 ssid, u32 tsid, 1013 u16 tclass, u32 requested, 1014 u8 driver, u8 xperm, unsigned int flags, 1015 struct av_decision *avd) |
984{ 985 if (flags & AVC_STRICT) 986 return -EACCES; 987 | 1016{ 1017 if (flags & AVC_STRICT) 1018 return -EACCES; 1019 |
988 if (enforcing_enabled(&selinux_state) && | 1020 if (enforcing_enabled(state) && |
989 !(avd->flags & AVD_FLAGS_PERMISSIVE)) 990 return -EACCES; 991 | 1021 !(avd->flags & AVD_FLAGS_PERMISSIVE)) 1022 return -EACCES; 1023 |
992 avc_update_node(AVC_CALLBACK_GRANT, requested, driver, xperm, ssid, 993 tsid, tclass, avd->seqno, NULL, flags); | 1024 avc_update_node(state->avc, AVC_CALLBACK_GRANT, requested, driver, 1025 xperm, ssid, tsid, tclass, avd->seqno, NULL, flags); |
994 return 0; 995} 996 997/* 998 * The avc extended permissions logic adds an additional 256 bits of 999 * permissions to an avc node when extended permissions for that node are 1000 * specified in the avtab. If the additional 256 permissions is not adequate, 1001 * as-is the case with ioctls, then multiple may be chained together and the 1002 * driver field is used to specify which set contains the permission. 1003 */ | 1026 return 0; 1027} 1028 1029/* 1030 * The avc extended permissions logic adds an additional 256 bits of 1031 * permissions to an avc node when extended permissions for that node are 1032 * specified in the avtab. If the additional 256 permissions is not adequate, 1033 * as-is the case with ioctls, then multiple may be chained together and the 1034 * driver field is used to specify which set contains the permission. 1035 */ |
1004int avc_has_extended_perms(u32 ssid, u32 tsid, u16 tclass, u32 requested, 1005 u8 driver, u8 xperm, struct common_audit_data *ad) | 1036int avc_has_extended_perms(struct selinux_state *state, 1037 u32 ssid, u32 tsid, u16 tclass, u32 requested, 1038 u8 driver, u8 xperm, struct common_audit_data *ad) |
1006{ 1007 struct avc_node *node; 1008 struct av_decision avd; 1009 u32 denied; 1010 struct extended_perms_decision local_xpd; 1011 struct extended_perms_decision *xpd = NULL; 1012 struct extended_perms_data allowed; 1013 struct extended_perms_data auditallow; 1014 struct extended_perms_data dontaudit; 1015 struct avc_xperms_node local_xp_node; 1016 struct avc_xperms_node *xp_node; 1017 int rc = 0, rc2; 1018 1019 xp_node = &local_xp_node; 1020 BUG_ON(!requested); 1021 1022 rcu_read_lock(); 1023 | 1039{ 1040 struct avc_node *node; 1041 struct av_decision avd; 1042 u32 denied; 1043 struct extended_perms_decision local_xpd; 1044 struct extended_perms_decision *xpd = NULL; 1045 struct extended_perms_data allowed; 1046 struct extended_perms_data auditallow; 1047 struct extended_perms_data dontaudit; 1048 struct avc_xperms_node local_xp_node; 1049 struct avc_xperms_node *xp_node; 1050 int rc = 0, rc2; 1051 1052 xp_node = &local_xp_node; 1053 BUG_ON(!requested); 1054 1055 rcu_read_lock(); 1056 |
1024 node = avc_lookup(ssid, tsid, tclass); | 1057 node = avc_lookup(state->avc, ssid, tsid, tclass); |
1025 if (unlikely(!node)) { | 1058 if (unlikely(!node)) { |
1026 node = avc_compute_av(ssid, tsid, tclass, &avd, xp_node); | 1059 node = avc_compute_av(state, ssid, tsid, tclass, &avd, xp_node); |
1027 } else { 1028 memcpy(&avd, &node->ae.avd, sizeof(avd)); 1029 xp_node = node->ae.xp_node; 1030 } 1031 /* if extended permissions are not defined, only consider av_decision */ 1032 if (!xp_node || !xp_node->xp.len) 1033 goto decision; 1034 --- 7 unchanged lines hidden (view full) --- 1042 * Compute the extended_perms_decision only if the driver 1043 * is flagged 1044 */ 1045 if (!security_xperm_test(xp_node->xp.drivers.p, driver)) { 1046 avd.allowed &= ~requested; 1047 goto decision; 1048 } 1049 rcu_read_unlock(); | 1060 } else { 1061 memcpy(&avd, &node->ae.avd, sizeof(avd)); 1062 xp_node = node->ae.xp_node; 1063 } 1064 /* if extended permissions are not defined, only consider av_decision */ 1065 if (!xp_node || !xp_node->xp.len) 1066 goto decision; 1067 --- 7 unchanged lines hidden (view full) --- 1075 * Compute the extended_perms_decision only if the driver 1076 * is flagged 1077 */ 1078 if (!security_xperm_test(xp_node->xp.drivers.p, driver)) { 1079 avd.allowed &= ~requested; 1080 goto decision; 1081 } 1082 rcu_read_unlock(); |
1050 security_compute_xperms_decision(&selinux_state, ssid, tsid, 1051 tclass, driver, &local_xpd); | 1083 security_compute_xperms_decision(state, ssid, tsid, tclass, 1084 driver, &local_xpd); |
1052 rcu_read_lock(); | 1085 rcu_read_lock(); |
1053 avc_update_node(AVC_CALLBACK_ADD_XPERMS, requested, driver, xperm, 1054 ssid, tsid, tclass, avd.seqno, &local_xpd, 0); | 1086 avc_update_node(state->avc, AVC_CALLBACK_ADD_XPERMS, requested, 1087 driver, xperm, ssid, tsid, tclass, avd.seqno, 1088 &local_xpd, 0); |
1055 } else { 1056 avc_quick_copy_xperms_decision(xperm, &local_xpd, xpd); 1057 } 1058 xpd = &local_xpd; 1059 1060 if (!avc_xperms_has_perm(xpd, xperm, XPERMS_ALLOWED)) 1061 avd.allowed &= ~requested; 1062 1063decision: 1064 denied = requested & ~(avd.allowed); 1065 if (unlikely(denied)) | 1089 } else { 1090 avc_quick_copy_xperms_decision(xperm, &local_xpd, xpd); 1091 } 1092 xpd = &local_xpd; 1093 1094 if (!avc_xperms_has_perm(xpd, xperm, XPERMS_ALLOWED)) 1095 avd.allowed &= ~requested; 1096 1097decision: 1098 denied = requested & ~(avd.allowed); 1099 if (unlikely(denied)) |
1066 rc = avc_denied(ssid, tsid, tclass, requested, driver, xperm, 1067 AVC_EXTENDED_PERMS, &avd); | 1100 rc = avc_denied(state, ssid, tsid, tclass, requested, 1101 driver, xperm, AVC_EXTENDED_PERMS, &avd); |
1068 1069 rcu_read_unlock(); 1070 | 1102 1103 rcu_read_unlock(); 1104 |
1071 rc2 = avc_xperms_audit(ssid, tsid, tclass, requested, | 1105 rc2 = avc_xperms_audit(state, ssid, tsid, tclass, requested, |
1072 &avd, xpd, xperm, rc, ad); 1073 if (rc2) 1074 return rc2; 1075 return rc; 1076} 1077 1078/** 1079 * avc_has_perm_noaudit - Check permissions but perform no auditing. --- 10 unchanged lines hidden (view full) --- 1090 * a new decision and add it to the cache. Return a copy of the decisions 1091 * in @avd. Return %0 if all @requested permissions are granted, 1092 * -%EACCES if any permissions are denied, or another -errno upon 1093 * other errors. This function is typically called by avc_has_perm(), 1094 * but may also be called directly to separate permission checking from 1095 * auditing, e.g. in cases where a lock must be held for the check but 1096 * should be released for the auditing. 1097 */ | 1106 &avd, xpd, xperm, rc, ad); 1107 if (rc2) 1108 return rc2; 1109 return rc; 1110} 1111 1112/** 1113 * avc_has_perm_noaudit - Check permissions but perform no auditing. --- 10 unchanged lines hidden (view full) --- 1124 * a new decision and add it to the cache. Return a copy of the decisions 1125 * in @avd. Return %0 if all @requested permissions are granted, 1126 * -%EACCES if any permissions are denied, or another -errno upon 1127 * other errors. This function is typically called by avc_has_perm(), 1128 * but may also be called directly to separate permission checking from 1129 * auditing, e.g. in cases where a lock must be held for the check but 1130 * should be released for the auditing. 1131 */ |
1098inline int avc_has_perm_noaudit(u32 ssid, u32 tsid, 1099 u16 tclass, u32 requested, 1100 unsigned flags, 1101 struct av_decision *avd) | 1132inline int avc_has_perm_noaudit(struct selinux_state *state, 1133 u32 ssid, u32 tsid, 1134 u16 tclass, u32 requested, 1135 unsigned int flags, 1136 struct av_decision *avd) |
1102{ 1103 struct avc_node *node; 1104 struct avc_xperms_node xp_node; 1105 int rc = 0; 1106 u32 denied; 1107 1108 BUG_ON(!requested); 1109 1110 rcu_read_lock(); 1111 | 1137{ 1138 struct avc_node *node; 1139 struct avc_xperms_node xp_node; 1140 int rc = 0; 1141 u32 denied; 1142 1143 BUG_ON(!requested); 1144 1145 rcu_read_lock(); 1146 |
1112 node = avc_lookup(ssid, tsid, tclass); | 1147 node = avc_lookup(state->avc, ssid, tsid, tclass); |
1113 if (unlikely(!node)) | 1148 if (unlikely(!node)) |
1114 node = avc_compute_av(ssid, tsid, tclass, avd, &xp_node); | 1149 node = avc_compute_av(state, ssid, tsid, tclass, avd, &xp_node); |
1115 else 1116 memcpy(avd, &node->ae.avd, sizeof(*avd)); 1117 1118 denied = requested & ~(avd->allowed); 1119 if (unlikely(denied)) | 1150 else 1151 memcpy(avd, &node->ae.avd, sizeof(*avd)); 1152 1153 denied = requested & ~(avd->allowed); 1154 if (unlikely(denied)) |
1120 rc = avc_denied(ssid, tsid, tclass, requested, 0, 0, flags, avd); | 1155 rc = avc_denied(state, ssid, tsid, tclass, requested, 0, 0, 1156 flags, avd); |
1121 1122 rcu_read_unlock(); 1123 return rc; 1124} 1125 1126/** 1127 * avc_has_perm - Check permissions and perform any appropriate auditing. 1128 * @ssid: source security identifier --- 5 unchanged lines hidden (view full) --- 1134 * Check the AVC to determine whether the @requested permissions are granted 1135 * for the SID pair (@ssid, @tsid), interpreting the permissions 1136 * based on @tclass, and call the security server on a cache miss to obtain 1137 * a new decision and add it to the cache. Audit the granting or denial of 1138 * permissions in accordance with the policy. Return %0 if all @requested 1139 * permissions are granted, -%EACCES if any permissions are denied, or 1140 * another -errno upon other errors. 1141 */ | 1157 1158 rcu_read_unlock(); 1159 return rc; 1160} 1161 1162/** 1163 * avc_has_perm - Check permissions and perform any appropriate auditing. 1164 * @ssid: source security identifier --- 5 unchanged lines hidden (view full) --- 1170 * Check the AVC to determine whether the @requested permissions are granted 1171 * for the SID pair (@ssid, @tsid), interpreting the permissions 1172 * based on @tclass, and call the security server on a cache miss to obtain 1173 * a new decision and add it to the cache. Audit the granting or denial of 1174 * permissions in accordance with the policy. Return %0 if all @requested 1175 * permissions are granted, -%EACCES if any permissions are denied, or 1176 * another -errno upon other errors. 1177 */ |
1142int avc_has_perm(u32 ssid, u32 tsid, u16 tclass, | 1178int avc_has_perm(struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass, |
1143 u32 requested, struct common_audit_data *auditdata) 1144{ 1145 struct av_decision avd; 1146 int rc, rc2; 1147 | 1179 u32 requested, struct common_audit_data *auditdata) 1180{ 1181 struct av_decision avd; 1182 int rc, rc2; 1183 |
1148 rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, 0, &avd); | 1184 rc = avc_has_perm_noaudit(state, ssid, tsid, tclass, requested, 0, 1185 &avd); |
1149 | 1186 |
1150 rc2 = avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata, 0); | 1187 rc2 = avc_audit(state, ssid, tsid, tclass, requested, &avd, rc, 1188 auditdata, 0); |
1151 if (rc2) 1152 return rc2; 1153 return rc; 1154} 1155 | 1189 if (rc2) 1190 return rc2; 1191 return rc; 1192} 1193 |
1156int avc_has_perm_flags(u32 ssid, u32 tsid, u16 tclass, 1157 u32 requested, struct common_audit_data *auditdata, | 1194int avc_has_perm_flags(struct selinux_state *state, 1195 u32 ssid, u32 tsid, u16 tclass, u32 requested, 1196 struct common_audit_data *auditdata, |
1158 int flags) 1159{ 1160 struct av_decision avd; 1161 int rc, rc2; 1162 | 1197 int flags) 1198{ 1199 struct av_decision avd; 1200 int rc, rc2; 1201 |
1163 rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, 0, &avd); | 1202 rc = avc_has_perm_noaudit(state, ssid, tsid, tclass, requested, 0, 1203 &avd); |
1164 | 1204 |
1165 rc2 = avc_audit(ssid, tsid, tclass, requested, &avd, rc, | 1205 rc2 = avc_audit(state, ssid, tsid, tclass, requested, &avd, rc, |
1166 auditdata, flags); 1167 if (rc2) 1168 return rc2; 1169 return rc; 1170} 1171 | 1206 auditdata, flags); 1207 if (rc2) 1208 return rc2; 1209 return rc; 1210} 1211 |
1172u32 avc_policy_seqno(void) | 1212u32 avc_policy_seqno(struct selinux_state *state) |
1173{ | 1213{ |
1174 return avc_cache.latest_notif; | 1214 return state->avc->avc_cache.latest_notif; |
1175} 1176 1177void avc_disable(void) 1178{ 1179 /* 1180 * If you are looking at this because you have realized that we are 1181 * not destroying the avc_node_cachep it might be easy to fix, but 1182 * I don't know the memory barrier semantics well enough to know. It's 1183 * possible that some other task dereferenced security_ops when 1184 * it still pointed to selinux operations. If that is the case it's 1185 * possible that it is about to use the avc and is about to need the 1186 * avc_node_cachep. I know I could wrap the security.c security_ops call 1187 * in an rcu_lock, but seriously, it's not worth it. Instead I just flush 1188 * the cache and get that memory back. 1189 */ 1190 if (avc_node_cachep) { | 1215} 1216 1217void avc_disable(void) 1218{ 1219 /* 1220 * If you are looking at this because you have realized that we are 1221 * not destroying the avc_node_cachep it might be easy to fix, but 1222 * I don't know the memory barrier semantics well enough to know. It's 1223 * possible that some other task dereferenced security_ops when 1224 * it still pointed to selinux operations. If that is the case it's 1225 * possible that it is about to use the avc and is about to need the 1226 * avc_node_cachep. I know I could wrap the security.c security_ops call 1227 * in an rcu_lock, but seriously, it's not worth it. Instead I just flush 1228 * the cache and get that memory back. 1229 */ 1230 if (avc_node_cachep) { |
1191 avc_flush(); | 1231 avc_flush(selinux_state.avc); |
1192 /* kmem_cache_destroy(avc_node_cachep); */ 1193 } 1194} | 1232 /* kmem_cache_destroy(avc_node_cachep); */ 1233 } 1234} |