Skip to content

libsepol,checkpolicy: introduce unconfined as a first class concept t… #472

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions checkpolicy/policy_define.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,49 @@ int define_permissive(void)
return rc;
}

int define_unconfined(void)
{
char *type = NULL;
struct type_datum *t;
int rc = 0;

type = queue_remove(id_queue);

if (!type) {
yyerror2("forgot to include type in unconfined definition?");
rc = -1;
goto out;
}

if (pass == 1)
goto out;

if (!is_id_in_scope(SYM_TYPES, type)) {
yyerror2("type %s is not within scope", type);
rc = -1;
goto out;
}

t = hashtab_search(policydbp->p_types.table, type);
if (!t) {
yyerror2("type is not defined: %s", type);
rc = -1;
goto out;
}

if (t->flavor == TYPE_ATTRIB) {
yyerror2("attributes may not be unconfined: %s", type);
rc = -1;
goto out;
}

t->flags |= TYPE_FLAGS_UNCONFINED;

out:
free(type);
return rc;
}

int define_polcap(void)
{
char *id = 0;
Expand Down
1 change: 1 addition & 0 deletions checkpolicy/policy_define.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ int define_ipv6_cidr_node_context(void);
int define_level(void);
int define_netif_context(void);
int define_permissive(void);
int define_unconfined(void);
int define_polcap(void);
int define_ibpkey_context(unsigned int low, unsigned int high);
int define_ibendport_context(unsigned int port);
Expand Down
4 changes: 4 additions & 0 deletions checkpolicy/policy_parse.y
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ typedef int (* require_func_t)(int pass);
%token MODULE VERSION_IDENTIFIER REQUIRE OPTIONAL
%token POLICYCAP
%token PERMISSIVE
%token UNCONFINED
%token FILESYSTEM
%token DEFAULT_USER DEFAULT_ROLE DEFAULT_TYPE DEFAULT_RANGE
%token LOW_HIGH LOW HIGH GLBLUB
Expand Down Expand Up @@ -330,6 +331,7 @@ te_decl : attribute_def
| range_trans_def
| te_avtab_def
| permissive_def
| unconfined_def
;
attribute_def : ATTRIBUTE identifier ';'
{ if (define_attrib()) YYABORT;}
Expand Down Expand Up @@ -934,6 +936,8 @@ policycap_def : POLICYCAP identifier ';'
;
permissive_def : PERMISSIVE identifier ';'
{if (define_permissive()) YYABORT;}
unconfined_def : UNCONFINED identifier ';'
{if (define_unconfined()) YYABORT;}

/*********** module grammar below ***********/

Expand Down
2 changes: 2 additions & 0 deletions checkpolicy/policy_scan.l
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,8 @@ policycap |
POLICYCAP { return(POLICYCAP); }
permissive |
PERMISSIVE { return(PERMISSIVE); }
unconfined |
UNCONFINED { return(UNCONFINED); }
default_user |
DEFAULT_USER { return(DEFAULT_USER); }
default_role |
Expand Down
15 changes: 15 additions & 0 deletions libsepol/cil/src/cil.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ char *CIL_KEY_TYPEALIAS;
char *CIL_KEY_TYPEALIASACTUAL;
char *CIL_KEY_TYPEBOUNDS;
char *CIL_KEY_TYPEPERMISSIVE;
char *CIL_KEY_TYPEUNCONFINED;
char *CIL_KEY_RANGETRANSITION;
char *CIL_KEY_USERROLE;
char *CIL_KEY_ROLETYPE;
Expand Down Expand Up @@ -320,6 +321,7 @@ static void cil_init_keys(void)
CIL_KEY_TYPEALIASACTUAL = cil_strpool_add("typealiasactual");
CIL_KEY_TYPEBOUNDS = cil_strpool_add("typebounds");
CIL_KEY_TYPEPERMISSIVE = cil_strpool_add("typepermissive");
CIL_KEY_TYPEUNCONFINED = cil_strpool_add("typeunconfined");
CIL_KEY_RANGETRANSITION = cil_strpool_add("rangetransition");
CIL_KEY_USERROLE = cil_strpool_add("userrole");
CIL_KEY_ROLETYPE = cil_strpool_add("roletype");
Expand Down Expand Up @@ -939,6 +941,9 @@ void cil_destroy_data(void **data, enum cil_flavor flavor)
case CIL_TYPEPERMISSIVE:
cil_destroy_typepermissive(*data);
break;
case CIL_TYPEUNCONFINED:
cil_destroy_typeunconfined(*data);
break;
case CIL_SENS:
cil_destroy_sensitivity(*data);
break;
Expand Down Expand Up @@ -1310,6 +1315,8 @@ const char * cil_node_to_string(struct cil_tree_node *node)
return CIL_KEY_TYPEBOUNDS;
case CIL_TYPEPERMISSIVE:
return CIL_KEY_TYPEPERMISSIVE;
case CIL_TYPEUNCONFINED:
return CIL_KEY_TYPEUNCONFINED;
case CIL_SENS:
return CIL_KEY_SENSITIVITY;
case CIL_SENSALIAS:
Expand Down Expand Up @@ -2451,6 +2458,14 @@ void cil_typepermissive_init(struct cil_typepermissive **typeperm)
(*typeperm)->type = NULL;
}

