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