1/* Authors: Frank Mayer <mayerf@tresys.com> 2 * and Karl MacMillan <kmacmillan@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 36struct val_to_name { 37 unsigned int val; 38 char *name; 39}; 40 41static 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 56int 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 88static 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 104struct callback_data 105{ 106 uint32_t attr; 107 policydb_t *policy; 108 FILE *fp; 109}; 110 111int 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 128static 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 145static 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 189void usage(char *progname) 190{ 191 printf("usage: %s policy_file out_file\n", progname); 192} 193 194int 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