Home | History | Annotate | Download | only in sepolicy-analyze
      1 #include <stdbool.h>
      2 #include <stdio.h>
      3 #include <sys/stat.h>
      4 #include <sys/types.h>
      5 
      6 #include "dups.h"
      7 
      8 void dups_usage() {
      9     fprintf(stderr, "\tdups\n");
     10 }
     11 
     12 static int find_dups_helper(avtab_key_t * k, avtab_datum_t * d,
     13                             void *args)
     14 {
     15     policydb_t *policydb = args;
     16     ebitmap_t *sattr, *tattr;
     17     ebitmap_node_t *snode, *tnode;
     18     unsigned int i, j;
     19     avtab_key_t avkey;
     20     avtab_ptr_t node;
     21     struct type_datum *stype, *ttype, *stype2, *ttype2;
     22     bool attrib1, attrib2;
     23 
     24     if (!(k->specified & AVTAB_ALLOWED))
     25         return 0;
     26 
     27     if (k->source_type == k->target_type)
     28         return 0; /* self rule */
     29 
     30     avkey.target_class = k->target_class;
     31     avkey.specified = k->specified;
     32 
     33     sattr = &policydb->type_attr_map[k->source_type - 1];
     34     tattr = &policydb->type_attr_map[k->target_type - 1];
     35     stype = policydb->type_val_to_struct[k->source_type - 1];
     36     ttype = policydb->type_val_to_struct[k->target_type - 1];
     37     attrib1 = stype->flavor || ttype->flavor;
     38     ebitmap_for_each_bit(sattr, snode, i) {
     39         if (!ebitmap_node_get_bit(snode, i))
     40             continue;
     41         ebitmap_for_each_bit(tattr, tnode, j) {
     42             if (!ebitmap_node_get_bit(tnode, j))
     43                 continue;
     44             avkey.source_type = i + 1;
     45             avkey.target_type = j + 1;
     46             if (avkey.source_type == k->source_type &&
     47                 avkey.target_type == k->target_type)
     48                 continue;
     49             if (avkey.source_type == avkey.target_type)
     50                 continue; /* self rule */
     51             stype2 = policydb->type_val_to_struct[avkey.source_type - 1];
     52             ttype2 = policydb->type_val_to_struct[avkey.target_type - 1];
     53             attrib2 = stype2->flavor || ttype2->flavor;
     54             if (attrib1 && attrib2)
     55                 continue; /* overlapping attribute-based rules */
     56             for (node = avtab_search_node(&policydb->te_avtab, &avkey);
     57                  node != NULL;
     58                  node = avtab_search_node_next(node, avkey.specified)) {
     59                 uint32_t perms = node->datum.data & d->data;
     60                 if ((attrib1 && perms == node->datum.data) ||
     61                     (attrib2 && perms == d->data)) {
     62                     /*
     63                      * The attribute-based rule is a superset of the
     64                      * non-attribute-based rule.  This is a dup.
     65                      */
     66                     printf("Duplicate allow rule found:\n");
     67                     display_allow(policydb, k, i, d->data);
     68                     display_allow(policydb, &node->key, i, node->datum.data);
     69                     printf("\n");
     70                 }
     71             }
     72         }
     73     }
     74 
     75     return 0;
     76 }
     77 
     78 static int find_dups(policydb_t * policydb)
     79 {
     80     if (avtab_map(&policydb->te_avtab, find_dups_helper, policydb))
     81         return -1;
     82     return 0;
     83 }
     84 
     85 int dups_func (int argc, __attribute__ ((unused)) char **argv, policydb_t *policydb) {
     86     if (argc != 1) {
     87         USAGE_ERROR = true;
     88         return -1;
     89     }
     90     return find_dups(policydb);
     91 }
     92