checkpolicy: clean expression on error
The passed expression needs to be transferred into the policy or free'd by the sink functions define_constraint() and define_validatetrans(). Signed-off-by: Christian Göttsche <cgzones@googlemail.com> Acked-by: James Carter <jwcart2@gmail.com>
This commit is contained in:
parent
770ad3ecac
commit
187e75849e
|
@ -3428,20 +3428,22 @@ int define_constraint(constraint_expr_t * expr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ebitmap_init(&classmap);
|
||||||
|
|
||||||
depth = -1;
|
depth = -1;
|
||||||
for (e = expr; e; e = e->next) {
|
for (e = expr; e; e = e->next) {
|
||||||
switch (e->expr_type) {
|
switch (e->expr_type) {
|
||||||
case CEXPR_NOT:
|
case CEXPR_NOT:
|
||||||
if (depth < 0) {
|
if (depth < 0) {
|
||||||
yyerror("illegal constraint expression");
|
yyerror("illegal constraint expression");
|
||||||
return -1;
|
goto bad;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CEXPR_AND:
|
case CEXPR_AND:
|
||||||
case CEXPR_OR:
|
case CEXPR_OR:
|
||||||
if (depth < 1) {
|
if (depth < 1) {
|
||||||
yyerror("illegal constraint expression");
|
yyerror("illegal constraint expression");
|
||||||
return -1;
|
goto bad;
|
||||||
}
|
}
|
||||||
depth--;
|
depth--;
|
||||||
break;
|
break;
|
||||||
|
@ -3449,51 +3451,48 @@ int define_constraint(constraint_expr_t * expr)
|
||||||
case CEXPR_NAMES:
|
case CEXPR_NAMES:
|
||||||
if (e->attr & CEXPR_XTARGET) {
|
if (e->attr & CEXPR_XTARGET) {
|
||||||
yyerror("illegal constraint expression");
|
yyerror("illegal constraint expression");
|
||||||
return -1; /* only for validatetrans rules */
|
goto bad; /* only for validatetrans rules */
|
||||||
}
|
}
|
||||||
if (depth == (CEXPR_MAXDEPTH - 1)) {
|
if (depth == (CEXPR_MAXDEPTH - 1)) {
|
||||||
yyerror("constraint expression is too deep");
|
yyerror("constraint expression is too deep");
|
||||||
return -1;
|
goto bad;
|
||||||
}
|
}
|
||||||
depth++;
|
depth++;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
yyerror("illegal constraint expression");
|
yyerror("illegal constraint expression");
|
||||||
return -1;
|
goto bad;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (depth != 0) {
|
if (depth != 0) {
|
||||||
yyerror("illegal constraint expression");
|
yyerror("illegal constraint expression");
|
||||||
return -1;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
ebitmap_init(&classmap);
|
|
||||||
while ((id = queue_remove(id_queue))) {
|
while ((id = queue_remove(id_queue))) {
|
||||||
if (!is_id_in_scope(SYM_CLASSES, id)) {
|
if (!is_id_in_scope(SYM_CLASSES, id)) {
|
||||||
yyerror2("class %s is not within scope", id);
|
yyerror2("class %s is not within scope", id);
|
||||||
free(id);
|
free(id);
|
||||||
return -1;
|
goto bad;
|
||||||
}
|
}
|
||||||
cladatum =
|
cladatum =
|
||||||
(class_datum_t *) hashtab_search(policydbp->p_classes.table,
|
(class_datum_t *) hashtab_search(policydbp->p_classes.table,
|
||||||
(hashtab_key_t) id);
|
(hashtab_key_t) id);
|
||||||
if (!cladatum) {
|
if (!cladatum) {
|
||||||
yyerror2("class %s is not defined", id);
|
yyerror2("class %s is not defined", id);
|
||||||
ebitmap_destroy(&classmap);
|
|
||||||
free(id);
|
free(id);
|
||||||
return -1;
|
goto bad;
|
||||||
}
|
}
|
||||||
if (ebitmap_set_bit(&classmap, cladatum->s.value - 1, TRUE)) {
|
if (ebitmap_set_bit(&classmap, cladatum->s.value - 1, TRUE)) {
|
||||||
yyerror("out of memory");
|
yyerror("out of memory");
|
||||||
ebitmap_destroy(&classmap);
|
|
||||||
free(id);
|
free(id);
|
||||||
return -1;
|
goto bad;
|
||||||
}
|
}
|
||||||
node = malloc(sizeof(struct constraint_node));
|
node = malloc(sizeof(struct constraint_node));
|
||||||
if (!node) {
|
if (!node) {
|
||||||
yyerror("out of memory");
|
yyerror("out of memory");
|
||||||
free(node);
|
free(node);
|
||||||
return -1;
|
goto bad;
|
||||||
}
|
}
|
||||||
memset(node, 0, sizeof(constraint_node_t));
|
memset(node, 0, sizeof(constraint_node_t));
|
||||||
if (useexpr) {
|
if (useexpr) {
|
||||||
|
@ -3505,7 +3504,7 @@ int define_constraint(constraint_expr_t * expr)
|
||||||
if (!node->expr) {
|
if (!node->expr) {
|
||||||
yyerror("out of memory");
|
yyerror("out of memory");
|
||||||
free(node);
|
free(node);
|
||||||
return -1;
|
goto bad;
|
||||||
}
|
}
|
||||||
node->permissions = 0;
|
node->permissions = 0;
|
||||||
|
|
||||||
|
@ -3557,8 +3556,7 @@ int define_constraint(constraint_expr_t * expr)
|
||||||
yyerror2("permission %s is not"
|
yyerror2("permission %s is not"
|
||||||
" defined for class %s", id, policydbp->p_class_val_to_name[i]);
|
" defined for class %s", id, policydbp->p_class_val_to_name[i]);
|
||||||
free(id);
|
free(id);
|
||||||
ebitmap_destroy(&classmap);
|
goto bad;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
node->permissions |= (UINT32_C(1) << (perdatum->s.value - 1));
|
node->permissions |= (UINT32_C(1) << (perdatum->s.value - 1));
|
||||||
|
@ -3569,6 +3567,13 @@ int define_constraint(constraint_expr_t * expr)
|
||||||
ebitmap_destroy(&classmap);
|
ebitmap_destroy(&classmap);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
bad:
|
||||||
|
ebitmap_destroy(&classmap);
|
||||||
|
if (useexpr)
|
||||||
|
constraint_expr_destroy(expr);
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int define_validatetrans(constraint_expr_t * expr)
|
int define_validatetrans(constraint_expr_t * expr)
|
||||||
|
@ -3587,20 +3592,22 @@ int define_validatetrans(constraint_expr_t * expr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ebitmap_init(&classmap);
|
||||||
|
|
||||||
depth = -1;
|
depth = -1;
|
||||||
for (e = expr; e; e = e->next) {
|
for (e = expr; e; e = e->next) {
|
||||||
switch (e->expr_type) {
|
switch (e->expr_type) {
|
||||||
case CEXPR_NOT:
|
case CEXPR_NOT:
|
||||||
if (depth < 0) {
|
if (depth < 0) {
|
||||||
yyerror("illegal validatetrans expression");
|
yyerror("illegal validatetrans expression");
|
||||||
return -1;
|
goto bad;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CEXPR_AND:
|
case CEXPR_AND:
|
||||||
case CEXPR_OR:
|
case CEXPR_OR:
|
||||||
if (depth < 1) {
|
if (depth < 1) {
|
||||||
yyerror("illegal validatetrans expression");
|
yyerror("illegal validatetrans expression");
|
||||||
return -1;
|
goto bad;
|
||||||
}
|
}
|
||||||
depth--;
|
depth--;
|
||||||
break;
|
break;
|
||||||
|
@ -3608,47 +3615,45 @@ int define_validatetrans(constraint_expr_t * expr)
|
||||||
case CEXPR_NAMES:
|
case CEXPR_NAMES:
|
||||||
if (depth == (CEXPR_MAXDEPTH - 1)) {
|
if (depth == (CEXPR_MAXDEPTH - 1)) {
|
||||||
yyerror("validatetrans expression is too deep");
|
yyerror("validatetrans expression is too deep");
|
||||||
return -1;
|
goto bad;
|
||||||
}
|
}
|
||||||
depth++;
|
depth++;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
yyerror("illegal validatetrans expression");
|
yyerror("illegal validatetrans expression");
|
||||||
return -1;
|
goto bad;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (depth != 0) {
|
if (depth != 0) {
|
||||||
yyerror("illegal validatetrans expression");
|
yyerror("illegal validatetrans expression");
|
||||||
return -1;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
ebitmap_init(&classmap);
|
|
||||||
while ((id = queue_remove(id_queue))) {
|
while ((id = queue_remove(id_queue))) {
|
||||||
if (!is_id_in_scope(SYM_CLASSES, id)) {
|
if (!is_id_in_scope(SYM_CLASSES, id)) {
|
||||||
yyerror2("class %s is not within scope", id);
|
yyerror2("class %s is not within scope", id);
|
||||||
free(id);
|
free(id);
|
||||||
return -1;
|
goto bad;
|
||||||
}
|
}
|
||||||
cladatum =
|
cladatum =
|
||||||
(class_datum_t *) hashtab_search(policydbp->p_classes.table,
|
(class_datum_t *) hashtab_search(policydbp->p_classes.table,
|
||||||
(hashtab_key_t) id);
|
(hashtab_key_t) id);
|
||||||
if (!cladatum) {
|
if (!cladatum) {
|
||||||
yyerror2("class %s is not defined", id);
|
yyerror2("class %s is not defined", id);
|
||||||
ebitmap_destroy(&classmap);
|
|
||||||
free(id);
|
free(id);
|
||||||
return -1;
|
goto bad;
|
||||||
}
|
}
|
||||||
if (ebitmap_set_bit(&classmap, (cladatum->s.value - 1), TRUE)) {
|
if (ebitmap_set_bit(&classmap, (cladatum->s.value - 1), TRUE)) {
|
||||||
yyerror("out of memory");
|
yyerror("out of memory");
|
||||||
ebitmap_destroy(&classmap);
|
|
||||||
free(id);
|
free(id);
|
||||||
return -1;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
node = malloc(sizeof(struct constraint_node));
|
node = malloc(sizeof(struct constraint_node));
|
||||||
if (!node) {
|
if (!node) {
|
||||||
yyerror("out of memory");
|
yyerror("out of memory");
|
||||||
return -1;
|
free(id);
|
||||||
|
goto bad;
|
||||||
}
|
}
|
||||||
memset(node, 0, sizeof(constraint_node_t));
|
memset(node, 0, sizeof(constraint_node_t));
|
||||||
if (useexpr) {
|
if (useexpr) {
|
||||||
|
@ -3668,6 +3673,13 @@ int define_validatetrans(constraint_expr_t * expr)
|
||||||
ebitmap_destroy(&classmap);
|
ebitmap_destroy(&classmap);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
bad:
|
||||||
|
ebitmap_destroy(&classmap);
|
||||||
|
if (useexpr)
|
||||||
|
constraint_expr_destroy(expr);
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2)
|
uintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2)
|
||||||
|
|
Loading…
Reference in New Issue