Blob Blame History Raw
From 9ac9d2dab40826abe049fd07d21a20386fe5b38b Mon Sep 17 00:00:00 2001
From: James Carter <jwcart2@gmail.com>
Date: Mon, 14 Jun 2021 12:53:25 -0400
Subject: [PATCH] libsepol/cil: Fix anonymous IP address call arguments

A named IP address (using an ipaddr rule) could be passed as an
argument, but trying to pass an actual IP address caused an error.

As an exmample, consider the following portion of a policy.
  (macro m4 ((ipaddr ip)(ipaddr nm))
    (nodecon ip nm (USER ROLE TYPE ((s0) (s0))))
  )
  (ipaddr nm1 255.255.255.0)
  (ipaddr ip1 1.2.3.4)
  (call m4 (ip1 nm1)) ; This works
  (call m4 (1.2.3.4 255.255.255.0)) ; This doesn't

Allow actual IP addresses to be passed as a call argument. Now the
second call works as well.

Signed-off-by: James Carter <jwcart2@gmail.com>
Acked-by: Nicolas Iooss <nicolas.iooss@m4x.org>
---
 libsepol/cil/src/cil_build_ast.c   |  4 ----
 libsepol/cil/src/cil_resolve_ast.c | 23 ++++++++++-------------
 2 files changed, 10 insertions(+), 17 deletions(-)

diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
index 71f14e20e25e..538df2794ade 100644
--- a/libsepol/cil/src/cil_build_ast.c
+++ b/libsepol/cil/src/cil_build_ast.c
@@ -5642,10 +5642,6 @@ int cil_fill_ipaddr(struct cil_tree_node *addr_node, struct cil_ipaddr *addr)
 		goto exit;
 	}
 
-	if (addr_node->cl_head != NULL ||  addr_node->next != NULL) {
-		goto exit;
-	}
-
 	if (strchr(addr_node->data, '.') != NULL) {
 		addr->family = AF_INET;
 	} else {
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
index 77ffe0ffd22b..16c8c7533ce3 100644
--- a/libsepol/cil/src/cil_resolve_ast.c
+++ b/libsepol/cil/src/cil_resolve_ast.c
@@ -3024,14 +3024,18 @@ static int cil_build_call_args(struct cil_tree_node *call_node, struct cil_call
 			break;
 		}
 		case CIL_IPADDR: {
-			if (arg_node->cl_head != NULL) {
+			if (arg_node->data == NULL) {
+				cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
+				cil_destroy_args(arg);
+				rc = SEPOL_ERR;
+				goto exit;
+			} else if (strchr(arg_node->data, '.') || strchr(arg_node->data, ':')) {
 				struct cil_ipaddr *ipaddr = NULL;
 				struct cil_tree_node *addr_node = NULL;
 				cil_ipaddr_init(&ipaddr);
-
-				rc = cil_fill_ipaddr(arg_node->cl_head, ipaddr);
+				rc = cil_fill_ipaddr(arg_node, ipaddr);
 				if (rc != SEPOL_OK) {
-					cil_log(CIL_ERR, "Failed to create anonymous ip address, rc: %d\n", rc);
+					cil_tree_log(call_node, CIL_ERR, "Failed to create anonymous ip address");
 					cil_destroy_ipaddr(ipaddr);
 					cil_destroy_args(arg);
 					goto exit;
@@ -3039,18 +3043,11 @@ static int cil_build_call_args(struct cil_tree_node *call_node, struct cil_call
 				cil_tree_node_init(&addr_node);
 				addr_node->flavor = CIL_IPADDR;
 				addr_node->data = ipaddr;
-				cil_list_append(((struct cil_symtab_datum*)ipaddr)->nodes,
-								CIL_LIST_ITEM, addr_node);
-				arg->arg = (struct cil_symtab_datum*)ipaddr;
-			} else if (arg_node->data == NULL) {
-				cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
-				cil_destroy_args(arg);
-				rc = SEPOL_ERR;
-				goto exit;
+				cil_list_append(DATUM(ipaddr)->nodes, CIL_LIST_ITEM, addr_node);
+				arg->arg = DATUM(ipaddr);
 			} else {
 				arg->arg_str = arg_node->data;
 			}
-
 			break;
 		}
 		case CIL_CLASS:
-- 
2.32.0