libsepol: Enclose identifier lists in CIL constraint expressions

When writing CIL policy from a kernel policy or module, if there are
multiple users, roles, or types, then the list needs to be enclosed
by "(" and ")".

When writing a constraint expression, check to see if there are
multiple identifiers in the names string and enclose the list with
"(" and ")" if there are.

Signed-off-by: James Carter <jwcart2@gmail.com>
This commit is contained in:
James Carter 2021-03-16 15:24:14 -04:00
parent 45d7a0a563
commit 6758addf85
2 changed files with 13 additions and 2 deletions

View file

@ -191,7 +191,11 @@ static char *constraint_expr_to_str(struct policydb *pdb, struct constraint_expr
if (!names) {
goto exit;
}
new_val = create_str("(%s %s %s)", 3, op, attr1, names);
if (strchr(names, ' ')) {
new_val = create_str("(%s %s (%s))", 3, op, attr1, names);
} else {
new_val = create_str("(%s %s %s)", 3, op, attr1, names);
}
free(names);
}
} else {

View file

@ -1800,13 +1800,20 @@ static int constraint_expr_to_string(struct policydb *pdb, struct constraint_exp
// length of values/oper + 2 spaces + 2 parens + null terminator
len = strlen(op) + strlen(attr1) + strlen(names) + 2 + 2 + 1;
if (num_names > 1) {
len += 2; // 2 more parens
}
new_val = malloc(len);
if (new_val == NULL) {
log_err("Out of memory");
rc = -1;
goto exit;
}
rlen = snprintf(new_val, len, "(%s %s %s)", op, attr1, names);
if (num_names > 1) {
rlen = snprintf(new_val, len, "(%s %s (%s))", op, attr1, names);
} else {
rlen = snprintf(new_val, len, "(%s %s %s)", op, attr1, names);
}
if (rlen < 0 || rlen >= len) {
log_err("Failed to generate constraint expression");
rc = -1;