예제 #1
0
/* 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;
}
예제 #2
0
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;
}
예제 #3
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;
}
예제 #4
0
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;
}
예제 #5
0
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);
        //}
    }
}
예제 #6
0
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;
}
예제 #7
0
/*
 * 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;
}
예제 #8
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;
}
예제 #10
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);
}
예제 #11
0
/*
 * 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;
}