!59 fix CVE-2021-36084 CVE-2021-36085 CVE-2021-36087
From: @jinlun123123 Reviewed-by: @HuaxinLuGitee Signed-off-by: @HuaxinLuGitee
This commit is contained in:
commit
74d88c96ef
94
backport-CVE-2021-36084.patch
Normal file
94
backport-CVE-2021-36084.patch
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
From f34d3d30c8325e4847a6b696fe7a3936a8a361f3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: James Carter <jwcart2@gmail.com>
|
||||||
|
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 <nicolas.iooss@m4x.org>
|
||||||
|
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||||
|
---
|
||||||
|
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)
|
||||||
33
backport-CVE-2021-36085.patch
Normal file
33
backport-CVE-2021-36085.patch
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
From 2d35fcc7e9e976a2346b1de20e54f8663e8a6cba Mon Sep 17 00:00:00 2001
|
||||||
|
From: James Carter <jwcart2@gmail.com>
|
||||||
|
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 <jwcart2@gmail.com>
|
||||||
|
---
|
||||||
|
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)
|
||||||
148
backport-CVE-2021-36087.patch
Normal file
148
backport-CVE-2021-36087.patch
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
From 340f0eb7f3673e8aacaf0a96cbfcd4d12a405521 Mon Sep 17 00:00:00 2001
|
||||||
|
From: James Carter <jwcart2@gmail.com>
|
||||||
|
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 <jwcart2@gmail.com>
|
||||||
|
---
|
||||||
|
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;
|
||||||
@ -0,0 +1,88 @@
|
|||||||
|
From f043078f1debeb1c84d4f6943aa689c33dd9cefc Mon Sep 17 00:00:00 2001
|
||||||
|
From: James Carter <jwcart2@gmail.com>
|
||||||
|
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 <jwcart2@gmail.com>
|
||||||
|
---
|
||||||
|
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)
|
||||||
@ -0,0 +1,95 @@
|
|||||||
|
From ab90cb46abd4cfc5927f48c7b61782aa97e2561f Mon Sep 17 00:00:00 2001
|
||||||
|
From: James Carter <jwcart2@gmail.com>
|
||||||
|
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 <jwcart2@gmail.com>
|
||||||
|
---
|
||||||
|
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;
|
||||||
|
}
|
||||||
@ -0,0 +1,216 @@
|
|||||||
|
From 69bfe64cdf659cc47c544e6b376f0a653ff06f6f Mon Sep 17 00:00:00 2001
|
||||||
|
From: James Carter <jwcart2@gmail.com>
|
||||||
|
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 <jwcart2@gmail.com>
|
||||||
|
---
|
||||||
|
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) {
|
||||||
@ -1,6 +1,6 @@
|
|||||||
Name: libsepol
|
Name: libsepol
|
||||||
Version: 3.1
|
Version: 3.1
|
||||||
Release: 8
|
Release: 9
|
||||||
Summary: SELinux binary policy manipulation library
|
Summary: SELinux binary policy manipulation library
|
||||||
License: LGPLv2+
|
License: LGPLv2+
|
||||||
URL: https://github.com/SELinuxProject/selinux/wiki/Releases
|
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
|
Patch38: backport-libsepol-cil-Properly-check-for-parameter-when-inser.patch
|
||||||
Patch39: backport-libsepol-cil-Reset-expandtypeattribute-rules-when-re.patch
|
Patch39: backport-libsepol-cil-Reset-expandtypeattribute-rules-when-re.patch
|
||||||
Patch40: backport-libsepol-cil-do-not-allow-0-in-quoted-strings.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
|
BuildRequires: gcc flex
|
||||||
|
|
||||||
@ -107,6 +113,9 @@ make DESTDIR="%{buildroot}" LIBDIR="%{_libdir}" SHLIBDIR="%{_libdir}" install
|
|||||||
%{_mandir}/man3/*
|
%{_mandir}/man3/*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu Dec 15 2022 jinlun <jinlun@huawei.com> - 3.1-9
|
||||||
|
- fix CVE-2021-36084 CVE-2021-36085 CVE-2021-36087
|
||||||
|
|
||||||
* Thu Jul 7 2022 panxiaohe <panxh.life@foxmail.com> - 3.1-8
|
* Thu Jul 7 2022 panxiaohe <panxh.life@foxmail.com> - 3.1-8
|
||||||
- fix CVE-2021-36086
|
- fix CVE-2021-36086
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user