Blame SOURCES/0053-libsepol-cil-Handle-disabled-optional-blocks-in-earl.patch

71cd55
From 5661efd459e7aa998390ab70e3ec50125a35e9e9 Mon Sep 17 00:00:00 2001
71cd55
From: James Carter <jwcart2@gmail.com>
71cd55
Date: Thu, 13 May 2021 12:30:37 -0400
71cd55
Subject: [PATCH] libsepol/cil: Handle disabled optional blocks in earlier
71cd55
 passes
71cd55
71cd55
A failed tunable resolution in a tunableif can cause an optional
71cd55
to be disabled before the CIL_PASS_CALL1 phase. If this occurs, the
71cd55
optional block and its subtree should be destroyed, but no reset
71cd55
will be required since tunables are not allowed inside an optional
71cd55
block.
71cd55
71cd55
Anytime there are optional blocks in the disabled_optionals list
71cd55
(changed == 1), destroy the optional block and its subtree even if
71cd55
in a pass before CIL_PASS_CALL1.
71cd55
71cd55
This bug was found by the secilc-fuzzer.
71cd55
71cd55
Signed-off-by: James Carter <jwcart2@gmail.com>
71cd55
---
71cd55
 libsepol/cil/src/cil_resolve_ast.c | 54 ++++++++++++++++--------------
71cd55
 1 file changed, 28 insertions(+), 26 deletions(-)
71cd55
71cd55
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
71cd55
index 74e5b78f9325..328add0421c5 100644
71cd55
--- a/libsepol/cil/src/cil_resolve_ast.c
71cd55
+++ b/libsepol/cil/src/cil_resolve_ast.c
71cd55
@@ -4132,35 +4132,37 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
71cd55
 			}
71cd55
 		}
71cd55
 
71cd55
-		if (changed && (pass > CIL_PASS_CALL1)) {
71cd55
+		if (changed) {
71cd55
 			struct cil_list_item *item;
71cd55
-			/* Need to re-resolve because an optional was disabled that contained
71cd55
-			 * one or more declarations. We only need to reset to the call1 pass 
71cd55
-			 * because things done in the preceding passes aren't allowed in 
71cd55
-			 * optionals, and thus can't be disabled.
71cd55
-			 * Note: set pass to CIL_PASS_CALL1 because the pass++ will increment 
71cd55
-			 * it to CIL_PASS_CALL2
71cd55
-			 */
71cd55
-			cil_log(CIL_INFO, "Resetting declarations\n");
71cd55
-
71cd55
-			if (pass >= CIL_PASS_MISC1) {
71cd55
-				__cil_ordered_lists_reset(&extra_args.sidorder_lists);
71cd55
-				__cil_ordered_lists_reset(&extra_args.classorder_lists);
71cd55
-				__cil_ordered_lists_reset(&extra_args.unordered_classorder_lists);
71cd55
-				__cil_ordered_lists_reset(&extra_args.catorder_lists);
71cd55
-				__cil_ordered_lists_reset(&extra_args.sensitivityorder_lists);
71cd55
-				cil_list_destroy(&db->sidorder, CIL_FALSE);
71cd55
-				cil_list_destroy(&db->classorder, CIL_FALSE);
71cd55
-				cil_list_destroy(&db->catorder, CIL_FALSE);
71cd55
-				cil_list_destroy(&db->sensitivityorder, CIL_FALSE);
71cd55
-			}
71cd55
+			if (pass > CIL_PASS_CALL1) {
71cd55
+				/* Need to re-resolve because an optional was disabled that contained
71cd55
+				 * one or more declarations. We only need to reset to the call1 pass
71cd55
+				 * because things done in the preceding passes aren't allowed in
71cd55
+				 * optionals, and thus can't be disabled.
71cd55
+				 * Note: set pass to CIL_PASS_CALL1 because the pass++ will increment
71cd55
+				 * it to CIL_PASS_CALL2
71cd55
+				 */
71cd55
+				cil_log(CIL_INFO, "Resetting declarations\n");
71cd55
+
71cd55
+				if (pass >= CIL_PASS_MISC1) {
71cd55
+					__cil_ordered_lists_reset(&extra_args.sidorder_lists);
71cd55
+					__cil_ordered_lists_reset(&extra_args.classorder_lists);
71cd55
+					__cil_ordered_lists_reset(&extra_args.unordered_classorder_lists);
71cd55
+					__cil_ordered_lists_reset(&extra_args.catorder_lists);
71cd55
+					__cil_ordered_lists_reset(&extra_args.sensitivityorder_lists);
71cd55
+					cil_list_destroy(&db->sidorder, CIL_FALSE);
71cd55
+					cil_list_destroy(&db->classorder, CIL_FALSE);
71cd55
+					cil_list_destroy(&db->catorder, CIL_FALSE);
71cd55
+					cil_list_destroy(&db->sensitivityorder, CIL_FALSE);
71cd55
+				}
71cd55
 
71cd55
-			pass = CIL_PASS_CALL1;
71cd55
+				pass = CIL_PASS_CALL1;
71cd55
 
71cd55
-			rc = cil_reset_ast(current);
71cd55
-			if (rc != SEPOL_OK) {
71cd55
-				cil_log(CIL_ERR, "Failed to reset declarations\n");
71cd55
-				goto exit;
71cd55
+				rc = cil_reset_ast(current);
71cd55
+				if (rc != SEPOL_OK) {
71cd55
+					cil_log(CIL_ERR, "Failed to reset declarations\n");
71cd55
+					goto exit;
71cd55
+				}
71cd55
 			}
71cd55
 			cil_list_for_each(item, extra_args.disabled_optionals) {
71cd55
 				cil_tree_children_destroy(item->data);
71cd55
-- 
71cd55
2.32.0
71cd55