summaryrefslogtreecommitdiffstats
path: root/security/selinux/avc.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/avc.c')
-rw-r--r--security/selinux/avc.c282
1 files changed, 163 insertions, 119 deletions
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 2380b8d72cec..f3aedf077509 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -82,14 +82,42 @@ struct avc_callback_node {
82 struct avc_callback_node *next; 82 struct avc_callback_node *next;
83}; 83};
84 84
85/* Exported via selinufs */
86unsigned int avc_cache_threshold = AVC_DEF_CACHE_THRESHOLD;
87
88#ifdef CONFIG_SECURITY_SELINUX_AVC_STATS 85#ifdef CONFIG_SECURITY_SELINUX_AVC_STATS
89DEFINE_PER_CPU(struct avc_cache_stats, avc_cache_stats) = { 0 }; 86DEFINE_PER_CPU(struct avc_cache_stats, avc_cache_stats) = { 0 };
90#endif 87#endif
91 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; 121static struct avc_callback_node *avc_callbacks;
94static struct kmem_cache *avc_node_cachep; 122static struct kmem_cache *avc_node_cachep;
95static struct kmem_cache *avc_xperms_data_cachep; 123static struct kmem_cache *avc_xperms_data_cachep;
@@ -143,13 +171,14 @@ static void avc_dump_av(struct audit_buffer *ab, u16 tclass, u32 av)
143 * @tsid: target security identifier 171 * @tsid: target security identifier
144 * @tclass: target security class 172 * @tclass: target security class
145 */ 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{ 176{
148 int rc; 177 int rc;
149 char *scontext; 178 char *scontext;
150 u32 scontext_len; 179 u32 scontext_len;
151 180
152 rc = security_sid_to_context(ssid, &scontext, &scontext_len); 181 rc = security_sid_to_context(state, ssid, &scontext, &scontext_len);
153 if (rc) 182 if (rc)
154 audit_log_format(ab, "ssid=%d", ssid); 183 audit_log_format(ab, "ssid=%d", ssid);
155 else { 184 else {
@@ -157,7 +186,7 @@ static void avc_dump_query(struct audit_buffer *ab, u32 ssid, u32 tsid, u16 tcla
157 kfree(scontext); 186 kfree(scontext);
158 } 187 }
159 188
160 rc = security_sid_to_context(tsid, &scontext, &scontext_len); 189 rc = security_sid_to_context(state, tsid, &scontext, &scontext_len);
161 if (rc) 190 if (rc)
162 audit_log_format(ab, " tsid=%d", tsid); 191 audit_log_format(ab, " tsid=%d", tsid);
163 else { 192 else {
@@ -176,15 +205,6 @@ static void avc_dump_query(struct audit_buffer *ab, u32 ssid, u32 tsid, u16 tcla
176 */ 205 */
177void __init avc_init(void) 206void __init avc_init(void)
178{ 207{
179 int i;
180
181 for (i = 0; i < AVC_CACHE_SLOTS; i++) {
182 INIT_HLIST_HEAD(&avc_cache.slots[i]);
183 spin_lock_init(&avc_cache.slots_lock[i]);
184 }
185 atomic_set(&avc_cache.active_nodes, 0);
186 atomic_set(&avc_cache.lru_hint, 0);
187
188 avc_node_cachep = kmem_cache_create("avc_node", sizeof(struct avc_node), 208 avc_node_cachep = kmem_cache_create("avc_node", sizeof(struct avc_node),
189 0, SLAB_PANIC, NULL); 209 0, SLAB_PANIC, NULL);
190 avc_xperms_cachep = kmem_cache_create("avc_xperms_node", 210 avc_xperms_cachep = kmem_cache_create("avc_xperms_node",
@@ -199,7 +219,7 @@ void __init avc_init(void)
199 0, SLAB_PANIC, NULL); 219 0, SLAB_PANIC, NULL);
200} 220}
201 221
202int avc_get_hash_stats(char *page) 222int avc_get_hash_stats(struct selinux_avc *avc, char *page)
203{ 223{
204 int i, chain_len, max_chain_len, slots_used; 224 int i, chain_len, max_chain_len, slots_used;
205 struct avc_node *node; 225 struct avc_node *node;
@@ -210,7 +230,7 @@ int avc_get_hash_stats(char *page)
210 slots_used = 0; 230 slots_used = 0;
211 max_chain_len = 0; 231 max_chain_len = 0;
212 for (i = 0; i < AVC_CACHE_SLOTS; i++) { 232 for (i = 0; i < AVC_CACHE_SLOTS; i++) {
213 head = &avc_cache.slots[i]; 233 head = &avc->avc_cache.slots[i];
214 if (!hlist_empty(head)) { 234 if (!hlist_empty(head)) {
215 slots_used++; 235 slots_used++;
216 chain_len = 0; 236 chain_len = 0;
@@ -225,7 +245,7 @@ int avc_get_hash_stats(char *page)
225 245
226 return scnprintf(page, PAGE_SIZE, "entries: %d\nbuckets used: %d/%d\n" 246 return scnprintf(page, PAGE_SIZE, "entries: %d\nbuckets used: %d/%d\n"
227 "longest chain: %d\n", 247 "longest chain: %d\n",
228 atomic_read(&avc_cache.active_nodes), 248 atomic_read(&avc->avc_cache.active_nodes),
229 slots_used, AVC_CACHE_SLOTS, max_chain_len); 249 slots_used, AVC_CACHE_SLOTS, max_chain_len);
230} 250}
231 251
@@ -462,11 +482,12 @@ static inline u32 avc_xperms_audit_required(u32 requested,
462 return audited; 482 return audited;
463} 483}
464 484
465static inline int avc_xperms_audit(u32 ssid, u32 tsid, u16 tclass, 485static inline int avc_xperms_audit(struct selinux_state *state,
466 u32 requested, struct av_decision *avd, 486 u32 ssid, u32 tsid, u16 tclass,
467 struct extended_perms_decision *xpd, 487 u32 requested, struct av_decision *avd,
468 u8 perm, int result, 488 struct extended_perms_decision *xpd,
469 struct common_audit_data *ad) 489 u8 perm, int result,
490 struct common_audit_data *ad)
470{ 491{
471 u32 audited, denied; 492 u32 audited, denied;
472 493
@@ -474,7 +495,7 @@ static inline int avc_xperms_audit(u32 ssid, u32 tsid, u16 tclass,
474 requested, avd, xpd, perm, result, &denied); 495 requested, avd, xpd, perm, result, &denied);
475 if (likely(!audited)) 496 if (likely(!audited))
476 return 0; 497 return 0;
477 return slow_avc_audit(ssid, tsid, tclass, requested, 498 return slow_avc_audit(state, ssid, tsid, tclass, requested,
478 audited, denied, result, ad, 0); 499 audited, denied, result, ad, 0);
479} 500}
480 501
@@ -486,29 +507,30 @@ static void avc_node_free(struct rcu_head *rhead)
486 avc_cache_stats_incr(frees); 507 avc_cache_stats_incr(frees);
487} 508}
488 509
489static void avc_node_delete(struct avc_node *node) 510static void avc_node_delete(struct selinux_avc *avc, struct avc_node *node)
490{ 511{
491 hlist_del_rcu(&node->list); 512 hlist_del_rcu(&node->list);
492 call_rcu(&node->rhead, avc_node_free); 513 call_rcu(&node->rhead, avc_node_free);
493 atomic_dec(&avc_cache.active_nodes); 514 atomic_dec(&avc->avc_cache.active_nodes);
494} 515}
495 516
496static void avc_node_kill(struct avc_node *node) 517static void avc_node_kill(struct selinux_avc *avc, struct avc_node *node)
497{ 518{
498 avc_xperms_free(node->ae.xp_node); 519 avc_xperms_free(node->ae.xp_node);
499 kmem_cache_free(avc_node_cachep, node); 520 kmem_cache_free(avc_node_cachep, node);
500 avc_cache_stats_incr(frees); 521 avc_cache_stats_incr(frees);
501 atomic_dec(&avc_cache.active_nodes); 522 atomic_dec(&avc->avc_cache.active_nodes);
502} 523}
503 524
504static 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)
505{ 527{
506 hlist_replace_rcu(&old->list, &new->list); 528 hlist_replace_rcu(&old->list, &new->list);
507 call_rcu(&old->rhead, avc_node_free); 529 call_rcu(&old->rhead, avc_node_free);
508 atomic_dec(&avc_cache.active_nodes); 530 atomic_dec(&avc->avc_cache.active_nodes);
509} 531}
510 532
511static inline int avc_reclaim_node(void) 533static inline int avc_reclaim_node(struct selinux_avc *avc)
512{ 534{
513 struct avc_node *node; 535 struct avc_node *node;
514 int hvalue, try, ecx; 536 int hvalue, try, ecx;
@@ -517,16 +539,17 @@ static inline int avc_reclaim_node(void)
517 spinlock_t *lock; 539 spinlock_t *lock;
518 540
519 for (try = 0, ecx = 0; try < AVC_CACHE_SLOTS; try++) { 541 for (try = 0, ecx = 0; try < AVC_CACHE_SLOTS; try++) {
520 hvalue = atomic_inc_return(&avc_cache.lru_hint) & (AVC_CACHE_SLOTS - 1); 542 hvalue = atomic_inc_return(&avc->avc_cache.lru_hint) &
521 head = &avc_cache.slots[hvalue]; 543 (AVC_CACHE_SLOTS - 1);
522 lock = &avc_cache.slots_lock[hvalue]; 544 head = &avc->avc_cache.slots[hvalue];
545 lock = &avc->avc_cache.slots_lock[hvalue];
523 546
524 if (!spin_trylock_irqsave(lock, flags)) 547 if (!spin_trylock_irqsave(lock, flags))
525 continue; 548 continue;
526 549
527 rcu_read_lock(); 550 rcu_read_lock();
528 hlist_for_each_entry(node, head, list) { 551 hlist_for_each_entry(node, head, list) {
529 avc_node_delete(node); 552 avc_node_delete(avc, node);
530 avc_cache_stats_incr(reclaims); 553 avc_cache_stats_incr(reclaims);
531 ecx++; 554 ecx++;
532 if (ecx >= AVC_CACHE_RECLAIM) { 555 if (ecx >= AVC_CACHE_RECLAIM) {
@@ -542,7 +565,7 @@ out:
542 return ecx; 565 return ecx;
543} 566}
544 567
545static struct avc_node *avc_alloc_node(void) 568static struct avc_node *avc_alloc_node(struct selinux_avc *avc)
546{ 569{
547 struct avc_node *node; 570 struct avc_node *node;
548 571
@@ -553,8 +576,9 @@ static struct avc_node *avc_alloc_node(void)
553 INIT_HLIST_NODE(&node->list); 576 INIT_HLIST_NODE(&node->list);
554 avc_cache_stats_incr(allocations); 577 avc_cache_stats_incr(allocations);
555 578
556 if (atomic_inc_return(&avc_cache.active_nodes) > avc_cache_threshold) 579 if (atomic_inc_return(&avc->avc_cache.active_nodes) >
557 avc_reclaim_node(); 580 avc->avc_cache_threshold)
581 avc_reclaim_node(avc);
558 582
559out: 583out:
560 return node; 584 return node;
@@ -568,14 +592,15 @@ static void avc_node_populate(struct avc_node *node, u32 ssid, u32 tsid, u16 tcl
568 memcpy(&node->ae.avd, avd, sizeof(node->ae.avd)); 592 memcpy(&node->ae.avd, avd, sizeof(node->ae.avd));
569} 593}
570 594
571static 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)
572{ 597{
573 struct avc_node *node, *ret = NULL; 598 struct avc_node *node, *ret = NULL;
574 int hvalue; 599 int hvalue;
575 struct hlist_head *head; 600 struct hlist_head *head;
576 601
577 hvalue = avc_hash(ssid, tsid, tclass); 602 hvalue = avc_hash(ssid, tsid, tclass);
578 head = &avc_cache.slots[hvalue]; 603 head = &avc->avc_cache.slots[hvalue];
579 hlist_for_each_entry_rcu(node, head, list) { 604 hlist_for_each_entry_rcu(node, head, list) {
580 if (ssid == node->ae.ssid && 605 if (ssid == node->ae.ssid &&
581 tclass == node->ae.tclass && 606 tclass == node->ae.tclass &&
@@ -600,12 +625,13 @@ static inline struct avc_node *avc_search_node(u32 ssid, u32 tsid, u16 tclass)
600 * then this function returns the avc_node. 625 * then this function returns the avc_node.
601 * Otherwise, this function returns NULL. 626 * Otherwise, this function returns NULL.
602 */ 627 */
603static 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)
604{ 630{
605 struct avc_node *node; 631 struct avc_node *node;
606 632
607 avc_cache_stats_incr(lookups); 633 avc_cache_stats_incr(lookups);
608 node = avc_search_node(ssid, tsid, tclass); 634 node = avc_search_node(avc, ssid, tsid, tclass);
609 635
610 if (node) 636 if (node)
611 return node; 637 return node;
@@ -614,7 +640,8 @@ static struct avc_node *avc_lookup(u32 ssid, u32 tsid, u16 tclass)
614 return NULL; 640 return NULL;
615} 641}
616 642
617static 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)
618{ 645{
619 int ret = 0; 646 int ret = 0;
620 static DEFINE_SPINLOCK(notif_lock); 647 static DEFINE_SPINLOCK(notif_lock);
@@ -622,14 +649,14 @@ static int avc_latest_notif_update(int seqno, int is_insert)
622 649
623 spin_lock_irqsave(&notif_lock, flag); 650 spin_lock_irqsave(&notif_lock, flag);
624 if (is_insert) { 651 if (is_insert) {
625 if (seqno < avc_cache.latest_notif) { 652 if (seqno < avc->avc_cache.latest_notif) {
626 printk(KERN_WARNING "SELinux: avc: seqno %d < latest_notif %d\n", 653 printk(KERN_WARNING "SELinux: avc: seqno %d < latest_notif %d\n",
627 seqno, avc_cache.latest_notif); 654 seqno, avc->avc_cache.latest_notif);
628 ret = -EAGAIN; 655 ret = -EAGAIN;
629 } 656 }
630 } else { 657 } else {
631 if (seqno > avc_cache.latest_notif) 658 if (seqno > avc->avc_cache.latest_notif)
632 avc_cache.latest_notif = seqno; 659 avc->avc_cache.latest_notif = seqno;
633 } 660 }
634 spin_unlock_irqrestore(&notif_lock, flag); 661 spin_unlock_irqrestore(&notif_lock, flag);
635 662
@@ -654,18 +681,19 @@ static int avc_latest_notif_update(int seqno, int is_insert)
654 * the access vectors into a cache entry, returns 681 * the access vectors into a cache entry, returns
655 * avc_node inserted. Otherwise, this function returns NULL. 682 * avc_node inserted. Otherwise, this function returns NULL.
656 */ 683 */
657static struct avc_node *avc_insert(u32 ssid, u32 tsid, u16 tclass, 684static struct avc_node *avc_insert(struct selinux_avc *avc,
658 struct av_decision *avd, 685 u32 ssid, u32 tsid, u16 tclass,
659 struct avc_xperms_node *xp_node) 686 struct av_decision *avd,
687 struct avc_xperms_node *xp_node)
660{ 688{
661 struct avc_node *pos, *node = NULL; 689 struct avc_node *pos, *node = NULL;
662 int hvalue; 690 int hvalue;
663 unsigned long flag; 691 unsigned long flag;
664 692
665 if (avc_latest_notif_update(avd->seqno, 1)) 693 if (avc_latest_notif_update(avc, avd->seqno, 1))
666 goto out; 694 goto out;
667 695
668 node = avc_alloc_node(); 696 node = avc_alloc_node(avc);
669 if (node) { 697 if (node) {
670 struct hlist_head *head; 698 struct hlist_head *head;
671 spinlock_t *lock; 699 spinlock_t *lock;
@@ -678,15 +706,15 @@ static struct avc_node *avc_insert(u32 ssid, u32 tsid, u16 tclass,
678 kmem_cache_free(avc_node_cachep, node); 706 kmem_cache_free(avc_node_cachep, node);
679 return NULL; 707 return NULL;
680 } 708 }
681 head = &avc_cache.slots[hvalue]; 709 head = &avc->avc_cache.slots[hvalue];
682 lock = &avc_cache.slots_lock[hvalue]; 710 lock = &avc->avc_cache.slots_lock[hvalue];
683 711
684 spin_lock_irqsave(lock, flag); 712 spin_lock_irqsave(lock, flag);
685 hlist_for_each_entry(pos, head, list) { 713 hlist_for_each_entry(pos, head, list) {
686 if (pos->ae.ssid == ssid && 714 if (pos->ae.ssid == ssid &&
687 pos->ae.tsid == tsid && 715 pos->ae.tsid == tsid &&
688 pos->ae.tclass == tclass) { 716 pos->ae.tclass == tclass) {
689 avc_node_replace(node, pos); 717 avc_node_replace(avc, node, pos);
690 goto found; 718 goto found;
691 } 719 }
692 } 720 }
@@ -724,9 +752,10 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a)
724{ 752{
725 struct common_audit_data *ad = a; 753 struct common_audit_data *ad = a;
726 audit_log_format(ab, " "); 754 audit_log_format(ab, " ");
727 avc_dump_query(ab, ad->selinux_audit_data->ssid, 755 avc_dump_query(ab, ad->selinux_audit_data->state,
728 ad->selinux_audit_data->tsid, 756 ad->selinux_audit_data->ssid,
729 ad->selinux_audit_data->tclass); 757 ad->selinux_audit_data->tsid,
758 ad->selinux_audit_data->tclass);
730 if (ad->selinux_audit_data->denied) { 759 if (ad->selinux_audit_data->denied) {
731 audit_log_format(ab, " permissive=%u", 760 audit_log_format(ab, " permissive=%u",
732 ad->selinux_audit_data->result ? 0 : 1); 761 ad->selinux_audit_data->result ? 0 : 1);
@@ -734,10 +763,11 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a)
734} 763}
735 764
736/* This is the slow part of avc audit with big stack footprint */ 765/* This is the slow part of avc audit with big stack footprint */
737noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, 766noinline int slow_avc_audit(struct selinux_state *state,
738 u32 requested, u32 audited, u32 denied, int result, 767 u32 ssid, u32 tsid, u16 tclass,
739 struct common_audit_data *a, 768 u32 requested, u32 audited, u32 denied, int result,
740 unsigned flags) 769 struct common_audit_data *a,
770 unsigned int flags)
741{ 771{
742 struct common_audit_data stack_data; 772 struct common_audit_data stack_data;
743 struct selinux_audit_data sad; 773 struct selinux_audit_data sad;
@@ -765,6 +795,7 @@ noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass,
765 sad.audited = audited; 795 sad.audited = audited;
766 sad.denied = denied; 796 sad.denied = denied;
767 sad.result = result; 797 sad.result = result;
798 sad.state = state;
768 799
769 a->selinux_audit_data = &sad; 800 a->selinux_audit_data = &sad;
770 801
@@ -813,10 +844,11 @@ out:
813 * otherwise, this function updates the AVC entry. The original AVC-entry object 844 * otherwise, this function updates the AVC entry. The original AVC-entry object
814 * will release later by RCU. 845 * will release later by RCU.
815 */ 846 */
816static int avc_update_node(u32 event, u32 perms, u8 driver, u8 xperm, u32 ssid, 847static int avc_update_node(struct selinux_avc *avc,
817 u32 tsid, u16 tclass, u32 seqno, 848 u32 event, u32 perms, u8 driver, u8 xperm, u32 ssid,
818 struct extended_perms_decision *xpd, 849 u32 tsid, u16 tclass, u32 seqno,
819 u32 flags) 850 struct extended_perms_decision *xpd,
851 u32 flags)
820{ 852{
821 int hvalue, rc = 0; 853 int hvalue, rc = 0;
822 unsigned long flag; 854 unsigned long flag;
@@ -824,7 +856,7 @@ static int avc_update_node(u32 event, u32 perms, u8 driver, u8 xperm, u32 ssid,
824 struct hlist_head *head; 856 struct hlist_head *head;
825 spinlock_t *lock; 857 spinlock_t *lock;
826 858
827 node = avc_alloc_node(); 859 node = avc_alloc_node(avc);
828 if (!node) { 860 if (!node) {
829 rc = -ENOMEM; 861 rc = -ENOMEM;
830 goto out; 862 goto out;
@@ -833,8 +865,8 @@ static int avc_update_node(u32 event, u32 perms, u8 driver, u8 xperm, u32 ssid,
833 /* Lock the target slot */ 865 /* Lock the target slot */
834 hvalue = avc_hash(ssid, tsid, tclass); 866 hvalue = avc_hash(ssid, tsid, tclass);
835 867
836 head = &avc_cache.slots[hvalue]; 868 head = &avc->avc_cache.slots[hvalue];
837 lock = &avc_cache.slots_lock[hvalue]; 869 lock = &avc->avc_cache.slots_lock[hvalue];
838 870
839 spin_lock_irqsave(lock, flag); 871 spin_lock_irqsave(lock, flag);
840 872
@@ -850,7 +882,7 @@ static int avc_update_node(u32 event, u32 perms, u8 driver, u8 xperm, u32 ssid,
850 882
851 if (!orig) { 883 if (!orig) {
852 rc = -ENOENT; 884 rc = -ENOENT;
853 avc_node_kill(node); 885 avc_node_kill(avc, node);
854 goto out_unlock; 886 goto out_unlock;
855 } 887 }
856 888
@@ -894,7 +926,7 @@ static int avc_update_node(u32 event, u32 perms, u8 driver, u8 xperm, u32 ssid,
894 avc_add_xperms_decision(node, xpd); 926 avc_add_xperms_decision(node, xpd);
895 break; 927 break;
896 } 928 }
897 avc_node_replace(node, orig); 929 avc_node_replace(avc, node, orig);
898out_unlock: 930out_unlock:
899 spin_unlock_irqrestore(lock, flag); 931 spin_unlock_irqrestore(lock, flag);
900out: 932out:
@@ -904,7 +936,7 @@ out:
904/** 936/**
905 * avc_flush - Flush the cache 937 * avc_flush - Flush the cache
906 */ 938 */
907static void avc_flush(void) 939static void avc_flush(struct selinux_avc *avc)
908{ 940{
909 struct hlist_head *head; 941 struct hlist_head *head;
910 struct avc_node *node; 942 struct avc_node *node;
@@ -913,8 +945,8 @@ static void avc_flush(void)
913 int i; 945 int i;
914 946
915 for (i = 0; i < AVC_CACHE_SLOTS; i++) { 947 for (i = 0; i < AVC_CACHE_SLOTS; i++) {
916 head = &avc_cache.slots[i]; 948 head = &avc->avc_cache.slots[i];
917 lock = &avc_cache.slots_lock[i]; 949 lock = &avc->avc_cache.slots_lock[i];
918 950
919 spin_lock_irqsave(lock, flag); 951 spin_lock_irqsave(lock, flag);
920 /* 952 /*
@@ -923,7 +955,7 @@ static void avc_flush(void)
923 */ 955 */
924 rcu_read_lock(); 956 rcu_read_lock();
925 hlist_for_each_entry(node, head, list) 957 hlist_for_each_entry(node, head, list)
926 avc_node_delete(node); 958 avc_node_delete(avc, node);
927 rcu_read_unlock(); 959 rcu_read_unlock();
928 spin_unlock_irqrestore(lock, flag); 960 spin_unlock_irqrestore(lock, flag);
929 } 961 }
@@ -933,12 +965,12 @@ static void avc_flush(void)
933 * avc_ss_reset - Flush the cache and revalidate migrated permissions. 965 * avc_ss_reset - Flush the cache and revalidate migrated permissions.
934 * @seqno: policy sequence number 966 * @seqno: policy sequence number
935 */ 967 */
936int avc_ss_reset(u32 seqno) 968int avc_ss_reset(struct selinux_avc *avc, u32 seqno)
937{ 969{
938 struct avc_callback_node *c; 970 struct avc_callback_node *c;
939 int rc = 0, tmprc; 971 int rc = 0, tmprc;
940 972
941 avc_flush(); 973 avc_flush(avc);
942 974
943 for (c = avc_callbacks; c; c = c->next) { 975 for (c = avc_callbacks; c; c = c->next) {
944 if (c->events & AVC_CALLBACK_RESET) { 976 if (c->events & AVC_CALLBACK_RESET) {
@@ -950,7 +982,7 @@ int avc_ss_reset(u32 seqno)
950 } 982 }
951 } 983 }
952 984
953 avc_latest_notif_update(seqno, 0); 985 avc_latest_notif_update(avc, seqno, 0);
954 return rc; 986 return rc;
955} 987}
956 988
@@ -963,30 +995,34 @@ int avc_ss_reset(u32 seqno)
963 * Don't inline this, since it's the slow-path and just 995 * Don't inline this, since it's the slow-path and just
964 * results in a bigger stack frame. 996 * results in a bigger stack frame.
965 */ 997 */
966static noinline struct avc_node *avc_compute_av(u32 ssid, u32 tsid, 998static noinline
967 u16 tclass, struct av_decision *avd, 999struct avc_node *avc_compute_av(struct selinux_state *state,
968 struct avc_xperms_node *xp_node) 1000 u32 ssid, u32 tsid,
1001 u16 tclass, struct av_decision *avd,
1002 struct avc_xperms_node *xp_node)
969{ 1003{
970 rcu_read_unlock(); 1004 rcu_read_unlock();
971 INIT_LIST_HEAD(&xp_node->xpd_head); 1005 INIT_LIST_HEAD(&xp_node->xpd_head);
972 security_compute_av(ssid, tsid, tclass, avd, &xp_node->xp); 1006 security_compute_av(state, ssid, tsid, tclass, avd, &xp_node->xp);
973 rcu_read_lock(); 1007 rcu_read_lock();
974 return avc_insert(ssid, tsid, tclass, avd, xp_node); 1008 return avc_insert(state->avc, ssid, tsid, tclass, avd, xp_node);
975} 1009}
976 1010
977static noinline int avc_denied(u32 ssid, u32 tsid, 1011static noinline int avc_denied(struct selinux_state *state,
978 u16 tclass, u32 requested, 1012 u32 ssid, u32 tsid,
979 u8 driver, u8 xperm, unsigned flags, 1013 u16 tclass, u32 requested,
980 struct av_decision *avd) 1014 u8 driver, u8 xperm, unsigned int flags,
1015 struct av_decision *avd)
981{ 1016{
982 if (flags & AVC_STRICT) 1017 if (flags & AVC_STRICT)
983 return -EACCES; 1018 return -EACCES;
984 1019
985 if (selinux_enforcing && !(avd->flags & AVD_FLAGS_PERMISSIVE)) 1020 if (enforcing_enabled(state) &&
1021 !(avd->flags & AVD_FLAGS_PERMISSIVE))
986 return -EACCES; 1022 return -EACCES;
987 1023
988 avc_update_node(AVC_CALLBACK_GRANT, requested, driver, xperm, ssid, 1024 avc_update_node(state->avc, AVC_CALLBACK_GRANT, requested, driver,
989 tsid, tclass, avd->seqno, NULL, flags); 1025 xperm, ssid, tsid, tclass, avd->seqno, NULL, flags);
990 return 0; 1026 return 0;
991} 1027}
992 1028
@@ -997,8 +1033,9 @@ static noinline int avc_denied(u32 ssid, u32 tsid,
997 * as-is the case with ioctls, then multiple may be chained together and the 1033 * as-is the case with ioctls, then multiple may be chained together and the
998 * driver field is used to specify which set contains the permission. 1034 * driver field is used to specify which set contains the permission.
999 */ 1035 */
1000int avc_has_extended_perms(u32 ssid, u32 tsid, u16 tclass, u32 requested, 1036int avc_has_extended_perms(struct selinux_state *state,
1001 u8 driver, u8 xperm, struct common_audit_data *ad) 1037 u32 ssid, u32 tsid, u16 tclass, u32 requested,
1038 u8 driver, u8 xperm, struct common_audit_data *ad)
1002{ 1039{
1003 struct avc_node *node; 1040 struct avc_node *node;
1004 struct av_decision avd; 1041 struct av_decision avd;
@@ -1017,9 +1054,9 @@ int avc_has_extended_perms(u32 ssid, u32 tsid, u16 tclass, u32 requested,
1017 1054
1018 rcu_read_lock(); 1055 rcu_read_lock();
1019 1056
1020 node = avc_lookup(ssid, tsid, tclass); 1057 node = avc_lookup(state->avc, ssid, tsid, tclass);
1021 if (unlikely(!node)) { 1058 if (unlikely(!node)) {
1022 node = avc_compute_av(ssid, tsid, tclass, &avd, xp_node); 1059 node = avc_compute_av(state, ssid, tsid, tclass, &avd, xp_node);
1023 } else { 1060 } else {
1024 memcpy(&avd, &node->ae.avd, sizeof(avd)); 1061 memcpy(&avd, &node->ae.avd, sizeof(avd));
1025 xp_node = node->ae.xp_node; 1062 xp_node = node->ae.xp_node;
@@ -1043,11 +1080,12 @@ int avc_has_extended_perms(u32 ssid, u32 tsid, u16 tclass, u32 requested,
1043 goto decision; 1080 goto decision;
1044 } 1081 }
1045 rcu_read_unlock(); 1082 rcu_read_unlock();
1046 security_compute_xperms_decision(ssid, tsid, tclass, driver, 1083 security_compute_xperms_decision(state, ssid, tsid, tclass,
1047 &local_xpd); 1084 driver, &local_xpd);
1048 rcu_read_lock(); 1085 rcu_read_lock();
1049 avc_update_node(AVC_CALLBACK_ADD_XPERMS, requested, driver, xperm, 1086 avc_update_node(state->avc, AVC_CALLBACK_ADD_XPERMS, requested,
1050 ssid, tsid, tclass, avd.seqno, &local_xpd, 0); 1087 driver, xperm, ssid, tsid, tclass, avd.seqno,
1088 &local_xpd, 0);
1051 } else { 1089 } else {
1052 avc_quick_copy_xperms_decision(xperm, &local_xpd, xpd); 1090 avc_quick_copy_xperms_decision(xperm, &local_xpd, xpd);
1053 } 1091 }
@@ -1059,12 +1097,12 @@ int avc_has_extended_perms(u32 ssid, u32 tsid, u16 tclass, u32 requested,
1059decision: 1097decision:
1060 denied = requested & ~(avd.allowed); 1098 denied = requested & ~(avd.allowed);
1061 if (unlikely(denied)) 1099 if (unlikely(denied))
1062 rc = avc_denied(ssid, tsid, tclass, requested, driver, xperm, 1100 rc = avc_denied(state, ssid, tsid, tclass, requested,
1063 AVC_EXTENDED_PERMS, &avd); 1101 driver, xperm, AVC_EXTENDED_PERMS, &avd);
1064 1102
1065 rcu_read_unlock(); 1103 rcu_read_unlock();
1066 1104
1067 rc2 = avc_xperms_audit(ssid, tsid, tclass, requested, 1105 rc2 = avc_xperms_audit(state, ssid, tsid, tclass, requested,
1068 &avd, xpd, xperm, rc, ad); 1106 &avd, xpd, xperm, rc, ad);
1069 if (rc2) 1107 if (rc2)
1070 return rc2; 1108 return rc2;
@@ -1091,10 +1129,11 @@ decision:
1091 * auditing, e.g. in cases where a lock must be held for the check but 1129 * auditing, e.g. in cases where a lock must be held for the check but
1092 * should be released for the auditing. 1130 * should be released for the auditing.
1093 */ 1131 */
1094inline int avc_has_perm_noaudit(u32 ssid, u32 tsid, 1132inline int avc_has_perm_noaudit(struct selinux_state *state,
1095 u16 tclass, u32 requested, 1133 u32 ssid, u32 tsid,
1096 unsigned flags, 1134 u16 tclass, u32 requested,
1097 struct av_decision *avd) 1135 unsigned int flags,
1136 struct av_decision *avd)
1098{ 1137{
1099 struct avc_node *node; 1138 struct avc_node *node;
1100 struct avc_xperms_node xp_node; 1139 struct avc_xperms_node xp_node;
@@ -1105,15 +1144,16 @@ inline int avc_has_perm_noaudit(u32 ssid, u32 tsid,
1105 1144
1106 rcu_read_lock(); 1145 rcu_read_lock();
1107 1146
1108 node = avc_lookup(ssid, tsid, tclass); 1147 node = avc_lookup(state->avc, ssid, tsid, tclass);
1109 if (unlikely(!node)) 1148 if (unlikely(!node))
1110 node = avc_compute_av(ssid, tsid, tclass, avd, &xp_node); 1149 node = avc_compute_av(state, ssid, tsid, tclass, avd, &xp_node);
1111 else 1150 else
1112 memcpy(avd, &node->ae.avd, sizeof(*avd)); 1151 memcpy(avd, &node->ae.avd, sizeof(*avd));
1113 1152
1114 denied = requested & ~(avd->allowed); 1153 denied = requested & ~(avd->allowed);
1115 if (unlikely(denied)) 1154 if (unlikely(denied))
1116 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);
1117 1157
1118 rcu_read_unlock(); 1158 rcu_read_unlock();
1119 return rc; 1159 return rc;
@@ -1135,39 +1175,43 @@ inline int avc_has_perm_noaudit(u32 ssid, u32 tsid,
1135 * permissions are granted, -%EACCES if any permissions are denied, or 1175 * permissions are granted, -%EACCES if any permissions are denied, or
1136 * another -errno upon other errors. 1176 * another -errno upon other errors.
1137 */ 1177 */
1138int avc_has_perm(u32 ssid, u32 tsid, u16 tclass, 1178int avc_has_perm(struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass,
1139 u32 requested, struct common_audit_data *auditdata) 1179 u32 requested, struct common_audit_data *auditdata)
1140{ 1180{
1141 struct av_decision avd; 1181 struct av_decision avd;
1142 int rc, rc2; 1182 int rc, rc2;
1143 1183
1144 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);
1145 1186
1146 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);
1147 if (rc2) 1189 if (rc2)
1148 return rc2; 1190 return rc2;
1149 return rc; 1191 return rc;
1150} 1192}
1151 1193
1152int avc_has_perm_flags(u32 ssid, u32 tsid, u16 tclass, 1194int avc_has_perm_flags(struct selinux_state *state,
1153 u32 requested, struct common_audit_data *auditdata, 1195 u32 ssid, u32 tsid, u16 tclass, u32 requested,
1196 struct common_audit_data *auditdata,
1154 int flags) 1197 int flags)
1155{ 1198{
1156 struct av_decision avd; 1199 struct av_decision avd;
1157 int rc, rc2; 1200 int rc, rc2;
1158 1201
1159 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);
1160 1204
1161 rc2 = avc_audit(ssid, tsid, tclass, requested, &avd, rc, 1205 rc2 = avc_audit(state, ssid, tsid, tclass, requested, &avd, rc,
1162 auditdata, flags); 1206 auditdata, flags);
1163 if (rc2) 1207 if (rc2)
1164 return rc2; 1208 return rc2;
1165 return rc; 1209 return rc;
1166} 1210}
1167 1211
1168u32 avc_policy_seqno(void) 1212u32 avc_policy_seqno(struct selinux_state *state)
1169{ 1213{
1170 return avc_cache.latest_notif; 1214 return state->avc->avc_cache.latest_notif;
1171} 1215}
1172 1216
1173void avc_disable(void) 1217void avc_disable(void)
@@ -1184,7 +1228,7 @@ void avc_disable(void)
1184 * the cache and get that memory back. 1228 * the cache and get that memory back.
1185 */ 1229 */
1186 if (avc_node_cachep) { 1230 if (avc_node_cachep) {
1187 avc_flush(); 1231 avc_flush(selinux_state.avc);
1188 /* kmem_cache_destroy(avc_node_cachep); */ 1232 /* kmem_cache_destroy(avc_node_cachep); */
1189 } 1233 }
1190} 1234}