15a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris/* Authors: Frank Mayer <mayerf@tresys.com> 25a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris * and Karl MacMillan <kmacmillan@tresys.com> 35a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris * 45a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris * Copyright (C) 2003,2010 Tresys Technology, LLC 55a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris * 65a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris * This program is free software; you can redistribute it and/or 75a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris * modify it under the terms of the GNU General Public License as 85a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris * published by the Free Software Foundation, version 2. 95a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris * 105a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris * Adapted from dispol.c. 115a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris * 125a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris * This program is used by sepolgen-ifgen to get the access for all of 135a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris * the attributes in the policy so that it can resolve the 145a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris * typeattribute statements in the interfaces. 155a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris * 165a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris * It outputs the attribute access in a similar format to what sepolgen 175a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris * uses to store interface vectors: 185a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris * [Attribute sandbox_x_domain] 195a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris * sandbox_x_domain,samba_var_t,file,ioctl,read,getattr,lock,open 205a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris * sandbox_x_domain,samba_var_t,dir,getattr,search,open 215a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris * sandbox_x_domain,initrc_var_run_t,file,ioctl,read,getattr,lock,open 225a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris * 235a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris */ 245a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 255a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris#include <sepol/policydb/policydb.h> 265a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris#include <sepol/policydb/avtab.h> 275a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris#include <sepol/policydb/util.h> 285a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 295a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris#include <stdio.h> 305a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris#include <sys/types.h> 315a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris#include <sys/stat.h> 325a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris#include <fcntl.h> 335a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris#include <sys/mman.h> 345a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris#include <unistd.h> 355a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 365a2173519c4210e4b99b08bc08006dfb872442d2Eric Parisstruct val_to_name { 375a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris unsigned int val; 385a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris char *name; 395a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris}; 405a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 415a2173519c4210e4b99b08bc08006dfb872442d2Eric Parisstatic int perm_name(hashtab_key_t key, hashtab_datum_t datum, void *data) 425a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris{ 435a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris struct val_to_name *v = data; 445a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris perm_datum_t *perdatum; 455a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 465a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris perdatum = (perm_datum_t *) datum; 475a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 485a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris if (v->val == perdatum->s.value) { 495a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris v->name = key; 505a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris return 1; 515a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris } 525a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 535a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris return 0; 545a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris} 555a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 565a2173519c4210e4b99b08bc08006dfb872442d2Eric Parisint render_access_mask(uint32_t av, avtab_key_t *key, policydb_t *policydbp, 575a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris FILE *fp) 585a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris{ 595a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris struct val_to_name v; 605a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris class_datum_t *cladatum; 615a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris char *perm = NULL; 625a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris unsigned int i; 635a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris int rc; 645a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris uint32_t tclass = key->target_class; 655a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 665a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris cladatum = policydbp->class_val_to_struct[tclass - 1]; 675a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris for (i = 0; i < cladatum->permissions.nprim; i++) { 685a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris if (av & (1 << i)) { 695a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris v.val = i + 1; 705a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris rc = hashtab_map(cladatum->permissions.table, 715a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris perm_name, &v); 725a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris if (!rc && cladatum->comdatum) { 735a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris rc = hashtab_map(cladatum->comdatum-> 745a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris permissions.table, perm_name, 755a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris &v); 765a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris } 775a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris if (rc) 785a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris perm = v.name; 795a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris if (perm) { 805a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris fprintf(fp, ",%s", perm); 815a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris } 825a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris } 835a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris } 845a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 855a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris return 0; 865a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris} 875a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 885a2173519c4210e4b99b08bc08006dfb872442d2Eric Parisstatic int render_key(avtab_key_t *key, policydb_t *p, FILE *fp) 895a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris{ 905a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris char *stype, *ttype, *tclass; 915a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris stype = p->p_type_val_to_name[key->source_type - 1]; 925a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris ttype = p->p_type_val_to_name[key->target_type - 1]; 935a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris tclass = p->p_class_val_to_name[key->target_class - 1]; 945a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris if (stype && ttype) { 955a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris fprintf(fp, "%s,%s,%s", stype, ttype, tclass); 965a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris } else { 975a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris fprintf(stderr, "error rendering key\n"); 985a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris exit(1); 995a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris } 1005a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 1015a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris return 0; 1025a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris} 1035a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 1045a2173519c4210e4b99b08bc08006dfb872442d2Eric Parisstruct callback_data 1055a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris{ 1065a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris uint32_t attr; 1075a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris policydb_t *policy; 1085a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris FILE *fp; 1095a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris}; 1105a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 1115a2173519c4210e4b99b08bc08006dfb872442d2Eric Parisint output_avrule(avtab_key_t *key, avtab_datum_t *datum, void *args) 1125a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris{ 1135a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris struct callback_data *cb_data = (struct callback_data *)args; 1145a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 1155a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris if (key->source_type != cb_data->attr) 1165a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris return 0; 1175a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 1185a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris if (!(key->specified & AVTAB_AV && key->specified & AVTAB_ALLOWED)) 1195a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris return 0; 1205a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 1215a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris render_key(key, cb_data->policy, cb_data->fp); 1225a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris render_access_mask(datum->data, key, cb_data->policy, cb_data->fp); 1235a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris fprintf(cb_data->fp, "\n"); 1245a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 1255a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris return 0; 1265a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris} 1275a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 1285a2173519c4210e4b99b08bc08006dfb872442d2Eric Parisstatic int attribute_callback(hashtab_key_t key, hashtab_datum_t datum, void *datap) 1295a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris{ 1305a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris struct callback_data *cb_data = (struct callback_data *)datap; 1315a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris type_datum_t *t = (type_datum_t *)datum; 1325a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 1335a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris if (t->flavor == TYPE_ATTRIB) { 1345a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris fprintf(cb_data->fp, "[Attribute %s]\n", key); 1355a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris cb_data->attr = t->s.value; 1365a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris if (avtab_map(&cb_data->policy->te_avtab, output_avrule, cb_data) < 0) 1375a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris return -1; 1385a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris if (avtab_map(&cb_data->policy->te_cond_avtab, output_avrule, cb_data) < 0) 1395a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris return -1; 1405a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris } 1415a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 1425a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris return 0; 1435a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris} 1445a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 1455a2173519c4210e4b99b08bc08006dfb872442d2Eric Parisstatic policydb_t *load_policy(const char *filename) 1465a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris{ 1475a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris policydb_t *policydb; 1485a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris struct policy_file pf; 1495a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris FILE *fp; 1505a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris int ret; 1515a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 1525a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris fp = fopen(filename, "r"); 1535a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris if (fp == NULL) { 1545a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris fprintf(stderr, "Can't open '%s': %s\n", 1555a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris filename, strerror(errno)); 1565a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris return NULL; 1575a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris } 1585a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 1595a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris policy_file_init(&pf); 1605a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris pf.type = PF_USE_STDIO; 1615a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris pf.fp = fp; 1625a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 1635a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris policydb = malloc(sizeof(policydb_t)); 1645a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris if (policydb == NULL) { 1655a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris fprintf(stderr, "Out of memory!\n"); 1665a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris return NULL; 1675a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris } 1685a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 1695a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris if (policydb_init(policydb)) { 1705a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris fprintf(stderr, "Out of memory!\n"); 1715a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris free(policydb); 1725a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris return NULL; 1735a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris } 1745a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 1755a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris ret = policydb_read(policydb, &pf, 1); 1765a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris if (ret) { 1775a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris fprintf(stderr, 1785a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris "error(s) encountered while parsing configuration\n"); 1795a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris free(policydb); 1805a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris return NULL; 1815a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris } 1825a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 1835a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris fclose(fp); 1845a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 1855a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris return policydb; 1865a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 1875a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris} 1885a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 1895a2173519c4210e4b99b08bc08006dfb872442d2Eric Parisvoid usage(char *progname) 1905a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris{ 1915a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris printf("usage: %s policy_file out_file\n", progname); 1925a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris} 1935a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 1945a2173519c4210e4b99b08bc08006dfb872442d2Eric Parisint main(int argc, char **argv) 1955a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris{ 1965a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris policydb_t *p; 1975a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris struct callback_data cb_data; 1985a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris FILE *fp; 1995a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 2005a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris if (argc != 3) { 2015a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris usage(argv[0]); 2025a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris return -1; 2035a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris } 2045a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 2055a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris /* Open the policy. */ 2065a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris p = load_policy(argv[1]); 2075a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris if (p == NULL) 2085a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris return -1; 2095a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 2105a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris /* Open the output policy. */ 2115a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris fp = fopen(argv[2], "w"); 2125a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris if (fp == NULL) { 2135a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris fprintf(stderr, "error opening output file\n"); 2145a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris policydb_destroy(p); 2155a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris free(p); 2165a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris return -1; 2175a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris } 2185a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 2195a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris /* Find all of the attributes and output their access. */ 2205a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris cb_data.policy = p; 2215a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris cb_data.fp = fp; 2225a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 2235a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris if (hashtab_map(p->p_types.table, attribute_callback, &cb_data)) { 2245a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris printf("error finding attributes\n"); 2255a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris } 2265a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 2275a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris policydb_destroy(p); 2285a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris free(p); 2295a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris fclose(fp); 2305a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris 2315a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris return 0; 2325a2173519c4210e4b99b08bc08006dfb872442d2Eric Paris} 233