Blob Blame History Raw
From 6758addf8592d950cba489703abedd4a3430602f Mon Sep 17 00:00:00 2001
From: James Carter <jwcart2@gmail.com>
Date: Tue, 16 Mar 2021 15:24:14 -0400
Subject: [PATCH] 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>
---
 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 edfebeafe283..101cb61240f5 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 cb1069caffdf..fdf56b701e2c 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.32.0