13fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman#include <getopt.h> 23fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman#include <sepol/policydb/expand.h> 33fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 43fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman#include "typecmp.h" 53fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 63fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashmanvoid typecmp_usage() { 73fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman fprintf(stderr, "\ttypecmp [-d|--diff] [-e|--equiv]\n"); 83fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman} 93fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 103fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashmanstatic int insert_type_rule(avtab_key_t * k, avtab_datum_t * d, 113fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman struct avtab_node *type_rules) 123fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman{ 133fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman struct avtab_node *p, *c, *n; 143fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 153fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman for (p = type_rules, c = type_rules->next; c; p = c, c = c->next) { 163fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman /* 173fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman * Find the insertion point, keeping the list 183fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman * ordered by source type, then target type, then 193fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman * target class. 203fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman */ 213fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (k->source_type < c->key.source_type) 223fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman break; 233fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (k->source_type == c->key.source_type && 243fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman k->target_type < c->key.target_type) 253fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman break; 263fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (k->source_type == c->key.source_type && 273fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman k->target_type == c->key.target_type && 283fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman k->target_class <= c->key.target_class) 293fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman break; 303fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman } 313fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 323fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (c && 333fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman k->source_type == c->key.source_type && 343fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman k->target_type == c->key.target_type && 353fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman k->target_class == c->key.target_class) { 363fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman c->datum.data |= d->data; 373fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman return 0; 383fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman } 393fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 403fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman /* Insert the rule */ 413fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman n = malloc(sizeof(struct avtab_node)); 423fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (!n) { 433fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman fprintf(stderr, "out of memory\n"); 443fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman exit(1); 453fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman } 463fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 473fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman n->key = *k; 483fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman n->datum = *d; 493fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman n->next = p->next; 503fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman p->next = n; 513fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman return 0; 523fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman} 533fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 543fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashmanstatic int create_type_rules_helper(avtab_key_t * k, avtab_datum_t * d, 553fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman void *args) 563fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman{ 573fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman struct avtab_node *type_rules = args; 583fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman avtab_key_t key; 593fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 603fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman /* 613fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman * Insert the rule into the list for 623fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman * the source type. The source type value 633fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman * is cleared as we want to compare against other type 643fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman * rules with different source types. 653fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman */ 663fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman key = *k; 673fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman key.source_type = 0; 683fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (k->source_type == k->target_type) { 693fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman /* Clear target type as well; this is a self rule. */ 703fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman key.target_type = 0; 713fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman } 723fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (insert_type_rule(&key, d, &type_rules[k->source_type - 1])) 733fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman return -1; 743fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 753fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (k->source_type == k->target_type) 763fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman return 0; 773fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 783fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman /* 793fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman * If the target type differs, then we also 803fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman * insert the rule into the list for the target 813fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman * type. We clear the target type value so that 823fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman * we can compare against other type rules with 833fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman * different target types. 843fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman */ 853fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman key = *k; 863fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman key.target_type = 0; 873fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (insert_type_rule(&key, d, &type_rules[k->target_type - 1])) 883fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman return -1; 893fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 903fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman return 0; 913fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman} 923fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 933fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashmanstatic int create_type_rules(avtab_key_t * k, avtab_datum_t * d, void *args) 943fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman{ 953fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (k->specified & AVTAB_ALLOWED) 963fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman return create_type_rules_helper(k, d, args); 973fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman return 0; 983fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman} 993fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 1003fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashmanstatic int create_type_rules_cond(avtab_key_t * k, avtab_datum_t * d, 1013fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman void *args) 1023fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman{ 1033fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if ((k->specified & (AVTAB_ALLOWED|AVTAB_ENABLED)) == 1043fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman (AVTAB_ALLOWED|AVTAB_ENABLED)) 1053fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman return create_type_rules_helper(k, d, args); 1063fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman return 0; 1073fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman} 1083fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 1093fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashmanstatic void free_type_rules(struct avtab_node *l) 1103fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman{ 1113fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman struct avtab_node *tmp; 1123fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 1133fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman while (l) { 1143fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman tmp = l; 1153fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman l = l->next; 1163fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman free(tmp); 1173fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman } 1183fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman} 1193fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 1203fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashmanstatic int find_match(policydb_t *policydb, struct avtab_node *l1, 1213fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman int idx1, struct avtab_node *l2, int idx2) 1223fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman{ 1233fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman struct avtab_node *c; 1243fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman uint32_t perms1, perms2; 1253fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 1263fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman for (c = l2; c; c = c->next) { 1273fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (l1->key.source_type < c->key.source_type) 1283fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman break; 1293fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (l1->key.source_type == c->key.source_type && 1303fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman l1->key.target_type < c->key.target_type) 1313fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman break; 1323fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (l1->key.source_type == c->key.source_type && 1333fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman l1->key.target_type == c->key.target_type && 1343fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman l1->key.target_class <= c->key.target_class) 1353fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman break; 1363fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman } 1373fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 1383fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (c && 1393fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman l1->key.source_type == c->key.source_type && 1403fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman l1->key.target_type == c->key.target_type && 1413fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman l1->key.target_class == c->key.target_class) { 1423fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman perms1 = l1->datum.data & ~c->datum.data; 1433fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman perms2 = c->datum.data & ~l1->datum.data; 1443fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (perms1 || perms2) { 1453fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (perms1) 1463fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman display_allow(policydb, &l1->key, idx1, perms1); 1473fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (perms2) 1483fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman display_allow(policydb, &c->key, idx2, perms2); 1493fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman printf("\n"); 1503fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman return 1; 1513fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman } 1523fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman } 1533fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 1543fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman return 0; 1553fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman} 1563fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 1573fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashmanstatic int analyze_types(policydb_t * policydb, char diff, char equiv) 1583fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman{ 1593fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman avtab_t exp_avtab, exp_cond_avtab; 1603fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman struct avtab_node *type_rules, *l1, *l2; 1613fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman struct type_datum *type; 1623fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman size_t i, j; 1633fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 1643fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman /* 1653fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman * Create a list of access vector rules for each type 1663fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman * from the access vector table. 1673fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman */ 1683fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman type_rules = malloc(sizeof(struct avtab_node) * policydb->p_types.nprim); 1693fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (!type_rules) { 1703fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman fprintf(stderr, "out of memory\n"); 1713fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman exit(1); 1723fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman } 1733fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman memset(type_rules, 0, sizeof(struct avtab_node) * policydb->p_types.nprim); 1743fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 1753fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (avtab_init(&exp_avtab) || avtab_init(&exp_cond_avtab)) { 1763fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman fputs("out of memory\n", stderr); 1773fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman return -1; 1783fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman } 1793fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 1803fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (expand_avtab(policydb, &policydb->te_avtab, &exp_avtab)) { 1813fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman fputs("out of memory\n", stderr); 1823fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman avtab_destroy(&exp_avtab); 1833fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman return -1; 1843fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman } 1853fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 1863fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (expand_avtab(policydb, &policydb->te_cond_avtab, &exp_cond_avtab)) { 1873fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman fputs("out of memory\n", stderr); 1883fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman avtab_destroy(&exp_avtab); /* */ 1893fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman return -1; 1903fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman } 1913fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 1923fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (avtab_map(&exp_avtab, create_type_rules, type_rules)) 1933fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman exit(1); 1943fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 1953fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (avtab_map(&exp_cond_avtab, create_type_rules_cond, type_rules)) 1963fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman exit(1); 1973fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 1983fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman avtab_destroy(&exp_avtab); 1993fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman avtab_destroy(&exp_cond_avtab); 2003fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 2013fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman /* 2023fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman * Compare the type lists and identify similar types. 2033fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman */ 2043fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman for (i = 0; i < policydb->p_types.nprim - 1; i++) { 2053fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (!type_rules[i].next) 2063fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman continue; 2073fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman type = policydb->type_val_to_struct[i]; 2083fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (type->flavor) { 2093fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman free_type_rules(type_rules[i].next); 2103fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman type_rules[i].next = NULL; 2113fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman continue; 2123fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman } 2133fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman for (j = i + 1; j < policydb->p_types.nprim; j++) { 2143fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman type = policydb->type_val_to_struct[j]; 2153fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (type->flavor) { 2163fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman free_type_rules(type_rules[j].next); 2173fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman type_rules[j].next = NULL; 2183fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman continue; 2193fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman } 2203fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman for (l1 = type_rules[i].next, l2 = type_rules[j].next; 2213fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman l1 && l2; l1 = l1->next, l2 = l2->next) { 2223fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (l1->key.source_type != l2->key.source_type) 2233fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman break; 2243fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (l1->key.target_type != l2->key.target_type) 2253fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman break; 2263fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (l1->key.target_class != l2->key.target_class 2273fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman || l1->datum.data != l2->datum.data) 2283fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman break; 2293fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman } 2303fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (l1 || l2) { 2313fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (diff) { 2323fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman printf 2333fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman ("Types %s and %s differ, starting with:\n", 2343fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman policydb->p_type_val_to_name[i], 2353fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman policydb->p_type_val_to_name[j]); 2363fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 2373fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (l1 && l2) { 2383fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (find_match(policydb, l1, i, l2, j)) 2393fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman continue; 2403fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (find_match(policydb, l2, j, l1, i)) 2413fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman continue; 2423fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman } 2433fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (l1) 2443fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman display_allow(policydb, &l1->key, i, l1->datum.data); 2453fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (l2) 2463fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman display_allow(policydb, &l2->key, j, l2->datum.data); 2473fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman printf("\n"); 2483fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman } 2493fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman continue; 2503fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman } 2513fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman free_type_rules(type_rules[j].next); 2523fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman type_rules[j].next = NULL; 2533fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (equiv) { 2543fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman printf("Types %s and %s are equivalent.\n", 2553fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman policydb->p_type_val_to_name[i], 2563fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman policydb->p_type_val_to_name[j]); 2573fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman } 2583fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman } 2593fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman free_type_rules(type_rules[i].next); 2603fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman type_rules[i].next = NULL; 2613fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman } 2623fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 2633fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman free(type_rules); 2643fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman return 0; 2653fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman} 2663fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 2673fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashmanint typecmp_func (int argc, char **argv, policydb_t *policydb) { 2683fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman char ch, diff = 0, equiv = 0; 2693fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 2703fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman struct option typecmp_options[] = { 2713fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman {"diff", no_argument, NULL, 'd'}, 2723fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman {"equiv", no_argument, NULL, 'e'}, 2733fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman {NULL, 0, NULL, 0} 2743fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman }; 2753fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 2763fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman while ((ch = getopt_long(argc, argv, "de", typecmp_options, NULL)) != -1) { 2773fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman switch (ch) { 2783fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman case 'd': 2793fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman diff = 1; 2803fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman break; 2813fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman case 'e': 2823fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman equiv = 1; 2833fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman break; 2843fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman default: 2853fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman USAGE_ERROR = true; 2863fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman return -1; 2873fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman } 2883fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman } 2893fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman 2903fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman if (!(diff || equiv)) { 2913fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman USAGE_ERROR = true; 2923fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman return -1; 2933fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman } 2943fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman return analyze_types(policydb, diff, equiv); 2953fa92beda7ee062b15f6b214bdc7e5f6a71df28edcashman} 296