From: Peter Enderborg <peter.enderb...@sony.com>

To be able to use rcu locks we need access the sidtab trough
a pointer. This moves the sittab to a dynamic allocated struture.

Signed-off-by: Peter Enderborg <peter.enderb...@sony.com>
---
 security/selinux/ss/services.c | 140 ++++++++++++++++++++++-------------------
 1 file changed, 74 insertions(+), 66 deletions(-)

diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 21400bd..2a8486c 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -89,7 +89,6 @@ int selinux_policycap_nnp_nosuid_transition;
 
 static DEFINE_RWLOCK(policy_rwlock);
 
-static struct sidtab sidtab;
 int ss_initialized;
 
 /*
@@ -120,6 +119,7 @@ struct shared_current_mapping {
        struct selinux_mapping *current_mapping;
        u16 current_mapping_size;
        struct policydb policydb;
+       struct sidtab sidtab;
 };
 
 static struct shared_current_mapping *crm;
@@ -804,7 +804,7 @@ static int security_compute_validatetrans(u32 oldsid, u32 
newsid, u32 tasksid,
        }
        tclass_datum = crm->policydb.class_val_to_struct[tclass - 1];
 
-       ocontext = sidtab_search(&sidtab, oldsid);
+       ocontext = sidtab_search(&crm->sidtab, oldsid);
        if (!ocontext) {
                printk(KERN_ERR "SELinux: %s:  unrecognized SID %d\n",
                        __func__, oldsid);
@@ -812,7 +812,7 @@ static int security_compute_validatetrans(u32 oldsid, u32 
newsid, u32 tasksid,
                goto out;
        }
 
-       ncontext = sidtab_search(&sidtab, newsid);
+       ncontext = sidtab_search(&crm->sidtab, newsid);
        if (!ncontext) {
                printk(KERN_ERR "SELinux: %s:  unrecognized SID %d\n",
                        __func__, newsid);
@@ -820,7 +820,7 @@ static int security_compute_validatetrans(u32 oldsid, u32 
newsid, u32 tasksid,
                goto out;
        }
 
-       tcontext = sidtab_search(&sidtab, tasksid);
+       tcontext = sidtab_search(&crm->sidtab, tasksid);
        if (!tcontext) {
                printk(KERN_ERR "SELinux: %s:  unrecognized SID %d\n",
                        __func__, tasksid);
@@ -882,7 +882,7 @@ int security_bounded_transition(u32 old_sid, u32 new_sid)
        read_lock(&policy_rwlock);
 
        rc = -EINVAL;
-       old_context = sidtab_search(&sidtab, old_sid);
+       old_context = sidtab_search(&crm->sidtab, old_sid);
        if (!old_context) {
                printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n",
                       __func__, old_sid);
@@ -890,7 +890,7 @@ int security_bounded_transition(u32 old_sid, u32 new_sid)
        }
 
        rc = -EINVAL;
-       new_context = sidtab_search(&sidtab, new_sid);
+       new_context = sidtab_search(&crm->sidtab, new_sid);
        if (!new_context) {
                printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n",
                       __func__, new_sid);
@@ -1033,14 +1033,14 @@ void security_compute_xperms_decision(u32 ssid,
        if (!ss_initialized)
                goto allow;
 
-       scontext = sidtab_search(&sidtab, ssid);
+       scontext = sidtab_search(&crm->sidtab, ssid);
        if (!scontext) {
                printk(KERN_ERR "SELinux: %s:  unrecognized SID %d\n",
                       __func__, ssid);
                goto out;
        }
 
-       tcontext = sidtab_search(&sidtab, tsid);
+       tcontext = sidtab_search(&crm->sidtab, tsid);
        if (!tcontext) {
                printk(KERN_ERR "SELinux: %s:  unrecognized SID %d\n",
                       __func__, tsid);
@@ -1116,7 +1116,7 @@ void security_compute_av(u32 ssid,
        if (!ss_initialized)
                goto allow;
 
-       scontext = sidtab_search(&sidtab, ssid);
+       scontext = sidtab_search(&crm->sidtab, ssid);
        if (!scontext) {
                printk(KERN_ERR "SELinux: %s:  unrecognized SID %d\n",
                       __func__, ssid);
@@ -1127,7 +1127,7 @@ void security_compute_av(u32 ssid,
        if (ebitmap_get_bit(&crm->policydb.permissive_map, scontext->type))
                avd->flags |= AVD_FLAGS_PERMISSIVE;
 
-       tcontext = sidtab_search(&sidtab, tsid);
+       tcontext = sidtab_search(&crm->sidtab, tsid);
        if (!tcontext) {
                printk(KERN_ERR "SELinux: %s:  unrecognized SID %d\n",
                       __func__, tsid);
@@ -1162,7 +1162,7 @@ void security_compute_av_user(u32 ssid,
        if (!ss_initialized)
                goto allow;
 
-       scontext = sidtab_search(&sidtab, ssid);
+       scontext = sidtab_search(&crm->sidtab, ssid);
        if (!scontext) {
                printk(KERN_ERR "SELinux: %s:  unrecognized SID %d\n",
                       __func__, ssid);
@@ -1173,7 +1173,7 @@ void security_compute_av_user(u32 ssid,
        if (ebitmap_get_bit(&crm->policydb.permissive_map, scontext->type))
                avd->flags |= AVD_FLAGS_PERMISSIVE;
 
-       tcontext = sidtab_search(&sidtab, tsid);
+       tcontext = sidtab_search(&crm->sidtab, tsid);
        if (!tcontext) {
                printk(KERN_ERR "SELinux: %s:  unrecognized SID %d\n",
                       __func__, tsid);
@@ -1295,9 +1295,9 @@ static int security_sid_to_context_core(u32 sid, char 
**scontext,
        }
        read_lock(&policy_rwlock);
        if (force)
-               context = sidtab_search_force(&sidtab, sid);
+               context = sidtab_search_force(&crm->sidtab, sid);
        else
-               context = sidtab_search(&sidtab, sid);
+               context = sidtab_search(&crm->sidtab, sid);
        if (!context) {
                printk(KERN_ERR "SELinux: %s:  unrecognized SID %d\n",
                        __func__, sid);
@@ -1459,7 +1459,7 @@ static int security_context_to_sid_core(const char 
*scontext, u32 scontext_len,
        }
 
        read_lock(&policy_rwlock);
-       rc = string_to_context_struct(&crm->policydb, &sidtab, scontext2,
+       rc = string_to_context_struct(&crm->policydb, &crm->sidtab, scontext2,
                                      scontext_len, &context, def_sid);
        if (rc == -EINVAL && force) {
                context.str = str;
@@ -1467,7 +1467,7 @@ static int security_context_to_sid_core(const char 
*scontext, u32 scontext_len,
                str = NULL;
        } else if (rc)
                goto out_unlock;
-       rc = sidtab_context_to_sid(&sidtab, &context, sid);
+       rc = sidtab_context_to_sid(&crm->sidtab, &context, sid);
        context_destroy(&context);
 out_unlock:
        read_unlock(&policy_rwlock);
@@ -1630,14 +1630,14 @@ static int security_compute_sid(u32 ssid,
                sock = security_is_socket_class(map_class(tclass));
        }
 
-       scontext = sidtab_search(&sidtab, ssid);
+       scontext = sidtab_search(&crm->sidtab, ssid);
        if (!scontext) {
                printk(KERN_ERR "SELinux: %s:  unrecognized SID %d\n",
                       __func__, ssid);
                rc = -EINVAL;
                goto out_unlock;
        }
-       tcontext = sidtab_search(&sidtab, tsid);
+       tcontext = sidtab_search(&crm->sidtab, tsid);
        if (!tcontext) {
                printk(KERN_ERR "SELinux: %s:  unrecognized SID %d\n",
                       __func__, tsid);
@@ -1757,7 +1757,7 @@ static int security_compute_sid(u32 ssid,
                        goto out_unlock;
        }
        /* Obtain the sid for the context. */
