#include <stdbool.h> #include <stdio.h> #include <sys/stat.h> #include <sys/types.h> #include "dups.h" void dups_usage() { fprintf(stderr, "\tdups\n"); } static int find_dups_helper(avtab_key_t * k, avtab_datum_t * d, void *args) { policydb_t *policydb = args; ebitmap_t *sattr, *tattr; ebitmap_node_t *snode, *tnode; unsigned int i, j; avtab_key_t avkey; avtab_ptr_t node; struct type_datum *stype, *ttype, *stype2, *ttype2; bool attrib1, attrib2; if (!(k->specified & AVTAB_ALLOWED)) return 0; if (k->source_type == k->target_type) return 0; /* self rule */ avkey.target_class = k->target_class; avkey.specified = k->specified; sattr = &policydb->type_attr_map[k->source_type - 1]; tattr = &policydb->type_attr_map[k->target_type - 1]; stype = policydb->type_val_to_struct[k->source_type - 1]; ttype = policydb->type_val_to_struct[k->target_type - 1]; attrib1 = stype->flavor || ttype->flavor; 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; if (avkey.source_type == k->source_type && avkey.target_type == k->target_type) continue; if (avkey.source_type == avkey.target_type) continue; /* self rule */ stype2 = policydb->type_val_to_struct[avkey.source_type - 1]; ttype2 = policydb->type_val_to_struct[avkey.target_type - 1]; attrib2 = stype2->flavor || ttype2->flavor; if (attrib1 && attrib2) continue; /* overlapping attribute-based rules */ for (node = avtab_search_node(&policydb->te_avtab, &avkey); node != NULL; node = avtab_search_node_next(node, avkey.specified)) { uint32_t perms = node->datum.data & d->data; if ((attrib1 && perms == node->datum.data) || (attrib2 && perms == d->data)) { /* * The attribute-based rule is a superset of the * non-attribute-based rule. This is a dup. */ printf("Duplicate allow rule found:\n"); display_allow(policydb, k, i, d->data); display_allow(policydb, &node->key, i, node->datum.data); printf("\n"); } } } } return 0; } static int find_dups(policydb_t * policydb) { if (avtab_map(&policydb->te_avtab, find_dups_helper, policydb)) return -1; return 0; } int dups_func (int argc, __attribute__ ((unused)) char **argv, policydb_t *policydb) { if (argc != 1) { USAGE_ERROR = true; return -1; } return find_dups(policydb); }