Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'selinux-pr-20210409' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux

Pull selinux fixes from Paul Moore:
"Three SELinux fixes.

These fix known problems relating to (re)loading SELinux policy or
changing the policy booleans, and pass our test suite without problem"

* tag 'selinux-pr-20210409' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux:
selinux: fix race between old and new sidtab
selinux: fix cond_list corruption when changing booleans
selinux: make nslot handling in avtab more robust

+185 -112
+33 -68
security/selinux/ss/avtab.c
··· 109 109 struct avtab_node *prev, *cur, *newnode; 110 110 u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD); 111 111 112 - if (!h) 112 + if (!h || !h->nslot) 113 113 return -EINVAL; 114 114 115 115 hvalue = avtab_hash(key, h->mask); ··· 154 154 struct avtab_node *prev, *cur; 155 155 u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD); 156 156 157 - if (!h) 157 + if (!h || !h->nslot) 158 158 return NULL; 159 159 hvalue = avtab_hash(key, h->mask); 160 160 for (prev = NULL, cur = h->htable[hvalue]; ··· 184 184 struct avtab_node *cur; 185 185 u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD); 186 186 187 - if (!h) 187 + if (!h || !h->nslot) 188 188 return NULL; 189 189 190 190 hvalue = avtab_hash(key, h->mask); ··· 220 220 struct avtab_node *cur; 221 221 u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD); 222 222 223 - if (!h) 223 + if (!h || !h->nslot) 224 224 return NULL; 225 225 226 226 hvalue = avtab_hash(key, h->mask); ··· 295 295 } 296 296 kvfree(h->htable); 297 297 h->htable = NULL; 298 + h->nel = 0; 298 299 h->nslot = 0; 299 300 h->mask = 0; 300 301 } ··· 304 303 { 305 304 h->htable = NULL; 306 305 h->nel = 0; 306 + h->nslot = 0; 307 + h->mask = 0; 307 308 } 308 309 309 - int avtab_alloc(struct avtab *h, u32 nrules) 310 + static int avtab_alloc_common(struct avtab *h, u32 nslot) 310 311 { 311 - u32 mask = 0; 312 - u32 shift = 0; 313 - u32 work = nrules; 314 - u32 nslot = 0; 315 - 316 - if (nrules == 0) 317 - goto avtab_alloc_out; 318 - 319 - while (work) { 320 - work = work >> 1; 321 - shift++; 322 - } 323 - if (shift > 2) 324 - shift = shift - 2; 325 - nslot = 1 << shift; 326 - if (nslot > MAX_AVTAB_HASH_BUCKETS) 327 - nslot = MAX_AVTAB_HASH_BUCKETS; 328 - mask = nslot - 1; 312 + if (!nslot) 313 + return 0; 329 314 330 315 h->htable = kvcalloc(nslot, sizeof(void *), GFP_KERNEL); 331 316 if (!h->htable) 332 317 return -ENOMEM; 333 318 334 - avtab_alloc_out: 335 - h->nel = 0; 336 319 h->nslot = nslot; 337 - h->mask = mask; 338 - pr_debug("SELinux: %d avtab hash slots, %d rules.\n", 339 - h->nslot, nrules); 320 + h->mask = nslot - 1; 340 321 return 0; 341 322 } 342 323 343 - int avtab_duplicate(struct avtab *new, struct avtab *orig) 324 + int avtab_alloc(struct avtab *h, u32 nrules) 344 325 { 345 - int i; 346 - struct avtab_node *node, *tmp, *tail; 326 + int rc; 327 + u32 nslot = 0; 347 328 348 - memset(new, 0, sizeof(*new)); 349 - 350 - new->htable = kvcalloc(orig->nslot, sizeof(void *), GFP_KERNEL); 351 - if (!new->htable) 352 - return -ENOMEM; 353 - new->nslot = orig->nslot; 354 - new->mask = orig->mask; 355 - 356 - for (i = 0; i < orig->nslot; i++) { 357 - tail = NULL; 358 - for (node = orig->htable[i]; node; node = node->next) { 359 - tmp = kmem_cache_zalloc(avtab_node_cachep, GFP_KERNEL); 360 - if (!tmp) 361 - goto error; 362 - tmp->key = node->key; 363 - if (tmp->key.specified & AVTAB_XPERMS) { 364 - tmp->datum.u.xperms = 365 - kmem_cache_zalloc(avtab_xperms_cachep, 366 - GFP_KERNEL); 367 - if (!tmp->datum.u.xperms) { 368 - kmem_cache_free(avtab_node_cachep, tmp); 369 - goto error; 370 - } 371 - tmp->datum.u.xperms = node->datum.u.xperms; 372 - } else 373 - tmp->datum.u.data = node->datum.u.data; 374 - 375 - if (tail) 376 - tail->next = tmp; 377 - else 378 - new->htable[i] = tmp; 379 - 380 - tail = tmp; 381 - new->nel++; 329 + if (nrules != 0) { 330 + u32 shift = 1; 331 + u32 work = nrules >> 3; 332 + while (work) { 333 + work >>= 1; 334 + shift++; 382 335 } 336 + nslot = 1 << shift; 337 + if (nslot > MAX_AVTAB_HASH_BUCKETS) 338 + nslot = MAX_AVTAB_HASH_BUCKETS; 339 + 340 + rc = avtab_alloc_common(h, nslot); 341 + if (rc) 342 + return rc; 383 343 } 384 344 345 + pr_debug("SELinux: %d avtab hash slots, %d rules.\n", nslot, nrules); 385 346 return 0; 386 - error: 387 - avtab_destroy(new); 388 - return -ENOMEM; 347 + } 348 + 349 + int avtab_alloc_dup(struct avtab *new, const struct avtab *orig) 350 + { 351 + return avtab_alloc_common(new, orig->nslot); 389 352 } 390 353 391 354 void avtab_hash_eval(struct avtab *h, char *tag)
+1 -1
security/selinux/ss/avtab.h
··· 89 89 90 90 void avtab_init(struct avtab *h); 91 91 int avtab_alloc(struct avtab *, u32); 92 - int avtab_duplicate(struct avtab *new, struct avtab *orig); 92 + int avtab_alloc_dup(struct avtab *new, const struct avtab *orig); 93 93 struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *k); 94 94 void avtab_destroy(struct avtab *h); 95 95 void avtab_hash_eval(struct avtab *h, char *tag);
+6 -6
security/selinux/ss/conditional.c
··· 605 605 struct cond_av_list *orig, 606 606 struct avtab *avtab) 607 607 { 608 - struct avtab_node *avnode; 609 608 u32 i; 610 609 611 610 memset(new, 0, sizeof(*new)); ··· 614 615 return -ENOMEM; 615 616 616 617 for (i = 0; i < orig->len; i++) { 617 - avnode = avtab_search_node(avtab, &orig->nodes[i]->key); 618 - if (WARN_ON(!avnode)) 619 - return -EINVAL; 620 - new->nodes[i] = avnode; 618 + new->nodes[i] = avtab_insert_nonunique(avtab, 619 + &orig->nodes[i]->key, 620 + &orig->nodes[i]->datum); 621 + if (!new->nodes[i]) 622 + return -ENOMEM; 621 623 new->len++; 622 624 } 623 625 ··· 630 630 { 631 631 int rc, i, j; 632 632 633 - rc = avtab_duplicate(&newp->te_cond_avtab, &origp->te_cond_avtab); 633 + rc = avtab_alloc_dup(&newp->te_cond_avtab, &origp->te_cond_avtab); 634 634 if (rc) 635 635 return rc; 636 636
+120 -37
security/selinux/ss/services.c
··· 1552 1552 if (!str) 1553 1553 goto out; 1554 1554 } 1555 + retry: 1555 1556 rcu_read_lock(); 1556 1557 policy = rcu_dereference(state->policy); 1557 1558 policydb = &policy->policydb; ··· 1566 1565 } else if (rc) 1567 1566 goto out_unlock; 1568 1567 rc = sidtab_context_to_sid(sidtab, &context, sid); 1568 + if (rc == -ESTALE) { 1569 + rcu_read_unlock(); 1570 + if (context.str) { 1571 + str = context.str; 1572 + context.str = NULL; 1573 + } 1574 + context_destroy(&context); 1575 + goto retry; 1576 + } 1569 1577 context_destroy(&context); 1570 1578 out_unlock: 1571 1579 rcu_read_unlock(); ··· 1724 1714 struct selinux_policy *policy; 1725 1715 struct policydb *policydb; 1726 1716 struct sidtab *sidtab; 1727 - struct class_datum *cladatum = NULL; 1717 + struct class_datum *cladatum; 1728 1718 struct context *scontext, *tcontext, newcontext; 1729 1719 struct sidtab_entry *sentry, *tentry; 1730 1720 struct avtab_key avkey; ··· 1746 1736 goto out; 1747 1737 } 1748 1738 1739 + retry: 1740 + cladatum = NULL; 1749 1741 context_init(&newcontext); 1750 1742 1751 1743 rcu_read_lock(); ··· 1892 1880 } 1893 1881 /* Obtain the sid for the context. */ 1894 1882 rc = sidtab_context_to_sid(sidtab, &newcontext, out_sid); 1883 + if (rc == -ESTALE) { 1884 + rcu_read_unlock(); 1885 + context_destroy(&newcontext); 1886 + goto retry; 1887 + } 1895 1888 out_unlock: 1896 1889 rcu_read_unlock(); 1897 1890 context_destroy(&newcontext); ··· 2209 2192 struct selinux_load_state *load_state) 2210 2193 { 2211 2194 struct selinux_policy *oldpolicy, *newpolicy = load_state->policy; 2195 + unsigned long flags; 2212 2196 u32 seqno; 2213 2197 2214 2198 oldpolicy = rcu_dereference_protected(state->policy, ··· 2231 2213 seqno = newpolicy->latest_granting; 2232 2214 2233 2215 /* Install the new policy. */ 2234 - rcu_assign_pointer(state->policy, newpolicy); 2216 + if (oldpolicy) { 2217 + sidtab_freeze_begin(oldpolicy->sidtab, &flags); 2218 + rcu_assign_pointer(state->policy, newpolicy); 2219 + sidtab_freeze_end(oldpolicy->sidtab, &flags); 2220 + } else { 2221 + rcu_assign_pointer(state->policy, newpolicy); 2222 + } 2235 2223 2236 2224 /* Load the policycaps from the new policy */ 2237 2225 security_load_policycaps(state, newpolicy); ··· 2381 2357 struct policydb *policydb; 2382 2358 struct sidtab *sidtab; 2383 2359 struct ocontext *c; 2384 - int rc = 0; 2360 + int rc; 2385 2361 2386 2362 if (!selinux_initialized(state)) { 2387 2363 *out_sid = SECINITSID_PORT; 2388 2364 return 0; 2389 2365 } 2390 2366 2367 + retry: 2368 + rc = 0; 2391 2369 rcu_read_lock(); 2392 2370 policy = rcu_dereference(state->policy); 2393 2371 policydb = &policy->policydb; ··· 2408 2382 if (!c->sid[0]) { 2409 2383 rc = sidtab_context_to_sid(sidtab, &c->context[0], 2410 2384 &c->sid[0]); 2385 + if (rc == -ESTALE) { 2386 + rcu_read_unlock(); 2387 + goto retry; 2388 + } 2411 2389 if (rc) 2412 2390 goto out; 2413 2391 } ··· 2438 2408 struct policydb *policydb; 2439 2409 struct sidtab *sidtab; 2440 2410 struct ocontext *c; 2441 - int rc = 0; 2411 + int rc; 2442 2412 2443 2413 if (!selinux_initialized(state)) { 2444 2414 *out_sid = SECINITSID_UNLABELED; 2445 2415 return 0; 2446 2416 } 2447 2417 2418 + retry: 2419 + rc = 0; 2448 2420 rcu_read_lock(); 2449 2421 policy = rcu_dereference(state->policy); 2450 2422 policydb = &policy->policydb; ··· 2467 2435 rc = sidtab_context_to_sid(sidtab, 2468 2436 &c->context[0], 2469 2437 &c->sid[0]); 2438 + if (rc == -ESTALE) { 2439 + rcu_read_unlock(); 2440 + goto retry; 2441 + } 2470 2442 if (rc) 2471 2443 goto out; 2472 2444 } ··· 2496 2460 struct policydb *policydb; 2497 2461 struct sidtab *sidtab; 2498 2462 struct ocontext *c; 2499 - int rc = 0; 2463 + int rc; 2500 2464 2501 2465 if (!selinux_initialized(state)) { 2502 2466 *out_sid = SECINITSID_UNLABELED; 2503 2467 return 0; 2504 2468 } 2505 2469 2470 + retry: 2471 + rc = 0; 2506 2472 rcu_read_lock(); 2507 2473 policy = rcu_dereference(state->policy); 2508 2474 policydb = &policy->policydb; ··· 2525 2487 if (!c->sid[0]) { 2526 2488 rc = sidtab_context_to_sid(sidtab, &c->context[0], 2527 2489 &c->sid[0]); 2490 + if (rc == -ESTALE) { 2491 + rcu_read_unlock(); 2492 + goto retry; 2493 + } 2528 2494 if (rc) 2529 2495 goto out; 2530 2496 } ··· 2552 2510 struct selinux_policy *policy; 2553 2511 struct policydb *policydb; 2554 2512 struct sidtab *sidtab; 2555 - int rc = 0; 2513 + int rc; 2556 2514 struct ocontext *c; 2557 2515 2558 2516 if (!selinux_initialized(state)) { ··· 2560 2518 return 0; 2561 2519 } 2562 2520 2521 + retry: 2522 + rc = 0; 2563 2523 rcu_read_lock(); 2564 2524 policy = rcu_dereference(state->policy); 2565 2525 policydb = &policy->policydb; ··· 2578 2534 if (!c->sid[0] || !c->sid[1]) { 2579 2535 rc = sidtab_context_to_sid(sidtab, &c->context[0], 2580 2536 &c->sid[0]); 2537 + if (rc == -ESTALE) { 2538 + rcu_read_unlock(); 2539 + goto retry; 2540 + } 2581 2541 if (rc) 2582 2542 goto out; 2583 2543 rc = sidtab_context_to_sid(sidtab, &c->context[1], 2584 2544 &c->sid[1]); 2545 + if (rc == -ESTALE) { 2546 + rcu_read_unlock(); 2547 + goto retry; 2548 + } 2585 2549 if (rc) 2586 2550 goto out; 2587 2551 } ··· 2639 2587 return 0; 2640 2588 } 2641 2589 2590 + retry: 2642 2591 rcu_read_lock(); 2643 2592 policy = rcu_dereference(state->policy); 2644 2593 policydb = &policy->policydb; ··· 2688 2635 rc = sidtab_context_to_sid(sidtab, 2689 2636 &c->context[0], 2690 2637 &c->sid[0]); 2638 + if (rc == -ESTALE) { 2639 + rcu_read_unlock(); 2640 + goto retry; 2641 + } 2691 2642 if (rc) 2692 2643 goto out; 2693 2644 } ··· 2733 2676 struct sidtab *sidtab; 2734 2677 struct context *fromcon, usercon; 2735 2678 u32 *mysids = NULL, *mysids2, sid; 2736 - u32 mynel = 0, maxnel = SIDS_NEL; 2679 + u32 i, j, mynel, maxnel = SIDS_NEL; 2737 2680 struct user_datum *user; 2738 2681 struct role_datum *role; 2739 2682 struct ebitmap_node *rnode, *tnode; 2740 - int rc = 0, i, j; 2683 + int rc; 2741 2684 2742 2685 *sids = NULL; 2743 2686 *nel = 0; 2744 2687 2745 2688 if (!selinux_initialized(state)) 2746 - goto out; 2689 + return 0; 2747 2690 2691 + mysids = kcalloc(maxnel, sizeof(*mysids), GFP_KERNEL); 2692 + if (!mysids) 2693 + return -ENOMEM; 2694 + 2695 + retry: 2696 + mynel = 0; 2748 2697 rcu_read_lock(); 2749 2698 policy = rcu_dereference(state->policy); 2750 2699 policydb = &policy->policydb; ··· 2770 2707 2771 2708 usercon.user = user->value; 2772 2709 2773 - rc = -ENOMEM; 2774 - mysids = kcalloc(maxnel, sizeof(*mysids), GFP_ATOMIC); 2775 - if (!mysids) 2776 - goto out_unlock; 2777 - 2778 2710 ebitmap_for_each_positive_bit(&user->roles, rnode, i) { 2779 2711 role = policydb->role_val_to_struct[i]; 2780 2712 usercon.role = i + 1; ··· 2781 2723 continue; 2782 2724 2783 2725 rc = sidtab_context_to_sid(sidtab, &usercon, &sid); 2726 + if (rc == -ESTALE) { 2727 + rcu_read_unlock(); 2728 + goto retry; 2729 + } 2784 2730 if (rc) 2785 2731 goto out_unlock; 2786 2732 if (mynel < maxnel) { ··· 2807 2745 rcu_read_unlock(); 2808 2746 if (rc || !mynel) { 2809 2747 kfree(mysids); 2810 - goto out; 2748 + return rc; 2811 2749 } 2812 2750 2813 2751 rc = -ENOMEM; 2814 2752 mysids2 = kcalloc(mynel, sizeof(*mysids2), GFP_KERNEL); 2815 2753 if (!mysids2) { 2816 2754 kfree(mysids); 2817 - goto out; 2755 + return rc; 2818 2756 } 2819 2757 for (i = 0, j = 0; i < mynel; i++) { 2820 2758 struct av_decision dummy_avd; ··· 2827 2765 mysids2[j++] = mysids[i]; 2828 2766 cond_resched(); 2829 2767 } 2830 - rc = 0; 2831 2768 kfree(mysids); 2832 2769 *sids = mysids2; 2833 2770 *nel = j; 2834 - out: 2835 - return rc; 2771 + return 0; 2836 2772 } 2837 2773 2838 2774 /** ··· 2843 2783 * Obtain a SID to use for a file in a filesystem that 2844 2784 * cannot support xattr or use a fixed labeling behavior like 2845 2785 * transition SIDs or task SIDs. 2786 + * 2787 + * WARNING: This function may return -ESTALE, indicating that the caller 2788 + * must retry the operation after re-acquiring the policy pointer! 2846 2789 */ 2847 2790 static inline int __security_genfs_sid(struct selinux_policy *policy, 2848 2791 const char *fstype, ··· 2924 2861 return 0; 2925 2862 } 2926 2863 2927 - rcu_read_lock(); 2928 - policy = rcu_dereference(state->policy); 2929 - retval = __security_genfs_sid(policy, 2930 - fstype, path, orig_sclass, sid); 2931 - rcu_read_unlock(); 2864 + do { 2865 + rcu_read_lock(); 2866 + policy = rcu_dereference(state->policy); 2867 + retval = __security_genfs_sid(policy, fstype, path, 2868 + orig_sclass, sid); 2869 + rcu_read_unlock(); 2870 + } while (retval == -ESTALE); 2932 2871 return retval; 2933 2872 } 2934 2873 ··· 2953 2888 struct selinux_policy *policy; 2954 2889 struct policydb *policydb; 2955 2890 struct sidtab *sidtab; 2956 - int rc = 0; 2891 + int rc; 2957 2892 struct ocontext *c; 2958 2893 struct superblock_security_struct *sbsec = sb->s_security; 2959 2894 const char *fstype = sb->s_type->name; ··· 2964 2899 return 0; 2965 2900 } 2966 2901 2902 + retry: 2903 + rc = 0; 2967 2904 rcu_read_lock(); 2968 2905 policy = rcu_dereference(state->policy); 2969 2906 policydb = &policy->policydb; ··· 2983 2916 if (!c->sid[0]) { 2984 2917 rc = sidtab_context_to_sid(sidtab, &c->context[0], 2985 2918 &c->sid[0]); 2919 + if (rc == -ESTALE) { 2920 + rcu_read_unlock(); 2921 + goto retry; 2922 + } 2986 2923 if (rc) 2987 2924 goto out; 2988 2925 } ··· 2994 2923 } else { 2995 2924 rc = __security_genfs_sid(policy, fstype, "/", 2996 2925 SECCLASS_DIR, &sbsec->sid); 2926 + if (rc == -ESTALE) { 2927 + rcu_read_unlock(); 2928 + goto retry; 2929 + } 2997 2930 if (rc) { 2998 2931 sbsec->behavior = SECURITY_FS_USE_NONE; 2999 2932 rc = 0; ··· 3207 3132 u32 len; 3208 3133 int rc; 3209 3134 3210 - rc = 0; 3211 3135 if (!selinux_initialized(state)) { 3212 3136 *new_sid = sid; 3213 - goto out; 3137 + return 0; 3214 3138 } 3215 3139 3140 + retry: 3141 + rc = 0; 3216 3142 context_init(&newcon); 3217 3143 3218 3144 rcu_read_lock(); ··· 3272 3196 } 3273 3197 } 3274 3198 rc = sidtab_context_to_sid(sidtab, &newcon, new_sid); 3199 + if (rc == -ESTALE) { 3200 + rcu_read_unlock(); 3201 + context_destroy(&newcon); 3202 + goto retry; 3203 + } 3275 3204 out_unlock: 3276 3205 rcu_read_unlock(); 3277 3206 context_destroy(&newcon); 3278 - out: 3279 3207 return rc; 3280 3208 } 3281 3209 ··· 3872 3792 return 0; 3873 3793 } 3874 3794 3795 + retry: 3796 + rc = 0; 3875 3797 rcu_read_lock(); 3876 3798 policy = rcu_dereference(state->policy); 3877 3799 policydb = &policy->policydb; ··· 3900 3818 goto out; 3901 3819 } 3902 3820 rc = -EIDRM; 3903 - if (!mls_context_isvalid(policydb, &ctx_new)) 3904 - goto out_free; 3821 + if (!mls_context_isvalid(policydb, &ctx_new)) { 3822 + ebitmap_destroy(&ctx_new.range.level[0].cat); 3823 + goto out; 3824 + } 3905 3825 3906 3826 rc = sidtab_context_to_sid(sidtab, &ctx_new, sid); 3827 + ebitmap_destroy(&ctx_new.range.level[0].cat); 3828 + if (rc == -ESTALE) { 3829 + rcu_read_unlock(); 3830 + goto retry; 3831 + } 3907 3832 if (rc) 3908 - goto out_free; 3833 + goto out; 3909 3834 3910 3835 security_netlbl_cache_add(secattr, *sid); 3911 - 3912 - ebitmap_destroy(&ctx_new.range.level[0].cat); 3913 3836 } else 3914 3837 *sid = SECSID_NULL; 3915 3838 3916 - rcu_read_unlock(); 3917 - return 0; 3918 - out_free: 3919 - ebitmap_destroy(&ctx_new.range.level[0].cat); 3920 3839 out: 3921 3840 rcu_read_unlock(); 3922 3841 return rc;
+21
security/selinux/ss/sidtab.c
··· 39 39 for (i = 0; i < SECINITSID_NUM; i++) 40 40 s->isids[i].set = 0; 41 41 42 + s->frozen = false; 42 43 s->count = 0; 43 44 s->convert = NULL; 44 45 hash_init(s->context_to_sid); ··· 282 281 if (*sid) 283 282 goto out_unlock; 284 283 284 + if (unlikely(s->frozen)) { 285 + /* 286 + * This sidtab is now frozen - tell the caller to abort and 287 + * get the new one. 288 + */ 289 + rc = -ESTALE; 290 + goto out_unlock; 291 + } 292 + 285 293 count = s->count; 286 294 convert = s->convert; 287 295 ··· 482 472 spin_lock_irqsave(&s->lock, flags); 483 473 s->convert = NULL; 484 474 spin_unlock_irqrestore(&s->lock, flags); 475 + } 476 + 477 + void sidtab_freeze_begin(struct sidtab *s, unsigned long *flags) __acquires(&s->lock) 478 + { 479 + spin_lock_irqsave(&s->lock, *flags); 480 + s->frozen = true; 481 + s->convert = NULL; 482 + } 483 + void sidtab_freeze_end(struct sidtab *s, unsigned long *flags) __releases(&s->lock) 484 + { 485 + spin_unlock_irqrestore(&s->lock, *flags); 485 486 } 486 487 487 488 static void sidtab_destroy_entry(struct sidtab_entry *entry)
+4
security/selinux/ss/sidtab.h
··· 86 86 u32 count; 87 87 /* access only under spinlock */ 88 88 struct sidtab_convert_params *convert; 89 + bool frozen; 89 90 spinlock_t lock; 90 91 91 92 #if CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE > 0 ··· 125 124 int sidtab_convert(struct sidtab *s, struct sidtab_convert_params *params); 126 125 127 126 void sidtab_cancel_convert(struct sidtab *s); 127 + 128 + void sidtab_freeze_begin(struct sidtab *s, unsigned long *flags) __acquires(&s->lock); 129 + void sidtab_freeze_end(struct sidtab *s, unsigned long *flags) __releases(&s->lock); 128 130 129 131 int sidtab_context_to_sid(struct sidtab *s, struct context *context, u32 *sid); 130 132