aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss/services.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/ss/services.c')
-rw-r--r--security/selinux/ss/services.c450
1 files changed, 285 insertions, 165 deletions
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index dcc2e1c4fd83..8e42da120101 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -71,14 +71,6 @@ int selinux_policycap_openperm;
71extern const struct selinux_class_perm selinux_class_perm; 71extern const struct selinux_class_perm selinux_class_perm;
72 72
73static DEFINE_RWLOCK(policy_rwlock); 73static DEFINE_RWLOCK(policy_rwlock);
74#define POLICY_RDLOCK read_lock(&policy_rwlock)
75#define POLICY_WRLOCK write_lock_irq(&policy_rwlock)
76#define POLICY_RDUNLOCK read_unlock(&policy_rwlock)
77#define POLICY_WRUNLOCK write_unlock_irq(&policy_rwlock)
78
79static DEFINE_MUTEX(load_mutex);
80#define LOAD_LOCK mutex_lock(&load_mutex)
81#define LOAD_UNLOCK mutex_unlock(&load_mutex)
82 74
83static struct sidtab sidtab; 75static struct sidtab sidtab;
84struct policydb policydb; 76struct policydb policydb;
@@ -332,7 +324,7 @@ static int context_struct_compute_av(struct context *scontext,
332 goto inval_class; 324 goto inval_class;
333 if (unlikely(tclass > policydb.p_classes.nprim)) 325 if (unlikely(tclass > policydb.p_classes.nprim))
334 if (tclass > kdefs->cts_len || 326 if (tclass > kdefs->cts_len ||
335 !kdefs->class_to_string[tclass - 1] || 327 !kdefs->class_to_string[tclass] ||
336 !policydb.allow_unknown) 328 !policydb.allow_unknown)
337 goto inval_class; 329 goto inval_class;
338 330
@@ -415,9 +407,19 @@ static int context_struct_compute_av(struct context *scontext,
415 return 0; 407 return 0;
416 408
417inval_class: 409inval_class:
418 printk(KERN_ERR "SELinux: %s: unrecognized class %d\n", __func__, 410 if (!tclass || tclass > kdefs->cts_len ||
419 tclass); 411 !kdefs->class_to_string[tclass]) {
420 return -EINVAL; 412 if (printk_ratelimit())
413 printk(KERN_ERR "SELinux: %s: unrecognized class %d\n",
414 __func__, tclass);
415 return -EINVAL;
416 }
417
418 /*
419 * Known to the kernel, but not to the policy.
420 * Handle as a denial (allowed is 0).
421 */
422 return 0;
421} 423}
422 424
423/* 425/*
@@ -429,7 +431,7 @@ int security_permissive_sid(u32 sid)
429 u32 type; 431 u32 type;
430 int rc; 432 int rc;
431 433
432 POLICY_RDLOCK; 434 read_lock(&policy_rwlock);
433 435
434 context = sidtab_search(&sidtab, sid); 436 context = sidtab_search(&sidtab, sid);
435 BUG_ON(!context); 437 BUG_ON(!context);
@@ -441,7 +443,7 @@ int security_permissive_sid(u32 sid)
441 */ 443 */
442 rc = ebitmap_get_bit(&policydb.permissive_map, type); 444 rc = ebitmap_get_bit(&policydb.permissive_map, type);
443 445
444 POLICY_RDUNLOCK; 446 read_unlock(&policy_rwlock);
445 return rc; 447 return rc;
446} 448}
447 449
@@ -486,7 +488,7 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
486 if (!ss_initialized) 488 if (!ss_initialized)
487 return 0; 489 return 0;
488 490
489 POLICY_RDLOCK; 491 read_lock(&policy_rwlock);
490 492
491 /* 493 /*
492 * Remap extended Netlink classes for old policy versions. 494 * Remap extended Netlink classes for old policy versions.
@@ -543,7 +545,7 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
543 } 545 }
544 546
545out: 547out:
546 POLICY_RDUNLOCK; 548 read_unlock(&policy_rwlock);
547 return rc; 549 return rc;
548} 550}
549 551
@@ -578,7 +580,7 @@ int security_compute_av(u32 ssid,
578 return 0; 580 return 0;
579 } 581 }
580 582
581 POLICY_RDLOCK; 583 read_lock(&policy_rwlock);
582 584
583 scontext = sidtab_search(&sidtab, ssid); 585 scontext = sidtab_search(&sidtab, ssid);
584 if (!scontext) { 586 if (!scontext) {
@@ -598,7 +600,7 @@ int security_compute_av(u32 ssid,
598 rc = context_struct_compute_av(scontext, tcontext, tclass, 600 rc = context_struct_compute_av(scontext, tcontext, tclass,
599 requested, avd); 601 requested, avd);
600out: 602out:
601 POLICY_RDUNLOCK; 603 read_unlock(&policy_rwlock);
602 return rc; 604 return rc;
603} 605}
604 606
@@ -616,6 +618,14 @@ static int context_struct_to_string(struct context *context, char **scontext, u3
616 *scontext = NULL; 618 *scontext = NULL;
617 *scontext_len = 0; 619 *scontext_len = 0;
618 620
621 if (context->len) {
622 *scontext_len = context->len;
623 *scontext = kstrdup(context->str, GFP_ATOMIC);
624 if (!(*scontext))
625 return -ENOMEM;
626 return 0;
627 }
628
619 /* Compute the size of the context. */ 629 /* Compute the size of the context. */
620 *scontext_len += strlen(policydb.p_user_val_to_name[context->user - 1]) + 1; 630 *scontext_len += strlen(policydb.p_user_val_to_name[context->user - 1]) + 1;
621 *scontext_len += strlen(policydb.p_role_val_to_name[context->role - 1]) + 1; 631 *scontext_len += strlen(policydb.p_role_val_to_name[context->role - 1]) + 1;
@@ -655,17 +665,8 @@ const char *security_get_initial_sid_context(u32 sid)
655 return initial_sid_to_string[sid]; 665 return initial_sid_to_string[sid];
656} 666}
657 667
658/** 668static int security_sid_to_context_core(u32 sid, char **scontext,
659 * security_sid_to_context - Obtain a context for a given SID. 669 u32 *scontext_len, int force)
660 * @sid: security identifier, SID
661 * @scontext: security context
662 * @scontext_len: length in bytes
663 *
664 * Write the string representation of the context associated with @sid
665 * into a dynamically allocated string of the correct size. Set @scontext
666 * to point to this string and set @scontext_len to the length of the string.
667 */
668int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len)
669{ 670{
670 struct context *context; 671 struct context *context;
671 int rc = 0; 672 int rc = 0;
@@ -692,8 +693,11 @@ int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len)
692 rc = -EINVAL; 693 rc = -EINVAL;
693 goto out; 694 goto out;
694 } 695 }
695 POLICY_RDLOCK; 696 read_lock(&policy_rwlock);
696 context = sidtab_search(&sidtab, sid); 697 if (force)
698 context = sidtab_search_force(&sidtab, sid);
699 else
700 context = sidtab_search(&sidtab, sid);
697 if (!context) { 701 if (!context) {
698 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", 702 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
699 __func__, sid); 703 __func__, sid);
@@ -702,59 +706,54 @@ int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len)
702 } 706 }
703 rc = context_struct_to_string(context, scontext, scontext_len); 707 rc = context_struct_to_string(context, scontext, scontext_len);
704out_unlock: 708out_unlock:
705 POLICY_RDUNLOCK; 709 read_unlock(&policy_rwlock);
706out: 710out:
707 return rc; 711 return rc;
708 712
709} 713}
710 714
711static int security_context_to_sid_core(const char *scontext, u32 scontext_len, 715/**
712 u32 *sid, u32 def_sid, gfp_t gfp_flags) 716 * security_sid_to_context - Obtain a context for a given SID.
717 * @sid: security identifier, SID
718 * @scontext: security context
719 * @scontext_len: length in bytes
720 *
721 * Write the string representation of the context associated with @sid
722 * into a dynamically allocated string of the correct size. Set @scontext
723 * to point to this string and set @scontext_len to the length of the string.
724 */
725int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len)
726{
727 return security_sid_to_context_core(sid, scontext, scontext_len, 0);
728}
729
730int security_sid_to_context_force(u32 sid, char **scontext, u32 *scontext_len)
731{
732 return security_sid_to_context_core(sid, scontext, scontext_len, 1);
733}
734
735/*
736 * Caveat: Mutates scontext.
737 */
738static int string_to_context_struct(struct policydb *pol,
739 struct sidtab *sidtabp,
740 char *scontext,
741 u32 scontext_len,
742 struct context *ctx,
743 u32 def_sid)
713{ 744{
714 char *scontext2;
715 struct context context;
716 struct role_datum *role; 745 struct role_datum *role;
717 struct type_datum *typdatum; 746 struct type_datum *typdatum;
718 struct user_datum *usrdatum; 747 struct user_datum *usrdatum;
719 char *scontextp, *p, oldc; 748 char *scontextp, *p, oldc;
720 int rc = 0; 749 int rc = 0;
721 750
722 if (!ss_initialized) { 751 context_init(ctx);
723 int i;
724
725 for (i = 1; i < SECINITSID_NUM; i++) {
726 if (!strcmp(initial_sid_to_string[i], scontext)) {
727 *sid = i;
728 goto out;
729 }
730 }
731 *sid = SECINITSID_KERNEL;
732 goto out;
733 }
734 *sid = SECSID_NULL;
735
736 /* Copy the string so that we can modify the copy as we parse it.
737 The string should already by null terminated, but we append a
738 null suffix to the copy to avoid problems with the existing
739 attr package, which doesn't view the null terminator as part
740 of the attribute value. */
741 scontext2 = kmalloc(scontext_len+1, gfp_flags);
742 if (!scontext2) {
743 rc = -ENOMEM;
744 goto out;
745 }
746 memcpy(scontext2, scontext, scontext_len);
747 scontext2[scontext_len] = 0;
748
749 context_init(&context);
750 *sid = SECSID_NULL;
751
752 POLICY_RDLOCK;
753 752
754 /* Parse the security context. */ 753 /* Parse the security context. */
755 754
756 rc = -EINVAL; 755 rc = -EINVAL;
757 scontextp = (char *) scontext2; 756 scontextp = (char *) scontext;
758 757
759 /* Extract the user. */ 758 /* Extract the user. */
760 p = scontextp; 759 p = scontextp;
@@ -762,15 +761,15 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len,
762 p++; 761 p++;
763 762
764 if (*p == 0) 763 if (*p == 0)
765 goto out_unlock; 764 goto out;
766 765
767 *p++ = 0; 766 *p++ = 0;
768 767
769 usrdatum = hashtab_search(policydb.p_users.table, scontextp); 768 usrdatum = hashtab_search(pol->p_users.table, scontextp);
770 if (!usrdatum) 769 if (!usrdatum)
771 goto out_unlock; 770 goto out;
772 771
773 context.user = usrdatum->value; 772 ctx->user = usrdatum->value;
774 773
775 /* Extract role. */ 774 /* Extract role. */
776 scontextp = p; 775 scontextp = p;
@@ -778,14 +777,14 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len,
778 p++; 777 p++;
779 778
780 if (*p == 0) 779 if (*p == 0)
781 goto out_unlock; 780 goto out;
782 781
783 *p++ = 0; 782 *p++ = 0;
784 783
785 role = hashtab_search(policydb.p_roles.table, scontextp); 784 role = hashtab_search(pol->p_roles.table, scontextp);
786 if (!role) 785 if (!role)
787 goto out_unlock; 786 goto out;
788 context.role = role->value; 787 ctx->role = role->value;
789 788
790 /* Extract type. */ 789 /* Extract type. */
791 scontextp = p; 790 scontextp = p;
@@ -794,33 +793,87 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len,
794 oldc = *p; 793 oldc = *p;
795 *p++ = 0; 794 *p++ = 0;
796 795
797 typdatum = hashtab_search(policydb.p_types.table, scontextp); 796 typdatum = hashtab_search(pol->p_types.table, scontextp);
798 if (!typdatum) 797 if (!typdatum)
799 goto out_unlock; 798 goto out;
800 799
801 context.type = typdatum->value; 800 ctx->type = typdatum->value;
802 801
803 rc = mls_context_to_sid(oldc, &p, &context, &sidtab, def_sid); 802 rc = mls_context_to_sid(pol, oldc, &p, ctx, sidtabp, def_sid);
804 if (rc) 803 if (rc)
805 goto out_unlock; 804 goto out;
806 805
807 if ((p - scontext2) < scontext_len) { 806 if ((p - scontext) < scontext_len) {
808 rc = -EINVAL; 807 rc = -EINVAL;
809 goto out_unlock; 808 goto out;
810 } 809 }
811 810
812 /* Check the validity of the new context. */ 811 /* Check the validity of the new context. */
813 if (!policydb_context_isvalid(&policydb, &context)) { 812 if (!policydb_context_isvalid(pol, ctx)) {
814 rc = -EINVAL; 813 rc = -EINVAL;
815 goto out_unlock; 814 context_destroy(ctx);
815 goto out;
816 } 816 }
817 /* Obtain the new sid. */ 817 rc = 0;
818out:
819 return rc;
820}
821
822static int security_context_to_sid_core(const char *scontext, u32 scontext_len,
823 u32 *sid, u32 def_sid, gfp_t gfp_flags,
824 int force)
825{
826 char *scontext2, *str = NULL;
827 struct context context;
828 int rc = 0;
829
830 if (!ss_initialized) {
831 int i;
832
833 for (i = 1; i < SECINITSID_NUM; i++) {
834 if (!strcmp(initial_sid_to_string[i], scontext)) {
835 *sid = i;
836 return 0;
837 }
838 }
839 *sid = SECINITSID_KERNEL;
840 return 0;
841 }
842 *sid = SECSID_NULL;
843
844 /* Copy the string so that we can modify the copy as we parse it. */
845 scontext2 = kmalloc(scontext_len+1, gfp_flags);
846 if (!scontext2)
847 return -ENOMEM;
848 memcpy(scontext2, scontext, scontext_len);
849 scontext2[scontext_len] = 0;
850
851 if (force) {
852 /* Save another copy for storing in uninterpreted form */
853 str = kstrdup(scontext2, gfp_flags);
854 if (!str) {
855 kfree(scontext2);
856 return -ENOMEM;
857 }
858 }
859
860 read_lock(&policy_rwlock);
861 rc = string_to_context_struct(&policydb, &sidtab,
862 scontext2, scontext_len,
863 &context, def_sid);
864 if (rc == -EINVAL && force) {
865 context.str = str;
866 context.len = scontext_len;
867 str = NULL;
868 } else if (rc)
869 goto out;
818 rc = sidtab_context_to_sid(&sidtab, &context, sid); 870 rc = sidtab_context_to_sid(&sidtab, &context, sid);
819out_unlock: 871 if (rc)
820 POLICY_RDUNLOCK; 872 context_destroy(&context);
821 context_destroy(&context);
822 kfree(scontext2);
823out: 873out:
874 read_unlock(&policy_rwlock);
875 kfree(scontext2);
876 kfree(str);
824 return rc; 877 return rc;
825} 878}
826 879
@@ -838,7 +891,7 @@ out:
838int security_context_to_sid(const char *scontext, u32 scontext_len, u32 *sid) 891int security_context_to_sid(const char *scontext, u32 scontext_len, u32 *sid)
839{ 892{
840 return security_context_to_sid_core(scontext, scontext_len, 893 return security_context_to_sid_core(scontext, scontext_len,
841 sid, SECSID_NULL, GFP_KERNEL); 894 sid, SECSID_NULL, GFP_KERNEL, 0);
842} 895}
843 896
844/** 897/**
@@ -855,6 +908,7 @@ int security_context_to_sid(const char *scontext, u32 scontext_len, u32 *sid)
855 * The default SID is passed to the MLS layer to be used to allow 908 * The default SID is passed to the MLS layer to be used to allow
856 * kernel labeling of the MLS field if the MLS field is not present 909 * kernel labeling of the MLS field if the MLS field is not present
857 * (for upgrading to MLS without full relabel). 910 * (for upgrading to MLS without full relabel).
911 * Implicitly forces adding of the context even if it cannot be mapped yet.
858 * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient 912 * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient
859 * memory is available, or 0 on success. 913 * memory is available, or 0 on success.
860 */ 914 */
@@ -862,7 +916,14 @@ int security_context_to_sid_default(const char *scontext, u32 scontext_len,
862 u32 *sid, u32 def_sid, gfp_t gfp_flags) 916 u32 *sid, u32 def_sid, gfp_t gfp_flags)
863{ 917{
864 return security_context_to_sid_core(scontext, scontext_len, 918 return security_context_to_sid_core(scontext, scontext_len,
865 sid, def_sid, gfp_flags); 919 sid, def_sid, gfp_flags, 1);
920}
921
922int security_context_to_sid_force(const char *scontext, u32 scontext_len,
923 u32 *sid)
924{
925 return security_context_to_sid_core(scontext, scontext_len,
926 sid, SECSID_NULL, GFP_KERNEL, 1);
866} 927}
867 928
868static int compute_sid_handle_invalid_context( 929static int compute_sid_handle_invalid_context(
@@ -922,7 +983,7 @@ static int security_compute_sid(u32 ssid,
922 983
923 context_init(&newcontext); 984 context_init(&newcontext);
924 985
925 POLICY_RDLOCK; 986 read_lock(&policy_rwlock);
926 987
927 scontext = sidtab_search(&sidtab, ssid); 988 scontext = sidtab_search(&sidtab, ssid);
928 if (!scontext) { 989 if (!scontext) {
@@ -1027,7 +1088,7 @@ static int security_compute_sid(u32 ssid,
1027 /* Obtain the sid for the context. */ 1088 /* Obtain the sid for the context. */
1028 rc = sidtab_context_to_sid(&sidtab, &newcontext, out_sid); 1089 rc = sidtab_context_to_sid(&sidtab, &newcontext, out_sid);
1029out_unlock: 1090out_unlock:
1030 POLICY_RDUNLOCK; 1091 read_unlock(&policy_rwlock);
1031 context_destroy(&newcontext); 1092 context_destroy(&newcontext);
1032out: 1093out:
1033 return rc; 1094 return rc;
@@ -1110,6 +1171,7 @@ static int validate_classes(struct policydb *p)
1110 const struct selinux_class_perm *kdefs = &selinux_class_perm; 1171 const struct selinux_class_perm *kdefs = &selinux_class_perm;
1111 const char *def_class, *def_perm, *pol_class; 1172 const char *def_class, *def_perm, *pol_class;
1112 struct symtab *perms; 1173 struct symtab *perms;
1174 bool print_unknown_handle = 0;
1113 1175
1114 if (p->allow_unknown) { 1176 if (p->allow_unknown) {
1115 u32 num_classes = kdefs->cts_len; 1177 u32 num_classes = kdefs->cts_len;
@@ -1130,6 +1192,7 @@ static int validate_classes(struct policydb *p)
1130 return -EINVAL; 1192 return -EINVAL;
1131 if (p->allow_unknown) 1193 if (p->allow_unknown)
1132 p->undefined_perms[i-1] = ~0U; 1194 p->undefined_perms[i-1] = ~0U;
1195 print_unknown_handle = 1;
1133 continue; 1196 continue;
1134 } 1197 }
1135 pol_class = p->p_class_val_to_name[i-1]; 1198 pol_class = p->p_class_val_to_name[i-1];
@@ -1159,6 +1222,7 @@ static int validate_classes(struct policydb *p)
1159 return -EINVAL; 1222 return -EINVAL;
1160 if (p->allow_unknown) 1223 if (p->allow_unknown)
1161 p->undefined_perms[class_val-1] |= perm_val; 1224 p->undefined_perms[class_val-1] |= perm_val;
1225 print_unknown_handle = 1;
1162 continue; 1226 continue;
1163 } 1227 }
1164 perdatum = hashtab_search(perms->table, def_perm); 1228 perdatum = hashtab_search(perms->table, def_perm);
@@ -1206,6 +1270,7 @@ static int validate_classes(struct policydb *p)
1206 return -EINVAL; 1270 return -EINVAL;
1207 if (p->allow_unknown) 1271 if (p->allow_unknown)
1208 p->undefined_perms[class_val-1] |= (1 << j); 1272 p->undefined_perms[class_val-1] |= (1 << j);
1273 print_unknown_handle = 1;
1209 continue; 1274 continue;
1210 } 1275 }
1211 perdatum = hashtab_search(perms->table, def_perm); 1276 perdatum = hashtab_search(perms->table, def_perm);
@@ -1223,6 +1288,9 @@ static int validate_classes(struct policydb *p)
1223 } 1288 }
1224 } 1289 }
1225 } 1290 }
1291 if (print_unknown_handle)
1292 printk(KERN_INFO "SELinux: the above unknown classes and permissions will be %s\n",
1293 (security_get_allow_unknown() ? "allowed" : "denied"));
1226 return 0; 1294 return 0;
1227} 1295}
1228 1296
@@ -1246,9 +1314,12 @@ static inline int convert_context_handle_invalid_context(struct context *context
1246 char *s; 1314 char *s;
1247 u32 len; 1315 u32 len;
1248 1316
1249 context_struct_to_string(context, &s, &len); 1317 if (!context_struct_to_string(context, &s, &len)) {
1250 printk(KERN_ERR "SELinux: context %s is invalid\n", s); 1318 printk(KERN_WARNING
1251 kfree(s); 1319 "SELinux: Context %s would be invalid if enforcing\n",
1320 s);
1321 kfree(s);
1322 }
1252 } 1323 }
1253 return rc; 1324 return rc;
1254} 1325}
@@ -1280,6 +1351,37 @@ static int convert_context(u32 key,
1280 1351
1281 args = p; 1352 args = p;
1282 1353
1354 if (c->str) {
1355 struct context ctx;
1356 s = kstrdup(c->str, GFP_KERNEL);
1357 if (!s) {
1358 rc = -ENOMEM;
1359 goto out;
1360 }
1361 rc = string_to_context_struct(args->newp, NULL, s,
1362 c->len, &ctx, SECSID_NULL);
1363 kfree(s);
1364 if (!rc) {
1365 printk(KERN_INFO
1366 "SELinux: Context %s became valid (mapped).\n",
1367 c->str);
1368 /* Replace string with mapped representation. */
1369 kfree(c->str);
1370 memcpy(c, &ctx, sizeof(*c));
1371 goto out;
1372 } else if (rc == -EINVAL) {
1373 /* Retain string representation for later mapping. */
1374 rc = 0;
1375 goto out;
1376 } else {
1377 /* Other error condition, e.g. ENOMEM. */
1378 printk(KERN_ERR
1379 "SELinux: Unable to map context %s, rc = %d.\n",
1380 c->str, -rc);
1381 goto out;
1382 }
1383 }
1384
1283 rc = context_cpy(&oldc, c); 1385 rc = context_cpy(&oldc, c);
1284 if (rc) 1386 if (rc)
1285 goto out; 1387 goto out;
@@ -1319,13 +1421,21 @@ static int convert_context(u32 key,
1319 } 1421 }
1320 1422
1321 context_destroy(&oldc); 1423 context_destroy(&oldc);
1424 rc = 0;
1322out: 1425out:
1323 return rc; 1426 return rc;
1324bad: 1427bad:
1325 context_struct_to_string(&oldc, &s, &len); 1428 /* Map old representation to string and save it. */
1429 if (context_struct_to_string(&oldc, &s, &len))
1430 return -ENOMEM;
1326 context_destroy(&oldc); 1431 context_destroy(&oldc);
1327 printk(KERN_ERR "SELinux: invalidating context %s\n", s); 1432 context_destroy(c);
1328 kfree(s); 1433 c->str = s;
1434 c->len = len;
1435 printk(KERN_INFO
1436 "SELinux: Context %s became invalid (unmapped).\n",
1437 c->str);
1438 rc = 0;
1329 goto out; 1439 goto out;
1330} 1440}
1331 1441
@@ -1359,17 +1469,13 @@ int security_load_policy(void *data, size_t len)
1359 int rc = 0; 1469 int rc = 0;
1360 struct policy_file file = { data, len }, *fp = &file; 1470 struct policy_file file = { data, len }, *fp = &file;
1361 1471
1362 LOAD_LOCK;
1363
1364 if (!ss_initialized) { 1472 if (!ss_initialized) {
1365 avtab_cache_init(); 1473 avtab_cache_init();
1366 if (policydb_read(&policydb, fp)) { 1474 if (policydb_read(&policydb, fp)) {
1367 LOAD_UNLOCK;
1368 avtab_cache_destroy(); 1475 avtab_cache_destroy();
1369 return -EINVAL; 1476 return -EINVAL;
1370 } 1477 }
1371 if (policydb_load_isids(&policydb, &sidtab)) { 1478 if (policydb_load_isids(&policydb, &sidtab)) {
1372 LOAD_UNLOCK;
1373 policydb_destroy(&policydb); 1479 policydb_destroy(&policydb);
1374 avtab_cache_destroy(); 1480 avtab_cache_destroy();
1375 return -EINVAL; 1481 return -EINVAL;
@@ -1378,7 +1484,6 @@ int security_load_policy(void *data, size_t len)
1378 if (validate_classes(&policydb)) { 1484 if (validate_classes(&policydb)) {
1379 printk(KERN_ERR 1485 printk(KERN_ERR
1380 "SELinux: the definition of a class is incorrect\n"); 1486 "SELinux: the definition of a class is incorrect\n");
1381 LOAD_UNLOCK;
1382 sidtab_destroy(&sidtab); 1487 sidtab_destroy(&sidtab);
1383 policydb_destroy(&policydb); 1488 policydb_destroy(&policydb);
1384 avtab_cache_destroy(); 1489 avtab_cache_destroy();
@@ -1388,7 +1493,6 @@ int security_load_policy(void *data, size_t len)
1388 policydb_loaded_version = policydb.policyvers; 1493 policydb_loaded_version = policydb.policyvers;
1389 ss_initialized = 1; 1494 ss_initialized = 1;
1390 seqno = ++latest_granting; 1495 seqno = ++latest_granting;
1391 LOAD_UNLOCK;
1392 selinux_complete_init(); 1496 selinux_complete_init();
1393 avc_ss_reset(seqno); 1497 avc_ss_reset(seqno);
1394 selnl_notify_policyload(seqno); 1498 selnl_notify_policyload(seqno);
@@ -1401,12 +1505,13 @@ int security_load_policy(void *data, size_t len)
1401 sidtab_hash_eval(&sidtab, "sids"); 1505 sidtab_hash_eval(&sidtab, "sids");
1402#endif 1506#endif
1403 1507
1404 if (policydb_read(&newpolicydb, fp)) { 1508 if (policydb_read(&newpolicydb, fp))
1405 LOAD_UNLOCK;
1406 return -EINVAL; 1509 return -EINVAL;
1407 }
1408 1510
1409 sidtab_init(&newsidtab); 1511 if (sidtab_init(&newsidtab)) {
1512 policydb_destroy(&newpolicydb);
1513 return -ENOMEM;
1514 }
1410 1515
1411 /* Verify that the kernel defined classes are correct. */ 1516 /* Verify that the kernel defined classes are correct. */
1412 if (validate_classes(&newpolicydb)) { 1517 if (validate_classes(&newpolicydb)) {
@@ -1429,25 +1534,28 @@ int security_load_policy(void *data, size_t len)
1429 goto err; 1534 goto err;
1430 } 1535 }
1431 1536
1432 /* Convert the internal representations of contexts 1537 /*
1433 in the new SID table and remove invalid SIDs. */ 1538 * Convert the internal representations of contexts
1539 * in the new SID table.
1540 */
1434 args.oldp = &policydb; 1541 args.oldp = &policydb;
1435 args.newp = &newpolicydb; 1542 args.newp = &newpolicydb;
1436 sidtab_map_remove_on_error(&newsidtab, convert_context, &args); 1543 rc = sidtab_map(&newsidtab, convert_context, &args);
1544 if (rc)
1545 goto err;
1437 1546
1438 /* Save the old policydb and SID table to free later. */ 1547 /* Save the old policydb and SID table to free later. */
1439 memcpy(&oldpolicydb, &policydb, sizeof policydb); 1548 memcpy(&oldpolicydb, &policydb, sizeof policydb);
1440 sidtab_set(&oldsidtab, &sidtab); 1549 sidtab_set(&oldsidtab, &sidtab);
1441 1550
1442 /* Install the new policydb and SID table. */ 1551 /* Install the new policydb and SID table. */
1443 POLICY_WRLOCK; 1552 write_lock_irq(&policy_rwlock);
1444 memcpy(&policydb, &newpolicydb, sizeof policydb); 1553 memcpy(&policydb, &newpolicydb, sizeof policydb);
1445 sidtab_set(&sidtab, &newsidtab); 1554 sidtab_set(&sidtab, &newsidtab);
1446 security_load_policycaps(); 1555 security_load_policycaps();
1447 seqno = ++latest_granting; 1556 seqno = ++latest_granting;
1448 policydb_loaded_version = policydb.policyvers; 1557 policydb_loaded_version = policydb.policyvers;
1449 POLICY_WRUNLOCK; 1558 write_unlock_irq(&policy_rwlock);
1450 LOAD_UNLOCK;
1451 1559
1452 /* Free the old policydb and SID table. */ 1560 /* Free the old policydb and SID table. */
1453 policydb_destroy(&oldpolicydb); 1561 policydb_destroy(&oldpolicydb);
@@ -1461,7 +1569,6 @@ int security_load_policy(void *data, size_t len)
1461 return 0; 1569 return 0;
1462 1570
1463err: 1571err:
1464 LOAD_UNLOCK;
1465 sidtab_destroy(&newsidtab); 1572 sidtab_destroy(&newsidtab);
1466 policydb_destroy(&newpolicydb); 1573 policydb_destroy(&newpolicydb);
1467 return rc; 1574 return rc;
@@ -1479,7 +1586,7 @@ int security_port_sid(u8 protocol, u16 port, u32 *out_sid)
1479 struct ocontext *c; 1586 struct ocontext *c;
1480 int rc = 0; 1587 int rc = 0;
1481 1588
1482 POLICY_RDLOCK; 1589 read_lock(&policy_rwlock);
1483 1590
1484 c = policydb.ocontexts[OCON_PORT]; 1591 c = policydb.ocontexts[OCON_PORT];
1485 while (c) { 1592 while (c) {
@@ -1504,7 +1611,7 @@ int security_port_sid(u8 protocol, u16 port, u32 *out_sid)
1504 } 1611 }
1505 1612
1506out: 1613out:
1507 POLICY_RDUNLOCK; 1614 read_unlock(&policy_rwlock);
1508 return rc; 1615 return rc;
1509} 1616}
1510 1617
@@ -1518,7 +1625,7 @@ int security_netif_sid(char *name, u32 *if_sid)
1518 int rc = 0; 1625 int rc = 0;
1519 struct ocontext *c; 1626 struct ocontext *c;
1520 1627
1521 POLICY_RDLOCK; 1628 read_lock(&policy_rwlock);
1522 1629
1523 c = policydb.ocontexts[OCON_NETIF]; 1630 c = policydb.ocontexts[OCON_NETIF];
1524 while (c) { 1631 while (c) {
@@ -1545,7 +1652,7 @@ int security_netif_sid(char *name, u32 *if_sid)
1545 *if_sid = SECINITSID_NETIF; 1652 *if_sid = SECINITSID_NETIF;
1546 1653
1547out: 1654out:
1548 POLICY_RDUNLOCK; 1655 read_unlock(&policy_rwlock);
1549 return rc; 1656 return rc;
1550} 1657}
1551 1658
@@ -1577,7 +1684,7 @@ int security_node_sid(u16 domain,
1577 int rc = 0; 1684 int rc = 0;
1578 struct ocontext *c; 1685 struct ocontext *c;
1579 1686
1580 POLICY_RDLOCK; 1687 read_lock(&policy_rwlock);
1581 1688
1582 switch (domain) { 1689 switch (domain) {
1583 case AF_INET: { 1690 case AF_INET: {
@@ -1632,7 +1739,7 @@ int security_node_sid(u16 domain,
1632 } 1739 }
1633 1740
1634out: 1741out:
1635 POLICY_RDUNLOCK; 1742 read_unlock(&policy_rwlock);
1636 return rc; 1743 return rc;
1637} 1744}
1638 1745
@@ -1671,7 +1778,9 @@ int security_get_user_sids(u32 fromsid,
1671 if (!ss_initialized) 1778 if (!ss_initialized)
1672 goto out; 1779 goto out;
1673 1780
1674 POLICY_RDLOCK; 1781 read_lock(&policy_rwlock);
1782
1783 context_init(&usercon);
1675 1784
1676 fromcon = sidtab_search(&sidtab, fromsid); 1785 fromcon = sidtab_search(&sidtab, fromsid);
1677 if (!fromcon) { 1786 if (!fromcon) {
@@ -1722,7 +1831,7 @@ int security_get_user_sids(u32 fromsid,
1722 } 1831 }
1723 1832
1724out_unlock: 1833out_unlock:
1725 POLICY_RDUNLOCK; 1834 read_unlock(&policy_rwlock);
1726 if (rc || !mynel) { 1835 if (rc || !mynel) {
1727 kfree(mysids); 1836 kfree(mysids);
1728 goto out; 1837 goto out;
@@ -1775,7 +1884,7 @@ int security_genfs_sid(const char *fstype,
1775 while (path[0] == '/' && path[1] == '/') 1884 while (path[0] == '/' && path[1] == '/')
1776 path++; 1885 path++;
1777 1886
1778 POLICY_RDLOCK; 1887 read_lock(&policy_rwlock);
1779 1888
1780 for (genfs = policydb.genfs; genfs; genfs = genfs->next) { 1889 for (genfs = policydb.genfs; genfs; genfs = genfs->next) {
1781 cmp = strcmp(fstype, genfs->fstype); 1890 cmp = strcmp(fstype, genfs->fstype);
@@ -1812,7 +1921,7 @@ int security_genfs_sid(const char *fstype,
1812 1921
1813 *sid = c->sid[0]; 1922 *sid = c->sid[0];
1814out: 1923out:
1815 POLICY_RDUNLOCK; 1924 read_unlock(&policy_rwlock);
1816 return rc; 1925 return rc;
1817} 1926}
1818 1927
@@ -1825,12 +1934,13 @@ out:
1825int security_fs_use( 1934int security_fs_use(
1826 const char *fstype, 1935 const char *fstype,
1827 unsigned int *behavior, 1936 unsigned int *behavior,
1828 u32 *sid) 1937 u32 *sid,
1938 bool can_xattr)
1829{ 1939{
1830 int rc = 0; 1940 int rc = 0;
1831 struct ocontext *c; 1941 struct ocontext *c;
1832 1942
1833 POLICY_RDLOCK; 1943 read_lock(&policy_rwlock);
1834 1944
1835 c = policydb.ocontexts[OCON_FSUSE]; 1945 c = policydb.ocontexts[OCON_FSUSE];
1836 while (c) { 1946 while (c) {
@@ -1839,6 +1949,7 @@ int security_fs_use(
1839 c = c->next; 1949 c = c->next;
1840 } 1950 }
1841 1951
1952 /* look for labeling behavior defined in policy */
1842 if (c) { 1953 if (c) {
1843 *behavior = c->v.behavior; 1954 *behavior = c->v.behavior;
1844 if (!c->sid[0]) { 1955 if (!c->sid[0]) {
@@ -1849,18 +1960,27 @@ int security_fs_use(
1849 goto out; 1960 goto out;
1850 } 1961 }
1851 *sid = c->sid[0]; 1962 *sid = c->sid[0];
1963 goto out;
1964 }
1965
1966 /* labeling behavior not in policy, use xattrs if possible */
1967 if (can_xattr) {
1968 *behavior = SECURITY_FS_USE_XATTR;
1969 *sid = SECINITSID_FS;
1970 goto out;
1971 }
1972
1973 /* no behavior in policy and can't use xattrs, try GENFS */
1974 rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, sid);
1975 if (rc) {
1976 *behavior = SECURITY_FS_USE_NONE;
1977 rc = 0;
1852 } else { 1978 } else {
1853 rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, sid); 1979 *behavior = SECURITY_FS_USE_GENFS;
1854 if (rc) {
1855 *behavior = SECURITY_FS_USE_NONE;
1856 rc = 0;
1857 } else {
1858 *behavior = SECURITY_FS_USE_GENFS;
1859 }
1860 } 1980 }
1861 1981
1862out: 1982out:
1863 POLICY_RDUNLOCK; 1983 read_unlock(&policy_rwlock);
1864 return rc; 1984 return rc;
1865} 1985}
1866 1986
@@ -1868,7 +1988,7 @@ int security_get_bools(int *len, char ***names, int **values)
1868{ 1988{
1869 int i, rc = -ENOMEM; 1989 int i, rc = -ENOMEM;
1870 1990
1871 POLICY_RDLOCK; 1991 read_lock(&policy_rwlock);
1872 *names = NULL; 1992 *names = NULL;
1873 *values = NULL; 1993 *values = NULL;
1874 1994
@@ -1898,7 +2018,7 @@ int security_get_bools(int *len, char ***names, int **values)
1898 } 2018 }
1899 rc = 0; 2019 rc = 0;
1900out: 2020out:
1901 POLICY_RDUNLOCK; 2021 read_unlock(&policy_rwlock);
1902 return rc; 2022 return rc;
1903err: 2023err:
1904 if (*names) { 2024 if (*names) {
@@ -1916,7 +2036,7 @@ int security_set_bools(int len, int *values)
1916 int lenp, seqno = 0; 2036 int lenp, seqno = 0;
1917 struct cond_node *cur; 2037 struct cond_node *cur;
1918 2038
1919 POLICY_WRLOCK; 2039 write_lock_irq(&policy_rwlock);
1920 2040
1921 lenp = policydb.p_bools.nprim; 2041 lenp = policydb.p_bools.nprim;
1922 if (len != lenp) { 2042 if (len != lenp) {
@@ -1950,7 +2070,7 @@ int security_set_bools(int len, int *values)
1950 seqno = ++latest_granting; 2070 seqno = ++latest_granting;
1951 2071
1952out: 2072out:
1953 POLICY_WRUNLOCK; 2073 write_unlock_irq(&policy_rwlock);
1954 if (!rc) { 2074 if (!rc) {
1955 avc_ss_reset(seqno); 2075 avc_ss_reset(seqno);
1956 selnl_notify_policyload(seqno); 2076 selnl_notify_policyload(seqno);
@@ -1964,7 +2084,7 @@ int security_get_bool_value(int bool)
1964 int rc = 0; 2084 int rc = 0;
1965 int len; 2085 int len;
1966 2086
1967 POLICY_RDLOCK; 2087 read_lock(&policy_rwlock);
1968 2088
1969 len = policydb.p_bools.nprim; 2089 len = policydb.p_bools.nprim;
1970 if (bool >= len) { 2090 if (bool >= len) {
@@ -1974,7 +2094,7 @@ int security_get_bool_value(int bool)
1974 2094
1975 rc = policydb.bool_val_to_struct[bool]->state; 2095 rc = policydb.bool_val_to_struct[bool]->state;
1976out: 2096out:
1977 POLICY_RDUNLOCK; 2097 read_unlock(&policy_rwlock);
1978 return rc; 2098 return rc;
1979} 2099}
1980 2100
@@ -2029,7 +2149,7 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid)
2029 2149
2030 context_init(&newcon); 2150 context_init(&newcon);
2031 2151
2032 POLICY_RDLOCK; 2152 read_lock(&policy_rwlock);
2033 context1 = sidtab_search(&sidtab, sid); 2153 context1 = sidtab_search(&sidtab, sid);
2034 if (!context1) { 2154 if (!context1) {
2035 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", 2155 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
@@ -2071,7 +2191,7 @@ bad:
2071 } 2191 }
2072 2192
2073out_unlock: 2193out_unlock:
2074 POLICY_RDUNLOCK; 2194 read_unlock(&policy_rwlock);
2075 context_destroy(&newcon); 2195 context_destroy(&newcon);
2076out: 2196out:
2077 return rc; 2197 return rc;
@@ -2128,7 +2248,7 @@ int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type,
2128 return 0; 2248 return 0;
2129 } 2249 }
2130 2250
2131 POLICY_RDLOCK; 2251 read_lock(&policy_rwlock);
2132 2252
2133 nlbl_ctx = sidtab_search(&sidtab, nlbl_sid); 2253 nlbl_ctx = sidtab_search(&sidtab, nlbl_sid);
2134 if (!nlbl_ctx) { 2254 if (!nlbl_ctx) {
@@ -2147,7 +2267,7 @@ int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type,
2147 rc = (mls_context_cmp(nlbl_ctx, xfrm_ctx) ? 0 : -EACCES); 2267 rc = (mls_context_cmp(nlbl_ctx, xfrm_ctx) ? 0 : -EACCES);
2148 2268
2149out_slowpath: 2269out_slowpath:
2150 POLICY_RDUNLOCK; 2270 read_unlock(&policy_rwlock);
2151 if (rc == 0) 2271 if (rc == 0)
2152 /* at present NetLabel SIDs/labels really only carry MLS 2272 /* at present NetLabel SIDs/labels really only carry MLS
2153 * information so if the MLS portion of the NetLabel SID 2273 * information so if the MLS portion of the NetLabel SID
@@ -2177,7 +2297,7 @@ int security_get_classes(char ***classes, int *nclasses)
2177{ 2297{
2178 int rc = -ENOMEM; 2298 int rc = -ENOMEM;
2179 2299
2180 POLICY_RDLOCK; 2300 read_lock(&policy_rwlock);
2181 2301
2182 *nclasses = policydb.p_classes.nprim; 2302 *nclasses = policydb.p_classes.nprim;
2183 *classes = kcalloc(*nclasses, sizeof(*classes), GFP_ATOMIC); 2303 *classes = kcalloc(*nclasses, sizeof(*classes), GFP_ATOMIC);
@@ -2194,7 +2314,7 @@ int security_get_classes(char ***classes, int *nclasses)
2194 } 2314 }
2195 2315
2196out: 2316out:
2197 POLICY_RDUNLOCK; 2317 read_unlock(&policy_rwlock);
2198 return rc; 2318 return rc;
2199} 2319}
2200 2320
@@ -2216,7 +2336,7 @@ int security_get_permissions(char *class, char ***perms, int *nperms)
2216 int rc = -ENOMEM, i; 2336 int rc = -ENOMEM, i;
2217 struct class_datum *match; 2337 struct class_datum *match;
2218 2338
2219 POLICY_RDLOCK; 2339 read_lock(&policy_rwlock);
2220 2340
2221 match = hashtab_search(policydb.p_classes.table, class); 2341 match = hashtab_search(policydb.p_classes.table, class);
2222 if (!match) { 2342 if (!match) {
@@ -2244,11 +2364,11 @@ int security_get_permissions(char *class, char ***perms, int *nperms)
2244 goto err; 2364 goto err;
2245 2365
2246out: 2366out:
2247 POLICY_RDUNLOCK; 2367 read_unlock(&policy_rwlock);
2248 return rc; 2368 return rc;
2249 2369
2250err: 2370err:
2251 POLICY_RDUNLOCK; 2371 read_unlock(&policy_rwlock);
2252 for (i = 0; i < *nperms; i++) 2372 for (i = 0; i < *nperms; i++)
2253 kfree((*perms)[i]); 2373 kfree((*perms)[i]);
2254 kfree(*perms); 2374 kfree(*perms);
@@ -2279,9 +2399,9 @@ int security_policycap_supported(unsigned int req_cap)
2279{ 2399{
2280 int rc; 2400 int rc;
2281 2401
2282 POLICY_RDLOCK; 2402 read_lock(&policy_rwlock);
2283 rc = ebitmap_get_bit(&policydb.policycaps, req_cap); 2403 rc = ebitmap_get_bit(&policydb.policycaps, req_cap);
2284 POLICY_RDUNLOCK; 2404 read_unlock(&policy_rwlock);
2285 2405
2286 return rc; 2406 return rc;
2287} 2407}
@@ -2345,7 +2465,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
2345 2465
2346 context_init(&tmprule->au_ctxt); 2466 context_init(&tmprule->au_ctxt);
2347 2467
2348 POLICY_RDLOCK; 2468 read_lock(&policy_rwlock);
2349 2469
2350 tmprule->au_seqno = latest_granting; 2470 tmprule->au_seqno = latest_granting;
2351 2471
@@ -2382,7 +2502,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
2382 break; 2502 break;
2383 } 2503 }
2384 2504
2385 POLICY_RDUNLOCK; 2505 read_unlock(&policy_rwlock);
2386 2506
2387 if (rc) { 2507 if (rc) {
2388 selinux_audit_rule_free(tmprule); 2508 selinux_audit_rule_free(tmprule);
@@ -2420,7 +2540,7 @@ int selinux_audit_rule_known(struct audit_krule *rule)
2420} 2540}
2421 2541
2422int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule, 2542int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,
2423 struct audit_context *actx) 2543 struct audit_context *actx)
2424{ 2544{
2425 struct context *ctxt; 2545 struct context *ctxt;
2426 struct mls_level *level; 2546 struct mls_level *level;
@@ -2433,7 +2553,7 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,
2433 return -ENOENT; 2553 return -ENOENT;
2434 } 2554 }
2435 2555
2436 POLICY_RDLOCK; 2556 read_lock(&policy_rwlock);
2437 2557
2438 if (rule->au_seqno < latest_granting) { 2558 if (rule->au_seqno < latest_granting) {
2439 audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, 2559 audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR,
@@ -2527,14 +2647,14 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,
2527 } 2647 }
2528 2648
2529out: 2649out:
2530 POLICY_RDUNLOCK; 2650 read_unlock(&policy_rwlock);
2531 return match; 2651 return match;
2532} 2652}
2533 2653
2534static int (*aurule_callback)(void) = audit_update_lsm_rules; 2654static int (*aurule_callback)(void) = audit_update_lsm_rules;
2535 2655
2536static int aurule_avc_callback(u32 event, u32 ssid, u32 tsid, 2656static int aurule_avc_callback(u32 event, u32 ssid, u32 tsid,
2537 u16 class, u32 perms, u32 *retained) 2657 u16 class, u32 perms, u32 *retained)
2538{ 2658{
2539 int err = 0; 2659 int err = 0;
2540 2660
@@ -2615,7 +2735,7 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
2615 return 0; 2735 return 0;
2616 } 2736 }
2617 2737
2618 POLICY_RDLOCK; 2738 read_lock(&policy_rwlock);
2619 2739
2620 if (secattr->flags & NETLBL_SECATTR_CACHE) { 2740 if (secattr->flags & NETLBL_SECATTR_CACHE) {
2621 *sid = *(u32 *)secattr->cache->data; 2741 *sid = *(u32 *)secattr->cache->data;
@@ -2660,7 +2780,7 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
2660 } 2780 }
2661 2781
2662netlbl_secattr_to_sid_return: 2782netlbl_secattr_to_sid_return:
2663 POLICY_RDUNLOCK; 2783 read_unlock(&policy_rwlock);
2664 return rc; 2784 return rc;
2665netlbl_secattr_to_sid_return_cleanup: 2785netlbl_secattr_to_sid_return_cleanup:
2666 ebitmap_destroy(&ctx_new.range.level[0].cat); 2786 ebitmap_destroy(&ctx_new.range.level[0].cat);
@@ -2685,7 +2805,7 @@ int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr)
2685 if (!ss_initialized) 2805 if (!ss_initialized)
2686 return 0; 2806 return 0;
2687 2807
2688 POLICY_RDLOCK; 2808 read_lock(&policy_rwlock);
2689 ctx = sidtab_search(&sidtab, sid); 2809 ctx = sidtab_search(&sidtab, sid);
2690 if (ctx == NULL) 2810 if (ctx == NULL)
2691 goto netlbl_sid_to_secattr_failure; 2811 goto netlbl_sid_to_secattr_failure;
@@ -2696,12 +2816,12 @@ int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr)
2696 rc = mls_export_netlbl_cat(ctx, secattr); 2816 rc = mls_export_netlbl_cat(ctx, secattr);
2697 if (rc != 0) 2817 if (rc != 0)
2698 goto netlbl_sid_to_secattr_failure; 2818 goto netlbl_sid_to_secattr_failure;
2699 POLICY_RDUNLOCK; 2819 read_unlock(&policy_rwlock);
2700 2820
2701 return 0; 2821 return 0;
2702 2822
2703netlbl_sid_to_secattr_failure: 2823netlbl_sid_to_secattr_failure:
2704 POLICY_RDUNLOCK; 2824 read_unlock(&policy_rwlock);
2705 return rc; 2825 return rc;
2706} 2826}
2707#endif /* CONFIG_NETLABEL */ 2827#endif /* CONFIG_NETLABEL */