/* Attempt to require a symbol within the current scope. If currently * within an optional (and not its else branch), add the symbol to the * required list. Return 0 on success, 1 if caller needs to free() * datum. If symbols may not be declared here return -1. For duplicate * declarations return -2. For all else, including out of memory, * return -3.. Note that dest_value and datum_value might not be * restricted pointers. */ int require_symbol(uint32_t symbol_type, hashtab_key_t key, hashtab_datum_t datum, uint32_t * dest_value, uint32_t * datum_value) { avrule_decl_t *decl = stack_top->decl; int retval; /* first check that symbols may be required here */ if (!is_require_allowed()) { return -1; } retval = symtab_insert(policydbp, symbol_type, key, datum, SCOPE_REQ, decl->decl_id, dest_value); if (retval == 1) { symtab_datum_t *s = (symtab_datum_t *) hashtab_search(policydbp->symtab[symbol_type].table, key); assert(s != NULL); if (symbol_type == SYM_LEVELS) { *dest_value = ((level_datum_t *) s)->level->sens; } else { *dest_value = s->value; } } else if (retval == -2) { /* ignore require statements if that symbol was * previously declared and is in current scope */ int prev_declaration_ok = 0; if (is_id_in_scope(symbol_type, key)) { if (symbol_type == SYM_TYPES) { /* check that previous symbol has same * type/attribute-ness */ unsigned char new_isattr = ((type_datum_t *) datum)->flavor; type_datum_t *old_datum = (type_datum_t *) hashtab_search(policydbp->symtab[SYM_TYPES].table, key); assert(old_datum != NULL); unsigned char old_isattr = old_datum->flavor; prev_declaration_ok = (old_isattr == new_isattr ? 1 : 0); } else { prev_declaration_ok = 1; } } if (prev_declaration_ok) { /* ignore this require statement because it * was already declared within my scope */ stack_top->require_given = 1; return 1; } else { /* previous declaration was not in scope or * had a mismatched type/attribute, so * generate an error */ return -2; } } else if (retval < 0) { return -3; } else { /* fall through possible if retval is 0 or 1 */ } if (datum_value != NULL) { if (ebitmap_set_bit(decl->required.scope + symbol_type, *datum_value - 1, 1)) { return -3; } } stack_top->require_given = 1; return retval; }
int add_perm_to_class(uint32_t perm_value, uint32_t class_value) { avrule_decl_t *decl = stack_top->decl; scope_index_t *scope; assert(perm_value >= 1); assert(class_value >= 1); scope = &decl->required; if (class_value > scope->class_perms_len) { int i; ebitmap_t *new_map = realloc(scope->class_perms_map, class_value * sizeof(*new_map)); if (new_map == NULL) { return -1; } scope->class_perms_map = new_map; for (i = scope->class_perms_len; i < class_value; i++) { ebitmap_init(scope->class_perms_map + i); } scope->class_perms_len = class_value; } if (ebitmap_set_bit(scope->class_perms_map + class_value - 1, perm_value - 1, 1)) { return -1; } return 0; }
/* Attempt to declare a symbol within the current declaration. If * currently within a non-conditional and in a non-else branch then * insert the symbol, return 0 on success if symbol was undeclared. * For roles and users, it is legal to have multiple declarations; as * such return 1 to indicate that caller must free() the datum because * it was not added. If symbols may not be declared here return -1. * For duplicate declarations return -2. For all else, including out * of memory, return -3. Note that dest_value and datum_value might * not be restricted pointers. */ int declare_symbol(uint32_t symbol_type, hashtab_key_t key, hashtab_datum_t datum, uint32_t * dest_value, uint32_t * datum_value) { avrule_decl_t *decl = stack_top->decl; int retval; /* first check that symbols may be declared here */ if (!is_declaration_allowed()) { return -1; } retval = symtab_insert(policydbp, symbol_type, key, datum, SCOPE_DECL, decl->decl_id, dest_value); if (retval == 1 && dest_value) { symtab_datum_t *s = (symtab_datum_t *) hashtab_search(policydbp->symtab[symbol_type].table, key); assert(s != NULL); if (symbol_type == SYM_LEVELS) { *dest_value = ((level_datum_t *) s)->level->sens; } else { *dest_value = s->value; } } else if (retval == -2) { return -2; } else if (retval < 0) { return -3; } else { /* fall through possible if retval is 0 */ } if (datum_value != NULL) { if (ebitmap_set_bit(decl->declared.scope + symbol_type, *datum_value - 1, 1)) { return -3; } } return retval; }
bool selinux_make_permissive(policydb_t *pdb, const std::string &type_str) { type_datum_t *type; type = (type_datum_t *) hashtab_search( pdb->p_types.table, (hashtab_key_t) type_str.c_str()); if (!type) { LOGV("Type %s not found in policy", type_str.c_str()); return false; } if (ebitmap_get_bit(&pdb->permissive_map, type->s.value)) { LOGV("Type %s is already permissive", type_str.c_str()); return true; } if (ebitmap_set_bit(&pdb->permissive_map, type->s.value, 1) < 0) { LOGE("Failed to set bit for type %s in the permissive map", type_str.c_str()); return false; } LOGD("Type %s is now permissive", type_str.c_str()); return true; }
void selinux_make_all_permissive(policydb_t *pdb) { //char *name; for (unsigned int i = 0; i < pdb->p_types.nprim - 1; i++) { //name = pdb->p_type_val_to_name[i]; //if (ebitmap_get_bit(&pdb->permissive_map, i + 1)) { // LOGD("Type %s is already permissive", name); //} else { ebitmap_set_bit(&pdb->permissive_map, i + 1, 1); // LOGD("Made %s permissive", name); //} } }
static bool ebitmap_attribute_assertion_init(ebitmap_t *assertions, const char * const attributes[]) { while (*attributes) { int bit_pos = get_attr_bit(global_state.sepolicy.pdb, *attributes); if (bit_pos < 0) { /* get_attr_bit() logs error */ return false; } int err = ebitmap_set_bit(assertions, bit_pos, 1); if (err) { fprintf(stderr, "Error: setting bit on assertion ebitmap!\n"); return false; } attributes++; } return true; }
/* * Convert the MLS fields in the security context * structure `c' from the values specified in the * policy `oldp' to the values specified in the policy `newp'. */ int mls_convert_context(struct policydb *oldp, struct policydb *newp, struct context *c) { struct level_datum *levdatum; struct cat_datum *catdatum; struct ebitmap bitmap; int l, i; for (l = 0; l < 2; l++) { levdatum = hashtab_search(newp->p_levels.table, oldp->p_sens_val_to_name[c->range.level[l].sens - 1]); if (!levdatum) return -EINVAL; c->range.level[l].sens = levdatum->level->sens; ebitmap_init(&bitmap); for (i = 1; i <= ebitmap_length(&c->range.level[l].cat); i++) { if (ebitmap_get_bit(&c->range.level[l].cat, i - 1)) { int rc; catdatum = hashtab_search(newp->p_cats.table, oldp->p_cat_val_to_name[i - 1]); if (!catdatum) return -EINVAL; rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1); if (rc) return rc; } } ebitmap_destroy(&c->range.level[l].cat); c->range.level[l].cat = bitmap; } return 0; }
role_datum_t *declare_role(void) { char *id = queue_remove(id_queue), *dest_id = NULL; role_datum_t *role = NULL, *dest_role = NULL; int retval; uint32_t value; if (id == NULL) { yyerror("no role name"); return NULL; } if ((role = (role_datum_t *) malloc(sizeof(*role))) == NULL) { yyerror("Out of memory!"); free(id); return NULL; } role_datum_init(role); retval = declare_symbol(SYM_ROLES, id, (hashtab_datum_t *) role, &value, &value); if (retval == 0) { role->s.value = value; if ((dest_id = strdup(id)) == NULL) { yyerror("Out of memory!"); return NULL; } } else { /* this role was already declared in this module, or error */ dest_id = id; role_datum_destroy(role); free(role); } if (retval == 0 || retval == 1) { /* create a new role_datum_t for this decl, if necessary */ hashtab_t roles_tab; assert(stack_top->type == 1); if (stack_top->parent == NULL) { /* in parent, so use global symbol table */ roles_tab = policydbp->p_roles.table; } else { roles_tab = stack_top->decl->p_roles.table; } dest_role = (role_datum_t *) hashtab_search(roles_tab, dest_id); if (dest_role == NULL) { if ((dest_role = (role_datum_t *) malloc(sizeof(*dest_role))) == NULL) { yyerror("Out of memory!"); free(dest_id); return NULL; } role_datum_init(dest_role); dest_role->s.value = value; if (role_implicit_bounds(roles_tab, dest_id, dest_role)) { free(dest_id); role_datum_destroy(dest_role); free(dest_role); return NULL; } if (hashtab_insert(roles_tab, dest_id, dest_role)) { yyerror("Out of memory!"); free(dest_id); role_datum_destroy(dest_role); free(dest_role); return NULL; } } else { free(dest_id); } } else { free(dest_id); } switch (retval) { case -3:{ yyerror("Out of memory!"); return NULL; } case -2:{ yyerror("duplicate declaration of role"); return NULL; } case -1:{ yyerror("could not declare role here"); return NULL; } case 0:{ if (ebitmap_set_bit(&dest_role->dominates, role->s.value - 1, 1)) { yyerror("out of memory"); return NULL; } return dest_role; } case 1:{ return dest_role; /* role already declared for this block */ } default:{ assert(0); /* should never get here */ } } }
int main_seinject(int argc, char **argv) { char *policy = NULL, *source = NULL, *target = NULL, *clazz = NULL, *perm = NULL, *perm_token = NULL, *perm_saveptr = NULL, *outfile = NULL, *permissive = NULL; policydb_t policydb; struct policy_file pf, outpf; sidtab_t sidtab; int ret_add_rule; int load = 0; int quiet = 0; FILE *fp; int i; for (i=1; i<argc; i++) { if (argv[i][0] == '-') { if (argv[i][1] == 's') { i++; source = argv[i]; continue; } if (argv[i][1] == 't') { i++; target = argv[i]; continue; } if (argv[i][1] == 'c') { i++; clazz = argv[i]; continue; } if (argv[i][1] == 'p') { i++; perm = argv[i]; continue; } if (argv[i][1] == 'P') { i++; policy = argv[i]; continue; } if (argv[i][1] == 'o') { i++; outfile = argv[i]; continue; } if (argv[i][1] == 'Z') { i++; permissive = argv[i]; continue; } if (argv[i][1] == 'l') { load = 1; continue; } if (argv[i][1] == 'q') { quiet = 1; continue; } break; } } if (i < argc || argc == 1 || ((!source || !target || !clazz || !perm) && !permissive)) { fprintf(stderr, "%s -s <source type> -t <target type> -c <class> -p <perm>[,<perm2>,<perm3>,...] [-P <policy file>] [-o <output file>] [-l|--load]\n", argv[0]); fprintf(stderr, "%s -Z permissive_type [-P <policy file>] [-o <output file>] [-l|--load]\n", argv[0]); exit(1); } if (!policy) policy = "/sys/fs/selinux/policy"; sepol_set_policydb(&policydb); sepol_set_sidtab(&sidtab); if (load_policy(policy, &policydb, &pf)) { fprintf(stderr, "Could not load policy\n"); return 1; } if (policydb_load_isids(&policydb, &sidtab)) return 1; if (permissive) { type_datum_t *type; type = hashtab_search(policydb.p_types.table, permissive); if (type == NULL) { fprintf(stderr, "type %s does not exist\n", permissive); return 2; } if (ebitmap_set_bit(&policydb.permissive_map, type->s.value, 1)) { fprintf(stderr, "Could not set bit in permissive map\n"); return 1; } } else { perm_token = strtok_r(perm, ",", &perm_saveptr); while (perm_token) { ret_add_rule = add_rule(source, target, clazz, perm_token, &policydb); if (ret_add_rule) { fprintf(stderr, "Could not add rule for perm: %s\n", perm_token); return ret_add_rule; } perm_token = strtok_r(NULL, ",", &perm_saveptr); } } if (outfile) { fp = fopen(outfile, "wb"); if (!fp) { fprintf(stderr, "Could not open outfile\n"); return 1; } policy_file_init(&outpf); outpf.type = PF_USE_STDIO; outpf.fp = fp; if (policydb_write(&policydb, &outpf)) { fprintf(stderr, "Could not write policy\n"); return 1; } fclose(fp); } if (load) { if (load_policy_into_kernel(&policydb)) { fprintf(stderr, "Could not load new policy into kernel\n"); return 1; } } policydb_destroy(&policydb); if (quiet == 0) fprintf(stdout, "Success\n"); return 0; }
static void set_permissive(const hashtab_key_t domain, policydb_t *pdb) { type_datum_t *type = hashtab_search(pdb->p_types.table, domain); ebitmap_set_bit(&pdb->permissive_map, type->s.value, 1); }
/* * Set the MLS fields in the security context structure * `context' based on the string representation in * the string `*scontext'. Update `*scontext' to * point to the end of the string representation of * the MLS fields. * * This function modifies the string in place, inserting * NULL characters to terminate the MLS fields. */ int mls_context_to_sid(char oldc, char **scontext, struct context *context) { char delim; char *scontextp, *p; struct level_datum *levdatum; struct cat_datum *catdatum; int l, rc = -EINVAL; if (!oldc) { /* No MLS component to the security context. Try to use a default 'unclassified' value. */ levdatum = hashtab_search(policydb.p_levels.table, "unclassified"); if (!levdatum) goto out; context->range.level[0].sens = levdatum->level->sens; context->range.level[1].sens = context->range.level[0].sens; rc = 0; goto out; } /* Extract low sensitivity. */ scontextp = p = *scontext; while (*p && *p != ':' && *p != '-') p++; delim = *p; if (delim != 0) *p++ = 0; for (l = 0; l < 2; l++) { levdatum = hashtab_search(policydb.p_levels.table, scontextp); if (!levdatum) goto out; context->range.level[l].sens = levdatum->level->sens; if (delim == ':') { /* Extract low category set. */ while (1) { scontextp = p; while (*p && *p != ',' && *p != '-') p++; delim = *p; if (delim != 0) *p++ = 0; catdatum = hashtab_search(policydb.p_cats.table, scontextp); if (!catdatum) goto out; rc = ebitmap_set_bit(&context->range.level[l].cat, catdatum->value - 1, 1); if (rc) goto out; if (delim != ',') break; } } if (delim == '-') { /* Extract high sensitivity. */ scontextp = p; while (*p && *p != ':') p++; delim = *p; if (delim != 0) *p++ = 0; } else break; } if (l == 0) { context->range.level[1].sens = context->range.level[0].sens; rc = ebitmap_cpy(&context->range.level[1].cat, &context->range.level[0].cat); if (rc) goto out; } *scontext = ++p; rc = 0; out: return rc; }