1 #include <stdbool.h>
2 #include <stdio.h>
3 #include <sys/stat.h>
4 #include <sys/types.h>
5
6 #include "dups.h"
7
dups_usage()8 void dups_usage() {
9 fprintf(stderr, "\tdups\n");
10 }
11
find_dups_helper(avtab_key_t * k,avtab_datum_t * d,void * args)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
find_dups(policydb_t * policydb)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
dups_func(int argc,char ** argv,policydb_t * policydb)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