Home | History | Annotate | Download | only in audit2allow
      1 /* Authors: Frank Mayer <mayerf (at) tresys.com>
      2  *   and Karl MacMillan <kmacmillan (at) tresys.com>
      3  *
      4  * Copyright (C) 2003,2010 Tresys Technology, LLC
      5  *
      6  *	This program is free software; you can redistribute it and/or
      7  *  	modify it under the terms of the GNU General Public License as
      8  *  	published by the Free Software Foundation, version 2.
      9  *
     10  * Adapted from dispol.c.
     11  *
     12  * This program is used by sepolgen-ifgen to get the access for all of
     13  * the attributes in the policy so that it can resolve the
     14  * typeattribute statements in the interfaces.
     15  *
     16  * It outputs the attribute access in a similar format to what sepolgen
     17  * uses to store interface vectors:
     18  *   [Attribute sandbox_x_domain]
     19  *   sandbox_x_domain,samba_var_t,file,ioctl,read,getattr,lock,open
     20  *   sandbox_x_domain,samba_var_t,dir,getattr,search,open
     21  *   sandbox_x_domain,initrc_var_run_t,file,ioctl,read,getattr,lock,open
     22  *
     23  */
     24 
     25 #include <sepol/policydb/policydb.h>
     26 #include <sepol/policydb/avtab.h>
     27 #include <sepol/policydb/util.h>
     28 
     29 #include <stdio.h>
     30 #include <sys/types.h>
     31 #include <sys/stat.h>
     32 #include <fcntl.h>
     33 #include <sys/mman.h>
     34 #include <unistd.h>
     35 
     36 struct val_to_name {
     37 	unsigned int val;
     38 	char *name;
     39 };
     40 
     41 static int perm_name(hashtab_key_t key, hashtab_datum_t datum, void *data)
     42 {
     43 	struct val_to_name *v = data;
     44 	perm_datum_t *perdatum;
     45 
     46 	perdatum = (perm_datum_t *) datum;
     47 
     48 	if (v->val == perdatum->s.value) {
     49 		v->name = key;
     50 		return 1;
     51 	}
     52 
     53 	return 0;
     54 }
     55 
     56 int render_access_mask(uint32_t av, avtab_key_t *key, policydb_t *policydbp,
     57 		       FILE *fp)
     58 {
     59 	struct val_to_name v;
     60 	class_datum_t *cladatum;
     61 	char *perm = NULL;
     62 	unsigned int i;
     63 	int rc;
     64 	uint32_t tclass = key->target_class;
     65 
     66 	cladatum = policydbp->class_val_to_struct[tclass - 1];
     67 	for (i = 0; i < cladatum->permissions.nprim; i++) {
     68 		if (av & (1 << i)) {
     69 			v.val = i + 1;
     70 			rc = hashtab_map(cladatum->permissions.table,
     71 					 perm_name, &v);
     72 			if (!rc && cladatum->comdatum) {
     73 				rc = hashtab_map(cladatum->comdatum->
     74 						 permissions.table, perm_name,
     75 						 &v);
     76 			}
     77 			if (rc)
     78 				perm = v.name;
     79 			if (perm) {
     80 				fprintf(fp, ",%s", perm);
     81 			}
     82 		}
     83 	}
     84 
     85 	return 0;
     86 }
     87 
     88 static int render_key(avtab_key_t *key, policydb_t *p, FILE *fp)
     89 {
     90 	char *stype, *ttype, *tclass;
     91 	stype = p->p_type_val_to_name[key->source_type - 1];
     92 	ttype = p->p_type_val_to_name[key->target_type - 1];
     93 	tclass = p->p_class_val_to_name[key->target_class - 1];
     94 	if (stype && ttype) {
     95 		fprintf(fp, "%s,%s,%s", stype, ttype, tclass);
     96 	} else {
     97 		fprintf(stderr, "error rendering key\n");
     98 		exit(1);
     99 	}
    100 
    101 	return 0;
    102 }
    103 
    104 struct callback_data
    105 {
    106 	uint32_t attr;
    107 	policydb_t *policy;
    108 	FILE *fp;
    109 };
    110 
    111 int output_avrule(avtab_key_t *key, avtab_datum_t *datum, void *args)
    112 {
    113 	struct callback_data *cb_data = (struct callback_data *)args;
    114 
    115 	if (key->source_type != cb_data->attr)
    116 		return 0;
    117 
    118 	if (!(key->specified & AVTAB_AV && key->specified & AVTAB_ALLOWED))
    119 		return 0;
    120 
    121 	render_key(key, cb_data->policy, cb_data->fp);
    122 	render_access_mask(datum->data, key, cb_data->policy, cb_data->fp);
    123 	fprintf(cb_data->fp, "\n");
    124 
    125 	return 0;
    126 }
    127 
    128 static int attribute_callback(hashtab_key_t key, hashtab_datum_t datum, void *datap)
    129 {
    130 	struct callback_data *cb_data = (struct callback_data *)datap;
    131 	type_datum_t *t = (type_datum_t *)datum;
    132 
    133 	if (t->flavor == TYPE_ATTRIB) {
    134 		fprintf(cb_data->fp, "[Attribute %s]\n", key);
    135 		cb_data->attr = t->s.value;
    136 		if (avtab_map(&cb_data->policy->te_avtab, output_avrule, cb_data) < 0)
    137 			return -1;
    138 		if (avtab_map(&cb_data->policy->te_cond_avtab, output_avrule, cb_data) < 0)
    139 			return -1;
    140 	}
    141 
    142 	return 0;
    143 }
    144 
    145 static policydb_t *load_policy(const char *filename)
    146 {
    147 	policydb_t *policydb;
    148 	struct policy_file pf;
    149 	FILE *fp;
    150 	int ret;
    151 
    152 	fp = fopen(filename, "r");
    153 	if (fp == NULL) {
    154 		fprintf(stderr, "Can't open '%s':  %s\n",
    155 			filename, strerror(errno));
    156 		return NULL;
    157 	}
    158 
    159 	policy_file_init(&pf);
    160 	pf.type = PF_USE_STDIO;
    161 	pf.fp = fp;
    162 
    163 	policydb = malloc(sizeof(policydb_t));
    164 	if (policydb == NULL) {
    165 		fprintf(stderr, "Out of memory!\n");
    166 		return NULL;
    167 	}
    168 
    169 	if (policydb_init(policydb)) {
    170 		fprintf(stderr, "Out of memory!\n");
    171 		free(policydb);
    172 		return NULL;
    173 	}
    174 
    175 	ret = policydb_read(policydb, &pf, 1);
    176 	if (ret) {
    177 		fprintf(stderr,
    178 			"error(s) encountered while parsing configuration\n");
    179 		free(policydb);
    180 		return NULL;
    181 	}
    182 
    183 	fclose(fp);
    184 
    185 	return policydb;
    186 
    187 }
    188 
    189 void usage(char *progname)
    190 {
    191 	printf("usage: %s policy_file out_file\n", progname);
    192 }
    193 
    194 int main(int argc, char **argv)
    195 {
    196 	policydb_t *p;
    197 	struct callback_data cb_data;
    198 	FILE *fp;
    199 
    200 	if (argc != 3) {
    201 		usage(argv[0]);
    202 		return -1;
    203 	}
    204 
    205 	/* Open the policy. */
    206 	p = load_policy(argv[1]);
    207 	if (p == NULL)
    208 		return -1;
    209 
    210 	/* Open the output policy. */
    211 	fp = fopen(argv[2], "w");
    212 	if (fp == NULL) {
    213 		fprintf(stderr, "error opening output file\n");
    214 		policydb_destroy(p);
    215 		free(p);
    216 		return -1;
    217 	}
    218 
    219 	/* Find all of the attributes and output their access. */
    220 	cb_data.policy = p;
    221 	cb_data.fp = fp;
    222 
    223 	if (hashtab_map(p->p_types.table, attribute_callback, &cb_data)) {
    224 		printf("error finding attributes\n");
    225 	}
    226 
    227 	policydb_destroy(p);
    228 	free(p);
    229 	fclose(fp);
    230 
    231 	return 0;
    232 }
    233