checkpolicy,libsepol: move filename transition rules to avrule

Similarly to the previous patch, filename transition rules are stored
and parsed separately from other type enforcement rules. Moving them to
avrule makes it consistent with the filename transitions in avtab and
makes future improvements easier to implement.

This patch adds an optional object name attribute to the avrule
structure and uses this new attribute to move filename transition rules
to avrule. It also updates functions for parsing type enforcement rules
to accept rules with a filename as their last argument (filename
transition rules), separate functions for parsing filename transitions
are therefore no longer needed.

Reviewed-by: Ondrej Mosnacek <omosnace@redhat.com>
Signed-off-by: Juraj Marcin <juraj@jurajmarcin.com>
Acked-by: James Carter <jwcart2@gmail.com>
This commit is contained in:
Juraj Marcin 2023-06-20 11:01:18 +02:00 committed by James Carter
parent e169fe2653
commit 565d87489b
16 changed files with 154 additions and 580 deletions

View File

@ -615,15 +615,6 @@ int main(int argc, char **argv)
parse_policy.mls = mlspol;
parse_policy.handle_unknown = handle_unknown;
/*
* Init and alloc te_avtab for filename transition duplicate
* checking
*/
if (avtab_init(&parse_policy.te_avtab))
exit(1);
if (avtab_alloc(&parse_policy.te_avtab, 1 << 11))
exit(1);
policydbp = &parse_policy;
if (read_source_policy(policydbp, file, "checkpolicy") < 0)

View File

