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