-       rc = sidtab_context_to_sid(&sidtab, &newcontext, out_sid);
+       rc = sidtab_context_to_sid(&crm->sidtab, &newcontext, out_sid);
 out_unlock:
        read_unlock(&policy_rwlock);
        context_destroy(&newcontext);
@@ -2017,36 +2017,33 @@ static int convert_context(u32 key,
        goto out;
 }
 
-static void security_load_policycaps(void)
+static void security_load_policycaps(struct policydb *pdb)
 {
        unsigned int i;
        struct ebitmap_node *node;
 
-       selinux_policycap_netpeer =
-               ebitmap_get_bit(&crm->policydb.policycaps,
-                         POLICYDB_CAPABILITY_NETPEER);
-       selinux_policycap_openperm =
-               ebitmap_get_bit(&crm->policydb.policycaps,
-                               POLICYDB_CAPABILITY_OPENPERM);
-       selinux_policycap_extsockclass =
-               ebitmap_get_bit(&crm->policydb.policycaps,
-                               POLICYDB_CAPABILITY_EXTSOCKCLASS);
+       selinux_policycap_netpeer = ebitmap_get_bit(&pdb->policycaps,
+                                                 POLICYDB_CAPABILITY_NETPEER);
+       selinux_policycap_openperm = ebitmap_get_bit(&pdb->policycaps,
+                                                 POLICYDB_CAPABILITY_OPENPERM);
+       selinux_policycap_extsockclass = ebitmap_get_bit(&pdb->policycaps,
+                                         POLICYDB_CAPABILITY_EXTSOCKCLASS);
        selinux_policycap_alwaysnetwork =
-               ebitmap_get_bit(&crm->policydb.policycaps,
+               ebitmap_get_bit(&pdb->policycaps,
                                POLICYDB_CAPABILITY_ALWAYSNETWORK);
        selinux_policycap_cgroupseclabel =
-               ebitmap_get_bit(&crm->policydb.policycaps,
+               ebitmap_get_bit(&pdb->policycaps,
                                POLICYDB_CAPABILITY_CGROUPSECLABEL);
        selinux_policycap_nnp_nosuid_transition =
-               ebitmap_get_bit(&crm->policydb.policycaps,
+               ebitmap_get_bit(&pdb->policycaps,
                                POLICYDB_CAPABILITY_NNP_NOSUID_TRANSITION);
 
        for (i = 0; i < ARRAY_SIZE(selinux_policycap_names); i++)
                pr_info("SELinux:  policy capability %s=%d\n",
                        selinux_policycap_names[i],
-                       ebitmap_get_bit(&crm->policydb.policycaps, i));
+                       ebitmap_get_bit(&pdb->policycaps, i));
 
-       ebitmap_for_each_positive_bit(&crm->policydb.policycaps, node, i) {
+       ebitmap_for_each_positive_bit(&pdb->policycaps, node, i) {
                if (i >= ARRAY_SIZE(selinux_policycap_names))
                        pr_info("SELinux:  unknown policy capability %u\n",
                                i);
@@ -2072,6 +2069,8 @@ int security_load_policy(void *data, size_t len)
        struct selinux_mapping *oldmap = NULL, *map = NULL;
        struct convert_context_args args;
        struct shared_current_mapping *new_mapping;
+       struct shared_current_mapping *next_rcu;
+
        u32 seqno;
        u16 map_size;
        int rc = 0;
@@ -2089,6 +2088,11 @@ int security_load_policy(void *data, size_t len)
                goto out;
        }
        newpolicydb = oldpolicydb + 1;
+       next_rcu = kmalloc(sizeof(struct shared_current_mapping), GFP_KERNEL);
+       if (!next_rcu) {
+               rc = -ENOMEM;
+               goto out;
+       }
 
        if (!ss_initialized) {
                crm = kzalloc(sizeof(struct shared_current_mapping),
@@ -2097,7 +2101,6 @@ int security_load_policy(void *data, size_t len)
                        rc = -ENOMEM;
                        goto out;
                }
-
                avtab_cache_init();
                ebitmap_cache_init();
                hashtab_cache_init();
@@ -2121,7 +2124,7 @@ int security_load_policy(void *data, size_t len)
                        goto out;
                }
 
-               rc = policydb_load_isids(&crm->policydb, &sidtab);
+               rc = policydb_load_isids(&crm->policydb, &crm->sidtab);
                if (rc) {
                        policydb_destroy(&crm->policydb);
                        avtab_cache_destroy();
@@ -2130,7 +2133,7 @@ int security_load_policy(void *data, size_t len)
                        goto out;
                }
 
-               security_load_policycaps();
+               security_load_policycaps(&crm->policydb);
                ss_initialized = 1;
                seqno = ++latest_granting;
                selinux_complete_init();
@@ -2143,7 +2146,7 @@ int security_load_policy(void *data, size_t len)
        }
 
 #if 0
-       sidtab_hash_eval(&sidtab, "sids");
+       sidtab_hash_eval(&crm->sidtab, "sids");
 #endif
 
        rc = policydb_read(newpolicydb, fp);
@@ -2175,9 +2178,9 @@ int security_load_policy(void *data, size_t len)
        }
 
        /* Clone the SID table. */
-       sidtab_shutdown(&sidtab);
+       sidtab_shutdown(&crm->sidtab);
 
-       rc = sidtab_map(&sidtab, clone_sid, &newsidtab);
+       rc = sidtab_map(&crm->sidtab, clone_sid, &newsidtab);
        if (rc)
                goto err;
 
@@ -2197,19 +2200,21 @@ int security_load_policy(void *data, size_t len)
 
        /* Save the old policydb and SID table to free later. */
        memcpy(oldpolicydb, &crm->policydb, sizeof(struct policydb));
-       sidtab_set(&oldsidtab, &sidtab);
+       sidtab_set(&oldsidtab, &crm->sidtab);
 
        /* Install the new policydb and SID table. */
+       /* next */
        write_lock_irq(&policy_rwlock);
-       memcpy(&crm->policydb, newpolicydb, sizeof(struct policydb));
-
-       sidtab_set(&sidtab, &newsidtab);
-       security_load_policycaps();
+       memcpy(&next_rcu->policydb, newpolicydb, sizeof(struct policydb));
+       sidtab_set(&next_rcu->sidtab, &newsidtab);
+       security_load_policycaps(&next_rcu->policydb);
        oldmap = crm->current_mapping;
-       crm->current_mapping = map;
-       crm->current_mapping_size = map_size;
+       next_rcu->current_mapping = map;
+       next_rcu->current_mapping_size = map_size;
+
        seqno = ++latest_granting;
        write_unlock_irq(&policy_rwlock);
+       crm = next_rcu;
 
        /* Free the old policydb and SID table. */
        policydb_destroy(oldpolicydb);
@@ -2270,7 +2275,7 @@ int security_port_sid(u8 protocol, u16 port, u32 *out_sid)
 
        if (c) {
                if (!c->sid[0]) {
-                       rc = sidtab_context_to_sid(&sidtab,
+                       rc = sidtab_context_to_sid(&crm->sidtab,
                                                   &c->context[0],
                                                   &c->sid[0]);
                        if (rc)
@@ -2311,7 +2316,7 @@ int security_ib_pkey_sid(u64 subnet_prefix, u16 pkey_num, 
u32 *out_sid)
 
        if (c) {
                if (!c->sid[0]) {
-                       rc = sidtab_context_to_sid(&sidtab,
+                       rc = sidtab_context_to_sid(&crm->sidtab,
                                                   &c->context[0],
                                                   &c->sid[0]);
                        if (rc)
@@ -2352,7 +2357,7 @@ int security_ib_endport_sid(const char *dev_name, u8 
port_num, u32 *out_sid)
 
        if (c) {
                if (!c->sid[0]) {
-                       rc = sidtab_context_to_sid(&sidtab,
+                       rc = sidtab_context_to_sid(&crm->sidtab,
                                                   &c->context[0],
                                                   &c->sid[0]);
                        if (rc)
@@ -2388,12 +2393,12 @@ int security_netif_sid(char *name, u32 *if_sid)
 
        if (c) {
                if (!c->sid[0] || !c->sid[1]) {
-                       rc = sidtab_context_to_sid(&sidtab,
+                       rc = sidtab_context_to_sid(&crm->sidtab,
                                                  &c->context[0],
                                                  &c->sid[0]);
                        if (rc)
                                goto out;
-                       rc = sidtab_context_to_sid(&sidtab,
+                       rc = sidtab_context_to_sid(&crm->sidtab,
                                                   &c->context[1],
                                                   &c->sid[1]);
                        if (rc)
@@ -2478,7 +2483,7 @@ int security_node_sid(u16 domain,
 
        if (c) {
                if (!c->sid[0]) {
-                       rc = sidtab_context_to_sid(&sidtab,
+                       rc = sidtab_context_to_sid(&crm->sidtab,
                                                   &c->context[0],
                                                   &c->sid[0]);
                        if (rc)
@@ -2535,7 +2540,7 @@ int security_get_user_sids(u32 fromsid,
        context_init(&usercon);
 
        rc = -EINVAL;
-       fromcon = sidtab_search(&sidtab, fromsid);
+       fromcon = sidtab_search(&crm->sidtab, fromsid);
        if (!fromcon)
                goto out_unlock;
 
@@ -2561,7 +2566,8 @@ int security_get_user_sids(u32 fromsid,
                                                 user, &usercon))
                                continue;
 
-                       rc = sidtab_context_to_sid(&sidtab, &usercon, &sid);
+                       rc = sidtab_context_to_sid(&crm->sidtab, &usercon,
+                                                  &sid);
                        if (rc)
                                goto out_unlock;
                        if (mynel < maxnel) {
@@ -2663,7 +2669,8 @@ static inline int __security_genfs_sid(const char *fstype,
                goto out;
 
        if (!c->sid[0]) {
-               rc = sidtab_context_to_sid(&sidtab, &c->context[0], &c->sid[0]);
+               rc = sidtab_context_to_sid(&crm->sidtab, &c->context[0],
+                                          &c->sid[0]);
                if (rc)
                        goto out;
        }
@@ -2720,7 +2727,8 @@ int security_fs_use(struct super_block *sb)
        if (c) {
                sbsec->behavior = c->v.behavior;
                if (!c->sid[0]) {
-                       rc = sidtab_context_to_sid(&sidtab, &c->context[0],
+                       rc = sidtab_context_to_sid(&crm->sidtab,
+                                                  &c->context[0],
                                                   &c->sid[0]);
                        if (rc)
                                goto out;
@@ -2911,7 +2919,7 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 
*new_sid)
        read_lock(&policy_rwlock);
 
        rc = -EINVAL;
-       context1 = sidtab_search(&sidtab, sid);
+       context1 = sidtab_search(&crm->sidtab, sid);
        if (!context1) {
                printk(KERN_ERR "SELinux: %s:  unrecognized SID %d\n",
                        __func__, sid);
@@ -2919,7 +2927,7 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 
*new_sid)
        }
 
        rc = -EINVAL;
-       context2 = sidtab_search(&sidtab, mls_sid);
+       context2 = sidtab_search(&crm->sidtab, mls_sid);
        if (!context2) {
                printk(KERN_ERR "SELinux: %s:  unrecognized SID %d\n",
                        __func__, mls_sid);
@@ -2948,7 +2956,7 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 
*new_sid)
                }
        }
 
-       rc = sidtab_context_to_sid(&sidtab, &newcon, new_sid);
+       rc = sidtab_context_to_sid(&crm->sidtab, &newcon, new_sid);
 out_unlock:
        read_unlock(&policy_rwlock);
        context_destroy(&newcon);
@@ -3010,14 +3018,14 @@ int security_net_peersid_resolve(u32 nlbl_sid, u32 
nlbl_type,
        read_lock(&policy_rwlock);
 
        rc = -EINVAL;
-       nlbl_ctx = sidtab_search(&sidtab, nlbl_sid);
+       nlbl_ctx = sidtab_search(&crm->sidtab, nlbl_sid);
        if (!nlbl_ctx) {
                printk(KERN_ERR "SELinux: %s:  unrecognized SID %d\n",
                       __func__, nlbl_sid);
                goto out;
        }
        rc = -EINVAL;
-       xfrm_ctx = sidtab_search(&sidtab, xfrm_sid);
+       xfrm_ctx = sidtab_search(&crm->sidtab, xfrm_sid);
        if (!xfrm_ctx) {
                printk(KERN_ERR "SELinux: %s:  unrecognized SID %d\n",
                       __func__, xfrm_sid);
@@ -3326,7 +3334,7 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, 
void *vrule,
                goto out;
        }
 
-       ctxt = sidtab_search(&sidtab, sid);
+       ctxt = sidtab_search(&crm->sidtab, sid);
        if (unlikely(!ctxt)) {
                WARN_ONCE(1, "selinux_audit_rule_match: unrecognized SID %d\n",
                          sid);
@@ -3504,7 +3512,7 @@ int security_netlbl_secattr_to_sid(struct 
netlbl_lsm_secattr *secattr,
                *sid = secattr->attr.secid;
        else if (secattr->flags & NETLBL_SECATTR_MLS_LVL) {
                rc = -EIDRM;
-               ctx = sidtab_search(&sidtab, SECINITSID_NETMSG);
+               ctx = sidtab_search(&crm->sidtab, SECINITSID_NETMSG);
                if (ctx == NULL)
                        goto out;
 
@@ -3523,7 +3531,7 @@ int security_netlbl_secattr_to_sid(struct 
netlbl_lsm_secattr *secattr,
                if (!mls_context_isvalid(&crm->policydb, &ctx_new))
                        goto out_free;
 
-               rc = sidtab_context_to_sid(&sidtab, &ctx_new, sid);
+               rc = sidtab_context_to_sid(&crm->sidtab, &ctx_new, sid);
                if (rc)
                        goto out_free;
 
@@ -3563,7 +3571,7 @@ int security_netlbl_sid_to_secattr(u32 sid, struct 
netlbl_lsm_secattr *secattr)
        read_lock(&policy_rwlock);
 
        rc = -ENOENT;
-       ctx = sidtab_search(&sidtab, sid);
+       ctx = sidtab_search(&crm->sidtab, sid);
        if (ctx == NULL)
                goto out;
 
-- 
2.7.4


Reply via email to