Blame SOURCES/0052-libsepol-cil-Do-not-resolve-arguments-to-declaration.patch

71cd55
From aa8ac8ffafb9e4121b95a721341371042a3b2994 Mon Sep 17 00:00:00 2001
71cd55
From: James Carter <jwcart2@gmail.com>
71cd55
Date: Tue, 11 May 2021 14:22:53 -0400
71cd55
Subject: [PATCH] libsepol/cil: Do not resolve arguments to declarations in the
71cd55
 call
71cd55
71cd55
Lorenzo Ceragioli <lorenzo.ceragioli@phd.unipi.it> noted that the
71cd55
following policy:
71cd55
  (type a)
71cd55
  (block A
71cd55
    (macro m ((type x))
71cd55
      (type a)
71cd55
      (allow x x (file (read))))
71cd55
  )
71cd55
  (block B
71cd55
    (call A.m(a))
71cd55
  )
71cd55
results in the allow rule (allow B.a B.a (file(read))). This makes
71cd55
no sense because the "a" being passed as an argument has to be the
71cd55
global "a" and not the "a" defined in the macro.
71cd55
71cd55
This behavior occurs because the call arguments are resolved AFTER
71cd55
the macro body has been copied and the declaration of "a" in the
71cd55
macro has been added to block B's namespace, so this is the "a"
71cd55
that the call argument resolves to, rather than the one in the
71cd55
global namespace.
71cd55
71cd55
When resolving call arguments, check if the datum found belongs to
71cd55
a declaration in the call. If it does, then remove the datum from
71cd55
the symbol table, re-resolve the argument, and add the datum back
71cd55
into the symbol table.
71cd55
71cd55
Signed-off-by: James Carter <jwcart2@gmail.com>
71cd55
---
71cd55
 libsepol/cil/src/cil_resolve_ast.c | 28 +++++++++++++++++++++++++++-
71cd55
 1 file changed, 27 insertions(+), 1 deletion(-)
71cd55
71cd55
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
71cd55
index 258fdb1bb69f..74e5b78f9325 100644
71cd55
--- a/libsepol/cil/src/cil_resolve_ast.c
71cd55
+++ b/libsepol/cil/src/cil_resolve_ast.c
71cd55
@@ -3263,11 +3263,37 @@ int cil_resolve_call_args(struct cil_tree_node *current, void *extra_args)
71cd55
 		}
71cd55
 
71cd55
 		if (sym_index != CIL_SYM_UNKNOWN) {
71cd55
-			rc = cil_resolve_name(current, arg->arg_str, sym_index, extra_args, &(arg->arg));
71cd55
+			struct cil_symtab_datum *datum;
71cd55
+			struct cil_tree_node *n;
71cd55
+			rc = cil_resolve_name(current, arg->arg_str, sym_index, extra_args, &datum);
71cd55
 			if (rc != SEPOL_OK) {
71cd55
 				cil_tree_log(current, CIL_ERR, "Failed to resolve %s in call argument list", arg->arg_str);
71cd55
 				goto exit;
71cd55
 			}
71cd55
+			arg->arg = datum;
71cd55
+			n = NODE(datum);
71cd55
+			while (n && n->flavor != CIL_ROOT) {
71cd55
+				if (n == current) {
71cd55
+					symtab_t *s = datum->symtab;
71cd55
+					/* Call arg should not resolve to declaration in the call
71cd55
+					 * Need to remove datum temporarily to resolve to a datum outside
71cd55
+					 * the call.
71cd55
+					 */
71cd55
+					cil_symtab_remove_datum(datum);
71cd55
+					rc = cil_resolve_name(current, arg->arg_str, sym_index, extra_args, &(arg->arg));
71cd55
+					if (rc != SEPOL_OK) {
71cd55
+						cil_tree_log(current, CIL_ERR, "Failed to resolve %s in call argument list", arg->arg_str);
71cd55
+						goto exit;
71cd55
+					}
71cd55
+					rc = cil_symtab_insert(s, datum->name, datum, NULL);
71cd55
+					if (rc != SEPOL_OK) {
71cd55
+						cil_tree_log(current, CIL_ERR, "Failed to re-insert datum while resolving %s in call argument list", arg->arg_str);
71cd55
+						goto exit;
71cd55
+					}
71cd55
+					break;
71cd55
+				}
71cd55
+				n = n->parent;
71cd55
+			}
71cd55
 		}
71cd55
 	}
71cd55
 
71cd55
-- 
71cd55
2.32.0
71cd55