1#include <stdbool.h>
2#include <stdio.h>
3#include <sys/stat.h>
4#include <sys/types.h>
5
6#include "dups.h"
7
8void dups_usage() {
9    fprintf(stderr, "\tdups\n");
10}
11
12static 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
78static 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
85int 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