void cil_typeunconfined_init(struct cil_typeunconfined **typeperm)
{
*typeperm = cil_malloc(sizeof(**typeperm));

(*typeperm)->type_str = NULL;
(*typeperm)->type = NULL;
}

void cil_nametypetransition_init(struct cil_nametypetransition **nametypetrans)
{
*nametypetrans = cil_malloc(sizeof(**nametypetrans));
Expand Down
24 changes: 24 additions & 0 deletions libsepol/cil/src/cil_binary.c
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,27 @@ int cil_typepermissive_to_policydb(policydb_t *pdb, struct cil_typepermissive *c

}

int cil_typeunconfined_to_policydb(policydb_t *pdb, struct cil_typeunconfined *cil_typeperm)
{
int rc = SEPOL_ERR;
type_datum_t *sepol_type = NULL;

rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_typeperm->type), &sepol_type);
if (rc != SEPOL_OK) goto exit;

if (ebitmap_set_bit(&pdb->unconfined_map, sepol_type->s.value, 1)) {
goto exit;
}

return SEPOL_OK;

exit:
type_datum_destroy(sepol_type);
free(sepol_type);
return rc;

}

int cil_typeattribute_to_policydb(policydb_t *pdb, struct cil_typeattribute *cil_attr, void *type_value_to_cil[])
{
int rc = SEPOL_ERR;
Expand Down Expand Up @@ -4101,6 +4122,9 @@ static int __cil_node_to_policydb(struct cil_tree_node *node, void *extra_args)
case CIL_TYPEPERMISSIVE:
rc = cil_typepermissive_to_policydb(pdb, node->data);
break;
case CIL_TYPEUNCONFINED:
rc = cil_typeunconfined_to_policydb(pdb, node->data);
break;
case CIL_TYPEATTRIBUTE:
rc = cil_typeattribute_to_bitmap(pdb, db, node->data);
break;
Expand Down
12 changes: 12 additions & 0 deletions libsepol/cil/src/cil_binary.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,18 @@ int cil_typealias_to_policydb(policydb_t *pdb, struct cil_alias *cil_alias);
*/
int cil_typepermissive_to_policydb(policydb_t *pdb, struct cil_typepermissive *cil_typeperm);

/**
* Insert cil typeunconfined structure into sepol policydb.
* The function looks up the previously inserted type and flips the bit
* in the unconfined types bitmap that corresponds to that type's value.
*
* @param[in] pdb The policy database to insert the typeunconfined into.
* @param[in] datum The cil_typeunconfined datum.
*
* @return SEPOL_OK upon success or an error otherwise.
*/
int cil_typeunconfined_to_policydb(policydb_t *pdb, struct cil_typeunconfined *cil_typeperm);

/**
* Insert cil attribute structure into sepol policydb.
*
Expand Down
46 changes: 46 additions & 0 deletions libsepol/cil/src/cil_build_ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -3374,6 +3374,50 @@ void cil_destroy_typepermissive(struct cil_typepermissive *typeperm)
free(typeperm);
}

int cil_gen_typeunconfined(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node)
{
enum cil_syntax syntax[] = {
CIL_SYN_STRING,
CIL_SYN_STRING,
CIL_SYN_END
};
size_t syntax_len = sizeof(syntax)/sizeof(*syntax);
struct cil_typeunconfined *typeperm = NULL;
int rc = SEPOL_ERR;

if (db == NULL || parse_current == NULL || ast_node == NULL) {
goto exit;
}

rc = __cil_verify_syntax(parse_current, syntax, syntax_len);
if (rc != SEPOL_OK) {
goto exit;
}

cil_typeunconfined_init(&typeperm);

typeperm->type_str = parse_current->next->data;

ast_node->data = typeperm;
ast_node->flavor = CIL_TYPEUNCONFINED;

return SEPOL_OK;

exit:
cil_tree_log(parse_current, CIL_ERR, "Bad typeunconfined declaration");
cil_destroy_typeunconfined(typeperm);
return rc;
}

void cil_destroy_typeunconfined(struct cil_typeunconfined *typeperm)
{
if (typeperm == NULL) {
return;
}

free(typeperm);
}

int cil_gen_typetransition(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node)
{
int rc = SEPOL_ERR;
Expand Down Expand Up @@ -6255,6 +6299,8 @@ static struct cil_tree_node * parse_statement(struct cil_db *db, struct cil_tree
rc = cil_gen_bounds(db, parse_current, new_ast_node, CIL_TYPE);
} else if (parse_current->data == CIL_KEY_TYPEPERMISSIVE) {
rc = cil_gen_typepermissive(db, parse_current, new_ast_node);
} else if (parse_current->data == CIL_KEY_TYPEUNCONFINED) {
rc = cil_gen_typeunconfined(db, parse_current, new_ast_node);
} else if (parse_current->data == CIL_KEY_RANGETRANSITION) {
rc = cil_gen_rangetransition(db, parse_current, new_ast_node);
} else if (parse_current->data == CIL_KEY_ROLE) {
Expand Down
2 changes: 2 additions & 0 deletions libsepol/cil/src/cil_build_ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,9 @@ int cil_gen_expandtypeattribute(struct cil_db *db, struct cil_tree_node *parse_c
void cil_destroy_expandtypeattribute(struct cil_expandtypeattribute *expandattr);
int cil_gen_typebounds(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
int cil_gen_typepermissive(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
int cil_gen_typeunconfined(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
void cil_destroy_typepermissive(struct cil_typepermissive *typeperm);
void cil_destroy_typeunconfined(struct cil_typeunconfined *typeperm);
int cil_gen_typetransition(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
void cil_destroy_typetransition(struct cil_nametypetransition *nametypetrans);
int cil_gen_rangetransition(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
Expand Down
17 changes: 17 additions & 0 deletions libsepol/cil/src/cil_copy_ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,20 @@ int cil_copy_typepermissive(__attribute__((unused)) struct cil_db *db, void *dat
return SEPOL_OK;
}

int cil_copy_typeunconfined(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
{
struct cil_typeunconfined *orig = data;
struct cil_typeunconfined *new = NULL;

cil_typeunconfined_init(&new);

new->type_str = orig->type_str;

*copy = new;

return SEPOL_OK;
}

int cil_copy_typeattribute(__attribute__((unused)) struct cil_db *db, __attribute__((unused)) void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
{
struct cil_typeattribute *new;
Expand Down Expand Up @@ -1807,6 +1821,9 @@ static int __cil_copy_node_helper(struct cil_tree_node *orig, uint32_t *finished
case CIL_TYPEPERMISSIVE:
copy_func = cil_copy_typepermissive;
break;
case CIL_TYPEUNCONFINED:
copy_func = cil_copy_typeunconfined;
break;
case CIL_TYPEATTRIBUTE:
copy_func = &cil_copy_typeattribute;
break;
Expand Down
1 change: 1 addition & 0 deletions libsepol/cil/src/cil_copy_ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ int cil_copy_roleallow(struct cil_db *db, void *data, void **copy, symtab_t *sym
int cil_copy_type(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
int cil_copy_typebounds(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
int cil_copy_typepermissive(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
int cil_copy_typeunconfined(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
int cil_copy_typeattribute(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
int cil_copy_typeattributeset(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
int cil_copy_typealias(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
Expand Down
1 change: 1 addition & 0 deletions libsepol/cil/src/cil_flavor.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ enum cil_flavor {
CIL_TYPEALIASACTUAL,
CIL_TYPEBOUNDS,
CIL_TYPEPERMISSIVE,
CIL_TYPEUNCONFINED,
CIL_SENSALIASACTUAL,
CIL_SENSITIVITYORDER,
CIL_SENSCAT,
Expand Down
7 changes: 7 additions & 0 deletions libsepol/cil/src/cil_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ extern char *CIL_KEY_TYPEALIAS;
extern char *CIL_KEY_TYPEALIASACTUAL;
extern char *CIL_KEY_TYPEBOUNDS;
extern char *CIL_KEY_TYPEPERMISSIVE;
extern char *CIL_KEY_TYPEUNCONFINED;
extern char *CIL_KEY_RANGETRANSITION;
extern char *CIL_KEY_USERROLE;
extern char *CIL_KEY_ROLETYPE;
Expand Down Expand Up @@ -580,6 +581,11 @@ struct cil_typepermissive {
void *type; /* type or alias */
};

