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