├── Makefile ├── README.txt ├── libs ├── x86 │ └── libsepol.a └── x86_64 │ └── libsepol.a └── sepolicy-inject.c /Makefile: -------------------------------------------------------------------------------- 1 | LBITS := $(shell getconf LONG_BIT) 2 | ifeq ($(LBITS),64) 3 | LIBDIR ?= libs/x86_64 4 | else 5 | LIBDIR ?= libs/x86 6 | endif 7 | 8 | CFLAGS ?= -g -Wall -Werror -Wshadow -O2 -pipe -std=gnu11 9 | LDLIBS=$(LIBDIR)/libsepol.a 10 | 11 | all: sepolicy-inject 12 | 13 | sepolicy-inject: sepolicy-inject.c 14 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | Injects allow rules into binary SELinux kernel policies 2 | 3 | Injecting a rule: 4 | $ ./sepolicy-inject -s shell -t system -c file -p read -P sepolicy 5 | 6 | Injecting multiple permissions: 7 | $ ./sepolicy-inject -s shell -t system -c file -p read,write,open -P sepolicy 8 | 9 | Add a type_attribute to a domain: 10 | $ ./sepolicy-inject -s su -a mlstrustedsubject -P sepolicy 11 | 12 | Injecting a permissive domain: 13 | $ ./sepolicy-inject -Z shell -P sepolicy 14 | 15 | Change a permissive domain to non-permissive: 16 | $ ./sepolicy-inject -z shell -P sepolicy 17 | 18 | Test a SELinux type exists: 19 | $ ./sepolicy-inject -e -s shell -P sepolicy 20 | 21 | Test a SELinux class exists: 22 | $ ./sepolicy-inject -e -c service_manager -P sepolicy 23 | 24 | Add a transition: 25 | $ ./sepolicy-inject -s su_daemon -f device -c file -t su_device -P sepolicy 26 | 27 | Add a filename transition: 28 | $ ./sepolicy-inject -s su_daemon -f device -c file -g "socket" -t su_device -P sepolicy 29 | -------------------------------------------------------------------------------- /libs/x86/libsepol.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phhusson/sepolicy-inject/76a26a4ac7a033d5ebed6f2a3c92c036b3c0002c/libs/x86/libsepol.a -------------------------------------------------------------------------------- /libs/x86_64/libsepol.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phhusson/sepolicy-inject/76a26a4ac7a033d5ebed6f2a3c92c036b3c0002c/libs/x86_64/libsepol.a -------------------------------------------------------------------------------- /sepolicy-inject.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This was derived from public domain works with updates to 3 | * work with more modern SELinux libraries. 4 | * 5 | * It is released into the public domain. 6 | * 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | void usage(char *arg0) { 27 | fprintf(stderr, "%s -s -t -c -p -P \n", arg0); 28 | fprintf(stderr, "\tInject a rule\n\n"); 29 | fprintf(stderr, "%s -s -a -P \n", arg0); 30 | fprintf(stderr, "\tAdd a type_attribute to a domain\n\n"); 31 | fprintf(stderr, "%s -Z -P \n", arg0); 32 | fprintf(stderr, "\tInject a permissive domain\n\n"); 33 | fprintf(stderr, "%s -z -P \n", arg0); 34 | fprintf(stderr, "\tInject a non-permissive domain\n\n"); 35 | fprintf(stderr, "%s -e -s -P \n", arg0); 36 | fprintf(stderr, "\tCheck if a SELinux type exists\n\n"); 37 | fprintf(stderr, "%s -e -c -P \n", arg0); 38 | fprintf(stderr, "\tCheck if a SELinux class exists\n\n"); 39 | fprintf(stderr, "All options can add -o to output to another file\n"); 40 | exit(1); 41 | } 42 | 43 | void *cmalloc(size_t s) { 44 | void *t = malloc(s); 45 | if (t == NULL) { 46 | fprintf(stderr, "Out of memory\n"); 47 | exit(1); 48 | } 49 | return t; 50 | } 51 | 52 | int get_attr(char *type, int value, policydb_t *policy) { 53 | type_datum_t *attr = hashtab_search(policy->p_types.table, type); 54 | if (!attr) 55 | exit(1); 56 | 57 | if (attr->flavor != TYPE_ATTRIB) 58 | exit(1); 59 | 60 | return !! ebitmap_get_bit(&policy->attr_type_map[attr->s.value-1], value-1); 61 | //return !! ebitmap_get_bit(&policy->type_attr_map[value-1], attr->s.value-1); 62 | } 63 | 64 | int get_attr_id(char *type, policydb_t *policy) { 65 | type_datum_t *attr = hashtab_search(policy->p_types.table, type); 66 | if (!attr) 67 | exit(1); 68 | 69 | if (attr->flavor != TYPE_ATTRIB) 70 | exit(1); 71 | 72 | return attr->s.value; 73 | } 74 | 75 | int set_attr(char *type, int value, policydb_t *policy) { 76 | type_datum_t *attr = hashtab_search(policy->p_types.table, type); 77 | if (!attr) 78 | exit(1); 79 | 80 | if (attr->flavor != TYPE_ATTRIB) 81 | exit(1); 82 | 83 | if(ebitmap_set_bit(&policy->type_attr_map[value-1], attr->s.value-1, 1)) 84 | exit(1); 85 | if(ebitmap_set_bit(&policy->attr_type_map[attr->s.value-1], value-1, 1)) 86 | exit(1); 87 | 88 | return 0; 89 | } 90 | 91 | void create_domain(char *d, policydb_t *policy) { 92 | symtab_datum_t *src = hashtab_search(policy->p_types.table, d); 93 | if(src) 94 | return; 95 | 96 | type_datum_t *typdatum = (type_datum_t *) malloc(sizeof(type_datum_t)); 97 | type_datum_init(typdatum); 98 | typdatum->primary = 1; 99 | typdatum->flavor = TYPE_TYPE; 100 | 101 | uint32_t value = 0; 102 | int r = symtab_insert(policy, SYM_TYPES, strdup(d), typdatum, SCOPE_DECL, 1, &value); 103 | typdatum->s.value = value; 104 | 105 | fprintf(stderr, "source type %s does not exist: %d,%d\n", d, r, value); 106 | if (ebitmap_set_bit(&policy->global->branch_list->declared.scope[SYM_TYPES], value - 1, 1)) { 107 | exit(1); 108 | } 109 | 110 | policy->type_attr_map = realloc(policy->type_attr_map, sizeof(ebitmap_t)*policy->p_types.nprim); 111 | policy->attr_type_map = realloc(policy->attr_type_map, sizeof(ebitmap_t)*policy->p_types.nprim); 112 | ebitmap_init(&policy->type_attr_map[value-1]); 113 | ebitmap_init(&policy->attr_type_map[value-1]); 114 | ebitmap_set_bit(&policy->type_attr_map[value-1], value-1, 1); 115 | 116 | //Add the domain to all roles 117 | for(unsigned i=0; ip_roles.nprim; ++i) { 118 | //Not sure all those three calls are needed 119 | ebitmap_set_bit(&policy->role_val_to_struct[i]->types.negset, value-1, 0); 120 | ebitmap_set_bit(&policy->role_val_to_struct[i]->types.types, value-1, 1); 121 | type_set_expand(&policy->role_val_to_struct[i]->types, &policy->role_val_to_struct[i]->cache, policy, 0); 122 | } 123 | 124 | 125 | src = hashtab_search(policy->p_types.table, d); 126 | if(!src) 127 | exit(1); 128 | 129 | extern int policydb_index_decls(policydb_t * p); 130 | if(policydb_index_decls(policy)) 131 | exit(1); 132 | 133 | if(policydb_index_classes(policy)) 134 | exit(1); 135 | 136 | if(policydb_index_others(NULL, policy, 1)) 137 | exit(1); 138 | 139 | set_attr("domain", value, policy); 140 | } 141 | 142 | int add_irule(int s, int t, int c, int p, int effect, int not, policydb_t* policy) { 143 | avtab_datum_t *av; 144 | avtab_key_t key; 145 | 146 | key.source_type = s; 147 | key.target_type = t; 148 | key.target_class = c; 149 | key.specified = effect; 150 | av = avtab_search(&policy->te_avtab, &key); 151 | 152 | if (av == NULL) { 153 | av = cmalloc(sizeof(*av)); 154 | av->data |= 1U << (p - 1); 155 | int ret = avtab_insert(&policy->te_avtab, &key, av); 156 | if (ret) { 157 | fprintf(stderr, "Error inserting into avtab\n"); 158 | return 1; 159 | } 160 | } 161 | 162 | if(not) 163 | av->data &= ~(1U << (p - 1)); 164 | else 165 | av->data |= 1U << (p - 1); 166 | return 0; 167 | } 168 | 169 | int add_rule(char *s, char *t, char *c, char *p, int effect, int not, policydb_t *policy) { 170 | type_datum_t *src, *tgt; 171 | class_datum_t *cls; 172 | perm_datum_t *perm; 173 | 174 | src = hashtab_search(policy->p_types.table, s); 175 | if (src == NULL) { 176 | fprintf(stderr, "source type %s does not exist\n", s); 177 | return 1; 178 | } 179 | tgt = hashtab_search(policy->p_types.table, t); 180 | if (tgt == NULL) { 181 | fprintf(stderr, "target type %s does not exist\n", t); 182 | return 1; 183 | } 184 | cls = hashtab_search(policy->p_classes.table, c); 185 | if (cls == NULL) { 186 | fprintf(stderr, "class %s does not exist\n", c); 187 | return 1; 188 | } 189 | perm = hashtab_search(cls->permissions.table, p); 190 | if (perm == NULL) { 191 | if (cls->comdatum == NULL) { 192 | fprintf(stderr, "perm %s does not exist in class %s\n", p, c); 193 | return 1; 194 | } 195 | perm = hashtab_search(cls->comdatum->permissions.table, p); 196 | if (perm == NULL) { 197 | fprintf(stderr, "perm %s does not exist in class %s\n", p, c); 198 | return 1; 199 | } 200 | } 201 | 202 | return add_irule(src->s.value, tgt->s.value, cls->s.value, perm->s.value, effect, not, policy); 203 | } 204 | 205 | int add_typerule(char *s, char *targetAttribute, char **minusses, char *c, char *p, int effect, int not, policydb_t *policy) { 206 | type_datum_t *src, *tgt; 207 | class_datum_t *cls; 208 | perm_datum_t *perm; 209 | 210 | //64(0kB) should be enough for everyone, right? 211 | int m[64] = { -1 }; 212 | 213 | src = hashtab_search(policy->p_types.table, s); 214 | if (src == NULL) { 215 | fprintf(stderr, "source type %s does not exist\n", s); 216 | return 1; 217 | } 218 | 219 | tgt = hashtab_search(policy->p_types.table, targetAttribute); 220 | if (tgt == NULL) { 221 | fprintf(stderr, "target type %s does not exist\n", targetAttribute); 222 | return 1; 223 | } 224 | if(tgt->flavor != TYPE_ATTRIB) 225 | exit(1); 226 | 227 | for(int i=0; minusses && minusses[i]; ++i) { 228 | type_datum_t *obj; 229 | obj = hashtab_search(policy->p_types.table, minusses[i]); 230 | if (obj == NULL) { 231 | fprintf(stderr, "minus type %s does not exist\n", minusses[i]); 232 | return 1; 233 | } 234 | m[i] = obj->s.value-1; 235 | m[i+1] = -1; 236 | } 237 | 238 | cls = hashtab_search(policy->p_classes.table, c); 239 | if (cls == NULL) { 240 | fprintf(stderr, "class %s does not exist\n", c); 241 | return 1; 242 | } 243 | 244 | perm = hashtab_search(cls->permissions.table, p); 245 | if (perm == NULL) { 246 | if (cls->comdatum == NULL) { 247 | fprintf(stderr, "perm %s does not exist in class %s\n", p, c); 248 | return 1; 249 | } 250 | perm = hashtab_search(cls->comdatum->permissions.table, p); 251 | if (perm == NULL) { 252 | fprintf(stderr, "perm %s does not exist in class %s\n", p, c); 253 | return 1; 254 | } 255 | } 256 | 257 | ebitmap_node_t *node; 258 | int i; 259 | 260 | int ret = 0; 261 | 262 | ebitmap_for_each_bit(&policy->attr_type_map[tgt->s.value-1], node, i) { 263 | if(ebitmap_node_get_bit(node, i)) { 264 | int found = 0; 265 | for(int j=0; m[j] != -1; ++j) { 266 | if(i == m[j]) 267 | found = 1; 268 | } 269 | 270 | if(!found) 271 | ret |= add_irule(src->s.value, i+1, cls->s.value, perm->s.value, effect, not, policy); 272 | } 273 | } 274 | return ret; 275 | } 276 | 277 | int add_transition(char *srcS, char *origS, char *tgtS, char *c, policydb_t *policy) { 278 | type_datum_t *src, *tgt, *orig; 279 | class_datum_t *cls; 280 | 281 | avtab_datum_t *av; 282 | avtab_key_t key; 283 | 284 | src = hashtab_search(policy->p_types.table, srcS); 285 | if (src == NULL) { 286 | fprintf(stderr, "source type %s does not exist\n", srcS); 287 | return 1; 288 | } 289 | tgt = hashtab_search(policy->p_types.table, tgtS); 290 | if (tgt == NULL) { 291 | fprintf(stderr, "target type %s does not exist\n", tgtS); 292 | return 1; 293 | } 294 | cls = hashtab_search(policy->p_classes.table, c); 295 | if (cls == NULL) { 296 | fprintf(stderr, "class %s does not exist\n", c); 297 | return 1; 298 | } 299 | orig = hashtab_search(policy->p_types.table, origS); 300 | if (cls == NULL) { 301 | fprintf(stderr, "class %s does not exist\n", origS); 302 | return 1; 303 | } 304 | 305 | key.source_type = src->s.value; 306 | key.target_type = orig->s.value; 307 | key.target_class = cls->s.value; 308 | key.specified = AVTAB_TRANSITION; 309 | av = avtab_search(&policy->te_avtab, &key); 310 | 311 | if (av == NULL) { 312 | av = cmalloc(sizeof(*av)); 313 | av->data = tgt->s.value; 314 | int ret = avtab_insert(&policy->te_avtab, &key, av); 315 | if (ret) { 316 | fprintf(stderr, "Error inserting into avtab\n"); 317 | return 1; 318 | } 319 | } else { 320 | fprintf(stderr, "Warning, rule already defined! Won't override.\n"); 321 | fprintf(stderr, "Previous value = %d, wanted value = %d\n", av->data, tgt->s.value); 322 | } 323 | 324 | return 0; 325 | } 326 | 327 | int add_file_transition(char *srcS, char *origS, char *tgtS, char *c, char* filename, policydb_t *policy) { 328 | type_datum_t *src, *tgt, *orig; 329 | class_datum_t *cls; 330 | 331 | src = hashtab_search(policy->p_types.table, srcS); 332 | if (src == NULL) { 333 | fprintf(stderr, "source type %s does not exist\n", srcS); 334 | return 1; 335 | } 336 | tgt = hashtab_search(policy->p_types.table, tgtS); 337 | if (tgt == NULL) { 338 | fprintf(stderr, "target type %s does not exist\n", tgtS); 339 | return 1; 340 | } 341 | cls = hashtab_search(policy->p_classes.table, c); 342 | if (cls == NULL) { 343 | fprintf(stderr, "class %s does not exist\n", c); 344 | return 1; 345 | } 346 | orig = hashtab_search(policy->p_types.table, origS); 347 | if (cls == NULL) { 348 | fprintf(stderr, "class %s does not exist\n", origS); 349 | return 1; 350 | } 351 | 352 | filename_trans_t *new_transition = cmalloc(sizeof(*new_transition)); 353 | new_transition->stype = src->s.value; 354 | new_transition->ttype = orig->s.value; 355 | new_transition->tclass = cls->s.value; 356 | new_transition->otype = tgt->s.value; 357 | new_transition->name = strdup(filename); 358 | new_transition->next = policy->filename_trans; 359 | 360 | policy->filename_trans = new_transition; 361 | 362 | return 0; 363 | } 364 | 365 | int add_type(char *domainS, char *typeS, policydb_t *policy) { 366 | type_datum_t *domain; 367 | 368 | domain = hashtab_search(policy->p_types.table, domainS); 369 | if (domain == NULL) { 370 | fprintf(stderr, "source type %s does not exist\n", domainS); 371 | return 1; 372 | } 373 | 374 | set_attr(typeS, domain->s.value, policy); 375 | 376 | int typeId = get_attr_id(typeS, policy); 377 | //Now let's update all constraints! 378 | //(kernel doesn't support (yet?) type_names rules) 379 | for(int i=0; ip_classes.nprim; ++i) { 380 | class_datum_t *cl = policy->class_val_to_struct[i]; 381 | for(constraint_node_t *n = cl->constraints; n ; n=n->next) { 382 | for(constraint_expr_t *e = n->expr; e; e=e->next) { 383 | if(e->expr_type == CEXPR_NAMES) { 384 | if(ebitmap_get_bit(&e->type_names->types, typeId-1)) { 385 | ebitmap_set_bit(&e->names, domain->s.value-1, 1); 386 | } 387 | } 388 | } 389 | } 390 | } 391 | return 0; 392 | } 393 | 394 | int load_policy(char *filename, policydb_t *policydb, struct policy_file *pf) { 395 | int fd; 396 | struct stat sb; 397 | void *map; 398 | int ret; 399 | 400 | fd = open(filename, O_RDONLY); 401 | if (fd < 0) { 402 | fprintf(stderr, "Can't open '%s': %s\n", 403 | filename, strerror(errno)); 404 | return 1; 405 | } 406 | if (fstat(fd, &sb) < 0) { 407 | fprintf(stderr, "Can't stat '%s': %s\n", 408 | filename, strerror(errno)); 409 | return 1; 410 | } 411 | map = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, 412 | fd, 0); 413 | if (map == MAP_FAILED) { 414 | fprintf(stderr, "Can't mmap '%s': %s\n", 415 | filename, strerror(errno)); 416 | return 1; 417 | } 418 | 419 | policy_file_init(pf); 420 | pf->type = PF_USE_MEMORY; 421 | pf->data = map; 422 | pf->len = sb.st_size; 423 | if (policydb_init(policydb)) { 424 | fprintf(stderr, "policydb_init: Out of memory!\n"); 425 | return 1; 426 | } 427 | ret = policydb_read(policydb, pf, 1); 428 | if (ret) { 429 | fprintf(stderr, "error(s) encountered while parsing configuration\n"); 430 | return 1; 431 | } 432 | 433 | return 0; 434 | } 435 | 436 | int auto_allow(type_datum_t *src, type_datum_t *tgt, class_datum_t *cls, policydb_t *policy) { 437 | perm_datum_t *perm; 438 | hashtab_t type_table, class_table, perm_table; 439 | hashtab_ptr_t cur; 440 | 441 | type_table = policy->p_types.table; 442 | class_table = policy->p_classes.table; 443 | 444 | if (src == NULL) { 445 | for (int i = 0; i < type_table->size; ++i) { 446 | cur = type_table->htable[i]; 447 | while (cur != NULL) { 448 | src = cur->datum; 449 | if(auto_allow(src, tgt, cls, policy)) 450 | return 1; 451 | cur = cur->next; 452 | } 453 | } 454 | } else if (tgt == NULL) { 455 | for (int i = 0; i < type_table->size; ++i) { 456 | cur = type_table->htable[i]; 457 | while (cur != NULL) { 458 | tgt = cur->datum; 459 | if(auto_allow(src, tgt, cls, policy)) 460 | return 1; 461 | cur = cur->next; 462 | } 463 | } 464 | } else if (cls == NULL) { 465 | for (int i = 0; i < class_table->size; ++i) { 466 | cur = class_table->htable[i]; 467 | while (cur != NULL) { 468 | cls = cur->datum; 469 | if(auto_allow(src, tgt, cls, policy)) 470 | return 1; 471 | cur = cur->next; 472 | } 473 | } 474 | } else { 475 | perm_table = cls->permissions.table; 476 | for (int i = 0; i < perm_table->size; ++i) { 477 | cur = perm_table->htable[i]; 478 | while (cur != NULL) { 479 | perm = cur->datum; 480 | if(add_irule(src->s.value, tgt->s.value, cls->s.value, perm->s.value, AVTAB_ALLOWED, 0, policy)) 481 | return 1; 482 | cur = cur->next; 483 | } 484 | } 485 | 486 | if (cls->comdatum != NULL) { 487 | perm_table = cls->comdatum->permissions.table; 488 | for (int i = 0; i < perm_table->size; ++i) { 489 | cur = perm_table->htable[i]; 490 | while (cur != NULL) { 491 | perm = cur->datum; 492 | if(add_irule(src->s.value, tgt->s.value, cls->s.value, perm->s.value, AVTAB_ALLOWED, 0, policy)) 493 | return 1; 494 | cur = cur->next; 495 | } 496 | } 497 | } 498 | } 499 | return 0; 500 | } 501 | 502 | int main(int argc, char **argv) 503 | { 504 | char *policy = NULL, *source = NULL, *target = NULL, *class = NULL, *perm = NULL; 505 | char *fcon = NULL, *outfile = NULL, *permissive = NULL, *attr = NULL, *filetrans = NULL; 506 | int exists = 0, not = 0, autoAllow = 0; 507 | policydb_t policydb; 508 | struct policy_file pf, outpf; 509 | sidtab_t sidtab; 510 | int ch; 511 | FILE *fp; 512 | int permissive_value = 0, noaudit = 0; 513 | 514 | struct option long_options[] = { 515 | {"attr", required_argument, NULL, 'a'}, 516 | {"exists", no_argument, NULL, 'e'}, 517 | {"source", required_argument, NULL, 's'}, 518 | {"target", required_argument, NULL, 't'}, 519 | {"class", required_argument, NULL, 'c'}, 520 | {"perm", required_argument, NULL, 'p'}, 521 | {"fcon", required_argument, NULL, 'f'}, 522 | {"filetransition", required_argument, NULL, 'g'}, 523 | {"noaudit", no_argument, NULL, 'n'}, 524 | {"policy", required_argument, NULL, 'P'}, 525 | {"output", required_argument, NULL, 'o'}, 526 | {"permissive", required_argument, NULL, 'Z'}, 527 | {"not-permissive", required_argument, NULL, 'z'}, 528 | {"not", no_argument, NULL, 0}, 529 | {"auto", no_argument, NULL, 0}, 530 | {NULL, 0, NULL, 0} 531 | }; 532 | 533 | int option_index = -1; 534 | while ((ch = getopt_long(argc, argv, "a:c:ef:g:s:t:p:P:o:Z:z:n", long_options, &option_index)) != -1) { 535 | switch (ch) { 536 | case 0: 537 | if(strcmp(long_options[option_index].name, "not") == 0) 538 | not = 1; 539 | else if(strcmp(long_options[option_index].name, "auto") == 0) 540 | autoAllow = 1; 541 | else 542 | usage(argv[0]); 543 | break; 544 | case 'a': 545 | attr = optarg; 546 | break; 547 | case 'e': 548 | exists = 1; 549 | break; 550 | case 'f': 551 | fcon = optarg; 552 | break; 553 | case 'g': 554 | filetrans = optarg; 555 | break; 556 | case 's': 557 | source = optarg; 558 | break; 559 | case 't': 560 | target = optarg; 561 | break; 562 | case 'c': 563 | class = optarg; 564 | break; 565 | case 'p': 566 | perm = optarg; 567 | break; 568 | case 'P': 569 | policy = optarg; 570 | break; 571 | case 'o': 572 | outfile = optarg; 573 | break; 574 | case 'Z': 575 | permissive = optarg; 576 | permissive_value = 1; 577 | break; 578 | case 'z': 579 | permissive = optarg; 580 | permissive_value = 0; 581 | break; 582 | case 'n': 583 | noaudit = 1; 584 | break; 585 | default: 586 | usage(argv[0]); 587 | } 588 | } 589 | 590 | if (((!source || !target || !class || !perm) && !permissive && !fcon && !attr &&!filetrans && !exists && !autoAllow) || !policy) 591 | usage(argv[0]); 592 | 593 | if(!outfile) 594 | outfile = policy; 595 | 596 | sepol_set_policydb(&policydb); 597 | sepol_set_sidtab(&sidtab); 598 | 599 | if (load_policy(policy, &policydb, &pf)) { 600 | fprintf(stderr, "Could not load policy\n"); 601 | return 1; 602 | } 603 | 604 | if (policydb_load_isids(&policydb, &sidtab)) 605 | return 1; 606 | 607 | if (autoAllow) { 608 | type_datum_t *src = NULL, *tgt = NULL; 609 | class_datum_t *cls = NULL; 610 | if (source) 611 | src = hashtab_search(policydb.p_types.table, source); 612 | if (target) 613 | tgt = hashtab_search(policydb.p_types.table, target); 614 | if (class) 615 | cls = hashtab_search(policydb.p_classes.table, class); 616 | if (auto_allow(src, tgt, cls, &policydb)) 617 | return 1; 618 | } else if (permissive) { 619 | type_datum_t *type; 620 | create_domain(permissive, &policydb); 621 | type = hashtab_search(policydb.p_types.table, permissive); 622 | if (type == NULL) { 623 | fprintf(stderr, "type %s does not exist\n", permissive); 624 | return 1; 625 | } 626 | if (ebitmap_set_bit(&policydb.permissive_map, type->s.value, permissive_value)) { 627 | fprintf(stderr, "Could not set bit in permissive map\n"); 628 | return 1; 629 | } 630 | } else if(exists) { 631 | if(source) { 632 | type_datum_t *tmp = hashtab_search(policydb.p_types.table, source); 633 | if (!tmp) 634 | exit(1); 635 | else 636 | exit(0); 637 | } else if(class) { 638 | class_datum_t *tmp = hashtab_search(policydb.p_classes.table, class); 639 | if(!tmp) 640 | exit(1); 641 | else 642 | exit(0); 643 | } else { 644 | usage(argv[0]); 645 | } 646 | } else if(filetrans) { 647 | if(add_file_transition(source, fcon, target, class, filetrans, &policydb)) 648 | return 1; 649 | } else if(fcon) { 650 | if(add_transition(source, fcon, target, class, &policydb)) 651 | return 1; 652 | } else if(attr) { 653 | if(add_type(source, attr, &policydb)) 654 | return 1; 655 | } else if(noaudit) { 656 | if(add_rule(source, target, class, perm, AVTAB_AUDITDENY, not, &policydb)) 657 | return 1; 658 | } else { 659 | //Add a rule to a whole set of typeattribute, not just a type 660 | if(*target == '=') { 661 | char *saveptr = NULL; 662 | 663 | char *targetAttribute = strtok_r(target, "-", &saveptr); 664 | 665 | char *vals[64]; 666 | int i = 0; 667 | 668 | char *m = NULL; 669 | while( (m = strtok_r(NULL, "-", &saveptr)) != NULL) { 670 | vals[i++] = m; 671 | } 672 | vals[i] = NULL; 673 | 674 | if(add_typerule(source, targetAttribute+1, vals, class, perm, AVTAB_ALLOWED, not, &policydb)) 675 | return 1; 676 | } else { 677 | char *saveptr = NULL; 678 | 679 | char *p = strtok_r(perm, ",", &saveptr); 680 | do { 681 | if (add_rule(source, target, class, p, AVTAB_ALLOWED, not, &policydb)) { 682 | fprintf(stderr, "Could not add rule\n"); 683 | return 1; 684 | } 685 | } while( (p = strtok_r(NULL, ",", &saveptr)) != NULL); 686 | } 687 | } 688 | 689 | fp = fopen(outfile, "w"); 690 | if (!fp) { 691 | fprintf(stderr, "Could not open outfile\n"); 692 | return 1; 693 | } 694 | 695 | policy_file_init(&outpf); 696 | outpf.type = PF_USE_STDIO; 697 | outpf.fp = fp; 698 | 699 | if (policydb_write(&policydb, &outpf)) { 700 | fprintf(stderr, "Could not write policy\n"); 701 | return 1; 702 | } 703 | 704 | policydb_destroy(&policydb); 705 | fclose(fp); 706 | 707 | return 0; 708 | } 709 | --------------------------------------------------------------------------------