From f3e662f15f0819f267d30df106fdc3ed12279a8b Mon Sep 17 00:00:00 2001 From: jinlun Date: Thu, 15 Dec 2022 16:47:12 +0800 Subject: [PATCH] fix CVE-2021-36084 CVE-2021-36085 CVE-2021-36087 --- backport-CVE-2021-36084.patch | 94 ++++++++ backport-CVE-2021-36085.patch | 33 +++ backport-CVE-2021-36087.patch | 148 ++++++++++++ ...l-Cleanup-build-AST-helper-functions.patch | 88 +++++++ ...ate-new-first-child-helper-function-.patch | 95 ++++++++ ...rder-checks-for-invalid-rules-when-b.patch | 216 ++++++++++++++++++ libsepol.spec | 13 +- 7 files changed, 685 insertions(+), 2 deletions(-) create mode 100644 backport-CVE-2021-36084.patch create mode 100644 backport-CVE-2021-36085.patch create mode 100644 backport-CVE-2021-36087.patch create mode 100644 backport-libsepol-cil-Cleanup-build-AST-helper-functions.patch create mode 100644 backport-libsepol-cil-Create-new-first-child-helper-function-.patch create mode 100644 backport-libsepol-cil-Reorder-checks-for-invalid-rules-when-b.patch diff --git a/backport-CVE-2021-36084.patch b/backport-CVE-2021-36084.patch new file mode 100644 index 0000000..c1e5e08 --- /dev/null +++ b/backport-CVE-2021-36084.patch @@ -0,0 +1,94 @@ +From f34d3d30c8325e4847a6b696fe7a3936a8a361f3 Mon Sep 17 00:00:00 2001 +From: James Carter +Date: Thu, 8 Apr 2021 13:32:01 -0400 +Subject: [PATCH] libsepol/cil: Destroy classperms list when resetting + classpermission + +Nicolas Iooss reports: + A few months ago, OSS-Fuzz found a crash in the CIL compiler, which + got reported as + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28648 (the title + is misleading, or is caused by another issue that conflicts with the + one I report in this message). Here is a minimized CIL policy which + reproduces the issue: + + (class CLASS (PERM)) + (classorder (CLASS)) + (sid SID) + (sidorder (SID)) + (user USER) + (role ROLE) + (type TYPE) + (category CAT) + (categoryorder (CAT)) + (sensitivity SENS) + (sensitivityorder (SENS)) + (sensitivitycategory SENS (CAT)) + (allow TYPE self (CLASS (PERM))) + (roletype ROLE TYPE) + (userrole USER ROLE) + (userlevel USER (SENS)) + (userrange USER ((SENS)(SENS (CAT)))) + (sidcontext SID (USER ROLE TYPE ((SENS)(SENS)))) + + (classpermission CLAPERM) + + (optional OPT + (roletype nonexistingrole nonexistingtype) + (classpermissionset CLAPERM (CLASS (PERM))) + ) + + The CIL policy fuzzer (which mimics secilc built with clang Address + Sanitizer) reports: + + ==36541==ERROR: AddressSanitizer: heap-use-after-free on address + 0x603000004f98 at pc 0x56445134c842 bp 0x7ffe2a256590 sp + 0x7ffe2a256588 + READ of size 8 at 0x603000004f98 thread T0 + #0 0x56445134c841 in __cil_verify_classperms + /selinux/libsepol/src/../cil/src/cil_verify.c:1620:8 + #1 0x56445134a43e in __cil_verify_classpermission + /selinux/libsepol/src/../cil/src/cil_verify.c:1650:9 + #2 0x56445134a43e in __cil_pre_verify_helper + /selinux/libsepol/src/../cil/src/cil_verify.c:1715:8 + #3 0x5644513225ac in cil_tree_walk_core + /selinux/libsepol/src/../cil/src/cil_tree.c:272:9 + #4 0x564451322ab1 in cil_tree_walk + /selinux/libsepol/src/../cil/src/cil_tree.c:316:7 + #5 0x5644513226af in cil_tree_walk_core + /selinux/libsepol/src/../cil/src/cil_tree.c:284:9 + #6 0x564451322ab1 in cil_tree_walk + /selinux/libsepol/src/../cil/src/cil_tree.c:316:7 + #7 0x5644512b88fd in cil_pre_verify + /selinux/libsepol/src/../cil/src/cil_post.c:2510:7 + #8 0x5644512b88fd in cil_post_process + /selinux/libsepol/src/../cil/src/cil_post.c:2524:7 + #9 0x5644511856ff in cil_compile + /selinux/libsepol/src/../cil/src/cil.c:564:7 + +The classperms list of a classpermission rule is created and filled +in when classpermissionset rules are processed, so it doesn't own any +part of the list and shouldn't retain any of it when it is reset. + +Destroy the classperms list (without destroying the data in it) when +resetting a classpermission rule. + +Reported-by: Nicolas Iooss +Signed-off-by: James Carter +--- + libsepol/cil/src/cil_reset_ast.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libsepol/cil/src/cil_reset_ast.c b/libsepol/cil/src/cil_reset_ast.c +index 3da1b9a64..db70a535b 100644 +--- a/libsepol/cil/src/cil_reset_ast.c ++++ b/libsepol/cil/src/cil_reset_ast.c +@@ -54,7 +54,7 @@ static void cil_reset_classpermission(struct cil_classpermission *cp) + return; + } + +- cil_reset_classperms_list(cp->classperms); ++ cil_list_destroy(&cp->classperms, CIL_FALSE); + } + + static void cil_reset_classperms_set(struct cil_classperms_set *cp_set) diff --git a/backport-CVE-2021-36085.patch b/backport-CVE-2021-36085.patch new file mode 100644 index 0000000..fdb13e3 --- /dev/null +++ b/backport-CVE-2021-36085.patch @@ -0,0 +1,33 @@ +From 2d35fcc7e9e976a2346b1de20e54f8663e8a6cba Mon Sep 17 00:00:00 2001 +From: James Carter +Date: Thu, 8 Apr 2021 13:32:04 -0400 +Subject: [PATCH] libsepol/cil: Destroy classperm list when resetting map perms + +Map perms share the same struct as regular perms, but only the +map perms use the classperms field. This field is a pointer to a +list of classperms that is created and added to when resolving +classmapping rules, so the map permission doesn't own any of the +data in the list and this list should be destroyed when the AST is +reset. + +When resetting a perm, destroy the classperms list without destroying +the data in the list. + +Signed-off-by: James Carter +--- + libsepol/cil/src/cil_reset_ast.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libsepol/cil/src/cil_reset_ast.c b/libsepol/cil/src/cil_reset_ast.c +index db70a535b..89f91e568 100644 +--- a/libsepol/cil/src/cil_reset_ast.c ++++ b/libsepol/cil/src/cil_reset_ast.c +@@ -36,7 +36,7 @@ static void cil_reset_class(struct cil_class *class) + + static void cil_reset_perm(struct cil_perm *perm) + { +- cil_reset_classperms_list(perm->classperms); ++ cil_list_destroy(&perm->classperms, CIL_FALSE); + } + + static inline void cil_reset_classperms(struct cil_classperms *cp) diff --git a/backport-CVE-2021-36087.patch b/backport-CVE-2021-36087.patch new file mode 100644 index 0000000..120ea20 --- /dev/null +++ b/backport-CVE-2021-36087.patch @@ -0,0 +1,148 @@ +From 340f0eb7f3673e8aacaf0a96cbfcd4d12a405521 Mon Sep 17 00:00:00 2001 +From: James Carter +Date: Tue, 30 Mar 2021 13:39:18 -0400 +Subject: [PATCH] libsepol/cil: Check for statements not allowed in optional + blocks + +While there are some checks for invalid statements in an optional +block when resolving the AST, there are no checks when building the +AST. + +OSS-Fuzz found the following policy which caused a null dereference +in cil_tree_get_next_path(). + (blockinherit b3) + (sid SID) + (sidorder(SID)) + (optional o + (ibpkeycon :(1 0)s) + (block b3 + (filecon""block()) + (filecon""block()))) + +The problem is that the blockinherit copies block b3 before +the optional block is disabled. When the optional is disabled, +block b3 is deleted along with everything else in the optional. +Later, when filecon statements with the same path are found an +error message is produced and in trying to find out where the block +was copied from, the reference to the deleted block is used. The +error handling code assumes (rightly) that if something was copied +from a block then that block should still exist. + +It is clear that in-statements, blocks, and macros cannot be in an +optional, because that allows nodes to be copied from the optional +block to somewhere outside even though the optional could be disabled +later. When optionals are disabled the AST is reset and the +resolution is restarted at the point of resolving macro calls, so +anything resolved before macro calls will never be re-resolved. +This includes tunableifs, in-statements, blockinherits, +blockabstracts, and macro definitions. Tunable declarations also +cannot be in an optional block because they are needed to resolve +tunableifs. It should be fine to allow blockinherit statements in +an optional, because that is copying nodes from outside the optional +to the optional and if the optional is later disabled, everything +will be deleted anyway. + +Check and quit with an error if a tunable declaration, in-statement, +block, blockabstract, or macro definition is found within an +optional when either building or resolving the AST. + +Signed-off-by: James Carter +--- + libsepol/cil/src/cil_build_ast.c | 32 ++++++++++++++++++++++++++++++ + libsepol/cil/src/cil_resolve_ast.c | 4 +++- + 2 files changed, 35 insertions(+), 1 deletion(-) + +diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c +index 96c944975..882548585 100644 +--- a/libsepol/cil/src/cil_build_ast.c ++++ b/libsepol/cil/src/cil_build_ast.c +@@ -52,6 +52,7 @@ struct cil_args_build { + struct cil_tree_node *tunif; + struct cil_tree_node *in; + struct cil_tree_node *macro; ++ struct cil_tree_node *optional; + struct cil_tree_node *boolif; + }; + +@@ -6071,6 +6072,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f + struct cil_tree_node *tunif = args->tunif; + struct cil_tree_node *in = args->in; + struct cil_tree_node *macro = args->macro; ++ struct cil_tree_node *optional = args->optional; + struct cil_tree_node *boolif = args->boolif; + struct cil_tree_node *ast_node = NULL; + int rc = SEPOL_ERR; +@@ -6121,6 +6123,18 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f + } + } + ++ if (optional != NULL) { ++ if (parse_current->data == CIL_KEY_TUNABLE || ++ parse_current->data == CIL_KEY_IN || ++ parse_current->data == CIL_KEY_BLOCK || ++ parse_current->data == CIL_KEY_BLOCKABSTRACT || ++ parse_current->data == CIL_KEY_MACRO) { ++ rc = SEPOL_ERR; ++ cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in optionals", (char *)parse_current->data); ++ goto exit; ++ } ++ } ++ + if (boolif != NULL) { + if (parse_current->data != CIL_KEY_TUNABLEIF && + parse_current->data != CIL_KEY_CALL && +@@ -6462,6 +6476,10 @@ int __cil_build_ast_first_child_helper(__attribute__((unused)) struct cil_tree_n + args->macro = ast; + } + ++ if (ast->flavor == CIL_OPTIONAL) { ++ args->optional = ast; ++ } ++ + if (ast->flavor == CIL_BOOLEANIF) { + args->boolif = ast; + } +@@ -6492,6 +6510,19 @@ int __cil_build_ast_last_child_helper(struct cil_tree_node *parse_current, void + args->macro = NULL; + } + ++ if (ast->flavor == CIL_OPTIONAL) { ++ struct cil_tree_node *n = ast->parent; ++ args->optional = NULL; ++ /* Optionals can be nested */ ++ while (n && n->flavor != CIL_ROOT) { ++ if (n->flavor == CIL_OPTIONAL) { ++ args->optional = n; ++ break; ++ } ++ n = n->parent; ++ } ++ } ++ + if (ast->flavor == CIL_BOOLEANIF) { + args->boolif = NULL; + } +@@ -6520,6 +6551,7 @@ int cil_build_ast(struct cil_db *db, struct cil_tree_node *parse_tree, struct ci + extra_args.tunif = NULL; + extra_args.in = NULL; + extra_args.macro = NULL; ++ extra_args.optional = NULL; + extra_args.boolif = NULL; + + rc = cil_tree_walk(parse_tree, __cil_build_ast_node_helper, __cil_build_ast_first_child_helper, __cil_build_ast_last_child_helper, &extra_args); +diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c +index 56295a047..efff0f2ec 100644 +--- a/libsepol/cil/src/cil_resolve_ast.c ++++ b/libsepol/cil/src/cil_resolve_ast.c +@@ -3808,8 +3808,10 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished + + if (optional != NULL) { + if (node->flavor == CIL_TUNABLE || ++ node->flavor == CIL_IN || ++ node->flavor == CIL_BLOCK || ++ node->flavor == CIL_BLOCKABSTRACT || + node->flavor == CIL_MACRO) { +- /* tuanbles and macros are not allowed in optionals*/ + cil_tree_log(node, CIL_ERR, "%s statement is not allowed in optionals", cil_node_to_string(node)); + rc = SEPOL_ERR; + goto exit; diff --git a/backport-libsepol-cil-Cleanup-build-AST-helper-functions.patch b/backport-libsepol-cil-Cleanup-build-AST-helper-functions.patch new file mode 100644 index 0000000..8542170 --- /dev/null +++ b/backport-libsepol-cil-Cleanup-build-AST-helper-functions.patch @@ -0,0 +1,88 @@ +From f043078f1debeb1c84d4f6943aa689c33dd9cefc Mon Sep 17 00:00:00 2001 +From: James Carter +Date: Tue, 30 Mar 2021 13:39:13 -0400 +Subject: [PATCH] libsepol/cil: Cleanup build AST helper functions + +Since parse_current, finished, and extra_args can never be NULL, +remove the useless check and directly assign local variables from +extra_args. + +Signed-off-by: James Carter +--- + libsepol/cil/src/cil_build_ast.c | 44 ++++++++------------------------ + 1 file changed, 10 insertions(+), 34 deletions(-) + +diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c +index eee21086b..0d6d91a7d 100644 +--- a/libsepol/cil/src/cil_build_ast.c ++++ b/libsepol/cil/src/cil_build_ast.c +@@ -6065,28 +6065,16 @@ void cil_destroy_src_info(struct cil_src_info *info) + + int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *finished, void *extra_args) + { +- struct cil_args_build *args = NULL; +- struct cil_tree_node *ast_current = NULL; +- struct cil_db *db = NULL; ++ struct cil_args_build *args = extra_args; ++ struct cil_db *db = args->db; ++ struct cil_tree_node *ast_current = args->ast; ++ struct cil_tree_node *tunif = args->tunif; ++ struct cil_tree_node *in = args->in; ++ struct cil_tree_node *macro = args->macro; ++ struct cil_tree_node *boolif = args->boolif; + struct cil_tree_node *ast_node = NULL; +- struct cil_tree_node *tunif = NULL; +- struct cil_tree_node *in = NULL; +- struct cil_tree_node *macro = NULL; +- struct cil_tree_node *boolif = NULL; + int rc = SEPOL_ERR; + +- if (parse_current == NULL || finished == NULL || extra_args == NULL) { +- goto exit; +- } +- +- args = extra_args; +- ast_current = args->ast; +- db = args->db; +- tunif = args->tunif; +- in = args->in; +- macro = args->macro; +- boolif = args->boolif; +- + if (parse_current->parent->cl_head != parse_current) { + /* ignore anything that isn't following a parenthesis */ + rc = SEPOL_OK; +@@ -6474,20 +6462,11 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f + + int __cil_build_ast_last_child_helper(struct cil_tree_node *parse_current, void *extra_args) + { +- int rc = SEPOL_ERR; +- struct cil_tree_node *ast = NULL; +- struct cil_args_build *args = NULL; +- +- if (extra_args == NULL) { +- goto exit; +- } +- +- args = extra_args; +- ast = args->ast; ++ struct cil_args_build *args = extra_args; ++ struct cil_tree_node *ast = args->ast; + + if (ast->flavor == CIL_ROOT) { +- rc = SEPOL_OK; +- goto exit; ++ return SEPOL_OK; + } + + args->ast = ast->parent; +@@ -6516,9 +6495,6 @@ int __cil_build_ast_last_child_helper(struct cil_tree_node *parse_current, void + cil_tree_children_destroy(parse_current->parent); + + return SEPOL_OK; +- +-exit: +- return rc; + } + + int cil_build_ast(struct cil_db *db, struct cil_tree_node *parse_tree, struct cil_tree_node *ast) diff --git a/backport-libsepol-cil-Create-new-first-child-helper-function-.patch b/backport-libsepol-cil-Create-new-first-child-helper-function-.patch new file mode 100644 index 0000000..bd7a802 --- /dev/null +++ b/backport-libsepol-cil-Create-new-first-child-helper-function-.patch @@ -0,0 +1,95 @@ +From ab90cb46abd4cfc5927f48c7b61782aa97e2561f Mon Sep 17 00:00:00 2001 +From: James Carter +Date: Tue, 30 Mar 2021 13:39:14 -0400 +Subject: [PATCH] libsepol/cil: Create new first child helper function for + building AST + +In order to find statements not allowed in tunableifs, in-statements, +macros, and booleanifs, there are tree node pointers that point to +each of these kinds of statements when its block is being parsed. +If the pointer is non-NULL, then the rule being parsed is in the block +of that kind of statement. + +The tree node pointers were being updated at the wrong point which +prevented an invalid statement from being found if it was the first +statement in the block of a tunableif, in-statement, macro, or +booleanif. + +Create a first child helper function for walking the parse tree and +in that function set the appropriate tree node pointer if the +current AST node is a tunableif, in-statement, macro, or booleanif. +This also makes the code symmetrical with the last child helper +where the tree node pointers are set to NULL. + +Signed-off-by: James Carter +--- + libsepol/cil/src/cil_build_ast.c | 42 +++++++++++++++++++------------- + 1 file changed, 25 insertions(+), 17 deletions(-) + +diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c +index 0d6d91a7d..9836f0445 100644 +--- a/libsepol/cil/src/cil_build_ast.c ++++ b/libsepol/cil/src/cil_build_ast.c +@@ -6429,22 +6429,6 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f + + if (rc == SEPOL_OK) { + if (ast_current->cl_head == NULL) { +- if (ast_current->flavor == CIL_TUNABLEIF) { +- args->tunif = ast_current; +- } +- +- if (ast_current->flavor == CIL_IN) { +- args->in = ast_current; +- } +- +- if (ast_current->flavor == CIL_MACRO) { +- args->macro = ast_current; +- } +- +- if (ast_current->flavor == CIL_BOOLEANIF) { +- args->boolif = ast_current; +- } +- + ast_current->cl_head = ast_node; + } else { + ast_current->cl_tail->next = ast_node; +@@ -6460,6 +6444,30 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f + return rc; + } + ++int __cil_build_ast_first_child_helper(__attribute__((unused)) struct cil_tree_node *parse_current, void *extra_args) ++{ ++ struct cil_args_build *args = extra_args; ++ struct cil_tree_node *ast = args->ast; ++ ++ if (ast->flavor == CIL_TUNABLEIF) { ++ args->tunif = ast; ++ } ++ ++ if (ast->flavor == CIL_IN) { ++ args->in = ast; ++ } ++ ++ if (ast->flavor == CIL_MACRO) { ++ args->macro = ast; ++ } ++ ++ if (ast->flavor == CIL_BOOLEANIF) { ++ args->boolif = ast; ++ } ++ ++ return SEPOL_OK; ++} ++ + int __cil_build_ast_last_child_helper(struct cil_tree_node *parse_current, void *extra_args) + { + struct cil_args_build *args = extra_args; +@@ -6513,7 +6521,7 @@ int cil_build_ast(struct cil_db *db, struct cil_tree_node *parse_tree, struct ci + extra_args.macro = NULL; + extra_args.boolif = NULL; + +- rc = cil_tree_walk(parse_tree, __cil_build_ast_node_helper, NULL, __cil_build_ast_last_child_helper, &extra_args); ++ rc = cil_tree_walk(parse_tree, __cil_build_ast_node_helper, __cil_build_ast_first_child_helper, __cil_build_ast_last_child_helper, &extra_args); + if (rc != SEPOL_OK) { + goto exit; + } diff --git a/backport-libsepol-cil-Reorder-checks-for-invalid-rules-when-b.patch b/backport-libsepol-cil-Reorder-checks-for-invalid-rules-when-b.patch new file mode 100644 index 0000000..51ce88c --- /dev/null +++ b/backport-libsepol-cil-Reorder-checks-for-invalid-rules-when-b.patch @@ -0,0 +1,216 @@ +From 69bfe64cdf659cc47c544e6b376f0a653ff06f6f Mon Sep 17 00:00:00 2001 +From: James Carter +Date: Tue, 30 Mar 2021 13:39:12 -0400 +Subject: [PATCH] libsepol/cil: Reorder checks for invalid rules when building + AST + +Reorder checks for invalid rules in the blocks of tunableifs, +in-statements, macros, and booleanifs when building the AST for +consistency. + +Order the checks in the same order the blocks will be resolved in, +so tuanbleif, in-statement, macro, booleanif, and then non-block +rules. + +Signed-off-by: James Carter +--- + libsepol/cil/src/cil_build_ast.c | 100 +++++++++++++++---------------- + 1 file changed, 50 insertions(+), 50 deletions(-) + +diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c +index a4a2baa0f..eee21086b 100644 +--- a/libsepol/cil/src/cil_build_ast.c ++++ b/libsepol/cil/src/cil_build_ast.c +@@ -49,10 +49,10 @@ + struct cil_args_build { + struct cil_tree_node *ast; + struct cil_db *db; +- struct cil_tree_node *macro; +- struct cil_tree_node *boolif; + struct cil_tree_node *tunif; + struct cil_tree_node *in; ++ struct cil_tree_node *macro; ++ struct cil_tree_node *boolif; + }; + + int cil_fill_list(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **list) +@@ -6069,10 +6069,10 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f + struct cil_tree_node *ast_current = NULL; + struct cil_db *db = NULL; + struct cil_tree_node *ast_node = NULL; +- struct cil_tree_node *macro = NULL; +- struct cil_tree_node *boolif = NULL; + struct cil_tree_node *tunif = NULL; + struct cil_tree_node *in = NULL; ++ struct cil_tree_node *macro = NULL; ++ struct cil_tree_node *boolif = NULL; + int rc = SEPOL_ERR; + + if (parse_current == NULL || finished == NULL || extra_args == NULL) { +@@ -6082,10 +6082,10 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f + args = extra_args; + ast_current = args->ast; + db = args->db; +- macro = args->macro; +- boolif = args->boolif; + tunif = args->tunif; + in = args->in; ++ macro = args->macro; ++ boolif = args->boolif; + + if (parse_current->parent->cl_head != parse_current) { + /* ignore anything that isn't following a parenthesis */ +@@ -6102,13 +6102,31 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f + goto exit; + } + ++ if (tunif != NULL) { ++ if (parse_current->data == CIL_KEY_TUNABLE) { ++ rc = SEPOL_ERR; ++ cil_tree_log(parse_current, CIL_ERR, "Found tunable"); ++ cil_log(CIL_ERR, "Tunables cannot be defined within tunableif statement\n"); ++ goto exit; ++ } ++ } ++ ++ if (in != NULL) { ++ if (parse_current->data == CIL_KEY_IN) { ++ rc = SEPOL_ERR; ++ cil_tree_log(parse_current, CIL_ERR, "Found in-statement"); ++ cil_log(CIL_ERR, "in-statements cannot be defined within in-statements\n"); ++ goto exit; ++ } ++ } ++ + if (macro != NULL) { +- if (parse_current->data == CIL_KEY_MACRO || +- parse_current->data == CIL_KEY_TUNABLE || ++ if (parse_current->data == CIL_KEY_TUNABLE || + parse_current->data == CIL_KEY_IN || + parse_current->data == CIL_KEY_BLOCK || + parse_current->data == CIL_KEY_BLOCKINHERIT || +- parse_current->data == CIL_KEY_BLOCKABSTRACT) { ++ parse_current->data == CIL_KEY_BLOCKABSTRACT || ++ parse_current->data == CIL_KEY_MACRO) { + rc = SEPOL_ERR; + cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in macros", (char *)parse_current->data); + goto exit; +@@ -6116,15 +6134,15 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f + } + + if (boolif != NULL) { +- if (parse_current->data != CIL_KEY_CONDTRUE && ++ if (parse_current->data != CIL_KEY_TUNABLEIF && ++ parse_current->data != CIL_KEY_CALL && ++ parse_current->data != CIL_KEY_CONDTRUE && + parse_current->data != CIL_KEY_CONDFALSE && +- parse_current->data != CIL_KEY_AUDITALLOW && +- parse_current->data != CIL_KEY_TUNABLEIF && + parse_current->data != CIL_KEY_ALLOW && + parse_current->data != CIL_KEY_DONTAUDIT && ++ parse_current->data != CIL_KEY_AUDITALLOW && + parse_current->data != CIL_KEY_TYPETRANSITION && +- parse_current->data != CIL_KEY_TYPECHANGE && +- parse_current->data != CIL_KEY_CALL) { ++ parse_current->data != CIL_KEY_TYPECHANGE) { + rc = SEPOL_ERR; + cil_tree_log(parse_current, CIL_ERR, "Found %s", (char*)parse_current->data); + if (((struct cil_booleanif*)boolif->data)->preserved_tunable) { +@@ -6138,24 +6156,6 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f + } + } + +- if (tunif != NULL) { +- if (parse_current->data == CIL_KEY_TUNABLE) { +- rc = SEPOL_ERR; +- cil_tree_log(parse_current, CIL_ERR, "Found tunable"); +- cil_log(CIL_ERR, "Tunables cannot be defined within tunableif statement\n"); +- goto exit; +- } +- } +- +- if (in != NULL) { +- if (parse_current->data == CIL_KEY_IN) { +- rc = SEPOL_ERR; +- cil_tree_log(parse_current, CIL_ERR, "Found in-statement"); +- cil_log(CIL_ERR, "in-statements cannot be defined within in-statements\n"); +- goto exit; +- } +- } +- + cil_tree_node_init(&ast_node); + + ast_node->parent = ast_current; +@@ -6441,14 +6441,6 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f + + if (rc == SEPOL_OK) { + if (ast_current->cl_head == NULL) { +- if (ast_current->flavor == CIL_MACRO) { +- args->macro = ast_current; +- } +- +- if (ast_current->flavor == CIL_BOOLEANIF) { +- args->boolif = ast_current; +- } +- + if (ast_current->flavor == CIL_TUNABLEIF) { + args->tunif = ast_current; + } +@@ -6457,6 +6449,14 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f + args->in = ast_current; + } + ++ if (ast_current->flavor == CIL_MACRO) { ++ args->macro = ast_current; ++ } ++ ++ if (ast_current->flavor == CIL_BOOLEANIF) { ++ args->boolif = ast_current; ++ } ++ + ast_current->cl_head = ast_node; + } else { + ast_current->cl_tail->next = ast_node; +@@ -6492,14 +6492,6 @@ int __cil_build_ast_last_child_helper(struct cil_tree_node *parse_current, void + + args->ast = ast->parent; + +- if (ast->flavor == CIL_MACRO) { +- args->macro = NULL; +- } +- +- if (ast->flavor == CIL_BOOLEANIF) { +- args->boolif = NULL; +- } +- + if (ast->flavor == CIL_TUNABLEIF) { + args->tunif = NULL; + } +@@ -6508,6 +6500,14 @@ int __cil_build_ast_last_child_helper(struct cil_tree_node *parse_current, void + args->in = NULL; + } + ++ if (ast->flavor == CIL_MACRO) { ++ args->macro = NULL; ++ } ++ ++ if (ast->flavor == CIL_BOOLEANIF) { ++ args->boolif = NULL; ++ } ++ + // At this point we no longer have any need for parse_current or any of its + // siblings; they have all been converted to the appropriate AST node. The + // full parse tree will get deleted elsewhere, but in an attempt to +@@ -6532,10 +6532,10 @@ int cil_build_ast(struct cil_db *db, struct cil_tree_node *parse_tree, struct ci + + extra_args.ast = ast; + extra_args.db = db; +- extra_args.macro = NULL; +- extra_args.boolif = NULL; + extra_args.tunif = NULL; + extra_args.in = NULL; ++ extra_args.macro = NULL; ++ extra_args.boolif = NULL; + + rc = cil_tree_walk(parse_tree, __cil_build_ast_node_helper, NULL, __cil_build_ast_last_child_helper, &extra_args); + if (rc != SEPOL_OK) { diff --git a/libsepol.spec b/libsepol.spec index 6ffc85c..b841ab4 100644 --- a/libsepol.spec +++ b/libsepol.spec @@ -1,6 +1,6 @@ Name: libsepol Version: 3.1 -Release: 8 +Release: 9 Summary: SELinux binary policy manipulation library License: LGPLv2+ URL: https://github.com/SELinuxProject/selinux/wiki/Releases @@ -47,7 +47,13 @@ Patch37: backport-libsepol-cil-fix-NULL-pointer-dereference-in-__cil_i.pa Patch38: backport-libsepol-cil-Properly-check-for-parameter-when-inser.patch Patch39: backport-libsepol-cil-Reset-expandtypeattribute-rules-when-re.patch Patch40: backport-libsepol-cil-do-not-allow-0-in-quoted-strings.patch -Patch41: backport-CVE-2021-36086.patch +Patch41: backport-CVE-2021-36084.patch +Patch42: backport-CVE-2021-36085.patch +Patch43: backport-CVE-2021-36086.patch +Patch44: backport-libsepol-cil-Reorder-checks-for-invalid-rules-when-b.patch +Patch45: backport-libsepol-cil-Cleanup-build-AST-helper-functions.patch +Patch46: backport-libsepol-cil-Create-new-first-child-helper-function-.patch +Patch47: backport-CVE-2021-36087.patch BuildRequires: gcc flex @@ -107,6 +113,9 @@ make DESTDIR="%{buildroot}" LIBDIR="%{_libdir}" SHLIBDIR="%{_libdir}" install %{_mandir}/man3/* %changelog +* Thu Dec 15 2022 jinlun - 3.1-9 +- fix CVE-2021-36084 CVE-2021-36085 CVE-2021-36087 + * Thu Jul 7 2022 panxiaohe - 3.1-8 - fix CVE-2021-36086