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@xxxxxxxxx> --- libsepol/src/kernel_to_cil.c | 6 +++++- libsepol/src/module_to_cil.c | 9 ++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/libsepol/src/kernel_to_cil.c b/libsepol/src/kernel_to_cil.c index a146ac51..96e0f5d3 100644 --- a/libsepol/src/kernel_to_cil.c +++ b/libsepol/src/kernel_to_cil.c @@ -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 { diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c index a87bc15e..3cc75b42 100644 --- a/libsepol/src/module_to_cil.c +++ b/libsepol/src/module_to_cil.c @@ -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; -- 2.26.2