Merge master.kernel.org:/pub/scm/linux/kernel/git/dwmw2/audit-2.6
[sfrench/cifs-2.6.git] / security / selinux / ss / services.c
index 45d317044cb2520788504d61c409d77535b9fa31..aecdded55e74aa04d4c2f9bcb05b2f39df8617fe 100644 (file)
@@ -266,8 +266,11 @@ static int context_struct_compute_av(struct context *scontext,
        struct constraint_node *constraint;
        struct role_allow *ra;
        struct avtab_key avkey;
-       struct avtab_datum *avdatum;
+       struct avtab_node *node;
        struct class_datum *tclass_datum;
+       struct ebitmap *sattr, *tattr;
+       struct ebitmap_node *snode, *tnode;
+       unsigned int i, j;
 
        /*
         * Remap extended Netlink classes for old policy versions.
@@ -300,21 +303,34 @@ static int context_struct_compute_av(struct context *scontext,
         * If a specific type enforcement rule was defined for
         * this permission check, then use it.
         */
-       avkey.source_type = scontext->type;
-       avkey.target_type = tcontext->type;
        avkey.target_class = tclass;
-       avdatum = avtab_search(&policydb.te_avtab, &avkey, AVTAB_AV);
-       if (avdatum) {
-               if (avdatum->specified & AVTAB_ALLOWED)
-                       avd->allowed = avtab_allowed(avdatum);
-               if (avdatum->specified & AVTAB_AUDITDENY)
-                       avd->auditdeny = avtab_auditdeny(avdatum);
-               if (avdatum->specified & AVTAB_AUDITALLOW)
-                       avd->auditallow = avtab_auditallow(avdatum);
-       }
+       avkey.specified = AVTAB_AV;
+       sattr = &policydb.type_attr_map[scontext->type - 1];
+       tattr = &policydb.type_attr_map[tcontext->type - 1];
+       ebitmap_for_each_bit(sattr, snode, i) {
+               if (!ebitmap_node_get_bit(snode, i))
+                       continue;
+               ebitmap_for_each_bit(tattr, tnode, j) {
+                       if (!ebitmap_node_get_bit(tnode, j))
+                               continue;
+                       avkey.source_type = i + 1;
+                       avkey.target_type = j + 1;
+                       for (node = avtab_search_node(&policydb.te_avtab, &avkey);
+                            node != NULL;
+                            node = avtab_search_node_next(node, avkey.specified)) {
+                               if (node->key.specified == AVTAB_ALLOWED)
+                                       avd->allowed |= node->datum.data;
+                               else if (node->key.specified == AVTAB_AUDITALLOW)
+                                       avd->auditallow |= node->datum.data;
+                               else if (node->key.specified == AVTAB_AUDITDENY)
+                                       avd->auditdeny &= node->datum.data;
+                       }
 
-       /* Check conditional av table for additional permissions */
-       cond_compute_av(&policydb.te_cond_avtab, &avkey, avd);
+                       /* Check conditional av table for additional permissions */
+                       cond_compute_av(&policydb.te_cond_avtab, &avkey, avd);
+
+               }
+       }
 
        /*
         * Remove any permissions prohibited by a constraint (this includes
@@ -797,7 +813,6 @@ static int security_compute_sid(u32 ssid,
        struct avtab_key avkey;
        struct avtab_datum *avdatum;
        struct avtab_node *node;
-       unsigned int type_change = 0;
        int rc = 0;
 
        if (!ss_initialized) {
@@ -862,33 +877,23 @@ static int security_compute_sid(u32 ssid,
        avkey.source_type = scontext->type;
        avkey.target_type = tcontext->type;
        avkey.target_class = tclass;
-       avdatum = avtab_search(&policydb.te_avtab, &avkey, AVTAB_TYPE);
+       avkey.specified = specified;
+       avdatum = avtab_search(&policydb.te_avtab, &avkey);
 
        /* If no permanent rule, also check for enabled conditional rules */
        if(!avdatum) {
-               node = avtab_search_node(&policydb.te_cond_avtab, &avkey, specified);
+               node = avtab_search_node(&policydb.te_cond_avtab, &avkey);
                for (; node != NULL; node = avtab_search_node_next(node, specified)) {
-                       if (node->datum.specified & AVTAB_ENABLED) {
+                       if (node->key.specified & AVTAB_ENABLED) {
                                avdatum = &node->datum;
                                break;
                        }
                }
        }
 
-       type_change = (avdatum && (avdatum->specified & specified));
-       if (type_change) {
+       if (avdatum) {
                /* Use the type from the type transition/member/change rule. */
-               switch (specified) {
-               case AVTAB_TRANSITION:
-                       newcontext.type = avtab_transition(avdatum);
-                       break;
-               case AVTAB_MEMBER:
-                       newcontext.type = avtab_member(avdatum);
-                       break;
-               case AVTAB_CHANGE:
-                       newcontext.type = avtab_change(avdatum);
-                       break;
-               }
+               newcontext.type = avdatum->data;
        }
 
        /* Check for class-specific changes. */
@@ -1502,6 +1507,7 @@ int security_get_user_sids(u32 fromsid,
        struct user_datum *user;
        struct role_datum *role;
        struct av_decision avd;
+       struct ebitmap_node *rnode, *tnode;
        int rc = 0, i, j;
 
        if (!ss_initialized) {
@@ -1532,13 +1538,13 @@ int security_get_user_sids(u32 fromsid,
        }
        memset(mysids, 0, maxnel*sizeof(*mysids));
 
-       for (i = ebitmap_startbit(&user->roles); i < ebitmap_length(&user->roles); i++) {
-               if (!ebitmap_get_bit(&user->roles, i))
+       ebitmap_for_each_bit(&user->roles, rnode, i) {
+               if (!ebitmap_node_get_bit(rnode, i))
                        continue;
                role = policydb.role_val_to_struct[i];
                usercon.role = i+1;
-               for (j = ebitmap_startbit(&role->types); j < ebitmap_length(&role->types); j++) {
-                       if (!ebitmap_get_bit(&role->types, j))
+               ebitmap_for_each_bit(&role->types, tnode, j) {
+                       if (!ebitmap_node_get_bit(tnode, j))
                                continue;
                        usercon.type = j+1;