selinux: skip bounded transition processing if the policy isn't loaded
[sfrench/cifs-2.6.git] / security / selinux / ss / services.c
index 2f02fa67ec2e833eefb6f98f9d6190f4012679a1..8900ea5cbabf21313b870dc12978bc81d4342c40 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Implementation of the security services.
  *
- * Authors : Stephen Smalley, <sds@epoch.ncsc.mil>
+ * Authors : Stephen Smalley, <sds@tycho.nsa.gov>
  *          James Morris <jmorris@redhat.com>
  *
  * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com>
@@ -76,7 +76,8 @@ char *selinux_policycap_names[__POLICYDB_CAPABILITY_MAX] = {
        "open_perms",
        "extended_socket_class",
        "always_check_network",
-       "cgroup_seclabel"
+       "cgroup_seclabel",
+       "nnp_nosuid_transition"
 };
 
 int selinux_policycap_netpeer;
@@ -84,6 +85,7 @@ int selinux_policycap_openperm;
 int selinux_policycap_extsockclass;
 int selinux_policycap_alwaysnetwork;
 int selinux_policycap_cgroupseclabel;
+int selinux_policycap_nnp_nosuid_transition;
 
 static DEFINE_RWLOCK(policy_rwlock);
 
@@ -865,6 +867,9 @@ int security_bounded_transition(u32 old_sid, u32 new_sid)
        int index;
        int rc;
 
+       if (!ss_initialized)
+               return 0;
+
        read_lock(&policy_rwlock);
 
        rc = -EINVAL;
@@ -1411,27 +1416,25 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len,
        if (!scontext_len)
                return -EINVAL;
 
+       /* Copy the string to allow changes and ensure a NUL terminator */
+       scontext2 = kmemdup_nul(scontext, scontext_len, gfp_flags);
+       if (!scontext2)
+               return -ENOMEM;
+
        if (!ss_initialized) {
                int i;
 
                for (i = 1; i < SECINITSID_NUM; i++) {
-                       if (!strcmp(initial_sid_to_string[i], scontext)) {
+                       if (!strcmp(initial_sid_to_string[i], scontext2)) {
                                *sid = i;
-                               return 0;
+                               goto out;
                        }
                }
                *sid = SECINITSID_KERNEL;
-               return 0;
+               goto out;
        }
        *sid = SECSID_NULL;
 
-       /* Copy the string so that we can modify the copy as we parse it. */
-       scontext2 = kmalloc(scontext_len + 1, gfp_flags);
-       if (!scontext2)
-               return -ENOMEM;
-       memcpy(scontext2, scontext, scontext_len);
-       scontext2[scontext_len] = 0;
-
        if (force) {
                /* Save another copy for storing in uninterpreted form */
                rc = -ENOMEM;
@@ -2009,6 +2012,9 @@ static void security_load_policycaps(void)
        selinux_policycap_cgroupseclabel =
                ebitmap_get_bit(&policydb.policycaps,
                                POLICYDB_CAPABILITY_CGROUPSECLABEL);
+       selinux_policycap_nnp_nosuid_transition =
+               ebitmap_get_bit(&policydb.policycaps,
+                               POLICYDB_CAPABILITY_NNP_NOSUID_TRANSITION);
 
        for (i = 0; i < ARRAY_SIZE(selinux_policycap_names); i++)
                pr_info("SELinux:  policy capability %s=%d\n",
@@ -2055,10 +2061,12 @@ int security_load_policy(void *data, size_t len)
        if (!ss_initialized) {
                avtab_cache_init();
                ebitmap_cache_init();
+               hashtab_cache_init();
                rc = policydb_read(&policydb, fp);
                if (rc) {
                        avtab_cache_destroy();
                        ebitmap_cache_destroy();
+                       hashtab_cache_destroy();
                        goto out;
                }
 
@@ -2070,6 +2078,7 @@ int security_load_policy(void *data, size_t len)
                        policydb_destroy(&policydb);
                        avtab_cache_destroy();
                        ebitmap_cache_destroy();
+                       hashtab_cache_destroy();
                        goto out;
                }
 
@@ -2078,6 +2087,7 @@ int security_load_policy(void *data, size_t len)
                        policydb_destroy(&policydb);
                        avtab_cache_destroy();
                        ebitmap_cache_destroy();
+                       hashtab_cache_destroy();
                        goto out;
                }