struct cil_typeunconfined {
char *type_str;
void *type; /* type or alias */
};

struct cil_nametypetransition {
char *src_str;
void *src; /* type, alias, or attribute */
Expand Down Expand Up @@ -1045,6 +1051,7 @@ void cil_expandtypeattribute_init(struct cil_expandtypeattribute **expandattr);
void cil_alias_init(struct cil_alias **alias);
void cil_aliasactual_init(struct cil_aliasactual **aliasactual);
void cil_typepermissive_init(struct cil_typepermissive **typeperm);
void cil_typeunconfined_init(struct cil_typeunconfined **typeperm);
void cil_nametypetransition_init(struct cil_nametypetransition **nametypetrans);
void cil_rangetransition_init(struct cil_rangetransition **rangetrans);
void cil_bool_init(struct cil_bool **cilbool);
Expand Down
14 changes: 14 additions & 0 deletions libsepol/cil/src/cil_policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -1297,6 +1297,11 @@ static void cil_typepermissive_to_policy(FILE *out, struct cil_typepermissive *r
fprintf(out, "permissive %s;\n", DATUM(rule->type)->fqn);
}

static void cil_typeunconfined_to_policy(FILE *out, struct cil_typeunconfined *rule)
{
fprintf(out, "unconfined %s;\n", DATUM(rule->type)->fqn);
}

struct block_te_rules_extra {
FILE *out;
enum cil_flavor flavor;
Expand Down Expand Up @@ -1359,6 +1364,11 @@ static int __cil_block_te_rules_to_policy_helper(struct cil_tree_node *node, uin
cil_typepermissive_to_policy(args->out, node->data);
}
break;
case CIL_TYPEUNCONFINED:
if (args->flavor == node->flavor) {
cil_typeunconfined_to_policy(args->out, node->data);
}
break;
default:
break;
}
Expand All @@ -1376,6 +1386,10 @@ static void cil_block_te_rules_to_policy(FILE *out, struct cil_tree_node *start,
args.rule_kind = 0;
cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args);

args.flavor = CIL_TYPEUNCONFINED;
args.rule_kind = 0;
cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args);

args.flavor = CIL_AVRULE;
args.rule_kind = CIL_AVRULE_ALLOWED;
cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args);
Expand Down
Loading
Loading