@ -1278,18 +1278,6 @@ void append_role_allow(role_allow_rule_t * role_allow_rules)
decl->role_allow_rules = role_allow_rules;
}
/* this doesn't actually append, but really prepends it */
void append_filename_trans(filename_trans_rule_t * filename_trans_rules)
{
avrule_decl_t *decl = stack_top->decl;
/* filename transitions are not allowed within conditionals */
assert(stack_top->type == 1);
filename_trans_rules->next = decl->filename_trans_rules;
decl->filename_trans_rules = filename_trans_rules;
}
/* this doesn't actually append, but really prepends it */
void append_range_trans(range_trans_rule_t * range_tr_rules)
{

View File

@ -83,7 +83,6 @@ void append_avrule(avrule_t * avrule);
void append_role_trans(role_trans_rule_t * role_tr_rules);
void append_role_allow(role_allow_rule_t * role_allow_rules);
void append_range_trans(range_trans_rule_t * range_tr_rules);
void append_filename_trans(filename_trans_rule_t * filename_trans_rules);
/* Create a new optional block and add it to the global policy.
* During the second pass resolve the block's requirements. Return 0

View File

@ -1601,7 +1601,7 @@ static int set_types(type_set_t * set, char *id, int *add, char starallowed)
return -1;
}
static int define_compute_type_helper(int which, avrule_t ** rule)
static int define_compute_type_helper(int which, avrule_t ** rule, int has_filename)
{
char *id;
type_datum_t *datum;
@ -1669,6 +1669,14 @@ static int define_compute_type_helper(int which, avrule_t ** rule)
}
free(id);
if (has_filename) {
avrule->object_name = queue_remove(id_queue);
if (!avrule->object_name) {
yyerror("no object_name?");
goto bad;
}
}
ebitmap_for_each_positive_bit(&tclasses, node, i) {
perm = malloc(sizeof(class_perm_node_t));
if (!perm) {
@ -1692,7 +1700,7 @@ static int define_compute_type_helper(int which, avrule_t ** rule)
return -1;
}
int define_compute_type(int which)
int define_compute_type(int which, int has_filename)
{
char *id;
avrule_t *avrule;
@ -1706,10 +1714,14 @@ int define_compute_type(int which)
free(id);
id = queue_remove(id_queue);
free(id);
if (has_filename) {
id = queue_remove(id_queue);
free(id);
}
return 0;
}
if (define_compute_type_helper(which, &avrule))
if (define_compute_type_helper(which, &avrule, has_filename))
return -1;
append_avrule(avrule);
@ -1733,7 +1745,7 @@ avrule_t *define_cond_compute_type(int which)
return (avrule_t *) 1;
}
if (define_compute_type_helper(which, &avrule))
if (define_compute_type_helper(which, &avrule, 0))
return COND_ERR;
return avrule;
@ -2375,6 +2387,13 @@ static int avrule_cpy(avrule_t *dest, const avrule_t *src)
yyerror("out of memory");
return -1;
}
if (src->object_name) {
dest->object_name = strdup(src->object_name);
if (!dest->object_name) {
yyerror("out of memory");
return -1;
}
}
dest->line = src->line;
dest->source_filename = strdup(source_file);
if (!dest->source_filename) {
@ -3343,194 +3362,6 @@ avrule_t *define_cond_filename_trans(void)
return COND_ERR;
}
int define_filename_trans(void)
{
char *id, *name = NULL;
type_set_t stypes, ttypes;
ebitmap_t e_stypes, e_ttypes;
ebitmap_t e_tclasses;
ebitmap_node_t *snode, *tnode, *cnode;
filename_trans_rule_t *ftr;
type_datum_t *typdatum;
avtab_key_t avt_key;
uint32_t otype;
unsigned int c, s, t;
int add, self, rc;
if (pass == 1) {
/* stype */
while ((id = queue_remove(id_queue)))
free(id);
/* ttype */
while ((id = queue_remove(id_queue)))
free(id);
/* tclass */
while ((id = queue_remove(id_queue)))
free(id);
/* otype */
id = queue_remove(id_queue);
free(id);
/* name */
id = queue_remove(id_queue);
free(id);
return 0;
}
type_set_init(&stypes);
type_set_init(&ttypes);
ebitmap_init(&e_stypes);
ebitmap_init(&e_ttypes);
ebitmap_init(&e_tclasses);
add = 1;
while ((id = queue_remove(id_queue))) {
if (set_types(&stypes, id, &add, 0))
goto bad;
}
self = 0;
add = 1;
while ((id = queue_remove(id_queue))) {
if (strcmp(id, "self") == 0) {
free(id);
if (add == 0) {
yyerror("-self is not supported");
goto bad;
}
self = 1;
continue;
}
if (set_types(&ttypes, id, &add, 0))
goto bad;
}
if (read_classes(&e_tclasses))
goto bad;
id = (char *)queue_remove(id_queue);
if (!id) {
yyerror("no otype in transition definition?");
goto bad;
}
if (!is_id_in_scope(SYM_TYPES, id)) {
yyerror2("type %s is not within scope", id);
free(id);
goto bad;
}
typdatum = hashtab_search(policydbp->p_types.table, id);
if (!typdatum) {
yyerror2("unknown type %s used in transition definition", id);
free(id);
goto bad;
}
free(id);
otype = typdatum->s.value;
name = queue_remove(id_queue);
if (!name) {
yyerror("no pathname specified in filename_trans definition?");
goto bad;
}
/* We expand the class set into separate rules. We expand the types
* just to make sure there are not duplicates. They will get turned
* into separate rules later */
if (type_set_expand(&stypes, &e_stypes, policydbp, 1))
goto bad;
if (type_set_expand(&ttypes, &e_ttypes, policydbp, 1))
goto bad;
ebitmap_for_each_positive_bit(&e_tclasses, cnode, c) {
ebitmap_for_each_positive_bit(&e_stypes, snode, s) {
ebitmap_for_each_positive_bit(&e_ttypes, tnode, t) {
avt_key.specified = AVTAB_TRANSITION;
avt_key.source_type = s + 1;
avt_key.target_type = t + 1;
avt_key.target_class = c + 1;
rc = avtab_insert_filename_trans(
&policydbp->te_avtab, &avt_key, otype,
name, NULL
);
if (rc != SEPOL_OK) {
if (rc == SEPOL_EEXIST) {
yyerror2("duplicate filename transition for: filename_trans %s %s %s:%s",
name,
policydbp->p_type_val_to_name[s],
policydbp->p_type_val_to_name[t],
policydbp->p_class_val_to_name[c]);
goto bad;
}
yyerror("out of memory");
goto bad;
}
}
if (self) {
avt_key.specified = AVTAB_TRANSITION;
avt_key.source_type = s + 1;
avt_key.target_type = t + 1;
avt_key.target_class = c + 1;
rc = avtab_insert_filename_trans(
&policydbp->te_avtab, &avt_key, otype,
name, NULL
);
if (rc != SEPOL_OK) {
if (rc == SEPOL_EEXIST) {
yyerror2("duplicate filename transition for: filename_trans %s %s %s:%s",
name,
policydbp->p_type_val_to_name[s],
policydbp->p_type_val_to_name[s],
policydbp->p_class_val_to_name[c]);
goto bad;
}
yyerror("out of memory");
goto bad;
}
}
}
/* Now add the real rule since we didn't find any duplicates */
ftr = malloc(sizeof(*ftr));
if (!ftr) {
yyerror("out of memory");
goto bad;
}
filename_trans_rule_init(ftr);
append_filename_trans(ftr);
ftr->name = strdup(name);
if (type_set_cpy(&ftr->stypes, &stypes)) {
yyerror("out of memory");
goto bad;
}
if (type_set_cpy(&ftr->ttypes, &ttypes)) {
yyerror("out of memory");
goto bad;
}
ftr->tclass = c + 1;
ftr->otype = otype;
ftr->flags = self ? RULE_SELF : 0;
}
free(name);
ebitmap_destroy(&e_stypes);
ebitmap_destroy(&e_ttypes);
ebitmap_destroy(&e_tclasses);
type_set_destroy(&stypes);
type_set_destroy(&ttypes);
return 0;
bad:
free(name);
ebitmap_destroy(&e_stypes);
ebitmap_destroy(&e_ttypes);
ebitmap_destroy(&e_tclasses);
type_set_destroy(&stypes);
type_set_destroy(&ttypes);
return -1;
}
static constraint_expr_t *constraint_expr_clone(const constraint_expr_t * expr)
{
constraint_expr_t *h = NULL, *l = NULL, *newe;

View File

@ -28,7 +28,7 @@ int define_default_role(int which);
int define_default_type(int which);
int define_default_range(int which);
int define_common_perms(void);
int define_compute_type(int which);
int define_compute_type(int which, int has_filename);
int define_conditional(cond_expr_t *expr, avrule_t *t_list, avrule_t *f_list );
int define_constraint(constraint_expr_t *expr);
int define_dominance(void);
@ -57,7 +57,6 @@ int define_role_trans(int class_specified);
int define_role_types(void);
int define_role_attr(void);
int define_roleattribute(void);
int define_filename_trans(void);
int define_sens(void);
int define_te_avtab(int which);
int define_te_avtab_extended_perms(int which);

View File

@ -451,13 +451,13 @@ cond_dontaudit_def : DONTAUDIT names names ':' names names ';'
;
;
transition_def : TYPE_TRANSITION names names ':' names identifier filename ';'
{if (define_filename_trans()) return -1; }
{if (define_compute_type(AVRULE_TRANSITION, 1)) return -1; }
| TYPE_TRANSITION names names ':' names identifier ';'
{if (define_compute_type(AVRULE_TRANSITION)) return -1;}
{if (define_compute_type(AVRULE_TRANSITION, 0)) return -1;}
| TYPE_MEMBER names names ':' names identifier ';'
{if (define_compute_type(AVRULE_MEMBER)) return -1;}
{if (define_compute_type(AVRULE_MEMBER, 0)) return -1;}
| TYPE_CHANGE names names ':' names identifier ';'
{if (define_compute_type(AVRULE_CHANGE)) return -1;}
{if (define_compute_type(AVRULE_CHANGE, 0)) return -1;}
;
range_trans_def : RANGE_TRANSITION names names mls_range_def ';'
{ if (define_range_trans(0)) return -1; }

View File

@ -50,7 +50,6 @@
#define DISPLAY_AVBLOCK_ROLE_ALLOW 4
#define DISPLAY_AVBLOCK_REQUIRES 5
#define DISPLAY_AVBLOCK_DECLARES 6
#define DISPLAY_AVBLOCK_FILENAME_TRANS 7
static policydb_t policydb;
@ -87,7 +86,6 @@ static struct command {
{CMD, 'c', "Display policy capabilities"},
{CMD|NOOPT, 'l', "Link in a module"},
{CMD, 'u', "Display the unknown handling setting"},
{CMD, 'F', "Display filename_trans rules"},
{CMD, 'v', "display the version of policy and/or module"},
{HEADER, 0, ""},
{CMD|NOOPT, 'f', "set output file"},
@ -345,6 +343,8 @@ static int display_avrule(avrule_t * avrule, policydb_t * policy,
policy, fp);
} else if (avrule->specified & AVRULE_TYPE) {
display_id(policy, fp, SYM_TYPES, avrule->perms->data - 1, "");
if (avrule->object_name)
fprintf(fp, " \"%s\"", avrule->object_name);
} else if (avrule->specified & AVRULE_XPERMS) {
avtab_extended_perms_t xperms;
int i;
@ -562,18 +562,6 @@ static void display_role_allow(role_allow_rule_t * ra, policydb_t * p, FILE * fp
}
}
static void display_filename_trans(filename_trans_rule_t * tr, policydb_t * p, FILE * fp)
{
fprintf(fp, "filename transition");
for (; tr; tr = tr->next) {
display_type_set(&tr->stypes, 0, p, fp);
display_type_set(&tr->ttypes, 0, p, fp);
display_id(p, fp, SYM_CLASSES, tr->tclass - 1, ":");
display_id(p, fp, SYM_TYPES, tr->otype - 1, "");
fprintf(fp, " %s\n", tr->name);
}
}
static int role_display_callback(hashtab_key_t key __attribute__((unused)),
hashtab_datum_t datum, void *data)
{
@ -738,10 +726,6 @@ static int display_avdecl(avrule_decl_t * decl, int field,
}
break;
}
case DISPLAY_AVBLOCK_FILENAME_TRANS:
display_filename_trans(decl->filename_trans_rules, policy,
out_fp);
break;
default:{
assert(0);
}
@ -1075,11 +1059,6 @@ int main(int argc, char **argv)
if (out_fp != stdout)
printf("\nOutput to file: %s\n", OutfileName);
break;
case 'F':
fprintf(out_fp, "filename_trans rules:\n");
display_avblock(DISPLAY_AVBLOCK_FILENAME_TRANS,
&policydb, out_fp);
break;
case 'l':
link_module(&policydb, out_fp, ops? 0: 1);
break;

View File

@ -4650,6 +4650,7 @@ static avrule_t *__cil_init_sepol_avrule(uint32_t kind, struct cil_tree_node *no
__cil_init_sepol_type_set(&avrule->stypes);
__cil_init_sepol_type_set(&avrule->ttypes);
avrule->perms = NULL;
avrule->object_name = NULL;
avrule->line = node->line;
avrule->source_filename = NULL;
@ -4676,6 +4677,7 @@ static void __cil_destroy_sepol_avrules(avrule_t *curr)
ebitmap_destroy(&curr->stypes.negset);
ebitmap_destroy(&curr->ttypes.types);
ebitmap_destroy(&curr->ttypes.negset);
free(curr->object_name);
__cil_destroy_sepol_class_perms(curr->perms);
free(curr);
curr = next;

View File

@ -278,6 +278,7 @@ typedef struct avrule {
type_set_t stypes;
type_set_t ttypes;
class_perm_node_t *perms;
char *object_name; /* optional object name */
av_extended_perms_t *xperms;
unsigned long line; /* line number from policy.conf where
* this rule originated */
@ -301,16 +302,6 @@ typedef struct role_allow_rule {
struct role_allow_rule *next;
} role_allow_rule_t;
typedef struct filename_trans_rule {
uint32_t flags; /* may have RULE_SELF set */
type_set_t stypes;
type_set_t ttypes;
uint32_t tclass;
char *name;
uint32_t otype; /* new type */
struct filename_trans_rule *next;
} filename_trans_rule_t;
typedef struct range_trans_rule {
type_set_t stypes;
type_set_t ttypes;
@ -451,9 +442,6 @@ typedef struct avrule_decl {
scope_index_t required; /* symbols needed to activate this block */
scope_index_t declared; /* symbols declared within this block */
/* type transition rules with a 'name' component */
filename_trans_rule_t *filename_trans_rules;
/* for additive statements (type attribute, roles, and users) */
symtab_t symtab[SYM_NUM];
@ -656,8 +644,6 @@ extern void avrule_destroy(avrule_t * x);
extern void avrule_list_destroy(avrule_t * x);
extern void role_trans_rule_init(role_trans_rule_t * x);
extern void role_trans_rule_list_destroy(role_trans_rule_t * x);
extern void filename_trans_rule_init(filename_trans_rule_t * x);
extern void filename_trans_rule_list_destroy(filename_trans_rule_t * x);
extern void role_datum_init(role_datum_t * x);
extern void role_datum_destroy(role_datum_t * x);

View File

@ -99,7 +99,6 @@ void avrule_decl_destroy(avrule_decl_t * x)
cond_list_destroy(x->cond_list);
avrule_list_destroy(x->avrules);
role_trans_rule_list_destroy(x->role_tr_rules);
filename_trans_rule_list_destroy(x->filename_trans_rules);
role_allow_rule_list_destroy(x->role_allow_rules);
range_trans_rule_list_destroy(x->range_tr_rules);
scope_index_destroy(&x->required);

View File

@ -1407,94 +1407,6 @@ static int copy_role_trans(expand_state_t * state, role_trans_rule_t * rules)
return 0;
}
static int expand_filename_trans_helper(expand_state_t *state,
filename_trans_rule_t *rule,
unsigned int s, unsigned int t)
{
uint32_t mapped_otype, present_otype;
int rc;
avtab_key_t avt_key;
mapped_otype = state->typemap[rule->otype - 1];
avt_key.specified = AVTAB_TRANSITION;
avt_key.source_type = s + 1;
avt_key.target_type = t + 1;
avt_key.target_class = rule->tclass;
rc = avtab_insert_filename_trans(&state->out->te_avtab, &avt_key,
mapped_otype, rule->name, &present_otype);
if (rc == SEPOL_EEXIST) {
/* duplicate rule, ignore */
if (present_otype == mapped_otype)
return 0;
ERR(state->handle, "Conflicting name-based type_transition %s %s:%s \"%s\": %s vs %s",
state->out->p_type_val_to_name[s],
state->out->p_type_val_to_name[t],
state->out->p_class_val_to_name[rule->tclass - 1],
rule->name,
state->out->p_type_val_to_name[present_otype - 1],
state->out->p_type_val_to_name[mapped_otype - 1]);
return -1;
} else if (rc < 0) {
ERR(state->handle, "Out of memory!");
return -1;
}
return 0;
}
static int expand_filename_trans(expand_state_t *state, filename_trans_rule_t *rules)
{
unsigned int i, j;
filename_trans_rule_t *cur_rule;
ebitmap_t stypes, ttypes;
ebitmap_node_t *snode, *tnode;
int rc;
cur_rule = rules;
while (cur_rule) {
ebitmap_init(&stypes);
ebitmap_init(&ttypes);
if (expand_convert_type_set(state->out, state->typemap,
&cur_rule->stypes, &stypes, 1)) {
ERR(state->handle, "Out of memory!");
return -1;
}
if (expand_convert_type_set(state->out, state->typemap,
&cur_rule->ttypes, &ttypes, 1)) {
ERR(state->handle, "Out of memory!");
return -1;
}
ebitmap_for_each_positive_bit(&stypes, snode, i) {
ebitmap_for_each_positive_bit(&ttypes, tnode, j) {
rc = expand_filename_trans_helper(
state, cur_rule, i, j
);
if (rc)
return rc;
}
if (cur_rule->flags & RULE_SELF) {
rc = expand_filename_trans_helper(
state, cur_rule, i, i
);
if (rc)
return rc;
}
}
ebitmap_destroy(&stypes);
ebitmap_destroy(&ttypes);
cur_rule = cur_rule->next;
}
return 0;
}
static int exp_rangetr_helper(uint32_t stype, uint32_t ttype, uint32_t tclass,
mls_semantic_range_t * trange,
expand_state_t * state)
@ -1708,7 +1620,7 @@ static int expand_terule_helper(sepol_handle_t * handle,
uint32_t specified, cond_av_list_t ** cond,
cond_av_list_t ** other, uint32_t stype,
uint32_t ttype, class_perm_node_t * perms,
avtab_t * avtab, int enabled)
char *object_name, avtab_t * avtab, int enabled)
{
avtab_key_t avkey;
avtab_datum_t *avdatump;
@ -1732,6 +1644,34 @@ static int expand_terule_helper(sepol_handle_t * handle,
typemap ? typemap[cur->data - 1] : cur->data;
avkey.target_class = cur->tclass;
/*
* if expanded node is a filename transition, insert it, insert
* function checks for duplicates
*/
if (specified & AVRULE_TRANSITION && object_name) {
int rc = avtab_insert_filename_trans(avtab, &avkey,
remapped_data,
object_name,
&oldtype);
if (rc == SEPOL_EEXIST) {
ERR(handle, "conflicting filename transition %s %s:%s \"%s\": %s vs %s",
p->p_type_val_to_name[avkey.source_type - 1],
p->p_type_val_to_name[avkey.target_type - 1],
p->p_class_val_to_name[avkey.target_class - 1],
object_name,
p->p_type_val_to_name[oldtype - 1],
p->p_type_val_to_name[remapped_data - 1]);
return EXPAND_RULE_CONFLICT;
}
if (rc < 0)
return EXPAND_RULE_ERROR;
/*
* filename transtion inserted, continue with next node
*/
cur = cur->next;
continue;
}
conflict = 0;
/* check to see if the expanded TE already exists --
* either in the global scope or in another
@ -1777,12 +1717,9 @@ static int expand_terule_helper(sepol_handle_t * handle,
|| node->parse_context == cond)
return EXPAND_RULE_SUCCESS;
ERR(handle, "duplicate TE rule for %s %s:%s %s",
p->p_type_val_to_name[avkey.source_type -
1],
p->p_type_val_to_name[avkey.target_type -
1],
p->p_class_val_to_name[avkey.target_class -
1],
p->p_type_val_to_name[avkey.source_type - 1],
p->p_type_val_to_name[avkey.target_type - 1],
p->p_class_val_to_name[avkey.target_class - 1],
p->p_type_val_to_name[oldtype - 1]);
return EXPAND_RULE_CONFLICT;
}
@ -1947,6 +1884,7 @@ static int expand_rule_helper(sepol_handle_t * handle,
retval = expand_terule_helper(handle, p, typemap,
source_rule->specified, cond,
other, i, i, source_rule->perms,
source_rule->object_name,
dest_avtab, enabled);
if (retval != EXPAND_RULE_SUCCESS)
return retval;
@ -1963,6 +1901,7 @@ static int expand_rule_helper(sepol_handle_t * handle,
retval = expand_terule_helper(handle, p, typemap,
source_rule->specified, cond,
other, i, j, source_rule->perms,
source_rule->object_name,
dest_avtab, enabled);
if (retval != EXPAND_RULE_SUCCESS)
return retval;
@ -2791,9 +2730,6 @@ static int copy_and_expand_avrule_block(expand_state_t * state)
goto cleanup;
}
if (expand_filename_trans(state, decl->filename_trans_rules))
goto cleanup;
/* expand the range transition rules */
if (expand_range_trans(state, decl->range_tr_rules))
goto cleanup;

View File

@ -1249,6 +1249,12 @@ static int copy_avrule_list(avrule_t * list, avrule_t ** dst,
goto cleanup;
}
if (cur->object_name) {
new_rule->object_name = strdup(cur->object_name);
if (!new_rule->object_name)
goto cleanup;
}
cur_perm = cur->perms;
tail_perm = NULL;
while (cur_perm) {
@ -1412,51 +1418,6 @@ static int copy_role_allow_list(role_allow_rule_t * list,
return -1;
}
static int copy_filename_trans_list(filename_trans_rule_t * list,
filename_trans_rule_t ** dst,
policy_module_t * module,
link_state_t * state)
{
filename_trans_rule_t *cur, *new_rule, *tail;
cur = list;
tail = *dst;
while (tail && tail->next)
tail = tail->next;
while (cur) {
new_rule = malloc(sizeof(*new_rule));
if (!new_rule)
goto err;
filename_trans_rule_init(new_rule);
if (*dst == NULL)
*dst = new_rule;
else
tail->next = new_rule;
tail = new_rule;
new_rule->name = strdup(cur->name);
if (!new_rule->name)
goto err;
if (type_set_or_convert(&cur->stypes, &new_rule->stypes, module) ||
type_set_or_convert(&cur->ttypes, &new_rule->ttypes, module))
goto err;
new_rule->tclass = module->map[SYM_CLASSES][cur->tclass - 1];
new_rule->otype = module->map[SYM_TYPES][cur->otype - 1];
new_rule->flags = cur->flags;
cur = cur->next;
}
return 0;
err:
ERR(state->handle, "Out of memory!");
return -1;
}
static int copy_range_trans_list(range_trans_rule_t * rules,
range_trans_rule_t ** dst,
policy_module_t * mod, link_state_t * state)
@ -1679,11 +1640,6 @@ static int copy_avrule_decl(link_state_t * state, policy_module_t * module,
return -1;
}
if (copy_filename_trans_list(src_decl->filename_trans_rules,
&dest_decl->filename_trans_rules,
module, state))
return -1;
if (copy_range_trans_list(src_decl->range_tr_rules,
&dest_decl->range_tr_rules, module, state))
return -1;

View File

@ -547,7 +547,7 @@ static int semantic_level_to_cil(struct policydb *pdb, int sens_offset, struct m
return 0;
}
static int avrule_to_cil(int indent, struct policydb *pdb, uint32_t type, const char *src, const char *tgt, const struct class_perm_node *classperms)
static int avrule_to_cil(int indent, struct policydb *pdb, uint32_t type, const char *src, const char *tgt, const char *object_name, const struct class_perm_node *classperms)
{
int rc = -1;
const char *rule;
@ -597,6 +597,12 @@ static int avrule_to_cil(int indent, struct policydb *pdb, uint32_t type, const
rule, src, tgt,
pdb->p_class_val_to_name[classperm->tclass - 1],
perms + 1);
} else if (object_name) {
cil_println(indent, "(%s %s %s %s \"%s\" %s)",
rule, src, tgt,
pdb->p_class_val_to_name[classperm->tclass - 1],
object_name,
pdb->p_type_val_to_name[classperm->data - 1]);
} else {
cil_println(indent, "(%s %s %s %s %s)",
rule, src, tgt,
@ -1199,7 +1205,7 @@ static int avrule_list_to_cil(int indent, struct policydb *pdb, struct avrule *a
if (avrule->specified & AVRULE_XPERMS) {
rc = avrulex_to_cil(indent, pdb, avrule->specified, snames[s], tnames[t], avrule->perms, avrule->xperms);
} else {
rc = avrule_to_cil(indent, pdb, avrule->specified, snames[s], tnames[t], avrule->perms);
rc = avrule_to_cil(indent, pdb, avrule->specified, snames[s], tnames[t], avrule->object_name, avrule->perms);
}
if (rc != 0) {
goto exit;
@ -1210,7 +1216,7 @@ static int avrule_list_to_cil(int indent, struct policydb *pdb, struct avrule *a
if (avrule->specified & AVRULE_XPERMS) {
rc = avrulex_to_cil(indent, pdb, avrule->specified, snames[s], "self", avrule->perms, avrule->xperms);
} else {
rc = avrule_to_cil(indent, pdb, avrule->specified, snames[s], "self", avrule->perms);
rc = avrule_to_cil(indent, pdb, avrule->specified, snames[s], "self", avrule->object_name, avrule->perms);
}
if (rc != 0) {
goto exit;
@ -1576,60 +1582,6 @@ exit:
return rc;
}
static int filename_trans_to_cil(int indent, struct policydb *pdb, struct filename_trans_rule *rules, struct list *attr_list)
{
int rc = -1;
char **stypes = NULL;
unsigned int num_stypes = 0;
unsigned int stype;
char **ttypes = NULL;
unsigned int num_ttypes = 0;
unsigned int ttype;
struct type_set *ts;
struct filename_trans_rule *rule;
for (rule = rules; rule != NULL; rule = rule->next) {
ts = &rule->stypes;
rc = process_typeset(pdb, ts, attr_list, &stypes, &num_stypes);
if (rc != 0) {
goto exit;
}
ts = &rule->ttypes;
rc = process_typeset(pdb, ts, attr_list, &ttypes, &num_ttypes);
if (rc != 0) {
goto exit;
}
for (stype = 0; stype < num_stypes; stype++) {
for (ttype = 0; ttype < num_ttypes; ttype++) {
cil_println(indent, "(typetransition %s %s %s \"%s\" %s)",
stypes[stype], ttypes[ttype],
pdb->p_class_val_to_name[rule->tclass - 1],
rule->name,
pdb->p_type_val_to_name[rule->otype - 1]);
}
if (rule->flags & RULE_SELF) {
cil_println(indent, "(typetransition %s self %s \"%s\" %s)",
stypes[stype],
pdb->p_class_val_to_name[rule->tclass - 1],
rule->name,
pdb->p_type_val_to_name[rule->otype - 1]);
}
}
names_destroy(&stypes, &num_stypes);
names_destroy(&ttypes, &num_ttypes);
}
rc = 0;
exit:
names_destroy(&stypes, &num_stypes);
names_destroy(&ttypes, &num_ttypes);
return rc;
}
struct class_perm_datum {
char *name;
uint32_t val;
@ -3683,11 +3635,6 @@ static int block_to_cil(struct policydb *pdb, struct avrule_block *block, struct
goto exit;
}
rc = filename_trans_to_cil(indent, pdb, decl->filename_trans_rules, type_attr_list);
if (rc != 0) {
goto exit;
}
rc = cond_list_to_cil(indent, pdb, decl->cond_list, type_attr_list);
if (rc != 0) {
goto exit;

View File

@ -638,6 +638,7 @@ void avrule_destroy(avrule_t * x)
}
free(x->xperms);
free(x->object_name);
}
void role_trans_rule_init(role_trans_rule_t * x)
@ -667,33 +668,6 @@ void role_trans_rule_list_destroy(role_trans_rule_t * x)
}
}
void filename_trans_rule_init(filename_trans_rule_t * x)
{
memset(x, 0, sizeof(*x));
type_set_init(&x->stypes);
type_set_init(&x->ttypes);
}
static void filename_trans_rule_destroy(filename_trans_rule_t * x)
{
if (!x)
return;
type_set_destroy(&x->stypes);
type_set_destroy(&x->ttypes);
free(x->name);
}
void filename_trans_rule_list_destroy(filename_trans_rule_t * x)
{
filename_trans_rule_t *next;
while (x) {
next = x->next;
filename_trans_rule_destroy(x);
free(x);
x = next;
}
}
void role_allow_rule_init(role_allow_rule_t * x)
{
memset(x, 0, sizeof(role_allow_rule_t));
@ -3493,31 +3467,32 @@ static int role_allow_rule_read(role_allow_rule_t ** r, struct policy_file *fp)
return 0;
}
static int filename_trans_rule_read(policydb_t *p, filename_trans_rule_t **r,
static int filename_trans_rule_read(policydb_t *p, avrule_t **r,
struct policy_file *fp)
{
uint32_t buf[3], nel, i, len;
unsigned int entries;
filename_trans_rule_t *ftr, *lftr;
avrule_t *cur;
int rc;
rc = next_entry(buf, fp, sizeof(uint32_t));
if (rc < 0)
return -1;
nel = le32_to_cpu(buf[0]);
lftr = NULL;
for (i = 0; i < nel; i++) {
ftr = malloc(sizeof(*ftr));
if (!ftr)
cur = malloc(sizeof(avrule_t));
if (!cur)
return -1;
avrule_init(cur);
filename_trans_rule_init(ftr);
cur->next = *r;
*r = cur;
if (lftr)
lftr->next = ftr;
else
*r = ftr;
lftr = ftr;
cur->specified = AVRULE_TRANSITION;
cur->perms = malloc(sizeof(class_perm_node_t));
if (!cur->perms)
return -1;
class_perm_node_init(cur->perms);
rc = next_entry(buf, fp, sizeof(uint32_t));
if (rc < 0)
@ -3527,19 +3502,14 @@ static int filename_trans_rule_read(policydb_t *p, filename_trans_rule_t **r,
if (zero_or_saturated(len))
return -1;
ftr->name = malloc(len + 1);
if (!ftr->name)
return -1;
rc = next_entry(ftr->name, fp, len);
rc = str_read(&cur->object_name, fp, len);
if (rc)
return -1;
ftr->name[len] = 0;
if (type_set_read(&ftr->stypes, fp))
if (type_set_read(&cur->stypes, fp))
return -1;
if (type_set_read(&ftr->ttypes, fp))
if (type_set_read(&cur->ttypes, fp))
return -1;
if (p->policyvers >= MOD_POLICYDB_VERSION_SELF_TYPETRANS)
@ -3550,10 +3520,10 @@ static int filename_trans_rule_read(policydb_t *p, filename_trans_rule_t **r,
rc = next_entry(buf, fp, sizeof(uint32_t) * entries);
if (rc < 0)
return -1;
ftr->tclass = le32_to_cpu(buf[0]);
ftr->otype = le32_to_cpu(buf[1]);
cur->perms->tclass = le32_to_cpu(buf[0]);
cur->perms->data = le32_to_cpu(buf[1]);
if (p->policyvers >= MOD_POLICYDB_VERSION_SELF_TYPETRANS)
ftr->flags = le32_to_cpu(buf[2]);
cur->flags = le32_to_cpu(buf[2]);
}
return 0;
@ -3656,7 +3626,7 @@ static int avrule_decl_read(policydb_t * p, avrule_decl_t * decl,
}
if (p->policyvers >= MOD_POLICYDB_VERSION_FILENAME_TRANS &&
filename_trans_rule_read(p, &decl->filename_trans_rules, fp))
filename_trans_rule_read(p, &decl->avrules, fp))
return -1;
if (p->policyvers >= MOD_POLICYDB_VERSION_RANGETRANS &&

View File

@ -1313,31 +1313,6 @@ bad:
return -1;
}
static int validate_filename_trans_rules(sepol_handle_t *handle, const filename_trans_rule_t *filename_trans, const policydb_t *p, validate_t flavors[])
{
for (; filename_trans; filename_trans = filename_trans->next) {
if (validate_type_set(&filename_trans->stypes, &flavors[SYM_TYPES]))
goto bad;
if (validate_type_set(&filename_trans->ttypes, &flavors[SYM_TYPES]))
goto bad;
if (validate_value(filename_trans->tclass,&flavors[SYM_CLASSES] ))
goto bad;
if (validate_simpletype(filename_trans->otype, p, flavors))
goto bad;
/* currently only the RULE_SELF flag can be set */
if ((filename_trans->flags & ~RULE_SELF) != 0)
goto bad;
}
return 0;
bad:
ERR(handle, "Invalid filename trans rule list");
return -1;
}
static int validate_symtabs(sepol_handle_t *handle, const symtab_t symtabs[], validate_t flavors[])
{
unsigned int i;
@ -1372,8 +1347,6 @@ static int validate_avrule_blocks(sepol_handle_t *handle, const avrule_block_t *
goto bad;
if (validate_scope_index(handle, &decl->declared, flavors))
goto bad;
if (validate_filename_trans_rules(handle, decl->filename_trans_rules, p, flavors))
goto bad;
if (validate_symtabs(handle, decl->symtab, flavors))
goto bad;
}

View File

@ -1970,6 +1970,10 @@ static int avrule_write(policydb_t *p, avrule_t * avrule,
uint32_t buf[32], len;
class_perm_node_t *cur;
/* skip filename transitions for now */
if (avrule->specified & AVRULE_TRANSITION && avrule->object_name)
return POLICYDB_SUCCESS;
if (p->policyvers < MOD_POLICYDB_VERSION_SELF_TYPETRANS &&
(avrule->specified & AVRULE_TYPE) &&
(avrule->flags & RULE_SELF)) {
@ -2063,7 +2067,9 @@ static int avrule_write_list(policydb_t *p, avrule_t * avrules,
avrule = avrules;
len = 0;
while (avrule) {
len++;
if (!(avrule->specified & AVRULE_TRANSITION &&
avrule->object_name))
len++;
avrule = avrule->next;
}
@ -2162,55 +2168,67 @@ static int role_allow_rule_write(role_allow_rule_t * r, struct policy_file *fp)
return POLICYDB_SUCCESS;
}
static int filename_trans_rule_write(policydb_t *p, filename_trans_rule_t *t,
static int filename_trans_rule_write(policydb_t *p, avrule_t *rules,
struct policy_file *fp)
{
int nel = 0;
size_t items, entries;
uint32_t buf[3], len;
filename_trans_rule_t *ftr;
avrule_t *rule;
class_perm_node_t *perm;
for (ftr = t; ftr; ftr = ftr->next)
nel++;
for (rule = rules; rule; rule = rule->next) {
if (rule->specified & AVRULE_TRANSITION && rule->object_name) {
for (perm = rule->perms; perm; perm = perm->next) {
nel++;
}
}
}
buf[0] = cpu_to_le32(nel);
items = put_entry(buf, sizeof(uint32_t), 1, fp);
if (items != 1)
return POLICYDB_ERROR;
for (ftr = t; ftr; ftr = ftr->next) {
len = strlen(ftr->name);
buf[0] = cpu_to_le32(len);
items = put_entry(buf, sizeof(uint32_t), 1, fp);
if (items != 1)
return POLICYDB_ERROR;
for (rule = rules; rule; rule = rule->next) {
if (!(rule->specified & AVRULE_TRANSITION && rule->object_name))
continue;
len = strlen(rule->object_name);
for (perm = rule->perms; perm; perm = perm->next) {
buf[0] = cpu_to_le32(len);
items = put_entry(buf, sizeof(uint32_t), 1, fp);
if (items != 1)
return POLICYDB_ERROR;
items = put_entry(ftr->name, sizeof(char), len, fp);
if (items != len)
return POLICYDB_ERROR;
items = put_entry(rule->object_name, sizeof(char), len,
fp);
if (items != len)
return POLICYDB_ERROR;
if (type_set_write(&ftr->stypes, fp))
return POLICYDB_ERROR;
if (type_set_write(&ftr->ttypes, fp))
return POLICYDB_ERROR;
if (type_set_write(&rule->stypes, fp))
return POLICYDB_ERROR;
if (type_set_write(&rule->ttypes, fp))
return POLICYDB_ERROR;
buf[0] = cpu_to_le32(ftr->tclass);
buf[1] = cpu_to_le32(ftr->otype);
buf[2] = cpu_to_le32(ftr->flags);
buf[0] = cpu_to_le32(perm->tclass);
buf[1] = cpu_to_le32(perm->data);
buf[2] = cpu_to_le32(rule->flags);
if (p->policyvers >= MOD_POLICYDB_VERSION_SELF_TYPETRANS) {
entries = 3;
} else if (!(ftr->flags & RULE_SELF)) {
entries = 2;
} else {
ERR(fp->handle,
"Module contains a self rule not supported by the target module policy version");
return POLICYDB_ERROR;
if (p->policyvers >=
MOD_POLICYDB_VERSION_SELF_TYPETRANS) {
entries = 3;
} else if (!(rule->flags & RULE_SELF)) {
entries = 2;
} else {
ERR(fp->handle,
"Module contains a self rule not supported by the target module policy version");
return POLICYDB_ERROR;
}
items = put_entry(buf, sizeof(uint32_t), entries, fp);
if (items != entries)
return POLICYDB_ERROR;
}
items = put_entry(buf, sizeof(uint32_t), entries, fp);
if (items != entries)
return POLICYDB_ERROR;
}
return POLICYDB_SUCCESS;
}
@ -2284,7 +2302,7 @@ static int avrule_decl_write(avrule_decl_t * decl, int num_scope_syms,
}
if (p->policyvers >= MOD_POLICYDB_VERSION_FILENAME_TRANS &&
filename_trans_rule_write(p, decl->filename_trans_rules, fp))
filename_trans_rule_write(p, decl->avrules, fp))
return POLICYDB_ERROR;
if (p->policyvers >= MOD_POLICYDB_VERSION_RANGETRANS &&