diff options
Diffstat (limited to 'tools/sepolicy-analyze/typecmp.c')
-rw-r--r-- | tools/sepolicy-analyze/typecmp.c | 295 |
1 files changed, 0 insertions, 295 deletions
diff --git a/tools/sepolicy-analyze/typecmp.c b/tools/sepolicy-analyze/typecmp.c deleted file mode 100644 index 5fffd63..0000000 --- a/tools/sepolicy-analyze/typecmp.c +++ /dev/null @@ -1,295 +0,0 @@ -#include <getopt.h> -#include <sepol/policydb/expand.h> - -#include "typecmp.h" - -void typecmp_usage() { - fprintf(stderr, "\ttypecmp [-d|--diff] [-e|--equiv]\n"); -} - -static int insert_type_rule(avtab_key_t * k, avtab_datum_t * d, - struct avtab_node *type_rules) -{ - struct avtab_node *p, *c, *n; - - for (p = type_rules, c = type_rules->next; c; p = c, c = c->next) { - /* - * Find the insertion point, keeping the list - * ordered by source type, then target type, then - * target class. - */ - if (k->source_type < c->key.source_type) - break; - if (k->source_type == c->key.source_type && - k->target_type < c->key.target_type) - break; - if (k->source_type == c->key.source_type && - k->target_type == c->key.target_type && - k->target_class <= c->key.target_class) - break; - } - - if (c && - k->source_type == c->key.source_type && - k->target_type == c->key.target_type && - k->target_class == c->key.target_class) { - c->datum.data |= d->data; - return 0; - } - - /* Insert the rule */ - n = malloc(sizeof(struct avtab_node)); - if (!n) { - fprintf(stderr, "out of memory\n"); - exit(1); - } - - n->key = *k; - n->datum = *d; - n->next = p->next; - p->next = n; - return 0; -} - -static int create_type_rules_helper(avtab_key_t * k, avtab_datum_t * d, - void *args) -{ - struct avtab_node *type_rules = args; - avtab_key_t key; - - /* - * Insert the rule into the list for - * the source type. The source type value - * is cleared as we want to compare against other type - * rules with different source types. - */ - key = *k; - key.source_type = 0; - if (k->source_type == k->target_type) { - /* Clear target type as well; this is a self rule. */ - key.target_type = 0; - } - if (insert_type_rule(&key, d, &type_rules[k->source_type - 1])) - return -1; - - if (k->source_type == k->target_type) - return 0; - - /* - * If the target type differs, then we also - * insert the rule into the list for the target - * type. We clear the target type value so that - * we can compare against other type rules with - * different target types. - */ - key = *k; - key.target_type = 0; - if (insert_type_rule(&key, d, &type_rules[k->target_type - 1])) - return -1; - - return 0; -} - -static int create_type_rules(avtab_key_t * k, avtab_datum_t * d, void *args) -{ - if (k->specified & AVTAB_ALLOWED) - return create_type_rules_helper(k, d, args); - return 0; -} - -static int create_type_rules_cond(avtab_key_t * k, avtab_datum_t * d, - void *args) -{ - if ((k->specified & (AVTAB_ALLOWED|AVTAB_ENABLED)) == - (AVTAB_ALLOWED|AVTAB_ENABLED)) - return create_type_rules_helper(k, d, args); - return 0; -} - -static void free_type_rules(struct avtab_node *l) -{ - struct avtab_node *tmp; - - while (l) { - tmp = l; - l = l->next; - free(tmp); - } -} - -static int find_match(policydb_t *policydb, struct avtab_node *l1, - int idx1, struct avtab_node *l2, int idx2) -{ - struct avtab_node *c; - uint32_t perms1, perms2; - - for (c = l2; c; c = c->next) { - if (l1->key.source_type < c->key.source_type) - break; - if (l1->key.source_type == c->key.source_type && - l1->key.target_type < c->key.target_type) - break; - if (l1->key.source_type == c->key.source_type && - l1->key.target_type == c->key.target_type && - l1->key.target_class <= c->key.target_class) - break; - } - - if (c && - l1->key.source_type == c->key.source_type && - l1->key.target_type == c->key.target_type && - l1->key.target_class == c->key.target_class) { - perms1 = l1->datum.data & ~c->datum.data; - perms2 = c->datum.data & ~l1->datum.data; - if (perms1 || perms2) { - if (perms1) - display_allow(policydb, &l1->key, idx1, perms1); - if (perms2) - display_allow(policydb, &c->key, idx2, perms2); - printf("\n"); - return 1; - } - } - - return 0; -} - -static int analyze_types(policydb_t * policydb, char diff, char equiv) -{ - avtab_t exp_avtab, exp_cond_avtab; - struct avtab_node *type_rules, *l1, *l2; - struct type_datum *type; - size_t i, j; - - /* - * Create a list of access vector rules for each type - * from the access vector table. - */ - type_rules = malloc(sizeof(struct avtab_node) * policydb->p_types.nprim); - if (!type_rules) { - fprintf(stderr, "out of memory\n"); - exit(1); - } - memset(type_rules, 0, sizeof(struct avtab_node) * policydb->p_types.nprim); - - if (avtab_init(&exp_avtab) || avtab_init(&exp_cond_avtab)) { - fputs("out of memory\n", stderr); - return -1; - } - - if (expand_avtab(policydb, &policydb->te_avtab, &exp_avtab)) { - fputs("out of memory\n", stderr); - avtab_destroy(&exp_avtab); - return -1; - } - - if (expand_avtab(policydb, &policydb->te_cond_avtab, &exp_cond_avtab)) { - fputs("out of memory\n", stderr); - avtab_destroy(&exp_avtab); /* */ - return -1; - } - - if (avtab_map(&exp_avtab, create_type_rules, type_rules)) - exit(1); - - if (avtab_map(&exp_cond_avtab, create_type_rules_cond, type_rules)) - exit(1); - - avtab_destroy(&exp_avtab); - avtab_destroy(&exp_cond_avtab); - - /* - * Compare the type lists and identify similar types. - */ - for (i = 0; i < policydb->p_types.nprim - 1; i++) { - if (!type_rules[i].next) - continue; - type = policydb->type_val_to_struct[i]; - if (type->flavor) { - free_type_rules(type_rules[i].next); - type_rules[i].next = NULL; - continue; - } - for (j = i + 1; j < policydb->p_types.nprim; j++) { - type = policydb->type_val_to_struct[j]; - if (type->flavor) { - free_type_rules(type_rules[j].next); - type_rules[j].next = NULL; - continue; - } - for (l1 = type_rules[i].next, l2 = type_rules[j].next; - l1 && l2; l1 = l1->next, l2 = l2->next) { - if (l1->key.source_type != l2->key.source_type) - break; - if (l1->key.target_type != l2->key.target_type) - break; - if (l1->key.target_class != l2->key.target_class - || l1->datum.data != l2->datum.data) - break; - } - if (l1 || l2) { - if (diff) { - printf - ("Types %s and %s differ, starting with:\n", - policydb->p_type_val_to_name[i], - policydb->p_type_val_to_name[j]); - - if (l1 && l2) { - if (find_match(policydb, l1, i, l2, j)) - continue; - if (find_match(policydb, l2, j, l1, i)) - continue; - } - if (l1) - display_allow(policydb, &l1->key, i, l1->datum.data); - if (l2) - display_allow(policydb, &l2->key, j, l2->datum.data); - printf("\n"); - } - continue; - } - free_type_rules(type_rules[j].next); - type_rules[j].next = NULL; - if (equiv) { - printf("Types %s and %s are equivalent.\n", - policydb->p_type_val_to_name[i], - policydb->p_type_val_to_name[j]); - } - } - free_type_rules(type_rules[i].next); - type_rules[i].next = NULL; - } - - free(type_rules); - return 0; -} - -int typecmp_func (int argc, char **argv, policydb_t *policydb) { - char ch, diff = 0, equiv = 0; - - struct option typecmp_options[] = { - {"diff", no_argument, NULL, 'd'}, - {"equiv", no_argument, NULL, 'e'}, - {NULL, 0, NULL, 0} - }; - - while ((ch = getopt_long(argc, argv, "de", typecmp_options, NULL)) != -1) { - switch (ch) { - case 'd': - diff = 1; - break; - case 'e': - equiv = 1; - break; - default: - USAGE_ERROR = true; - return -1; - } - } - - if (!(diff || equiv)) { - USAGE_ERROR = true; - return -1; - } - return analyze_types(policydb, diff, equiv); -} |