fix CVE-2021-36084 CVE-2021-36085 CVE-2021-36087
This commit is contained in:
parent
58f0ff44fb
commit
f3e662f15f
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
|
||||
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 <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
|
||||
- fix CVE-2021-36086
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user