commit
97016e0f05
@ -1,276 +0,0 @@
|
|||||||
From 67a8dc8117e0c3887c39f7add8932e4ad23c1d9c Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Carter <jwcart2@gmail.com>
|
|
||||||
Date: Wed, 16 Jun 2021 17:04:00 -0400
|
|
||||||
Subject: [PATCH] libsepol/cil: Allow duplicate optional blocks in most cases
|
|
||||||
|
|
||||||
The commit d155b410d4bbc90d28f361b966f0429598da8188 (libsepol/cil:
|
|
||||||
Check for duplicate blocks, optionals, and macros) fixed a bug
|
|
||||||
that allowed duplicate blocks, optionals, and macros with the same
|
|
||||||
name in the same namespace. For blocks and macros, a duplicate
|
|
||||||
is always a problem, but optional block names are only used for
|
|
||||||
in-statement resolution. If no in-statement refers to an optional
|
|
||||||
block, then it does not matter if more than one with same name
|
|
||||||
exists.
|
|
||||||
|
|
||||||
One easy way to generate multiple optional blocks with the same
|
|
||||||
name declaration is to call a macro with an optional block multiple
|
|
||||||
times in the same namespace.
|
|
||||||
|
|
||||||
As an example, here is a portion of CIL policy
|
|
||||||
(macro m1 ((type t))
|
|
||||||
(optional op1
|
|
||||||
(allow t self (CLASS (PERM)))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(type t1)
|
|
||||||
(call m1 (t1))
|
|
||||||
(type t2)
|
|
||||||
(call m1 (t2))
|
|
||||||
This will result in two optional blocks with the name op1.
|
|
||||||
|
|
||||||
There are three parts to allowing multiple optional blocks with
|
|
||||||
the same name declaration.
|
|
||||||
|
|
||||||
1) Track an optional block's enabled status in a different way.
|
|
||||||
|
|
||||||
One hinderance to allowing multiple optional blocks with the same
|
|
||||||
name declaration is that they cannot share the same datum. This is
|
|
||||||
because the datum is used to get the struct cil_optional which has
|
|
||||||
the enabled field and each block's enabled status is independent of
|
|
||||||
the others.
|
|
||||||
|
|
||||||
Remove the enabled field from struct cil_optional, so it only contains
|
|
||||||
the datum. Use a stack to track which optional blocks are being
|
|
||||||
disabled, so they can be deleted in the right order.
|
|
||||||
|
|
||||||
2) Allow multiple declarations of optional blocks.
|
|
||||||
|
|
||||||
Update cil_allow_multiple_decls() so that a flavor of CIL_OPTIONAL
|
|
||||||
will return CIL_TRUE. Also remove the check in cil_copy_optional().
|
|
||||||
|
|
||||||
3) Check if an in-statement refers to an optional with multiple
|
|
||||||
declarations and exit with an error if it does.
|
|
||||||
|
|
||||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
|
||||||
Acked-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil.c | 1 -
|
|
||||||
libsepol/cil/src/cil_build_ast.c | 3 +++
|
|
||||||
libsepol/cil/src/cil_copy_ast.c | 11 +-------
|
|
||||||
libsepol/cil/src/cil_internal.h | 1 -
|
|
||||||
libsepol/cil/src/cil_resolve_ast.c | 55 +++++++++++++++++++++++---------------
|
|
||||||
5 files changed, 37 insertions(+), 34 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c
|
|
||||||
index 0d351b4..671b5ec 100644
|
|
||||||
--- a/libsepol/cil/src/cil.c
|
|
||||||
+++ b/libsepol/cil/src/cil.c
|
|
||||||
@@ -2752,7 +2752,6 @@ void cil_call_init(struct cil_call **call)
|
|
||||||
void cil_optional_init(struct cil_optional **optional)
|
|
||||||
{
|
|
||||||
*optional = cil_malloc(sizeof(**optional));
|
|
||||||
- (*optional)->enabled = CIL_TRUE;
|
|
||||||
cil_symtab_datum_init(&(*optional)->datum);
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
|
|
||||||
index 71ddada..ea665a3 100644
|
|
||||||
--- a/libsepol/cil/src/cil_build_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_build_ast.c
|
|
||||||
@@ -96,6 +96,9 @@ static int cil_allow_multiple_decls(struct cil_db *db, enum cil_flavor f_new, en
|
|
||||||
return CIL_TRUE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
+ case CIL_OPTIONAL:
|
|
||||||
+ return CIL_TRUE;
|
|
||||||
+ break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
diff --git a/libsepol/cil/src/cil_copy_ast.c b/libsepol/cil/src/cil_copy_ast.c
|
|
||||||
index 954eab3..9c0231f 100644
|
|
||||||
--- a/libsepol/cil/src/cil_copy_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_copy_ast.c
|
|
||||||
@@ -1529,19 +1529,10 @@ int cil_copy_macro(__attribute__((unused)) struct cil_db *db, void *data, void *
|
|
||||||
return SEPOL_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
-int cil_copy_optional(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
|
|
||||||
+int cil_copy_optional(__attribute__((unused)) struct cil_db *db, __attribute__((unused)) void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
|
|
||||||
{
|
|
||||||
- struct cil_optional *orig = data;
|
|
||||||
- char *key = orig->datum.name;
|
|
||||||
- struct cil_symtab_datum *datum = NULL;
|
|
||||||
struct cil_optional *new;
|
|
||||||
|
|
||||||
- cil_symtab_get_datum(symtab, key, &datum);
|
|
||||||
- if (datum != NULL) {
|
|
||||||
- cil_tree_log(NODE(datum), CIL_ERR, "Re-declaration of %s %s", cil_node_to_string(NODE(datum)), key);
|
|
||||||
- return SEPOL_ERR;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
cil_optional_init(&new);
|
|
||||||
*copy = new;
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_internal.h b/libsepol/cil/src/cil_internal.h
|
|
||||||
index a77c952..24be09a 100644
|
|
||||||
--- a/libsepol/cil/src/cil_internal.h
|
|
||||||
+++ b/libsepol/cil/src/cil_internal.h
|
|
||||||
@@ -358,7 +358,6 @@ struct cil_in {
|
|
||||||
|
|
||||||
struct cil_optional {
|
|
||||||
struct cil_symtab_datum datum;
|
|
||||||
- int enabled;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct cil_perm {
|
|
||||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
index b5199ba..6d13544 100644
|
|
||||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
@@ -46,12 +46,13 @@
|
|
||||||
#include "cil_verify.h"
|
|
||||||
#include "cil_strpool.h"
|
|
||||||
#include "cil_symtab.h"
|
|
||||||
+#include "cil_stack.h"
|
|
||||||
|
|
||||||
struct cil_args_resolve {
|
|
||||||
struct cil_db *db;
|
|
||||||
enum cil_pass pass;
|
|
||||||
uint32_t *changed;
|
|
||||||
- struct cil_list *disabled_optionals;
|
|
||||||
+ struct cil_list *to_destroy;
|
|
||||||
struct cil_tree_node *block;
|
|
||||||
struct cil_tree_node *macro;
|
|
||||||
struct cil_tree_node *optional;
|
|
||||||
@@ -62,6 +63,7 @@ struct cil_args_resolve {
|
|
||||||
struct cil_list *catorder_lists;
|
|
||||||
struct cil_list *sensitivityorder_lists;
|
|
||||||
struct cil_list *in_list;
|
|
||||||
+ struct cil_stack *disabled_optionals;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct cil_name * __cil_insert_name(struct cil_db *db, hashtab_key_t key, struct cil_tree_node *ast_node)
|
|
||||||
@@ -2552,6 +2554,15 @@ int cil_resolve_in(struct cil_tree_node *current, void *extra_args)
|
|
||||||
|
|
||||||
block_node = NODE(block_datum);
|
|
||||||
|
|
||||||
+ if (block_node->flavor == CIL_OPTIONAL) {
|
|
||||||
+ if (block_datum->nodes && block_datum->nodes->head != block_datum->nodes->tail) {
|
|
||||||
+ cil_tree_log(current, CIL_ERR, "Multiple optional blocks referred to by in-statement");
|
|
||||||
+ cil_tree_log(block_node, CIL_ERR, "First optional block");
|
|
||||||
+ rc = SEPOL_ERR;
|
|
||||||
+ goto exit;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
rc = cil_copy_ast(db, current, block_node);
|
|
||||||
if (rc != SEPOL_OK) {
|
|
||||||
cil_tree_log(current, CIL_ERR, "Failed to copy in-statement");
|
|
||||||
@@ -3874,6 +3885,7 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished
|
|
||||||
struct cil_tree_node *macro = args->macro;
|
|
||||||
struct cil_tree_node *optional = args->optional;
|
|
||||||
struct cil_tree_node *boolif = args->boolif;
|
|
||||||
+ struct cil_stack *disabled_optionals = args->disabled_optionals;
|
|
||||||
|
|
||||||
if (node == NULL) {
|
|
||||||
goto exit;
|
|
||||||
@@ -3953,22 +3965,14 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished
|
|
||||||
|
|
||||||
rc = __cil_resolve_ast_node(node, extra_args);
|
|
||||||
if (rc == SEPOL_ENOENT) {
|
|
||||||
- enum cil_log_level lvl = CIL_ERR;
|
|
||||||
-
|
|
||||||
- if (optional != NULL) {
|
|
||||||
- struct cil_optional *opt = (struct cil_optional *)optional->data;
|
|
||||||
- struct cil_tree_node *opt_node = NODE(opt);
|
|
||||||
-
|
|
||||||
- lvl = CIL_INFO;
|
|
||||||
- /* disable an optional if something failed to resolve */
|
|
||||||
- opt->enabled = CIL_FALSE;
|
|
||||||
- cil_tree_log(node, lvl, "Failed to resolve %s statement", cil_node_to_string(node));
|
|
||||||
- cil_tree_log(opt_node, lvl, "Disabling optional '%s'", opt->datum.name);
|
|
||||||
+ if (optional == NULL) {
|
|
||||||
+ cil_tree_log(node, CIL_ERR, "Failed to resolve %s statement", cil_node_to_string(node));
|
|
||||||
+ } else {
|
|
||||||
+ cil_stack_push(disabled_optionals, CIL_NODE, optional);
|
|
||||||
+ cil_tree_log(node, CIL_INFO, "Failed to resolve %s statement", cil_node_to_string(node));
|
|
||||||
+ cil_tree_log(optional, CIL_INFO, "Disabling optional '%s'", DATUM(optional->data)->name);
|
|
||||||
rc = SEPOL_OK;
|
|
||||||
- goto exit;
|
|
||||||
}
|
|
||||||
-
|
|
||||||
- cil_tree_log(node, lvl, "Failed to resolve %s statement", cil_node_to_string(node));
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -4011,6 +4015,7 @@ int __cil_resolve_ast_last_child_helper(struct cil_tree_node *current, void *ext
|
|
||||||
{
|
|
||||||
int rc = SEPOL_ERR;
|
|
||||||
struct cil_args_resolve *args = extra_args;
|
|
||||||
+ struct cil_stack *disabled_optionals = args->disabled_optionals;
|
|
||||||
struct cil_tree_node *parent = NULL;
|
|
||||||
|
|
||||||
if (current == NULL || extra_args == NULL) {
|
|
||||||
@@ -4033,9 +4038,11 @@ int __cil_resolve_ast_last_child_helper(struct cil_tree_node *current, void *ext
|
|
||||||
args->macro = NULL;
|
|
||||||
} else if (parent->flavor == CIL_OPTIONAL) {
|
|
||||||
struct cil_tree_node *n = parent->parent;
|
|
||||||
- if (((struct cil_optional *)parent->data)->enabled == CIL_FALSE) {
|
|
||||||
+ struct cil_stack_item *item = cil_stack_peek(disabled_optionals);
|
|
||||||
+ if (item && item->data == parent) {
|
|
||||||
+ cil_stack_pop(disabled_optionals);
|
|
||||||
*(args->changed) = CIL_TRUE;
|
|
||||||
- cil_list_append(args->disabled_optionals, CIL_NODE, parent);
|
|
||||||
+ cil_list_append(args->to_destroy, CIL_NODE, parent);
|
|
||||||
}
|
|
||||||
args->optional = NULL;
|
|
||||||
while (n && n->flavor != CIL_ROOT) {
|
|
||||||
@@ -4079,14 +4086,17 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
|
|
||||||
extra_args.catorder_lists = NULL;
|
|
||||||
extra_args.sensitivityorder_lists = NULL;
|
|
||||||
extra_args.in_list = NULL;
|
|
||||||
+ extra_args.disabled_optionals = NULL;
|
|
||||||
|
|
||||||
- cil_list_init(&extra_args.disabled_optionals, CIL_NODE);
|
|
||||||
+ cil_list_init(&extra_args.to_destroy, CIL_NODE);
|
|
||||||
cil_list_init(&extra_args.sidorder_lists, CIL_LIST_ITEM);
|
|
||||||
cil_list_init(&extra_args.classorder_lists, CIL_LIST_ITEM);
|
|
||||||
cil_list_init(&extra_args.unordered_classorder_lists, CIL_LIST_ITEM);
|
|
||||||
cil_list_init(&extra_args.catorder_lists, CIL_LIST_ITEM);
|
|
||||||
cil_list_init(&extra_args.sensitivityorder_lists, CIL_LIST_ITEM);
|
|
||||||
cil_list_init(&extra_args.in_list, CIL_IN);
|
|
||||||
+ cil_stack_init(&extra_args.disabled_optionals);
|
|
||||||
+
|
|
||||||
for (pass = CIL_PASS_TIF; pass < CIL_PASS_NUM; pass++) {
|
|
||||||
extra_args.pass = pass;
|
|
||||||
rc = cil_tree_walk(current, __cil_resolve_ast_node_helper, __cil_resolve_ast_first_child_helper, __cil_resolve_ast_last_child_helper, &extra_args);
|
|
||||||
@@ -4179,11 +4189,11 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- cil_list_for_each(item, extra_args.disabled_optionals) {
|
|
||||||
+ cil_list_for_each(item, extra_args.to_destroy) {
|
|
||||||
cil_tree_children_destroy(item->data);
|
|
||||||
}
|
|
||||||
- cil_list_destroy(&extra_args.disabled_optionals, CIL_FALSE);
|
|
||||||
- cil_list_init(&extra_args.disabled_optionals, CIL_NODE);
|
|
||||||
+ cil_list_destroy(&extra_args.to_destroy, CIL_FALSE);
|
|
||||||
+ cil_list_init(&extra_args.to_destroy, CIL_NODE);
|
|
||||||
changed = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4200,8 +4210,9 @@ exit:
|
|
||||||
__cil_ordered_lists_destroy(&extra_args.catorder_lists);
|
|
||||||
__cil_ordered_lists_destroy(&extra_args.sensitivityorder_lists);
|
|
||||||
__cil_ordered_lists_destroy(&extra_args.unordered_classorder_lists);
|
|
||||||
- cil_list_destroy(&extra_args.disabled_optionals, CIL_FALSE);
|
|
||||||
+ cil_list_destroy(&extra_args.to_destroy, CIL_FALSE);
|
|
||||||
cil_list_destroy(&extra_args.in_list, CIL_FALSE);
|
|
||||||
+ cil_stack_destroy(&extra_args.disabled_optionals);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
@ -1,75 +0,0 @@
|
|||||||
From 22fb6f477bf10e834ece9eff84438fcaebf7d2ec Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Carter <jwcart2@gmail.com>
|
|
||||||
Date: Thu, 8 Apr 2021 13:32:14 -0400
|
|
||||||
Subject: [PATCH] libsepol/cil: Allow permission expressions when using map
|
|
||||||
classes
|
|
||||||
|
|
||||||
The following policy will cause a segfault:
|
|
||||||
(class CLASS (PERM))
|
|
||||||
(class C (P1 P2 P3))
|
|
||||||
(classorder (CLASS C))
|
|
||||||
(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))))
|
|
||||||
|
|
||||||
(classmap CM (PM1 PM2 PM3))
|
|
||||||
(classmapping CM PM1 (C (P1)))
|
|
||||||
(classmapping CM PM2 (C (P2)))
|
|
||||||
(classmapping CM PM3 (C (P3)))
|
|
||||||
(allow TYPE self (CM (and (all) (not PM2))))
|
|
||||||
|
|
||||||
The problem is that, while permission expressions are allowed for
|
|
||||||
normal classes, map classes are expected to only have permission
|
|
||||||
lists and no check is done to verify that only a permission list
|
|
||||||
is being used.
|
|
||||||
|
|
||||||
When the above policy is parsed, the "and" and "all" are seen as
|
|
||||||
expression operators, but when the map permissions are converted to
|
|
||||||
normal class and permissions, the permission expression is assumed
|
|
||||||
to be a list of datums and since the operators are not datums a
|
|
||||||
segfault is the result.
|
|
||||||
|
|
||||||
There is no reason to limit map classes to only using a list of
|
|
||||||
permissions and, in fact, it would be better to be able to use them
|
|
||||||
in the same way normal classes are used.
|
|
||||||
|
|
||||||
Allow permissions expressions to be used for map classes by first
|
|
||||||
evaluating the permission expression and then converting the
|
|
||||||
resulting list to normal classes and permissions.
|
|
||||||
|
|
||||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_post.c | 4 ++++
|
|
||||||
1 file changed, 4 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c
|
|
||||||
index fd4758d..05842b6 100644
|
|
||||||
--- a/libsepol/cil/src/cil_post.c
|
|
||||||
+++ b/libsepol/cil/src/cil_post.c
|
|
||||||
@@ -2137,6 +2137,10 @@ static int __evaluate_classperms_list(struct cil_list *classperms, struct cil_db
|
|
||||||
}
|
|
||||||
} else { /* MAP */
|
|
||||||
struct cil_list_item *i = NULL;
|
|
||||||
+ rc = __evaluate_classperms(cp, db);
|
|
||||||
+ if (rc != SEPOL_OK) {
|
|
||||||
+ goto exit;
|
|
||||||
+ }
|
|
||||||
cil_list_for_each(i, cp->perms) {
|
|
||||||
struct cil_perm *cmp = i->data;
|
|
||||||
rc = __evaluate_classperms_list(cmp->classperms, db);
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
@ -1,216 +0,0 @@
|
|||||||
From 8d197879f91337c2c4d972a3dd23bb4b133ff355 Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Carter <jwcart2@gmail.com>
|
|
||||||
Date: Mon, 16 Aug 2021 16:01:39 -0400
|
|
||||||
Subject: [PATCH] libsepol/cil: Allow some duplicate macro and block
|
|
||||||
declarations
|
|
||||||
|
|
||||||
The commit d155b410d4bbc90d28f361b966f0429598da8188 (libsepol/cil:
|
|
||||||
Check for duplicate blocks, optionals, and macros) added checks when
|
|
||||||
copying blocks, macros, and optionals so that a duplicate would cause
|
|
||||||
an exit with an error. Unfortunately, some policies exist that depend
|
|
||||||
on this behavior when using inheritance.
|
|
||||||
|
|
||||||
The behavior is as follows.
|
|
||||||
|
|
||||||
For macros only the first declared macro matters.
|
|
||||||
;
|
|
||||||
(macro m ((type ARG1))
|
|
||||||
(allow ARG1 self (CLASS (PERM1)))
|
|
||||||
)
|
|
||||||
(block b
|
|
||||||
(macro m ((type ARG1))
|
|
||||||
(allow ARG1 self (CLASS (PERM2)))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(blockinherit b)
|
|
||||||
(type t)
|
|
||||||
(call m (t))
|
|
||||||
;
|
|
||||||
For this policy segment, the macro m in block b will not be called.
|
|
||||||
Only the original macro m will be.
|
|
||||||
|
|
||||||
This behavior has been used to override macros that are going to
|
|
||||||
be inherited. Only the inherited macros that have not already been
|
|
||||||
declared in the destination namespace will be used.
|
|
||||||
|
|
||||||
Blocks seem to work fine even though there are two of them
|
|
||||||
;
|
|
||||||
(block b1
|
|
||||||
(blockinherit b2)
|
|
||||||
(block b
|
|
||||||
(type t1)
|
|
||||||
(allow t1 self (CLASS (PERM)))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(block b2
|
|
||||||
(block b
|
|
||||||
(type t2)
|
|
||||||
(allow t2 self (CLASS (PERM)))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(blockinherit b1)
|
|
||||||
;
|
|
||||||
In this example, the blockinherit of b2 will cause there to be
|
|
||||||
two block b's in block b1. Note that if both block b's tried to
|
|
||||||
declare the same type, then that would be an error. The blockinherit
|
|
||||||
of b1 will copy both block b's.
|
|
||||||
|
|
||||||
This behavior has been used to allow the use of in-statements for
|
|
||||||
a block that is being inherited. Since the in-statements are resolved
|
|
||||||
before block inheritance, this only works if a block with the same
|
|
||||||
name as the block to be inherited is declared in the namespace.
|
|
||||||
|
|
||||||
To support the use of these two behaviors, allow duplicate blocks
|
|
||||||
and macros when they occur as the result of block inheritance. In
|
|
||||||
any other circumstances and error for a redeclaration will be given.
|
|
||||||
|
|
||||||
Since the duplicate macro is not going to be used it is just skipped.
|
|
||||||
The duplicate block will use the datum of the original block. In both
|
|
||||||
cases a warning message will be produced (it will only be seen if
|
|
||||||
"-v" is used when compiling the policy).
|
|
||||||
|
|
||||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_copy_ast.c | 69 +++++++++++++++++++++++++++++------------
|
|
||||||
1 file changed, 50 insertions(+), 19 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_copy_ast.c b/libsepol/cil/src/cil_copy_ast.c
|
|
||||||
index 34282a9..cdbc84e 100644
|
|
||||||
--- a/libsepol/cil/src/cil_copy_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_copy_ast.c
|
|
||||||
@@ -43,6 +43,7 @@
|
|
||||||
#include "cil_strpool.h"
|
|
||||||
|
|
||||||
struct cil_args_copy {
|
|
||||||
+ struct cil_tree_node *orig_dest;
|
|
||||||
struct cil_tree_node *dest;
|
|
||||||
struct cil_db *db;
|
|
||||||
};
|
|
||||||
@@ -101,17 +102,23 @@ int cil_copy_block(__attribute__((unused)) struct cil_db *db, void *data, void *
|
|
||||||
struct cil_block *orig = data;
|
|
||||||
char *key = orig->datum.name;
|
|
||||||
struct cil_symtab_datum *datum = NULL;
|
|
||||||
- struct cil_block *new;
|
|
||||||
|
|
||||||
cil_symtab_get_datum(symtab, key, &datum);
|
|
||||||
if (datum != NULL) {
|
|
||||||
- cil_tree_log(NODE(datum), CIL_ERR, "Re-declaration of %s %s", cil_node_to_string(NODE(datum)), key);
|
|
||||||
- return SEPOL_ERR;
|
|
||||||
+ if (FLAVOR(datum) != CIL_BLOCK) {
|
|
||||||
+ cil_tree_log(NODE(orig), CIL_ERR, "Block %s being copied", key);
|
|
||||||
+ cil_tree_log(NODE(datum), CIL_ERR, " Conflicts with %s already declared", cil_node_to_string(NODE(datum)));
|
|
||||||
+ return SEPOL_ERR;
|
|
||||||
+ }
|
|
||||||
+ cil_tree_log(NODE(orig), CIL_WARN, "Block %s being copied", key);
|
|
||||||
+ cil_tree_log(NODE(datum), CIL_WARN, " Previously declared");
|
|
||||||
+ *copy = datum;
|
|
||||||
+ } else {
|
|
||||||
+ struct cil_block *new;
|
|
||||||
+ cil_block_init(&new);
|
|
||||||
+ *copy = new;
|
|
||||||
}
|
|
||||||
|
|
||||||
- cil_block_init(&new);
|
|
||||||
- *copy = new;
|
|
||||||
-
|
|
||||||
return SEPOL_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1511,21 +1518,26 @@ int cil_copy_macro(__attribute__((unused)) struct cil_db *db, void *data, void *
|
|
||||||
struct cil_macro *orig = data;
|
|
||||||
char *key = orig->datum.name;
|
|
||||||
struct cil_symtab_datum *datum = NULL;
|
|
||||||
- struct cil_macro *new;
|
|
||||||
|
|
||||||
cil_symtab_get_datum(symtab, key, &datum);
|
|
||||||
if (datum != NULL) {
|
|
||||||
- cil_tree_log(NODE(datum), CIL_ERR, "Re-declaration of %s %s", cil_node_to_string(NODE(datum)), key);
|
|
||||||
- return SEPOL_ERR;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- cil_macro_init(&new);
|
|
||||||
- if (orig->params != NULL) {
|
|
||||||
- cil_copy_list(orig->params, &new->params);
|
|
||||||
+ if (FLAVOR(datum) != CIL_MACRO) {
|
|
||||||
+ cil_tree_log(NODE(orig), CIL_ERR, "Macro %s being copied", key);
|
|
||||||
+ cil_tree_log(NODE(datum), CIL_ERR, " Conflicts with %s already declared", cil_node_to_string(NODE(datum)));
|
|
||||||
+ return SEPOL_ERR;
|
|
||||||
+ }
|
|
||||||
+ cil_tree_log(NODE(orig), CIL_WARN, "Skipping macro %s", key);
|
|
||||||
+ cil_tree_log(NODE(datum), CIL_WARN, " Previously declared");
|
|
||||||
+ *copy = NULL;
|
|
||||||
+ } else {
|
|
||||||
+ struct cil_macro *new;
|
|
||||||
+ cil_macro_init(&new);
|
|
||||||
+ if (orig->params != NULL) {
|
|
||||||
+ cil_copy_list(orig->params, &new->params);
|
|
||||||
+ }
|
|
||||||
+ *copy = new;
|
|
||||||
}
|
|
||||||
|
|
||||||
- *copy = new;
|
|
||||||
-
|
|
||||||
return SEPOL_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1701,7 +1713,7 @@ int cil_copy_src_info(__attribute__((unused)) struct cil_db *db, void *data, voi
|
|
||||||
return SEPOL_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
-int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) uint32_t *finished, void *extra_args)
|
|
||||||
+int __cil_copy_node_helper(struct cil_tree_node *orig, uint32_t *finished, void *extra_args)
|
|
||||||
{
|
|
||||||
int rc = SEPOL_ERR;
|
|
||||||
struct cil_tree_node *parent = NULL;
|
|
||||||
@@ -2006,6 +2018,16 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) u
|
|
||||||
|
|
||||||
rc = (*copy_func)(db, orig->data, &data, symtab);
|
|
||||||
if (rc == SEPOL_OK) {
|
|
||||||
+ if (orig->flavor == CIL_MACRO && data == NULL) {
|
|
||||||
+ /* Skipping macro re-declaration */
|
|
||||||
+ if (args->orig_dest->flavor != CIL_BLOCKINHERIT) {
|
|
||||||
+ cil_log(CIL_ERR, " Re-declaration of macro is only allowed when inheriting a block\n");
|
|
||||||
+ return SEPOL_ERR;
|
|
||||||
+ }
|
|
||||||
+ *finished = CIL_TREE_SKIP_HEAD;
|
|
||||||
+ return SEPOL_OK;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
cil_tree_node_init(&new);
|
|
||||||
|
|
||||||
new->parent = parent;
|
|
||||||
@@ -2014,7 +2036,15 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) u
|
|
||||||
new->flavor = orig->flavor;
|
|
||||||
new->data = data;
|
|
||||||
|
|
||||||
- if (orig->flavor >= CIL_MIN_DECLARATIVE) {
|
|
||||||
+ if (orig->flavor == CIL_BLOCK && DATUM(data)->nodes->head != NULL) {
|
|
||||||
+ /* Duplicate block */
|
|
||||||
+ if (args->orig_dest->flavor != CIL_BLOCKINHERIT) {
|
|
||||||
+ cil_log(CIL_ERR, " Re-declaration of block is only allowed when inheriting a block\n");
|
|
||||||
+ rc = SEPOL_ERR;
|
|
||||||
+ goto exit;
|
|
||||||
+ }
|
|
||||||
+ cil_list_append(DATUM(new->data)->nodes, CIL_NODE, new);
|
|
||||||
+ } else if (orig->flavor >= CIL_MIN_DECLARATIVE) {
|
|
||||||
/* Check the flavor of data if was found in the destination symtab */
|
|
||||||
if (DATUM(data)->nodes->head && FLAVOR(data) != orig->flavor) {
|
|
||||||
cil_tree_log(orig, CIL_ERR, "Incompatible flavor when trying to copy %s", DATUM(data)->name);
|
|
||||||
@@ -2099,12 +2129,13 @@ int cil_copy_ast(struct cil_db *db, struct cil_tree_node *orig, struct cil_tree_
|
|
||||||
int rc = SEPOL_ERR;
|
|
||||||
struct cil_args_copy extra_args;
|
|
||||||
|
|
||||||
+ extra_args.orig_dest = dest;
|
|
||||||
extra_args.dest = dest;
|
|
||||||
extra_args.db = db;
|
|
||||||
|
|
||||||
rc = cil_tree_walk(orig, __cil_copy_node_helper, NULL, __cil_copy_last_child_helper, &extra_args);
|
|
||||||
if (rc != SEPOL_OK) {
|
|
||||||
- cil_log(CIL_INFO, "cil_tree_walk failed, rc: %d\n", rc);
|
|
||||||
+ cil_tree_log(dest, CIL_ERR, "Failed to copy %s to %s", cil_node_to_string(orig), cil_node_to_string(dest));
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
@ -1,163 +0,0 @@
|
|||||||
From d155b410d4bbc90d28f361b966f0429598da8188 Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Carter <jwcart2@gmail.com>
|
|
||||||
Date: Tue, 16 Mar 2021 10:26:28 -0400
|
|
||||||
Subject: [PATCH] libsepol/cil: Check for duplicate blocks, optionals, and
|
|
||||||
macros
|
|
||||||
|
|
||||||
In CIL, blocks, optionals, and macros share the same symbol table so
|
|
||||||
that the targets of "in" statements can be located. Because of this,
|
|
||||||
they cannot have the same name in the same namespace, but, because
|
|
||||||
they do not show up in the final policy, they can have the same name
|
|
||||||
as long as they are in different namespaces. Unfortunately, when
|
|
||||||
copying from one namespace to another, no check was being done to see
|
|
||||||
if there was a conflict.
|
|
||||||
|
|
||||||
When copying blocks, optionals, and macros, if a datum is found in
|
|
||||||
the destination namespace, then there is a conflict with a previously
|
|
||||||
declared block, optional, or macro, so exit with an error.
|
|
||||||
|
|
||||||
Reported-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
|
||||||
Reported-by: Evgeny Vereshchagin <evvers@ya.ru>
|
|
||||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_copy_ast.c | 89 ++++++++++++-----------------------------
|
|
||||||
1 file changed, 25 insertions(+), 64 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_copy_ast.c b/libsepol/cil/src/cil_copy_ast.c
|
|
||||||
index c9aada9..ed96786 100644
|
|
||||||
--- a/libsepol/cil/src/cil_copy_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_copy_ast.c
|
|
||||||
@@ -100,16 +100,17 @@ int cil_copy_block(__attribute__((unused)) struct cil_db *db, void *data, void *
|
|
||||||
struct cil_block *orig = data;
|
|
||||||
char *key = orig->datum.name;
|
|
||||||
struct cil_symtab_datum *datum = NULL;
|
|
||||||
+ struct cil_block *new;
|
|
||||||
|
|
||||||
cil_symtab_get_datum(symtab, key, &datum);
|
|
||||||
- if (datum == NULL) {
|
|
||||||
- struct cil_block *new;
|
|
||||||
- cil_block_init(&new);
|
|
||||||
- *copy = new;
|
|
||||||
- } else {
|
|
||||||
- *copy = datum;;
|
|
||||||
+ if (datum != NULL) {
|
|
||||||
+ cil_tree_log(NODE(datum), CIL_ERR, "Re-declaration of %s %s", cil_node_to_string(NODE(datum)), key);
|
|
||||||
+ return SEPOL_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ cil_block_init(&new);
|
|
||||||
+ *copy = new;
|
|
||||||
+
|
|
||||||
return SEPOL_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1509,64 +1510,22 @@ int cil_copy_macro(__attribute__((unused)) struct cil_db *db, void *data, void *
|
|
||||||
struct cil_macro *orig = data;
|
|
||||||
char *key = orig->datum.name;
|
|
||||||
struct cil_symtab_datum *datum = NULL;
|
|
||||||
+ struct cil_macro *new;
|
|
||||||
|
|
||||||
cil_symtab_get_datum(symtab, key, &datum);
|
|
||||||
- if (datum == NULL) {
|
|
||||||
- struct cil_macro *new;
|
|
||||||
- cil_macro_init(&new);
|
|
||||||
- if (orig->params != NULL) {
|
|
||||||
- cil_copy_list(orig->params, &new->params);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- *copy = new;
|
|
||||||
-
|
|
||||||
- } else {
|
|
||||||
- struct cil_list_item *curr_orig = NULL;
|
|
||||||
- struct cil_list_item *curr_new = NULL;
|
|
||||||
- struct cil_param *param_orig = NULL;
|
|
||||||
- struct cil_param *param_new = NULL;
|
|
||||||
-
|
|
||||||
- if (((struct cil_macro*)datum)->params != NULL) {
|
|
||||||
- curr_new = ((struct cil_macro*)datum)->params->head;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- if (orig->params != NULL) {
|
|
||||||
- curr_orig = orig->params->head;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- if (curr_orig != NULL && curr_new != NULL) {
|
|
||||||
- while (curr_orig != NULL) {
|
|
||||||
- if (curr_new == NULL) {
|
|
||||||
- goto exit;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- param_orig = (struct cil_param*)curr_orig->data;
|
|
||||||
- param_new = (struct cil_param*)curr_new->data;
|
|
||||||
- if (param_orig->str != param_new->str) {
|
|
||||||
- goto exit;
|
|
||||||
- } else if (param_orig->flavor != param_new->flavor) {
|
|
||||||
- goto exit;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- curr_orig = curr_orig->next;
|
|
||||||
- curr_new = curr_new->next;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- if (curr_new != NULL) {
|
|
||||||
- goto exit;
|
|
||||||
- }
|
|
||||||
- } else if (!(curr_orig == NULL && curr_new == NULL)) {
|
|
||||||
- goto exit;
|
|
||||||
- }
|
|
||||||
+ if (datum != NULL) {
|
|
||||||
+ cil_tree_log(NODE(datum), CIL_ERR, "Re-declaration of %s %s", cil_node_to_string(NODE(datum)), key);
|
|
||||||
+ return SEPOL_ERR;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- *copy = datum;
|
|
||||||
+ cil_macro_init(&new);
|
|
||||||
+ if (orig->params != NULL) {
|
|
||||||
+ cil_copy_list(orig->params, &new->params);
|
|
||||||
}
|
|
||||||
|
|
||||||
- return SEPOL_OK;
|
|
||||||
+ *copy = new;
|
|
||||||
|
|
||||||
-exit:
|
|
||||||
- cil_log(CIL_INFO, "cil_copy_macro: macro cannot be redefined\n");
|
|
||||||
- return SEPOL_ERR;
|
|
||||||
+ return SEPOL_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cil_copy_optional(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
|
|
||||||
@@ -1574,16 +1533,17 @@ int cil_copy_optional(__attribute__((unused)) struct cil_db *db, void *data, voi
|
|
||||||
struct cil_optional *orig = data;
|
|
||||||
char *key = orig->datum.name;
|
|
||||||
struct cil_symtab_datum *datum = NULL;
|
|
||||||
+ struct cil_optional *new;
|
|
||||||
|
|
||||||
cil_symtab_get_datum(symtab, key, &datum);
|
|
||||||
- if (datum == NULL) {
|
|
||||||
- struct cil_optional *new;
|
|
||||||
- cil_optional_init(&new);
|
|
||||||
- *copy = new;
|
|
||||||
- } else {
|
|
||||||
- *copy = datum;
|
|
||||||
+ if (datum != NULL) {
|
|
||||||
+ cil_tree_log(NODE(datum), CIL_ERR, "Re-declaration of %s %s", cil_node_to_string(NODE(datum)), key);
|
|
||||||
+ return SEPOL_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ cil_optional_init(&new);
|
|
||||||
+ *copy = new;
|
|
||||||
+
|
|
||||||
return SEPOL_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -2122,6 +2082,7 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) u
|
|
||||||
args->dest = new;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
+ cil_tree_log(orig, CIL_ERR, "Problem copying %s node", cil_node_to_string(orig));
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
From f33745a22b4133c59059356a23dbbc229067e3c1 Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Carter <jwcart2@gmail.com>
|
|
||||||
Date: Mon, 21 Jun 2021 10:56:43 -0400
|
|
||||||
Subject: [PATCH] libsepol/cil: Check for empty list when marking neverallow
|
|
||||||
attributes
|
|
||||||
|
|
||||||
When marking a type attribute as used in a neverallow (to help determine
|
|
||||||
whether or not it should be expanded), check if the attribute's expression
|
|
||||||
list is empty (no attributes are associated with it) before iterating
|
|
||||||
over the list.
|
|
||||||
|
|
||||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
|
||||||
Acked-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_post.c | 4 ++++
|
|
||||||
1 file changed, 4 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c
|
|
||||||
index 7bca083..7e2c2b9 100644
|
|
||||||
--- a/libsepol/cil/src/cil_post.c
|
|
||||||
+++ b/libsepol/cil/src/cil_post.c
|
|
||||||
@@ -1494,6 +1494,10 @@ static void __mark_neverallow_attrs(struct cil_list *expr_list)
|
|
||||||
{
|
|
||||||
struct cil_list_item *curr;
|
|
||||||
|
|
||||||
+ if (!expr_list) {
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
cil_list_for_each(curr, expr_list) {
|
|
||||||
if (curr->flavor == CIL_DATUM) {
|
|
||||||
if (FLAVOR(curr->data) == CIL_TYPEATTRIBUTE) {
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
@ -1,115 +0,0 @@
|
|||||||
From 0451adebdf153eee1f69914141311114a0130982 Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Carter <jwcart2@gmail.com>
|
|
||||||
Date: Mon, 8 Feb 2021 11:23:42 -0500
|
|
||||||
Subject: [PATCH] libsepol/cil: Destroy disabled optional blocks after pass is
|
|
||||||
complete
|
|
||||||
|
|
||||||
Nicolas Iooss reports:
|
|
||||||
I am continuing to investigate OSS-Fuzz crashes and the following one
|
|
||||||
is quite complex. Here is a CIL policy which triggers a
|
|
||||||
heap-use-after-free error in the CIL compiler:
|
|
||||||
|
|
||||||
(class CLASS (PERM2))
|
|
||||||
(classorder (CLASS))
|
|
||||||
(classpermission CLSPRM)
|
|
||||||
(optional o
|
|
||||||
(mlsvalidatetrans x (domby l1 h1))
|
|
||||||
(common CLSCOMMON (PERM1))
|
|
||||||
(classcommon CLASS CLSCOMMON)
|
|
||||||
)
|
|
||||||
(classpermissionset CLSPRM (CLASS (PERM1)))
|
|
||||||
|
|
||||||
The issue is that the mlsvalidatetrans fails to resolve in pass
|
|
||||||
CIL_PASS_MISC3, which comes after the resolution of classcommon (in
|
|
||||||
pass CIL_PASS_MISC2). So:
|
|
||||||
|
|
||||||
* In pass CIL_PASS_MISC2, the optional block still exists, the
|
|
||||||
classcommon is resolved and class CLASS is linked with common
|
|
||||||
CLSCOMMON.
|
|
||||||
* In pass CIL_PASS_MISC3, the optional block is destroyed, including
|
|
||||||
the common CLSCOMMON.
|
|
||||||
* When classpermissionset is resolved, function cil_resolve_classperms
|
|
||||||
uses "common_symtab = &class->common->perms;", which has been freed.
|
|
||||||
The use-after-free issue occurs in __cil_resolve_perms (in
|
|
||||||
libsepol/cil/src/cil_resolve_ast.c):
|
|
||||||
|
|
||||||
// common_symtab was freed
|
|
||||||
rc = cil_symtab_get_datum(common_symtab, curr->data, &perm_datum);
|
|
||||||
|
|
||||||
The fundamental problem here is that when the optional block is
|
|
||||||
disabled it is immediately destroyed in the middle of the pass, so
|
|
||||||
the class has not been reset and still refers to the now destroyed
|
|
||||||
common when the classpermissionset is resolved later in the same pass.
|
|
||||||
|
|
||||||
Added a list, disabled_optionals, to struct cil_args_resolve which is
|
|
||||||
passed when resolving the tree. When optionals are disabled, they are
|
|
||||||
now added to this list and then are destroyed after the tree has been
|
|
||||||
reset between passes.
|
|
||||||
|
|
||||||
Reported-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
|
||||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
|
||||||
Acked-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_resolve_ast.c | 11 ++++++++++-
|
|
||||||
1 file changed, 10 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
index 208bc01..0e07856 100644
|
|
||||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
@@ -51,6 +51,7 @@ struct cil_args_resolve {
|
|
||||||
struct cil_db *db;
|
|
||||||
enum cil_pass pass;
|
|
||||||
uint32_t *changed;
|
|
||||||
+ struct cil_list *disabled_optionals;
|
|
||||||
struct cil_tree_node *optstack;
|
|
||||||
struct cil_tree_node *boolif;
|
|
||||||
struct cil_tree_node *macro;
|
|
||||||
@@ -3942,7 +3943,7 @@ int __cil_resolve_ast_last_child_helper(struct cil_tree_node *current, void *ext
|
|
||||||
|
|
||||||
if (((struct cil_optional *)parent->data)->enabled == CIL_FALSE) {
|
|
||||||
*(args->changed) = CIL_TRUE;
|
|
||||||
- cil_tree_children_destroy(parent);
|
|
||||||
+ cil_list_append(args->disabled_optionals, CIL_NODE, parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* pop off the stack */
|
|
||||||
@@ -4005,6 +4006,7 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
|
|
||||||
extra_args.in_list = NULL;
|
|
||||||
extra_args.blockstack = NULL;
|
|
||||||
|
|
||||||
+ cil_list_init(&extra_args.disabled_optionals, CIL_NODE);
|
|
||||||
cil_list_init(&extra_args.sidorder_lists, CIL_LIST_ITEM);
|
|
||||||
cil_list_init(&extra_args.classorder_lists, CIL_LIST_ITEM);
|
|
||||||
cil_list_init(&extra_args.unordered_classorder_lists, CIL_LIST_ITEM);
|
|
||||||
@@ -4072,6 +4074,7 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (changed && (pass > CIL_PASS_CALL1)) {
|
|
||||||
+ struct cil_list_item *item;
|
|
||||||
/* Need to re-resolve because an optional was disabled that contained
|
|
||||||
* one or more declarations. We only need to reset to the call1 pass
|
|
||||||
* because things done in the preceding passes aren't allowed in
|
|
||||||
@@ -4100,6 +4103,11 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
|
|
||||||
cil_log(CIL_ERR, "Failed to reset declarations\n");
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
+ cil_list_for_each(item, extra_args.disabled_optionals) {
|
|
||||||
+ cil_tree_children_destroy(item->data);
|
|
||||||
+ }
|
|
||||||
+ cil_list_destroy(&extra_args.disabled_optionals, CIL_FALSE);
|
|
||||||
+ cil_list_init(&extra_args.disabled_optionals, CIL_NODE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* reset the arguments */
|
|
||||||
@@ -4128,6 +4136,7 @@ exit:
|
|
||||||
__cil_ordered_lists_destroy(&extra_args.catorder_lists);
|
|
||||||
__cil_ordered_lists_destroy(&extra_args.sensitivityorder_lists);
|
|
||||||
__cil_ordered_lists_destroy(&extra_args.unordered_classorder_lists);
|
|
||||||
+ cil_list_destroy(&extra_args.disabled_optionals, CIL_FALSE);
|
|
||||||
cil_list_destroy(&extra_args.in_list, CIL_FALSE);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
@ -1,136 +0,0 @@
|
|||||||
From 74d00a8decebf940d95064ff60042dcb2cbcc2c0 Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Carter <jwcart2@gmail.com>
|
|
||||||
Date: Wed, 28 Apr 2021 16:07:02 -0400
|
|
||||||
Subject: [PATCH] libsepol/cil: Detect degenerate inheritance and exit with an
|
|
||||||
error
|
|
||||||
|
|
||||||
A CIL policy with inheritance of the form
|
|
||||||
...
|
|
||||||
(blockinherit ba)
|
|
||||||
(block ba
|
|
||||||
(block b1
|
|
||||||
(blockinherit bb)
|
|
||||||
)
|
|
||||||
(block bb
|
|
||||||
(block b2
|
|
||||||
(blockinherit bc)
|
|
||||||
)
|
|
||||||
(block bc
|
|
||||||
(block b3
|
|
||||||
(blockinherit bd)
|
|
||||||
)
|
|
||||||
(block bd
|
|
||||||
(block b4
|
|
||||||
(blockinherit be)
|
|
||||||
)
|
|
||||||
(block be
|
|
||||||
...
|
|
||||||
will require creating 2^depth copies of the block at the bottom of
|
|
||||||
the inheritance chain. This pattern can quickly consume all the
|
|
||||||
memory of the system compiling this policy.
|
|
||||||
|
|
||||||
The depth of the inheritance chain can be found be walking the
|
|
||||||
tree up through the parents and noting how many of the parent
|
|
||||||
blocks have been inherited. The number of times a block will be
|
|
||||||
copied is found by counting the list of nodes in the "bi_nodes"
|
|
||||||
list of the block. To minimize legitimate policies from being
|
|
||||||
falsely detected as being degenerate, both the depth and breadth
|
|
||||||
(number of copies) are checked and an error is given only if both
|
|
||||||
exceed the limits (depth >= 12 and breadth >= 4096).
|
|
||||||
|
|
||||||
This problem was found by the secilc-fuzzer.
|
|
||||||
|
|
||||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_internal.h | 2 ++
|
|
||||||
libsepol/cil/src/cil_resolve_ast.c | 54 ++++++++++++++++++++++++++++++++++++++
|
|
||||||
2 files changed, 56 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_internal.h b/libsepol/cil/src/cil_internal.h
|
|
||||||
index 9bdcbdd..74e0b34 100644
|
|
||||||
--- a/libsepol/cil/src/cil_internal.h
|
|
||||||
+++ b/libsepol/cil/src/cil_internal.h
|
|
||||||
@@ -48,6 +48,8 @@
|
|
||||||
|
|
||||||
#define CIL_MAX_NAME_LENGTH 2048
|
|
||||||
|
|
||||||
+#define CIL_DEGENERATE_INHERITANCE_DEPTH 12
|
|
||||||
+#define CIL_DEGENERATE_INHERITANCE_BREADTH (0x1 << CIL_DEGENERATE_INHERITANCE_DEPTH)
|
|
||||||
|
|
||||||
enum cil_pass {
|
|
||||||
CIL_PASS_INIT = 0,
|
|
||||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
index 5389df4..6890964 100644
|
|
||||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
@@ -2410,6 +2410,55 @@ exit:
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
+/*
|
|
||||||
+ * Detect degenerate inheritance of the form:
|
|
||||||
+ * ...
|
|
||||||
+ * (blockinherit ba)
|
|
||||||
+ * (block ba
|
|
||||||
+ * (block b1
|
|
||||||
+ * (blockinherit bb)
|
|
||||||
+ * )
|
|
||||||
+ * (block bb
|
|
||||||
+ * (block b2
|
|
||||||
+ * (blockinherit bc)
|
|
||||||
+ * )
|
|
||||||
+ * (block bc
|
|
||||||
+ * ...
|
|
||||||
+ */
|
|
||||||
+static int cil_check_for_degenerate_inheritance(struct cil_tree_node *current)
|
|
||||||
+{
|
|
||||||
+ struct cil_block *block = current->data;
|
|
||||||
+ struct cil_tree_node *node;
|
|
||||||
+ struct cil_list_item *item;
|
|
||||||
+ unsigned depth;
|
|
||||||
+ unsigned breadth = 0;
|
|
||||||
+
|
|
||||||
+ cil_list_for_each(item, block->bi_nodes) {
|
|
||||||
+ breadth++;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (breadth >= CIL_DEGENERATE_INHERITANCE_BREADTH) {
|
|
||||||
+ node = current->parent;
|
|
||||||
+ depth = 0;
|
|
||||||
+ while (node && node->flavor != CIL_ROOT) {
|
|
||||||
+ if (node->flavor == CIL_BLOCK) {
|
|
||||||
+ block = node->data;
|
|
||||||
+ if (block->bi_nodes != NULL) {
|
|
||||||
+ depth++;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ node = node->parent;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (depth >= CIL_DEGENERATE_INHERITANCE_DEPTH) {
|
|
||||||
+ cil_tree_log(current, CIL_ERR, "Degenerate inheritance detected (depth=%u, breadth=%u)", depth, breadth);
|
|
||||||
+ return SEPOL_ERR;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return SEPOL_OK;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
int cil_resolve_blockinherit_copy(struct cil_tree_node *current, void *extra_args)
|
|
||||||
{
|
|
||||||
struct cil_block *block = current->data;
|
|
||||||
@@ -2426,6 +2475,11 @@ int cil_resolve_blockinherit_copy(struct cil_tree_node *current, void *extra_arg
|
|
||||||
|
|
||||||
db = args->db;
|
|
||||||
|
|
||||||
+ rc = cil_check_for_degenerate_inheritance(current);
|
|
||||||
+ if (rc != SEPOL_OK) {
|
|
||||||
+ goto exit;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
// Make sure this is the original block and not a merged block from a blockinherit
|
|
||||||
if (current != block->datum.nodes->head->data) {
|
|
||||||
rc = SEPOL_OK;
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
@ -1,90 +0,0 @@
|
|||||||
From f0d98f83d28a0cdf437b4cafe229e27cb91eb493 Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Carter <jwcart2@gmail.com>
|
|
||||||
Date: Wed, 6 Jan 2021 13:43:26 -0500
|
|
||||||
Subject: [PATCH] libsepol/cil: Fix heap-use-after-free in
|
|
||||||
__class_reset_perm_values()
|
|
||||||
|
|
||||||
Nicolas Iooss reports:
|
|
||||||
A few weeks ago, OSS-Fuzz got configured in order to fuzz the CIL
|
|
||||||
policy compiler (cf.
|
|
||||||
https://github.com/SELinuxProject/selinux/issues/215 and
|
|
||||||
https://github.com/google/oss-fuzz/pull/4790). It reported a bunch of
|
|
||||||
simple issues, for which I will submit patches. There are also more
|
|
||||||
subtle bugs, like the one triggered by this CIL policy:
|
|
||||||
|
|
||||||
(class CLASS (PERM))
|
|
||||||
(classorder (CLASS))
|
|
||||||
(sid SID)
|
|
||||||
(sidorder (SID))
|
|
||||||
(sensitivity SENS)
|
|
||||||
(sensitivityorder (SENS))
|
|
||||||
(type TYPE)
|
|
||||||
(allow TYPE self (CLASS (PERM)))
|
|
||||||
|
|
||||||
(block b
|
|
||||||
(optional o
|
|
||||||
(sensitivitycategory SENS (C)) ; Non-existing category
|
|
||||||
triggers disabling the optional
|
|
||||||
(common COMMON (PERM1))
|
|
||||||
(classcommon CLASS COMMON)
|
|
||||||
(allow TYPE self (CLASS (PERM1)))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
On my computer, secilc manages to build this policy fine, but when
|
|
||||||
clang's Address Sanitizer is enabled, running secilc leads to the
|
|
||||||
following report:
|
|
||||||
|
|
||||||
$ make -C libsepol/src CC=clang CFLAGS='-g -fsanitize=address' libsepol.a
|
|
||||||
$ clang -g -fsanitize=address secilc/secilc.c libsepol/src/libsepol.a
|
|
||||||
-o my_secilc
|
|
||||||
$ ./my_secilc -vv testcase.cil
|
|
||||||
Parsing testcase.cil
|
|
||||||
Building AST from Parse Tree
|
|
||||||
Destroying Parse Tree
|
|
||||||
Resolving AST
|
|
||||||
Failed to resolve sensitivitycategory statement at testcase.cil:12
|
|
||||||
Disabling optional 'o' at testcase.cil:11
|
|
||||||
Resetting declarations
|
|
||||||
=================================================================
|
|
||||||
==181743==ERROR: AddressSanitizer: heap-use-after-free on address
|
|
||||||
0x6070000000c0 at pc 0x55ff7e445d24 bp 0x7ffe7eecfba0 sp
|
|
||||||
0x7ffe7eecfb98
|
|
||||||
READ of size 4 at 0x6070000000c0 thread T0
|
|
||||||
#0 0x55ff7e445d23 in __class_reset_perm_values
|
|
||||||
/git/selinux-userspace/libsepol/src/../cil/src/cil_reset_ast.c:17:17
|
|
||||||
|
|
||||||
The problem is that the optional branch is destroyed when it is disabled,
|
|
||||||
so the common has already been destroyed when the reset code tries to
|
|
||||||
access the number of common permissions, so that it can change the
|
|
||||||
value of the class permissions back to their original values.
|
|
||||||
|
|
||||||
The solution is to count the number of class permissions and then
|
|
||||||
calculate the number of common permissions.
|
|
||||||
|
|
||||||
Reported-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
|
||||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_reset_ast.c | 7 ++++---
|
|
||||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_reset_ast.c b/libsepol/cil/src/cil_reset_ast.c
|
|
||||||
index 43e6b88e0..52e5f6401 100644
|
|
||||||
--- a/libsepol/cil/src/cil_reset_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_reset_ast.c
|
|
||||||
@@ -22,11 +22,12 @@ static int __class_reset_perm_values(__attribute__((unused)) hashtab_key_t k, ha
|
|
||||||
static void cil_reset_class(struct cil_class *class)
|
|
||||||
{
|
|
||||||
if (class->common != NULL) {
|
|
||||||
- struct cil_class *common = class->common;
|
|
||||||
- cil_symtab_map(&class->perms, __class_reset_perm_values, &common->num_perms);
|
|
||||||
+ /* Must assume that the common has been destroyed */
|
|
||||||
+ int num_common_perms = class->num_perms - class->perms.nprim;
|
|
||||||
+ cil_symtab_map(&class->perms, __class_reset_perm_values, &num_common_perms);
|
|
||||||
/* during a re-resolve, we need to reset the common, so a classcommon
|
|
||||||
* statement isn't seen as a duplicate */
|
|
||||||
- class->num_perms -= common->num_perms;
|
|
||||||
+ class->num_perms = class->perms.nprim;
|
|
||||||
class->common = NULL; /* Must make this NULL or there will be an error when re-resolving */
|
|
||||||
}
|
|
||||||
class->ordered = CIL_FALSE;
|
|
||||||
@ -1,80 +0,0 @@
|
|||||||
From 5681c6275b5ad9cf3d84af243a66b900a0628f72 Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Carter <jwcart2@gmail.com>
|
|
||||||
Date: Wed, 28 Apr 2021 16:06:58 -0400
|
|
||||||
Subject: [PATCH] libsepol/cil: Fix instances where an error returns SEPOL_OK
|
|
||||||
|
|
||||||
There are six instances when the CIL policy is being built or
|
|
||||||
resolved where an error can be detected, but SEPOL_OK is returned
|
|
||||||
instead of SEPOL_ERR. This causes the policy compiler to continue
|
|
||||||
when it should exit with an error.
|
|
||||||
|
|
||||||
Return SEPOL_ERR in these cases, so the compiler exits with an
|
|
||||||
error.
|
|
||||||
|
|
||||||
Two of the instances were found by the secilc-fuzzer.
|
|
||||||
|
|
||||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_build_ast.c | 3 +++
|
|
||||||
libsepol/cil/src/cil_resolve_ast.c | 3 +++
|
|
||||||
2 files changed, 6 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
|
|
||||||
index 5b1e282..87043a8 100644
|
|
||||||
--- a/libsepol/cil/src/cil_build_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_build_ast.c
|
|
||||||
@@ -444,6 +444,7 @@ int cil_gen_class(struct cil_db *db, struct cil_tree_node *parse_current, struct
|
|
||||||
}
|
|
||||||
if (class->num_perms > CIL_PERMS_PER_CLASS) {
|
|
||||||
cil_tree_log(parse_current, CIL_ERR, "Too many permissions in class '%s'", class->datum.name);
|
|
||||||
+ rc = SEPOL_ERR;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1018,6 +1019,7 @@ int cil_gen_common(struct cil_db *db, struct cil_tree_node *parse_current, struc
|
|
||||||
}
|
|
||||||
if (common->num_perms > CIL_PERMS_PER_CLASS) {
|
|
||||||
cil_tree_log(parse_current, CIL_ERR, "Too many permissions in common '%s'", common->datum.name);
|
|
||||||
+ rc = SEPOL_ERR;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -3209,6 +3211,7 @@ int cil_gen_expandtypeattribute(struct cil_db *db, struct cil_tree_node *parse_c
|
|
||||||
expandattr->expand = CIL_FALSE;
|
|
||||||
} else {
|
|
||||||
cil_log(CIL_ERR, "Value must be either \'true\' or \'false\'");
|
|
||||||
+ rc = SEPOL_ERR;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
index 872b679..5389df4 100644
|
|
||||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
@@ -772,6 +772,7 @@ int cil_resolve_classcommon(struct cil_tree_node *current, void *extra_args)
|
|
||||||
class->num_perms += common->num_perms;
|
|
||||||
if (class->num_perms > CIL_PERMS_PER_CLASS) {
|
|
||||||
cil_tree_log(current, CIL_ERR, "Too many permissions in class '%s' when including common permissions", class->datum.name);
|
|
||||||
+ rc = SEPOL_ERR;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1484,6 +1485,7 @@ int cil_resolve_classorder(struct cil_tree_node *current, void *extra_args)
|
|
||||||
rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CLASSES, extra_args, &datum);
|
|
||||||
if (rc != SEPOL_OK) {
|
|
||||||
cil_log(CIL_ERR, "Failed to resolve class %s in classorder\n", (char *)curr->data);
|
|
||||||
+ rc = SEPOL_ERR;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
cil_list_append(new, CIL_CLASS, datum);
|
|
||||||
@@ -2464,6 +2466,7 @@ int cil_resolve_blockabstract(struct cil_tree_node *current, void *extra_args)
|
|
||||||
block_node = NODE(block_datum);
|
|
||||||
if (block_node->flavor != CIL_BLOCK) {
|
|
||||||
cil_log(CIL_ERR, "Failed to resolve blockabstract to a block, rc: %d\n", rc);
|
|
||||||
+ rc = SEPOL_ERR;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
@ -1,52 +0,0 @@
|
|||||||
From 974da80e08d24e92e5409bb040f95d06a47776a2 Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Carter <jwcart2@gmail.com>
|
|
||||||
Date: Fri, 8 Oct 2021 10:27:49 -0400
|
|
||||||
Subject: [PATCH] libsepol/cil: Fix potential undefined shifts
|
|
||||||
|
|
||||||
An expression of the form "1 << x" is undefined if x == 31 because
|
|
||||||
the "1" is an int and cannot be left shifted by 31.
|
|
||||||
|
|
||||||
Instead, use "UINT32_C(1) << x" which will be an unsigned int of
|
|
||||||
at least 32 bits.
|
|
||||||
|
|
||||||
This bug was found by the secilc-fuzzer.
|
|
||||||
|
|
||||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_binary.c | 6 +++---
|
|
||||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c
|
|
||||||
index ec5f01e..d8aa495 100644
|
|
||||||
--- a/libsepol/cil/src/cil_binary.c
|
|
||||||
+++ b/libsepol/cil/src/cil_binary.c
|
|
||||||
@@ -1225,7 +1225,7 @@ int __perm_str_to_datum(char *perm_str, class_datum_t *sepol_class, uint32_t *da
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- *datum |= 1 << (sepol_perm->s.value - 1);
|
|
||||||
+ *datum |= UINT32_C(1) << (sepol_perm->s.value - 1);
|
|
||||||
|
|
||||||
return SEPOL_OK;
|
|
||||||
|
|
||||||
@@ -1523,7 +1523,7 @@ int cil_avrule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_
|
|
||||||
/* index of the u32 containing the permission */
|
|
||||||
#define XPERM_IDX(x) (x >> 5)
|
|
||||||
/* set bits 0 through x-1 within the u32 */
|
|
||||||
-#define XPERM_SETBITS(x) ((1U << (x & 0x1f)) - 1)
|
|
||||||
+#define XPERM_SETBITS(x) ((UINT32_C(1) << (x & 0x1f)) - 1)
|
|
||||||
/* low value for this u32 */
|
|
||||||
#define XPERM_LOW(x) (x << 5)
|
|
||||||
/* high value for this u32 */
|
|
||||||
@@ -4760,7 +4760,7 @@ static struct cil_list *cil_classperms_from_sepol(policydb_t *pdb, uint16_t clas
|
|
||||||
cil_list_init(&cp->perms, CIL_PERM);
|
|
||||||
for (i = 0; i < sepol_class->permissions.nprim; i++) {
|
|
||||||
struct cil_perm *perm;
|
|
||||||
- if ((data & (1 << i)) == 0) continue;
|
|
||||||
+ if ((data & (UINT32_C(1) << i)) == 0) continue;
|
|
||||||
perm = perm_value_to_cil[class][i+1];
|
|
||||||
if (!perm) goto exit;
|
|
||||||
cil_list_append(cp->perms, CIL_PERM, perm);
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
@ -1,55 +0,0 @@
|
|||||||
From ac8b35d910750b56d38d54f312a712a73c95749c Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Carter <jwcart2@gmail.com>
|
|
||||||
Date: Mon, 21 Jun 2021 10:34:33 -0400
|
|
||||||
Subject: [PATCH] libsepol/cil: Fix syntax checking of defaultrange rule
|
|
||||||
|
|
||||||
When "glblub" was added as a default for the defaultrange rule, the
|
|
||||||
syntax array was updated because the "glblub" default does not need
|
|
||||||
to specify a range of "low", "high", or "low-high". Unfortunately,
|
|
||||||
additional checking was not added for the "source" and "target"
|
|
||||||
defaults to make sure they specified a range. This means that using
|
|
||||||
the "source" or "target" defaults without specifying the range will
|
|
||||||
result in a segfault.
|
|
||||||
|
|
||||||
When the "source" or "target" defaults are used, check that the rule
|
|
||||||
specifies a range as well.
|
|
||||||
|
|
||||||
This bug was found by the secilc-fuzzer.
|
|
||||||
|
|
||||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
|
||||||
Acked-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_build_ast.c | 10 ++++++++++
|
|
||||||
1 file changed, 10 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
|
|
||||||
index ea665a3..baed3e5 100644
|
|
||||||
--- a/libsepol/cil/src/cil_build_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_build_ast.c
|
|
||||||
@@ -5886,6 +5886,11 @@ int cil_gen_defaultrange(struct cil_tree_node *parse_current, struct cil_tree_no
|
|
||||||
|
|
||||||
object = parse_current->next->next->data;
|
|
||||||
if (object == CIL_KEY_SOURCE) {
|
|
||||||
+ if (!parse_current->next->next->next) {
|
|
||||||
+ cil_log(CIL_ERR, "Missing 'low', 'high', or 'low-high'\n");
|
|
||||||
+ rc = SEPOL_ERR;
|
|
||||||
+ goto exit;
|
|
||||||
+ }
|
|
||||||
range = parse_current->next->next->next->data;
|
|
||||||
if (range == CIL_KEY_LOW) {
|
|
||||||
def->object_range = CIL_DEFAULT_SOURCE_LOW;
|
|
||||||
@@ -5899,6 +5904,11 @@ int cil_gen_defaultrange(struct cil_tree_node *parse_current, struct cil_tree_no
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
} else if (object == CIL_KEY_TARGET) {
|
|
||||||
+ if (!parse_current->next->next->next) {
|
|
||||||
+ cil_log(CIL_ERR, "Missing 'low', 'high', or 'low-high'\n");
|
|
||||||
+ rc = SEPOL_ERR;
|
|
||||||
+ goto exit;
|
|
||||||
+ }
|
|
||||||
range = parse_current->next->next->next->data;
|
|
||||||
if (range == CIL_KEY_LOW) {
|
|
||||||
def->object_range = CIL_DEFAULT_TARGET_LOW;
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
@ -1,94 +0,0 @@
|
|||||||
From 5661efd459e7aa998390ab70e3ec50125a35e9e9 Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Carter <jwcart2@gmail.com>
|
|
||||||
Date: Thu, 13 May 2021 12:30:37 -0400
|
|
||||||
Subject: [PATCH] libsepol/cil: Handle disabled optional blocks in earlier
|
|
||||||
passes
|
|
||||||
|
|
||||||
A failed tunable resolution in a tunableif can cause an optional
|
|
||||||
to be disabled before the CIL_PASS_CALL1 phase. If this occurs, the
|
|
||||||
optional block and its subtree should be destroyed, but no reset
|
|
||||||
will be required since tunables are not allowed inside an optional
|
|
||||||
block.
|
|
||||||
|
|
||||||
Anytime there are optional blocks in the disabled_optionals list
|
|
||||||
(changed == 1), destroy the optional block and its subtree even if
|
|
||||||
in a pass before CIL_PASS_CALL1.
|
|
||||||
|
|
||||||
This bug was found by the secilc-fuzzer.
|
|
||||||
|
|
||||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_resolve_ast.c | 54 ++++++++++++++++++++------------------
|
|
||||||
1 file changed, 28 insertions(+), 26 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
index 74e5b78..328add0 100644
|
|
||||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
@@ -4132,35 +4132,37 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (changed && (pass > CIL_PASS_CALL1)) {
|
|
||||||
+ if (changed) {
|
|
||||||
struct cil_list_item *item;
|
|
||||||
- /* Need to re-resolve because an optional was disabled that contained
|
|
||||||
- * one or more declarations. We only need to reset to the call1 pass
|
|
||||||
- * because things done in the preceding passes aren't allowed in
|
|
||||||
- * optionals, and thus can't be disabled.
|
|
||||||
- * Note: set pass to CIL_PASS_CALL1 because the pass++ will increment
|
|
||||||
- * it to CIL_PASS_CALL2
|
|
||||||
- */
|
|
||||||
- cil_log(CIL_INFO, "Resetting declarations\n");
|
|
||||||
-
|
|
||||||
- if (pass >= CIL_PASS_MISC1) {
|
|
||||||
- __cil_ordered_lists_reset(&extra_args.sidorder_lists);
|
|
||||||
- __cil_ordered_lists_reset(&extra_args.classorder_lists);
|
|
||||||
- __cil_ordered_lists_reset(&extra_args.unordered_classorder_lists);
|
|
||||||
- __cil_ordered_lists_reset(&extra_args.catorder_lists);
|
|
||||||
- __cil_ordered_lists_reset(&extra_args.sensitivityorder_lists);
|
|
||||||
- cil_list_destroy(&db->sidorder, CIL_FALSE);
|
|
||||||
- cil_list_destroy(&db->classorder, CIL_FALSE);
|
|
||||||
- cil_list_destroy(&db->catorder, CIL_FALSE);
|
|
||||||
- cil_list_destroy(&db->sensitivityorder, CIL_FALSE);
|
|
||||||
- }
|
|
||||||
+ if (pass > CIL_PASS_CALL1) {
|
|
||||||
+ /* Need to re-resolve because an optional was disabled that contained
|
|
||||||
+ * one or more declarations. We only need to reset to the call1 pass
|
|
||||||
+ * because things done in the preceding passes aren't allowed in
|
|
||||||
+ * optionals, and thus can't be disabled.
|
|
||||||
+ * Note: set pass to CIL_PASS_CALL1 because the pass++ will increment
|
|
||||||
+ * it to CIL_PASS_CALL2
|
|
||||||
+ */
|
|
||||||
+ cil_log(CIL_INFO, "Resetting declarations\n");
|
|
||||||
+
|
|
||||||
+ if (pass >= CIL_PASS_MISC1) {
|
|
||||||
+ __cil_ordered_lists_reset(&extra_args.sidorder_lists);
|
|
||||||
+ __cil_ordered_lists_reset(&extra_args.classorder_lists);
|
|
||||||
+ __cil_ordered_lists_reset(&extra_args.unordered_classorder_lists);
|
|
||||||
+ __cil_ordered_lists_reset(&extra_args.catorder_lists);
|
|
||||||
+ __cil_ordered_lists_reset(&extra_args.sensitivityorder_lists);
|
|
||||||
+ cil_list_destroy(&db->sidorder, CIL_FALSE);
|
|
||||||
+ cil_list_destroy(&db->classorder, CIL_FALSE);
|
|
||||||
+ cil_list_destroy(&db->catorder, CIL_FALSE);
|
|
||||||
+ cil_list_destroy(&db->sensitivityorder, CIL_FALSE);
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- pass = CIL_PASS_CALL1;
|
|
||||||
+ pass = CIL_PASS_CALL1;
|
|
||||||
|
|
||||||
- rc = cil_reset_ast(current);
|
|
||||||
- if (rc != SEPOL_OK) {
|
|
||||||
- cil_log(CIL_ERR, "Failed to reset declarations\n");
|
|
||||||
- goto exit;
|
|
||||||
+ rc = cil_reset_ast(current);
|
|
||||||
+ if (rc != SEPOL_OK) {
|
|
||||||
+ cil_log(CIL_ERR, "Failed to reset declarations\n");
|
|
||||||
+ goto exit;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
cil_list_for_each(item, extra_args.disabled_optionals) {
|
|
||||||
cil_tree_children_destroy(item->data);
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
@ -1,95 +0,0 @@
|
|||||||
From 18f8747b28f1620903c7a3aa8a6616c199c173a6 Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Carter <jwcart2@gmail.com>
|
|
||||||
Date: Thu, 16 Sep 2021 16:29:00 -0400
|
|
||||||
Subject: [PATCH] libsepol/cil: Handle operations in a class mapping when
|
|
||||||
verifying
|
|
||||||
|
|
||||||
When checking for circular class permission declarations and a class
|
|
||||||
mapping is encountered, the class permissions for each map permission
|
|
||||||
must be checked. An assumption was made that there were no operators
|
|
||||||
in the class permissions. An operator in the class permissions would
|
|
||||||
cause a segfault.
|
|
||||||
|
|
||||||
Example causing segault:
|
|
||||||
(classmap cm1 (mp1))
|
|
||||||
(classmapping cm1 mp1 (CLASS (PERM)))
|
|
||||||
(classpermission cp1)
|
|
||||||
(classpermissionset cp1 (cm1 (all)))
|
|
||||||
|
|
||||||
For map class permissions, check each item in the permission list to
|
|
||||||
see if it is an operator. If it is not, then verify the class
|
|
||||||
permissions associated with the map permission. If it is an operator
|
|
||||||
and the operator is "all", then create a list of all permissions for
|
|
||||||
that map class and verify the class permissions associated with each
|
|
||||||
map permission. If it is a different operator, then it can be skipped.
|
|
||||||
|
|
||||||
This bug was found by the secilc-fuzzer.
|
|
||||||
|
|
||||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_verify.c | 40 +++++++++++++++++++++++++++++++++++-----
|
|
||||||
1 file changed, 35 insertions(+), 5 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_verify.c b/libsepol/cil/src/cil_verify.c
|
|
||||||
index 5502c4d..dc29ea6 100644
|
|
||||||
--- a/libsepol/cil/src/cil_verify.c
|
|
||||||
+++ b/libsepol/cil/src/cil_verify.c
|
|
||||||
@@ -1689,6 +1689,15 @@ exit:
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static int __add_perm_to_list(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
|
|
||||||
+{
|
|
||||||
+ struct cil_list *perm_list = (struct cil_list *)args;
|
|
||||||
+
|
|
||||||
+ cil_list_append(perm_list, CIL_DATUM, d);
|
|
||||||
+
|
|
||||||
+ return SEPOL_OK;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static int __cil_verify_classperms(struct cil_list *classperms,
|
|
||||||
struct cil_symtab_datum *orig,
|
|
||||||
struct cil_symtab_datum *parent,
|
|
||||||
@@ -1730,13 +1739,34 @@ static int __cil_verify_classperms(struct cil_list *classperms,
|
|
||||||
if (FLAVOR(cp->class) != CIL_CLASS) { /* MAP */
|
|
||||||
struct cil_list_item *i = NULL;
|
|
||||||
cil_list_for_each(i, cp->perms) {
|
|
||||||
- struct cil_perm *cmp = i->data;
|
|
||||||
- rc = __cil_verify_classperms(cmp->classperms, orig, &cp->class->datum, &cmp->datum, CIL_MAP_PERM, steps, limit);
|
|
||||||
- if (rc != SEPOL_OK) {
|
|
||||||
- goto exit;
|
|
||||||
+ if (i->flavor != CIL_OP) {
|
|
||||||
+ struct cil_perm *cmp = i->data;
|
|
||||||
+ rc = __cil_verify_classperms(cmp->classperms, orig, &cp->class->datum, &cmp->datum, CIL_MAP_PERM, steps, limit);
|
|
||||||
+ if (rc != SEPOL_OK) {
|
|
||||||
+ goto exit;
|
|
||||||
+ }
|
|
||||||
+ } else {
|
|
||||||
+ enum cil_flavor op = (enum cil_flavor)i->data;
|
|
||||||
+ if (op == CIL_ALL) {
|
|
||||||
+ struct cil_class *mc = cp->class;
|
|
||||||
+ struct cil_list *perm_list;
|
|
||||||
+ struct cil_list_item *j = NULL;
|
|
||||||
+
|
|
||||||
+ cil_list_init(&perm_list, CIL_MAP_PERM);
|
|
||||||
+ cil_symtab_map(&mc->perms, __add_perm_to_list, perm_list);
|
|
||||||
+ cil_list_for_each(j, perm_list) {
|
|
||||||
+ struct cil_perm *cmp = j->data;
|
|
||||||
+ rc = __cil_verify_classperms(cmp->classperms, orig, &cp->class->datum, &cmp->datum, CIL_MAP_PERM, steps, limit);
|
|
||||||
+ if (rc != SEPOL_OK) {
|
|
||||||
+ cil_list_destroy(&perm_list, CIL_FALSE);
|
|
||||||
+ goto exit;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ cil_list_destroy(&perm_list, CIL_FALSE);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- }
|
|
||||||
+ }
|
|
||||||
} else { /* SET */
|
|
||||||
struct cil_classperms_set *cp_set = curr->data;
|
|
||||||
struct cil_classpermission *cp = cp_set->set;
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
@ -1,315 +0,0 @@
|
|||||||
From 9af91692416d01814f4b2ac22e39d3b57993af4f Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Carter <jwcart2@gmail.com>
|
|
||||||
Date: Wed, 30 Jun 2021 15:12:16 -0400
|
|
||||||
Subject: [PATCH] libsepol/cil: Improve checking for bad inheritance patterns
|
|
||||||
|
|
||||||
commits 37863b0b1444c85a1ddc6c333c8bfea0c678c592 (libsepol/cil:
|
|
||||||
Improve degenerate inheritance check) and
|
|
||||||
74d00a8decebf940d95064ff60042dcb2cbcc2c0 (libsepol/cil: Detect
|
|
||||||
degenerate inheritance and exit with an error) attempted to detect
|
|
||||||
and exit with an error when compiling policies that have degenerate
|
|
||||||
inheritances. These policies result in the exponential growth of memory
|
|
||||||
usage while copying the blocks that are inherited.
|
|
||||||
|
|
||||||
There were two problems with the previous attempts to detect this
|
|
||||||
bad inheritance problem. The first is that the quick check using
|
|
||||||
cil_possible_degenerate_inheritance() did not detect all patterns
|
|
||||||
of degenerate inheritance. The second problem is that the detection
|
|
||||||
of inheritance loops during the CIL_PASS_BLKIN_LINK pass did not
|
|
||||||
detect all inheritance loops which made it possible for the full
|
|
||||||
degenerate inheritance checking done with
|
|
||||||
cil_check_for_degenerate_inheritance() to have a stack overflow
|
|
||||||
when encountering the inheritance loops. Both the degenerate and
|
|
||||||
loop inheritance checks need to be done at the same time and done
|
|
||||||
after the CIL_PASS_BLKIN_LINK pass. Otherwise, if loops are being
|
|
||||||
detected first, then a degenerate policy can cause the consumption
|
|
||||||
of all system memory and if degenerate policy is being detected
|
|
||||||
first, then an inheritance loop can cause a stack overflow.
|
|
||||||
|
|
||||||
With the new approach, the quick check is eliminated and the full
|
|
||||||
check is always done after the CIL_PASS_BLKIN_LINK pass. Because
|
|
||||||
of this the "inheritance_check" field in struct cil_resolve_args
|
|
||||||
is not needed and removed and the functions
|
|
||||||
cil_print_recursive_blockinherit(), cil_check_recursive_blockinherit(),
|
|
||||||
and cil_possible_degenerate_inheritance() have been deleted. The
|
|
||||||
function cil_count_potential() is renamed cil_check_inheritances()
|
|
||||||
and has checks for both degenerate inheritance and inheritance loops.
|
|
||||||
The inheritance checking is improved and uses an approach similar
|
|
||||||
to commit c28525a26fa145cb5fd911fd2a3b9125a275677f (libsepol/cil:
|
|
||||||
Properly check for loops in sets).
|
|
||||||
|
|
||||||
As has been the case with these degenerate inheritance patches,
|
|
||||||
these issues were discovered by the secilc-fuzzer.
|
|
||||||
|
|
||||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_resolve_ast.c | 172 +++++++++----------------------------
|
|
||||||
1 file changed, 42 insertions(+), 130 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
index 9a02e38..145d4e7 100644
|
|
||||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
@@ -64,7 +64,6 @@ struct cil_args_resolve {
|
|
||||||
struct cil_list *sensitivityorder_lists;
|
|
||||||
struct cil_list *in_list;
|
|
||||||
struct cil_stack *disabled_optionals;
|
|
||||||
- int *inheritance_check;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct cil_name * __cil_insert_name(struct cil_db *db, hashtab_key_t key, struct cil_tree_node *ast_node)
|
|
||||||
@@ -2309,100 +2308,8 @@ exit:
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void cil_print_recursive_blockinherit(struct cil_tree_node *bi_node, struct cil_tree_node *terminating_node)
|
|
||||||
-{
|
|
||||||
- struct cil_list *trace = NULL;
|
|
||||||
- struct cil_list_item *item = NULL;
|
|
||||||
- struct cil_tree_node *curr = NULL;
|
|
||||||
-
|
|
||||||
- cil_list_init(&trace, CIL_NODE);
|
|
||||||
-
|
|
||||||
- for (curr = bi_node; curr != terminating_node; curr = curr->parent) {
|
|
||||||
- if (curr->flavor == CIL_BLOCK) {
|
|
||||||
- cil_list_prepend(trace, CIL_NODE, curr);
|
|
||||||
- } else if (curr->flavor == CIL_BLOCKINHERIT) {
|
|
||||||
- if (curr != bi_node) {
|
|
||||||
- cil_list_prepend(trace, CIL_NODE, NODE(((struct cil_blockinherit *)curr->data)->block));
|
|
||||||
- }
|
|
||||||
- cil_list_prepend(trace, CIL_NODE, curr);
|
|
||||||
- } else {
|
|
||||||
- cil_list_prepend(trace, CIL_NODE, curr);
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- cil_list_prepend(trace, CIL_NODE, terminating_node);
|
|
||||||
-
|
|
||||||
- cil_list_for_each(item, trace) {
|
|
||||||
- curr = item->data;
|
|
||||||
- if (curr->flavor == CIL_BLOCK) {
|
|
||||||
- cil_tree_log(curr, CIL_ERR, "block %s", DATUM(curr->data)->name);
|
|
||||||
- } else if (curr->flavor == CIL_BLOCKINHERIT) {
|
|
||||||
- cil_tree_log(curr, CIL_ERR, "blockinherit %s", ((struct cil_blockinherit *)curr->data)->block_str);
|
|
||||||
- } else if (curr->flavor == CIL_OPTIONAL) {
|
|
||||||
- cil_tree_log(curr, CIL_ERR, "optional %s", DATUM(curr->data)->name);
|
|
||||||
- } else {
|
|
||||||
- cil_tree_log(curr, CIL_ERR, "%s", cil_node_to_string(curr));
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- cil_list_destroy(&trace, CIL_FALSE);
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static int cil_check_recursive_blockinherit(struct cil_tree_node *bi_node)
|
|
||||||
-{
|
|
||||||
- struct cil_tree_node *curr = NULL;
|
|
||||||
- struct cil_blockinherit *bi = NULL;
|
|
||||||
- struct cil_block *block = NULL;
|
|
||||||
- int rc = SEPOL_ERR;
|
|
||||||
-
|
|
||||||
- bi = bi_node->data;
|
|
||||||
-
|
|
||||||
- for (curr = bi_node->parent; curr != NULL; curr = curr->parent) {
|
|
||||||
- if (curr->flavor != CIL_BLOCK) {
|
|
||||||
- continue;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- block = curr->data;
|
|
||||||
-
|
|
||||||
- if (block != bi->block) {
|
|
||||||
- continue;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- cil_log(CIL_ERR, "Recursive blockinherit found:\n");
|
|
||||||
- cil_print_recursive_blockinherit(bi_node, curr);
|
|
||||||
-
|
|
||||||
- rc = SEPOL_ERR;
|
|
||||||
- goto exit;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- rc = SEPOL_OK;
|
|
||||||
-
|
|
||||||
-exit:
|
|
||||||
- return rc;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static int cil_possible_degenerate_inheritance(struct cil_tree_node *node)
|
|
||||||
-{
|
|
||||||
- unsigned depth = 1;
|
|
||||||
-
|
|
||||||
- node = node->parent;
|
|
||||||
- while (node && node->flavor != CIL_ROOT) {
|
|
||||||
- if (node->flavor == CIL_BLOCK) {
|
|
||||||
- if (((struct cil_block *)(node->data))->bi_nodes != NULL) {
|
|
||||||
- depth++;
|
|
||||||
- if (depth >= CIL_DEGENERATE_INHERITANCE_DEPTH) {
|
|
||||||
- return CIL_TRUE;
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- node = node->parent;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- return CIL_FALSE;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
int cil_resolve_blockinherit_link(struct cil_tree_node *current, void *extra_args)
|
|
||||||
{
|
|
||||||
- struct cil_args_resolve *args = extra_args;
|
|
||||||
struct cil_blockinherit *inherit = current->data;
|
|
||||||
struct cil_symtab_datum *block_datum = NULL;
|
|
||||||
struct cil_tree_node *node = NULL;
|
|
||||||
@@ -2423,20 +2330,11 @@ int cil_resolve_blockinherit_link(struct cil_tree_node *current, void *extra_arg
|
|
||||||
|
|
||||||
inherit->block = (struct cil_block *)block_datum;
|
|
||||||
|
|
||||||
- rc = cil_check_recursive_blockinherit(current);
|
|
||||||
- if (rc != SEPOL_OK) {
|
|
||||||
- goto exit;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
if (inherit->block->bi_nodes == NULL) {
|
|
||||||
cil_list_init(&inherit->block->bi_nodes, CIL_NODE);
|
|
||||||
}
|
|
||||||
cil_list_append(inherit->block->bi_nodes, CIL_NODE, current);
|
|
||||||
|
|
||||||
- if (*(args->inheritance_check) == CIL_FALSE) {
|
|
||||||
- *(args->inheritance_check) = cil_possible_degenerate_inheritance(node);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
return SEPOL_OK;
|
|
||||||
|
|
||||||
exit:
|
|
||||||
@@ -2466,11 +2364,6 @@ int cil_resolve_blockinherit_copy(struct cil_tree_node *current, void *extra_arg
|
|
||||||
}
|
|
||||||
|
|
||||||
cil_list_for_each(item, block->bi_nodes) {
|
|
||||||
- rc = cil_check_recursive_blockinherit(item->data);
|
|
||||||
- if (rc != SEPOL_OK) {
|
|
||||||
- goto exit;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
rc = cil_copy_ast(db, current, item->data);
|
|
||||||
if (rc != SEPOL_OK) {
|
|
||||||
cil_log(CIL_ERR, "Failed to copy block contents into blockinherit\n");
|
|
||||||
@@ -3611,34 +3504,58 @@ static unsigned cil_count_actual(struct cil_tree_node *node)
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static unsigned cil_count_potential(struct cil_tree_node *node, unsigned max)
|
|
||||||
+static int cil_check_inheritances(struct cil_tree_node *node, unsigned max, unsigned *count, struct cil_stack *stack, unsigned *loop)
|
|
||||||
{
|
|
||||||
- unsigned count = 0;
|
|
||||||
+ int rc;
|
|
||||||
|
|
||||||
if (node->flavor == CIL_BLOCKINHERIT) {
|
|
||||||
struct cil_blockinherit *bi = node->data;
|
|
||||||
- count += 1;
|
|
||||||
+ *count += 1;
|
|
||||||
+ if (*count > max) {
|
|
||||||
+ cil_tree_log(node, CIL_ERR, "Degenerate inheritance detected");
|
|
||||||
+ return SEPOL_ERR;
|
|
||||||
+ }
|
|
||||||
if (bi->block) {
|
|
||||||
- count += cil_count_potential(NODE(bi->block), max);
|
|
||||||
- if (count > max) {
|
|
||||||
- return count;
|
|
||||||
+ struct cil_tree_node *block_node = NODE(bi->block);
|
|
||||||
+ struct cil_stack_item *item;
|
|
||||||
+ int i = 0;
|
|
||||||
+ cil_stack_for_each(stack, i, item) {
|
|
||||||
+ if (block_node == (struct cil_tree_node *)item->data) {
|
|
||||||
+ *loop = CIL_TRUE;
|
|
||||||
+ cil_tree_log(block_node, CIL_ERR, "Block inheritance loop found");
|
|
||||||
+ cil_tree_log(node, CIL_ERR, " blockinherit");
|
|
||||||
+ return SEPOL_ERR;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ cil_stack_push(stack, CIL_BLOCK, block_node);
|
|
||||||
+ rc = cil_check_inheritances(block_node, max, count, stack, loop);
|
|
||||||
+ cil_stack_pop(stack);
|
|
||||||
+ if (rc != SEPOL_OK) {
|
|
||||||
+ if (*loop == CIL_TRUE) {
|
|
||||||
+ cil_tree_log(node, CIL_ERR, " blockinherit");
|
|
||||||
+ }
|
|
||||||
+ return SEPOL_ERR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (node = node->cl_head; node; node = node->next) {
|
|
||||||
- count += cil_count_potential(node, max);
|
|
||||||
- if (count > max) {
|
|
||||||
- return count;
|
|
||||||
+ rc = cil_check_inheritances(node, max, count, stack, loop);
|
|
||||||
+ if (rc != SEPOL_OK) {
|
|
||||||
+ return SEPOL_ERR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- return count;
|
|
||||||
+ return SEPOL_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int cil_check_for_degenerate_inheritance(struct cil_tree_node *node)
|
|
||||||
+static int cil_check_for_bad_inheritance(struct cil_tree_node *node)
|
|
||||||
{
|
|
||||||
- uint64_t num_actual, num_potential, max;
|
|
||||||
+ unsigned num_actual, max;
|
|
||||||
+ unsigned num_potential = 0;
|
|
||||||
+ unsigned loop = CIL_FALSE;
|
|
||||||
+ struct cil_stack *stack;
|
|
||||||
+ int rc;
|
|
||||||
|
|
||||||
num_actual = cil_count_actual(node);
|
|
||||||
|
|
||||||
@@ -3647,13 +3564,11 @@ static int cil_check_for_degenerate_inheritance(struct cil_tree_node *node)
|
|
||||||
max = CIL_DEGENERATE_INHERITANCE_MINIMUM;
|
|
||||||
}
|
|
||||||
|
|
||||||
- num_potential = cil_count_potential(node, max);
|
|
||||||
+ cil_stack_init(&stack);
|
|
||||||
+ rc = cil_check_inheritances(node, max, &num_potential, stack, &loop);
|
|
||||||
+ cil_stack_destroy(&stack);
|
|
||||||
|
|
||||||
- if (num_potential > max) {
|
|
||||||
- return SEPOL_ERR;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- return SEPOL_OK;
|
|
||||||
+ return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args)
|
|
||||||
@@ -4127,7 +4042,6 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
|
|
||||||
struct cil_args_resolve extra_args;
|
|
||||||
enum cil_pass pass = CIL_PASS_TIF;
|
|
||||||
uint32_t changed = 0;
|
|
||||||
- int inheritance_check = 0;
|
|
||||||
|
|
||||||
if (db == NULL || current == NULL) {
|
|
||||||
return rc;
|
|
||||||
@@ -4147,7 +4061,6 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
|
|
||||||
extra_args.sensitivityorder_lists = NULL;
|
|
||||||
extra_args.in_list = NULL;
|
|
||||||
extra_args.disabled_optionals = NULL;
|
|
||||||
- extra_args.inheritance_check = &inheritance_check;
|
|
||||||
|
|
||||||
cil_list_init(&extra_args.to_destroy, CIL_NODE);
|
|
||||||
cil_list_init(&extra_args.sidorder_lists, CIL_LIST_ITEM);
|
|
||||||
@@ -4174,10 +4087,9 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
|
|
||||||
cil_list_destroy(&extra_args.in_list, CIL_FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (pass == CIL_PASS_BLKIN_LINK && inheritance_check == CIL_TRUE) {
|
|
||||||
- rc = cil_check_for_degenerate_inheritance(current);
|
|
||||||
+ if (pass == CIL_PASS_BLKIN_LINK) {
|
|
||||||
+ rc = cil_check_for_bad_inheritance(current);
|
|
||||||
if (rc != SEPOL_OK) {
|
|
||||||
- cil_log(CIL_ERR, "Degenerate inheritance detected\n");
|
|
||||||
rc = SEPOL_ERR;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
@ -1,362 +0,0 @@
|
|||||||
From 37863b0b1444c85a1ddc6c333c8bfea0c678c592 Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Carter <jwcart2@gmail.com>
|
|
||||||
Date: Mon, 21 Jun 2021 10:56:55 -0400
|
|
||||||
Subject: [PATCH] libsepol/cil: Improve degenerate inheritance check
|
|
||||||
|
|
||||||
The commit 74d00a8decebf940d95064ff60042dcb2cbcc2c0 (libsepol/cil:
|
|
||||||
Detect degenerate inheritance and exit with an error) detects the
|
|
||||||
use of inheritance (mostly by the secilc-fuzzer and not in any real
|
|
||||||
policies) that results in the exponential growth of the policy through
|
|
||||||
the copying of blocks that takes place with inheritance in CIL.
|
|
||||||
Unfortunately, the check takes place during the pass when all the
|
|
||||||
blocks are being copied, so it is possible to consume all of a system's
|
|
||||||
memory before an error is produced.
|
|
||||||
|
|
||||||
The new check happens in two parts. First, a check is made while the
|
|
||||||
block inheritance is being linked to the block it will inherit. In
|
|
||||||
this check, all of the parent nodes of the inheritance rule up to the
|
|
||||||
root node are checked and if enough of these blocks are being inherited
|
|
||||||
(>= CIL_DEGENERATE_INHERITANCE_DEPTH), then a flag is set for a more
|
|
||||||
in-depth check after the pass. This in-depth check will determine the
|
|
||||||
number of potential inheritances that will occur when resolving the
|
|
||||||
all of the inheritance rules. If this value is greater than
|
|
||||||
CIL_DEGENERATE_INHERITANCE_GROWTH * the original number of inheritance
|
|
||||||
rules and greater than CIL_DEGENERATE_INHERITANCE_MINIMUM (which is
|
|
||||||
set to 0x1 << CIL_DEGENERATE_INHERITANCE_DEPTH), then degenerate
|
|
||||||
inheritance is determined to have occurred and an error result will
|
|
||||||
be returned.
|
|
||||||
|
|
||||||
Since the potential number of inheritances can quickly be an extremely
|
|
||||||
large number, the count of potential inheritances is aborted as soon
|
|
||||||
as the threshold for degenerate inheritance has been exceeded.
|
|
||||||
|
|
||||||
Normal policies should rarely, if ever, have the in-depth check occur.
|
|
||||||
|
|
||||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
|
||||||
Acked-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_internal.h | 5 +-
|
|
||||||
libsepol/cil/src/cil_resolve_ast.c | 226 ++++++++++++++++++++++++-------------
|
|
||||||
2 files changed, 151 insertions(+), 80 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_internal.h b/libsepol/cil/src/cil_internal.h
|
|
||||||
index 24be09a..8b9aeab 100644
|
|
||||||
--- a/libsepol/cil/src/cil_internal.h
|
|
||||||
+++ b/libsepol/cil/src/cil_internal.h
|
|
||||||
@@ -48,8 +48,9 @@
|
|
||||||
|
|
||||||
#define CIL_MAX_NAME_LENGTH 2048
|
|
||||||
|
|
||||||
-#define CIL_DEGENERATE_INHERITANCE_DEPTH 12
|
|
||||||
-#define CIL_DEGENERATE_INHERITANCE_BREADTH (0x1 << CIL_DEGENERATE_INHERITANCE_DEPTH)
|
|
||||||
+#define CIL_DEGENERATE_INHERITANCE_DEPTH 10UL
|
|
||||||
+#define CIL_DEGENERATE_INHERITANCE_MINIMUM (0x01 << CIL_DEGENERATE_INHERITANCE_DEPTH)
|
|
||||||
+#define CIL_DEGENERATE_INHERITANCE_GROWTH 10UL
|
|
||||||
|
|
||||||
enum cil_pass {
|
|
||||||
CIL_PASS_INIT = 0,
|
|
||||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
index 6d13544..5245cc1 100644
|
|
||||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
@@ -64,6 +64,7 @@ struct cil_args_resolve {
|
|
||||||
struct cil_list *sensitivityorder_lists;
|
|
||||||
struct cil_list *in_list;
|
|
||||||
struct cil_stack *disabled_optionals;
|
|
||||||
+ int *inheritance_check;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct cil_name * __cil_insert_name(struct cil_db *db, hashtab_key_t key, struct cil_tree_node *ast_node)
|
|
||||||
@@ -2308,40 +2309,7 @@ exit:
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
-int cil_resolve_blockinherit_link(struct cil_tree_node *current, void *extra_args)
|
|
||||||
-{
|
|
||||||
- struct cil_blockinherit *inherit = current->data;
|
|
||||||
- struct cil_symtab_datum *block_datum = NULL;
|
|
||||||
- struct cil_tree_node *node = NULL;
|
|
||||||
- int rc = SEPOL_ERR;
|
|
||||||
-
|
|
||||||
- rc = cil_resolve_name(current, inherit->block_str, CIL_SYM_BLOCKS, extra_args, &block_datum);
|
|
||||||
- if (rc != SEPOL_OK) {
|
|
||||||
- goto exit;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- node = NODE(block_datum);
|
|
||||||
-
|
|
||||||
- if (node->flavor != CIL_BLOCK) {
|
|
||||||
- cil_log(CIL_ERR, "%s is not a block\n", cil_node_to_string(node));
|
|
||||||
- rc = SEPOL_ERR;
|
|
||||||
- goto exit;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- inherit->block = (struct cil_block *)block_datum;
|
|
||||||
-
|
|
||||||
- if (inherit->block->bi_nodes == NULL) {
|
|
||||||
- cil_list_init(&inherit->block->bi_nodes, CIL_NODE);
|
|
||||||
- }
|
|
||||||
- cil_list_append(inherit->block->bi_nodes, CIL_NODE, current);
|
|
||||||
-
|
|
||||||
- return SEPOL_OK;
|
|
||||||
-
|
|
||||||
-exit:
|
|
||||||
- return rc;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-void cil_print_recursive_blockinherit(struct cil_tree_node *bi_node, struct cil_tree_node *terminating_node)
|
|
||||||
+static void cil_print_recursive_blockinherit(struct cil_tree_node *bi_node, struct cil_tree_node *terminating_node)
|
|
||||||
{
|
|
||||||
struct cil_list *trace = NULL;
|
|
||||||
struct cil_list_item *item = NULL;
|
|
||||||
@@ -2379,7 +2347,7 @@ void cil_print_recursive_blockinherit(struct cil_tree_node *bi_node, struct cil_
|
|
||||||
cil_list_destroy(&trace, CIL_FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
-int cil_check_recursive_blockinherit(struct cil_tree_node *bi_node)
|
|
||||||
+static int cil_check_recursive_blockinherit(struct cil_tree_node *bi_node)
|
|
||||||
{
|
|
||||||
struct cil_tree_node *curr = NULL;
|
|
||||||
struct cil_blockinherit *bi = NULL;
|
|
||||||
@@ -2412,53 +2380,67 @@ exit:
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
-/*
|
|
||||||
- * Detect degenerate inheritance of the form:
|
|
||||||
- * ...
|
|
||||||
- * (blockinherit ba)
|
|
||||||
- * (block ba
|
|
||||||
- * (block b1
|
|
||||||
- * (blockinherit bb)
|
|
||||||
- * )
|
|
||||||
- * (block bb
|
|
||||||
- * (block b2
|
|
||||||
- * (blockinherit bc)
|
|
||||||
- * )
|
|
||||||
- * (block bc
|
|
||||||
- * ...
|
|
||||||
- */
|
|
||||||
-static int cil_check_for_degenerate_inheritance(struct cil_tree_node *current)
|
|
||||||
+static int cil_possible_degenerate_inheritance(struct cil_tree_node *node)
|
|
||||||
{
|
|
||||||
- struct cil_block *block = current->data;
|
|
||||||
- struct cil_tree_node *node;
|
|
||||||
- struct cil_list_item *item;
|
|
||||||
- unsigned depth;
|
|
||||||
- unsigned breadth = 0;
|
|
||||||
+ unsigned depth = 1;
|
|
||||||
|
|
||||||
- cil_list_for_each(item, block->bi_nodes) {
|
|
||||||
- breadth++;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- if (breadth >= CIL_DEGENERATE_INHERITANCE_BREADTH) {
|
|
||||||
- node = current->parent;
|
|
||||||
- depth = 0;
|
|
||||||
- while (node && node->flavor != CIL_ROOT) {
|
|
||||||
- if (node->flavor == CIL_BLOCK) {
|
|
||||||
- block = node->data;
|
|
||||||
- if (block->bi_nodes != NULL) {
|
|
||||||
- depth++;
|
|
||||||
+ node = node->parent;
|
|
||||||
+ while (node && node->flavor != CIL_ROOT) {
|
|
||||||
+ if (node->flavor == CIL_BLOCK) {
|
|
||||||
+ if (((struct cil_block *)(node->data))->bi_nodes != NULL) {
|
|
||||||
+ depth++;
|
|
||||||
+ if (depth >= CIL_DEGENERATE_INHERITANCE_DEPTH) {
|
|
||||||
+ return CIL_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- node = node->parent;
|
|
||||||
}
|
|
||||||
+ node = node->parent;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- if (depth >= CIL_DEGENERATE_INHERITANCE_DEPTH) {
|
|
||||||
- cil_tree_log(current, CIL_ERR, "Degenerate inheritance detected (depth=%u, breadth=%u)", depth, breadth);
|
|
||||||
- return SEPOL_ERR;
|
|
||||||
- }
|
|
||||||
+ return CIL_FALSE;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+int cil_resolve_blockinherit_link(struct cil_tree_node *current, void *extra_args)
|
|
||||||
+{
|
|
||||||
+ struct cil_args_resolve *args = extra_args;
|
|
||||||
+ struct cil_blockinherit *inherit = current->data;
|
|
||||||
+ struct cil_symtab_datum *block_datum = NULL;
|
|
||||||
+ struct cil_tree_node *node = NULL;
|
|
||||||
+ int rc = SEPOL_ERR;
|
|
||||||
+
|
|
||||||
+ rc = cil_resolve_name(current, inherit->block_str, CIL_SYM_BLOCKS, extra_args, &block_datum);
|
|
||||||
+ if (rc != SEPOL_OK) {
|
|
||||||
+ goto exit;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ node = NODE(block_datum);
|
|
||||||
+
|
|
||||||
+ if (node->flavor != CIL_BLOCK) {
|
|
||||||
+ cil_log(CIL_ERR, "%s is not a block\n", cil_node_to_string(node));
|
|
||||||
+ rc = SEPOL_ERR;
|
|
||||||
+ goto exit;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ inherit->block = (struct cil_block *)block_datum;
|
|
||||||
+
|
|
||||||
+ rc = cil_check_recursive_blockinherit(current);
|
|
||||||
+ if (rc != SEPOL_OK) {
|
|
||||||
+ goto exit;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (inherit->block->bi_nodes == NULL) {
|
|
||||||
+ cil_list_init(&inherit->block->bi_nodes, CIL_NODE);
|
|
||||||
+ }
|
|
||||||
+ cil_list_append(inherit->block->bi_nodes, CIL_NODE, current);
|
|
||||||
+
|
|
||||||
+ if (*(args->inheritance_check) == CIL_FALSE) {
|
|
||||||
+ *(args->inheritance_check) = cil_possible_degenerate_inheritance(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
return SEPOL_OK;
|
|
||||||
+
|
|
||||||
+exit:
|
|
||||||
+ return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cil_resolve_blockinherit_copy(struct cil_tree_node *current, void *extra_args)
|
|
||||||
@@ -2477,11 +2459,6 @@ int cil_resolve_blockinherit_copy(struct cil_tree_node *current, void *extra_arg
|
|
||||||
|
|
||||||
db = args->db;
|
|
||||||
|
|
||||||
- rc = cil_check_for_degenerate_inheritance(current);
|
|
||||||
- if (rc != SEPOL_OK) {
|
|
||||||
- goto exit;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
// Make sure this is the original block and not a merged block from a blockinherit
|
|
||||||
if (current != block->datum.nodes->head->data) {
|
|
||||||
rc = SEPOL_OK;
|
|
||||||
@@ -3597,6 +3574,88 @@ exit:
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
+/*
|
|
||||||
+ * Degenerate inheritance leads to exponential growth of the policy
|
|
||||||
+ * It can take many forms, but here is one example.
|
|
||||||
+ * ...
|
|
||||||
+ * (blockinherit ba)
|
|
||||||
+ * (block b0
|
|
||||||
+ * (block b1
|
|
||||||
+ * (block b2
|
|
||||||
+ * (block b3
|
|
||||||
+ * ...
|
|
||||||
+ * )
|
|
||||||
+ * (blockinherit b3)
|
|
||||||
+ * )
|
|
||||||
+ * (blockinherit b2)
|
|
||||||
+ * )
|
|
||||||
+ * (blockinherit b1)
|
|
||||||
+ * )
|
|
||||||
+ * (blockinherit b0)
|
|
||||||
+ * ...
|
|
||||||
+ * This leads to 2^4 copies of the content of block b3, 2^3 copies of the
|
|
||||||
+ * contents of block b2, etc.
|
|
||||||
+ */
|
|
||||||
+static unsigned cil_count_actual(struct cil_tree_node *node)
|
|
||||||
+{
|
|
||||||
+ unsigned count = 0;
|
|
||||||
+
|
|
||||||
+ if (node->flavor == CIL_BLOCKINHERIT) {
|
|
||||||
+ count += 1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ for (node = node->cl_head; node; node = node->next) {
|
|
||||||
+ count += cil_count_actual(node);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return count;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static unsigned cil_count_potential(struct cil_tree_node *node, unsigned max)
|
|
||||||
+{
|
|
||||||
+ unsigned count = 0;
|
|
||||||
+
|
|
||||||
+ if (node->flavor == CIL_BLOCKINHERIT) {
|
|
||||||
+ struct cil_blockinherit *bi = node->data;
|
|
||||||
+ count += 1;
|
|
||||||
+ if (bi->block) {
|
|
||||||
+ count += cil_count_potential(NODE(bi->block), max);
|
|
||||||
+ if (count > max) {
|
|
||||||
+ return count;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ for (node = node->cl_head; node; node = node->next) {
|
|
||||||
+ count += cil_count_potential(node, max);
|
|
||||||
+ if (count > max) {
|
|
||||||
+ return count;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return count;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int cil_check_for_degenerate_inheritance(struct cil_tree_node *node)
|
|
||||||
+{
|
|
||||||
+ uint64_t num_actual, num_potential, max;
|
|
||||||
+
|
|
||||||
+ num_actual = cil_count_actual(node);
|
|
||||||
+
|
|
||||||
+ max = num_actual * CIL_DEGENERATE_INHERITANCE_GROWTH;
|
|
||||||
+ if (max < CIL_DEGENERATE_INHERITANCE_MINIMUM) {
|
|
||||||
+ max = CIL_DEGENERATE_INHERITANCE_MINIMUM;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ num_potential = cil_count_potential(node, max);
|
|
||||||
+
|
|
||||||
+ if (num_potential > max) {
|
|
||||||
+ return SEPOL_ERR;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return SEPOL_OK;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args)
|
|
||||||
{
|
|
||||||
int rc = SEPOL_OK;
|
|
||||||
@@ -4068,6 +4127,7 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
|
|
||||||
struct cil_args_resolve extra_args;
|
|
||||||
enum cil_pass pass = CIL_PASS_TIF;
|
|
||||||
uint32_t changed = 0;
|
|
||||||
+ int inheritance_check = 0;
|
|
||||||
|
|
||||||
if (db == NULL || current == NULL) {
|
|
||||||
return rc;
|
|
||||||
@@ -4087,6 +4147,7 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
|
|
||||||
extra_args.sensitivityorder_lists = NULL;
|
|
||||||
extra_args.in_list = NULL;
|
|
||||||
extra_args.disabled_optionals = NULL;
|
|
||||||
+ extra_args.inheritance_check = &inheritance_check;
|
|
||||||
|
|
||||||
cil_list_init(&extra_args.to_destroy, CIL_NODE);
|
|
||||||
cil_list_init(&extra_args.sidorder_lists, CIL_LIST_ITEM);
|
|
||||||
@@ -4113,6 +4174,15 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
|
|
||||||
cil_list_destroy(&extra_args.in_list, CIL_FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if (pass == CIL_PASS_BLKIN_LINK && inheritance_check == CIL_TRUE) {
|
|
||||||
+ rc = cil_check_for_degenerate_inheritance(current);
|
|
||||||
+ if (rc != SEPOL_OK) {
|
|
||||||
+ cil_log(CIL_ERR, "Degenerate inheritance detected\n");
|
|
||||||
+ rc = SEPOL_ERR;
|
|
||||||
+ goto exit;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
if (pass == CIL_PASS_MISC1) {
|
|
||||||
db->sidorder = __cil_ordered_lists_merge_all(&extra_args.sidorder_lists, NULL);
|
|
||||||
if (db->sidorder == NULL) {
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
@ -1,48 +0,0 @@
|
|||||||
From 69fc31d1fb5d3bc1d4a919285284d1fb9d679a6e Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Carter <jwcart2@gmail.com>
|
|
||||||
Date: Thu, 13 May 2021 12:37:59 -0400
|
|
||||||
Subject: [PATCH] libsepol/cil: Limit the number of open parenthesis allowed
|
|
||||||
|
|
||||||
When parsing a CIL policy, the number of open parenthesis is tracked
|
|
||||||
to verify that each has a matching close parenthesis. If there are
|
|
||||||
too many open parenthesis, a stack overflow could occur during later
|
|
||||||
processing.
|
|
||||||
|
|
||||||
Exit with an error if the number of open parenthesis exceeds 4096
|
|
||||||
(which should be enough for any policy.)
|
|
||||||
|
|
||||||
This bug was found by the secilc-fuzzer.
|
|
||||||
|
|
||||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_parser.c | 7 ++++++-
|
|
||||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_parser.c b/libsepol/cil/src/cil_parser.c
|
|
||||||
index a930621..fb95f40 100644
|
|
||||||
--- a/libsepol/cil/src/cil_parser.c
|
|
||||||
+++ b/libsepol/cil/src/cil_parser.c
|
|
||||||
@@ -42,6 +42,8 @@
|
|
||||||
#include "cil_strpool.h"
|
|
||||||
#include "cil_stack.h"
|
|
||||||
|
|
||||||
+#define CIL_PARSER_MAX_EXPR_DEPTH (0x1 << 12)
|
|
||||||
+
|
|
||||||
char *CIL_KEY_HLL_LMS;
|
|
||||||
char *CIL_KEY_HLL_LMX;
|
|
||||||
char *CIL_KEY_HLL_LME;
|
|
||||||
@@ -245,7 +247,10 @@ int cil_parser(const char *_path, char *buffer, uint32_t size, struct cil_tree *
|
|
||||||
break;
|
|
||||||
case OPAREN:
|
|
||||||
paren_count++;
|
|
||||||
-
|
|
||||||
+ if (paren_count > CIL_PARSER_MAX_EXPR_DEPTH) {
|
|
||||||
+ cil_log(CIL_ERR, "Number of open parenthesis exceeds limit of %d at line %d of %s\n", CIL_PARSER_MAX_EXPR_DEPTH, tok.line, path);
|
|
||||||
+ goto exit;
|
|
||||||
+ }
|
|
||||||
create_node(&node, current, tok.line, hll_lineno, NULL);
|
|
||||||
insert_node(node, current);
|
|
||||||
current = node;
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
From 05d1c66aaae2b1ce3eaac7d241f24be121fddb39 Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Carter <jwcart2@gmail.com>
|
|
||||||
Date: Fri, 27 Aug 2021 10:12:42 -0400
|
|
||||||
Subject: [PATCH] libsepol/cil: Properly check for parameter when inserting
|
|
||||||
name
|
|
||||||
|
|
||||||
File names for typetransition rules are stored in their own datums.
|
|
||||||
This allows them to be passed as a parameter, but there needs to be
|
|
||||||
a check in __cil_insert_name() so that parameter names are not
|
|
||||||
mistaken for file name strings. This check did not verify that a
|
|
||||||
matching parameter name had the flavor of CIL_NAME.
|
|
||||||
|
|
||||||
Check that the parameter flavor is CIL_NAME and that the paramter
|
|
||||||
name matches the file name to be stored in the datum.
|
|
||||||
|
|
||||||
This bug was found by the secilc-fuzzer.
|
|
||||||
|
|
||||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_resolve_ast.c | 3 ++-
|
|
||||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
index 1800732..a4de1c7 100644
|
|
||||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
@@ -87,7 +87,8 @@ static struct cil_name * __cil_insert_name(struct cil_db *db, hashtab_key_t key,
|
|
||||||
if (macro != NULL && macro->params != NULL) {
|
|
||||||
struct cil_list_item *item;
|
|
||||||
cil_list_for_each(item, macro->params) {
|
|
||||||
- if (((struct cil_param*)item->data)->str == key) {
|
|
||||||
+ struct cil_param *param = item->data;
|
|
||||||
+ if (param->flavor == CIL_NAME && param->str == key) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
@ -1,74 +0,0 @@
|
|||||||
From 63ce05ba07fc3517900fac22efe1c761d856762f Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Carter <jwcart2@gmail.com>
|
|
||||||
Date: Thu, 8 Apr 2021 13:32:16 -0400
|
|
||||||
Subject: [PATCH] libsepol/cil: Refactor helper function for cil_gen_node()
|
|
||||||
|
|
||||||
Change the name of cil_is_datum_multiple_decl() to
|
|
||||||
cil_allow_multiple_decls() and make it static. The new function
|
|
||||||
takes the CIL db and the flavors of the old and new datum as
|
|
||||||
arguments. Also, put all of the logic of determining if multiple
|
|
||||||
declarations are allowed into the new function. Finally, update
|
|
||||||
the call from cil_gen_node().
|
|
||||||
|
|
||||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_build_ast.c | 27 ++++++++++-----------------
|
|
||||||
1 file changed, 10 insertions(+), 17 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
|
|
||||||
index e57de66..14cdce1 100644
|
|
||||||
--- a/libsepol/cil/src/cil_build_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_build_ast.c
|
|
||||||
@@ -82,30 +82,24 @@ exit:
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
-/*
|
|
||||||
- * Determine whether or not multiple declarations of the same key can share a
|
|
||||||
- * datum, given the new datum and the one already present in a given symtab.
|
|
||||||
- */
|
|
||||||
-int cil_is_datum_multiple_decl(__attribute__((unused)) struct cil_symtab_datum *cur,
|
|
||||||
- struct cil_symtab_datum *old,
|
|
||||||
- enum cil_flavor f)
|
|
||||||
+static int cil_allow_multiple_decls(struct cil_db *db, enum cil_flavor f_new, enum cil_flavor f_old)
|
|
||||||
{
|
|
||||||
- int rc = CIL_FALSE;
|
|
||||||
+ if (f_new != f_old) {
|
|
||||||
+ return CIL_FALSE;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- switch (f) {
|
|
||||||
+ switch (f_new) {
|
|
||||||
case CIL_TYPE:
|
|
||||||
case CIL_TYPEATTRIBUTE:
|
|
||||||
- if (!old || f != FLAVOR(old)) {
|
|
||||||
- rc = CIL_FALSE;
|
|
||||||
- } else {
|
|
||||||
- /* type and typeattribute statements insert empty datums */
|
|
||||||
- rc = CIL_TRUE;
|
|
||||||
+ if (db->multiple_decls) {
|
|
||||||
+ return CIL_TRUE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
- return rc;
|
|
||||||
+
|
|
||||||
+ return CIL_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cil_gen_node(struct cil_db *db, struct cil_tree_node *ast_node, struct cil_symtab_datum *datum, hashtab_key_t key, enum cil_sym_index sflavor, enum cil_flavor nflavor)
|
|
||||||
@@ -135,8 +129,7 @@ int cil_gen_node(struct cil_db *db, struct cil_tree_node *ast_node, struct cil_s
|
|
||||||
cil_log(CIL_ERR, "Re-declaration of %s %s, but previous declaration could not be found\n",cil_node_to_string(ast_node), key);
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
- if (!db->multiple_decls ||
|
|
||||||
- !cil_is_datum_multiple_decl(datum, prev, nflavor)) {
|
|
||||||
+ if (!cil_allow_multiple_decls(db, nflavor, FLAVOR(prev))) {
|
|
||||||
/* multiple_decls not ok, ret error */
|
|
||||||
struct cil_tree_node *node = NODE(prev);
|
|
||||||
cil_log(CIL_ERR, "Re-declaration of %s %s\n",
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
@ -1,47 +0,0 @@
|
|||||||
From 9b9761cfaa09958ead2bcad256dd0f1706e8b5b3 Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Carter <jwcart2@gmail.com>
|
|
||||||
Date: Mon, 16 Nov 2020 17:06:59 -0500
|
|
||||||
Subject: [PATCH] libsepol/cil: Remove unused field from struct
|
|
||||||
cil_args_resolve
|
|
||||||
|
|
||||||
When resolving names, the struct cil_args_resolve is passed to the
|
|
||||||
various resolve functions. The field last_resolved_name is not used.
|
|
||||||
|
|
||||||
Remove the last_resolved_name field from struct cil_args_resolve.
|
|
||||||
|
|
||||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_resolve_ast.c | 4 ----
|
|
||||||
1 file changed, 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
index daf873b..410b8c8 100644
|
|
||||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
@@ -51,7 +51,6 @@ struct cil_args_resolve {
|
|
||||||
struct cil_db *db;
|
|
||||||
enum cil_pass pass;
|
|
||||||
uint32_t *changed;
|
|
||||||
- char *last_resolved_name;
|
|
||||||
struct cil_tree_node *optstack;
|
|
||||||
struct cil_tree_node *boolif;
|
|
||||||
struct cil_tree_node *macro;
|
|
||||||
@@ -3905,7 +3904,6 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
|
|
||||||
extra_args.db = db;
|
|
||||||
extra_args.pass = pass;
|
|
||||||
extra_args.changed = &changed;
|
|
||||||
- extra_args.last_resolved_name = NULL;
|
|
||||||
extra_args.optstack = NULL;
|
|
||||||
extra_args.boolif= NULL;
|
|
||||||
extra_args.macro = NULL;
|
|
||||||
@@ -4234,7 +4232,5 @@ exit:
|
|
||||||
*datum = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
- args->last_resolved_name = name;
|
|
||||||
-
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
@ -1,175 +0,0 @@
|
|||||||
From ef533c8fd941bfb0c9a729b757d8a5b68fe3d080 Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Carter <jwcart2@gmail.com>
|
|
||||||
Date: Tue, 30 Mar 2021 13:39:16 -0400
|
|
||||||
Subject: [PATCH] libsepol/cil: Reorder checks for invalid rules when resolving
|
|
||||||
AST
|
|
||||||
|
|
||||||
Reorder checks for invalid rules in the blocks of tunableifs,
|
|
||||||
in-statements, macros, and booleanifs when resolving 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_resolve_ast.c | 76 +++++++++++++++++++-------------------
|
|
||||||
1 file changed, 39 insertions(+), 37 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
index a61462d..93fc0d6 100644
|
|
||||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
@@ -52,10 +52,10 @@ struct cil_args_resolve {
|
|
||||||
enum cil_pass pass;
|
|
||||||
uint32_t *changed;
|
|
||||||
struct cil_list *disabled_optionals;
|
|
||||||
+ struct cil_tree_node *block;
|
|
||||||
+ struct cil_tree_node *macro;
|
|
||||||
struct cil_tree_node *optional;
|
|
||||||
struct cil_tree_node *boolif;
|
|
||||||
- struct cil_tree_node *macro;
|
|
||||||
- struct cil_tree_node *block;
|
|
||||||
struct cil_list *sidorder_lists;
|
|
||||||
struct cil_list *classorder_lists;
|
|
||||||
struct cil_list *unordered_classorder_lists;
|
|
||||||
@@ -3777,50 +3777,52 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished
|
|
||||||
int rc = SEPOL_ERR;
|
|
||||||
struct cil_args_resolve *args = extra_args;
|
|
||||||
enum cil_pass pass = args->pass;
|
|
||||||
- struct cil_tree_node *optional = args->optional;
|
|
||||||
- struct cil_tree_node *boolif = args->boolif;
|
|
||||||
struct cil_tree_node *block = args->block;
|
|
||||||
struct cil_tree_node *macro = args->macro;
|
|
||||||
+ struct cil_tree_node *optional = args->optional;
|
|
||||||
+ struct cil_tree_node *boolif = args->boolif;
|
|
||||||
|
|
||||||
if (node == NULL) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (optional != NULL) {
|
|
||||||
- if (node->flavor == CIL_TUNABLE || 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));
|
|
||||||
+ if (block != NULL) {
|
|
||||||
+ if (node->flavor == CIL_CAT ||
|
|
||||||
+ node->flavor == CIL_SENS) {
|
|
||||||
+ cil_tree_log(node, CIL_ERR, "%s statement is not allowed in blocks", cil_node_to_string(node));
|
|
||||||
rc = SEPOL_ERR;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (block != NULL) {
|
|
||||||
- if (node->flavor == CIL_CAT || node->flavor == CIL_SENS) {
|
|
||||||
- cil_tree_log(node, CIL_ERR, "%s statement is not allowed in blocks", cil_node_to_string(node));
|
|
||||||
+ if (macro != NULL) {
|
|
||||||
+ if (node->flavor == CIL_BLOCK ||
|
|
||||||
+ node->flavor == CIL_BLOCKINHERIT ||
|
|
||||||
+ node->flavor == CIL_BLOCKABSTRACT ||
|
|
||||||
+ node->flavor == CIL_MACRO) {
|
|
||||||
+ cil_tree_log(node, CIL_ERR, "%s statement is not allowed in macros", cil_node_to_string(node));
|
|
||||||
rc = SEPOL_ERR;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (macro != NULL) {
|
|
||||||
- if (node->flavor == CIL_BLOCKINHERIT ||
|
|
||||||
- node->flavor == CIL_BLOCK ||
|
|
||||||
- node->flavor == CIL_BLOCKABSTRACT ||
|
|
||||||
- node->flavor == CIL_MACRO) {
|
|
||||||
- cil_tree_log(node, CIL_ERR, "%s statement is not allowed in macros", cil_node_to_string(node));
|
|
||||||
+ if (optional != NULL) {
|
|
||||||
+ if (node->flavor == CIL_TUNABLE ||
|
|
||||||
+ 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (boolif != NULL) {
|
|
||||||
- if (!(node->flavor == CIL_CONDBLOCK ||
|
|
||||||
- node->flavor == CIL_AVRULE ||
|
|
||||||
- node->flavor == CIL_TYPE_RULE ||
|
|
||||||
- node->flavor == CIL_CALL ||
|
|
||||||
- node->flavor == CIL_TUNABLEIF ||
|
|
||||||
- node->flavor == CIL_NAMETYPETRANSITION)) {
|
|
||||||
+ if (!(node->flavor == CIL_TUNABLEIF ||
|
|
||||||
+ node->flavor == CIL_CALL ||
|
|
||||||
+ node->flavor == CIL_CONDBLOCK ||
|
|
||||||
+ node->flavor == CIL_AVRULE ||
|
|
||||||
+ node->flavor == CIL_TYPE_RULE ||
|
|
||||||
+ node->flavor == CIL_NAMETYPETRANSITION)) {
|
|
||||||
if (((struct cil_booleanif*)boolif->data)->preserved_tunable) {
|
|
||||||
cil_tree_log(node, CIL_ERR, "%s statement is not allowed in booleanifs (tunableif treated as a booleanif)", cil_node_to_string(node));
|
|
||||||
} else {
|
|
||||||
@@ -3886,12 +3888,12 @@ int __cil_resolve_ast_first_child_helper(struct cil_tree_node *current, void *ex
|
|
||||||
|
|
||||||
if (parent->flavor == CIL_BLOCK) {
|
|
||||||
args->block = parent;
|
|
||||||
+ } else if (parent->flavor == CIL_MACRO) {
|
|
||||||
+ args->macro = parent;
|
|
||||||
} else if (parent->flavor == CIL_OPTIONAL) {
|
|
||||||
args->optional = parent;
|
|
||||||
} else if (parent->flavor == CIL_BOOLEANIF) {
|
|
||||||
args->boolif = parent;
|
|
||||||
- } else if (parent->flavor == CIL_MACRO) {
|
|
||||||
- args->macro = parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
return SEPOL_OK;
|
|
||||||
@@ -3913,7 +3915,17 @@ int __cil_resolve_ast_last_child_helper(struct cil_tree_node *current, void *ext
|
|
||||||
|
|
||||||
parent = current->parent;
|
|
||||||
|
|
||||||
- if (parent->flavor == CIL_MACRO) {
|
|
||||||
+ if (parent->flavor == CIL_BLOCK) {
|
|
||||||
+ struct cil_tree_node *n = parent->parent;
|
|
||||||
+ args->block = NULL;
|
|
||||||
+ while (n && n->flavor != CIL_ROOT) {
|
|
||||||
+ if (n->flavor == CIL_BLOCK) {
|
|
||||||
+ args->block = n;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ n = n->parent;
|
|
||||||
+ }
|
|
||||||
+ } else if (parent->flavor == CIL_MACRO) {
|
|
||||||
args->macro = NULL;
|
|
||||||
} else if (parent->flavor == CIL_OPTIONAL) {
|
|
||||||
struct cil_tree_node *n = parent->parent;
|
|
||||||
@@ -3931,16 +3943,6 @@ int __cil_resolve_ast_last_child_helper(struct cil_tree_node *current, void *ext
|
|
||||||
}
|
|
||||||
} else if (parent->flavor == CIL_BOOLEANIF) {
|
|
||||||
args->boolif = NULL;
|
|
||||||
- } else if (parent->flavor == CIL_BLOCK) {
|
|
||||||
- struct cil_tree_node *n = parent->parent;
|
|
||||||
- args->block = NULL;
|
|
||||||
- while (n && n->flavor != CIL_ROOT) {
|
|
||||||
- if (n->flavor == CIL_BLOCK) {
|
|
||||||
- args->block = n;
|
|
||||||
- break;
|
|
||||||
- }
|
|
||||||
- n = n->parent;
|
|
||||||
- }
|
|
||||||
}
|
|
||||||
|
|
||||||
return SEPOL_OK;
|
|
||||||
@@ -3964,9 +3966,9 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
|
|
||||||
extra_args.pass = pass;
|
|
||||||
extra_args.changed = &changed;
|
|
||||||
extra_args.block = NULL;
|
|
||||||
+ extra_args.macro = NULL;
|
|
||||||
extra_args.optional = NULL;
|
|
||||||
extra_args.boolif= NULL;
|
|
||||||
- extra_args.macro = NULL;
|
|
||||||
extra_args.sidorder_lists = NULL;
|
|
||||||
extra_args.classorder_lists = NULL;
|
|
||||||
extra_args.unordered_classorder_lists = NULL;
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
@ -1,57 +0,0 @@
|
|||||||
From b57535318af6f3f5e79c90caed06423b1f50abb1 Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Carter <jwcart2@gmail.com>
|
|
||||||
Date: Fri, 27 Aug 2021 10:11:19 -0400
|
|
||||||
Subject: [PATCH] libsepol/cil: Reset expandtypeattribute rules when resetting
|
|
||||||
AST
|
|
||||||
|
|
||||||
A list is created to store type attribute datums when resolving an
|
|
||||||
expandtypeattribute rule and that list needs to be destroyed if the
|
|
||||||
AST is reset or a memory leak will occur.
|
|
||||||
|
|
||||||
Destroy the list storing type attributes datums when resetting
|
|
||||||
expandtypeattribute rules.
|
|
||||||
|
|
||||||
This bug was found by the secilc-fuzzer.
|
|
||||||
|
|
||||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_reset_ast.c | 9 ++++++++-
|
|
||||||
1 file changed, 8 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_reset_ast.c b/libsepol/cil/src/cil_reset_ast.c
|
|
||||||
index 6d1d2da..0ba075c 100644
|
|
||||||
--- a/libsepol/cil/src/cil_reset_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_reset_ast.c
|
|
||||||
@@ -208,6 +208,11 @@ static void cil_reset_typeattributeset(struct cil_typeattributeset *tas)
|
|
||||||
cil_list_destroy(&tas->datum_expr, CIL_FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void cil_reset_expandtypeattribute(struct cil_expandtypeattribute *expandattr)
|
|
||||||
+{
|
|
||||||
+ cil_list_destroy(&expandattr->attr_datums, CIL_FALSE);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static void cil_reset_avrule(struct cil_avrule *rule)
|
|
||||||
{
|
|
||||||
cil_reset_classperms_list(rule->perms.classperms);
|
|
||||||
@@ -531,6 +536,9 @@ int __cil_reset_node(struct cil_tree_node *node, __attribute__((unused)) uint32
|
|
||||||
case CIL_TYPEATTRIBUTESET:
|
|
||||||
cil_reset_typeattributeset(node->data);
|
|
||||||
break;
|
|
||||||
+ case CIL_EXPANDTYPEATTRIBUTE:
|
|
||||||
+ cil_reset_expandtypeattribute(node->data);
|
|
||||||
+ break;
|
|
||||||
case CIL_RANGETRANSITION:
|
|
||||||
cil_reset_rangetransition(node->data);
|
|
||||||
break;
|
|
||||||
@@ -630,7 +638,6 @@ int __cil_reset_node(struct cil_tree_node *node, __attribute__((unused)) uint32
|
|
||||||
case CIL_CLASSORDER:
|
|
||||||
case CIL_CATORDER:
|
|
||||||
case CIL_SENSITIVITYORDER:
|
|
||||||
- case CIL_EXPANDTYPEATTRIBUTE:
|
|
||||||
break; /* Nothing to reset */
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
@ -1,249 +0,0 @@
|
|||||||
From 525f0312d51d3afd48f5e0cd8a58cced3532cfdf Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Carter <jwcart2@gmail.com>
|
|
||||||
Date: Tue, 30 Mar 2021 13:39:15 -0400
|
|
||||||
Subject: [PATCH] libsepol/cil: Use AST to track blocks and optionals when
|
|
||||||
resolving
|
|
||||||
|
|
||||||
When resolving the AST, block and optional stacks are used to
|
|
||||||
determine if the current rule being resolved is in a block or
|
|
||||||
an optional. There is no need to do this since the parent node
|
|
||||||
pointers can be used when exiting a block or an optional to
|
|
||||||
determine if resolution is still within a block or an optional.
|
|
||||||
|
|
||||||
When entering either a block or an optional, update the appropriate
|
|
||||||
tree node pointer. When finished with the last child of a block or
|
|
||||||
optional, set the appropriate pointer to NULL. If a parent of the
|
|
||||||
same kind is found when the parent node pointers are followed back
|
|
||||||
to the root node, then set the pointer to that tree node.
|
|
||||||
|
|
||||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_resolve_ast.c | 107 +++++++++++--------------------------
|
|
||||||
1 file changed, 32 insertions(+), 75 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
index 63beed9..a61462d 100644
|
|
||||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
@@ -52,10 +52,10 @@ struct cil_args_resolve {
|
|
||||||
enum cil_pass pass;
|
|
||||||
uint32_t *changed;
|
|
||||||
struct cil_list *disabled_optionals;
|
|
||||||
- struct cil_tree_node *optstack;
|
|
||||||
+ struct cil_tree_node *optional;
|
|
||||||
struct cil_tree_node *boolif;
|
|
||||||
struct cil_tree_node *macro;
|
|
||||||
- struct cil_tree_node *blockstack;
|
|
||||||
+ struct cil_tree_node *block;
|
|
||||||
struct cil_list *sidorder_lists;
|
|
||||||
struct cil_list *classorder_lists;
|
|
||||||
struct cil_list *unordered_classorder_lists;
|
|
||||||
@@ -3777,16 +3777,16 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished
|
|
||||||
int rc = SEPOL_ERR;
|
|
||||||
struct cil_args_resolve *args = extra_args;
|
|
||||||
enum cil_pass pass = args->pass;
|
|
||||||
- struct cil_tree_node *optstack = args->optstack;
|
|
||||||
+ struct cil_tree_node *optional = args->optional;
|
|
||||||
struct cil_tree_node *boolif = args->boolif;
|
|
||||||
- struct cil_tree_node *blockstack = args->blockstack;
|
|
||||||
+ struct cil_tree_node *block = args->block;
|
|
||||||
struct cil_tree_node *macro = args->macro;
|
|
||||||
|
|
||||||
if (node == NULL) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (optstack != NULL) {
|
|
||||||
+ if (optional != NULL) {
|
|
||||||
if (node->flavor == CIL_TUNABLE || 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));
|
|
||||||
@@ -3795,7 +3795,7 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (blockstack != NULL) {
|
|
||||||
+ if (block != NULL) {
|
|
||||||
if (node->flavor == CIL_CAT || node->flavor == CIL_SENS) {
|
|
||||||
cil_tree_log(node, CIL_ERR, "%s statement is not allowed in blocks", cil_node_to_string(node));
|
|
||||||
rc = SEPOL_ERR;
|
|
||||||
@@ -3849,11 +3849,11 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished
|
|
||||||
if (rc == SEPOL_ENOENT) {
|
|
||||||
enum cil_log_level lvl = CIL_ERR;
|
|
||||||
|
|
||||||
- if (optstack != NULL) {
|
|
||||||
+ if (optional != NULL) {
|
|
||||||
lvl = CIL_INFO;
|
|
||||||
|
|
||||||
- struct cil_optional *opt = (struct cil_optional *)optstack->data;
|
|
||||||
- struct cil_tree_node *opt_node = opt->datum.nodes->head->data;
|
|
||||||
+ struct cil_optional *opt = (struct cil_optional *)optional->data;
|
|
||||||
+ struct cil_tree_node *opt_node = NODE(opt);;
|
|
||||||
/* disable an optional if something failed to resolve */
|
|
||||||
opt->enabled = CIL_FALSE;
|
|
||||||
cil_tree_log(node, lvl, "Failed to resolve %s statement", cil_node_to_string(node));
|
|
||||||
@@ -3876,39 +3876,18 @@ int __cil_resolve_ast_first_child_helper(struct cil_tree_node *current, void *ex
|
|
||||||
{
|
|
||||||
int rc = SEPOL_ERR;
|
|
||||||
struct cil_args_resolve *args = extra_args;
|
|
||||||
- struct cil_tree_node *optstack = NULL;
|
|
||||||
struct cil_tree_node *parent = NULL;
|
|
||||||
- struct cil_tree_node *blockstack = NULL;
|
|
||||||
- struct cil_tree_node *new = NULL;
|
|
||||||
|
|
||||||
if (current == NULL || extra_args == NULL) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
- optstack = args->optstack;
|
|
||||||
parent = current->parent;
|
|
||||||
- blockstack = args->blockstack;
|
|
||||||
|
|
||||||
- if (parent->flavor == CIL_OPTIONAL || parent->flavor == CIL_BLOCK) {
|
|
||||||
- /* push this node onto a stack */
|
|
||||||
- cil_tree_node_init(&new);
|
|
||||||
-
|
|
||||||
- new->data = parent->data;
|
|
||||||
- new->flavor = parent->flavor;
|
|
||||||
-
|
|
||||||
- if (parent->flavor == CIL_OPTIONAL) {
|
|
||||||
- if (optstack != NULL) {
|
|
||||||
- optstack->parent = new;
|
|
||||||
- new->cl_head = optstack;
|
|
||||||
- }
|
|
||||||
- args->optstack = new;
|
|
||||||
- } else if (parent->flavor == CIL_BLOCK) {
|
|
||||||
- if (blockstack != NULL) {
|
|
||||||
- blockstack->parent = new;
|
|
||||||
- new->cl_head = blockstack;
|
|
||||||
- }
|
|
||||||
- args->blockstack = new;
|
|
||||||
- }
|
|
||||||
+ if (parent->flavor == CIL_BLOCK) {
|
|
||||||
+ args->block = parent;
|
|
||||||
+ } else if (parent->flavor == CIL_OPTIONAL) {
|
|
||||||
+ args->optional = parent;
|
|
||||||
} else if (parent->flavor == CIL_BOOLEANIF) {
|
|
||||||
args->boolif = parent;
|
|
||||||
} else if (parent->flavor == CIL_MACRO) {
|
|
||||||
@@ -3927,7 +3906,6 @@ int __cil_resolve_ast_last_child_helper(struct cil_tree_node *current, void *ext
|
|
||||||
int rc = SEPOL_ERR;
|
|
||||||
struct cil_args_resolve *args = extra_args;
|
|
||||||
struct cil_tree_node *parent = NULL;
|
|
||||||
- struct cil_tree_node *blockstack = NULL;
|
|
||||||
|
|
||||||
if (current == NULL || extra_args == NULL) {
|
|
||||||
goto exit;
|
|
||||||
@@ -3938,30 +3916,31 @@ int __cil_resolve_ast_last_child_helper(struct cil_tree_node *current, void *ext
|
|
||||||
if (parent->flavor == CIL_MACRO) {
|
|
||||||
args->macro = NULL;
|
|
||||||
} else if (parent->flavor == CIL_OPTIONAL) {
|
|
||||||
- struct cil_tree_node *optstack;
|
|
||||||
-
|
|
||||||
+ struct cil_tree_node *n = parent->parent;
|
|
||||||
if (((struct cil_optional *)parent->data)->enabled == CIL_FALSE) {
|
|
||||||
*(args->changed) = CIL_TRUE;
|
|
||||||
cil_list_append(args->disabled_optionals, CIL_NODE, parent);
|
|
||||||
}
|
|
||||||
-
|
|
||||||
- /* pop off the stack */
|
|
||||||
- optstack = args->optstack;
|
|
||||||
- args->optstack = optstack->cl_head;
|
|
||||||
- if (optstack->cl_head) {
|
|
||||||
- optstack->cl_head->parent = NULL;
|
|
||||||
+ args->optional = NULL;
|
|
||||||
+ while (n && n->flavor != CIL_ROOT) {
|
|
||||||
+ if (n->flavor == CIL_OPTIONAL) {
|
|
||||||
+ args->optional = n;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ n = n->parent;
|
|
||||||
}
|
|
||||||
- free(optstack);
|
|
||||||
} else if (parent->flavor == CIL_BOOLEANIF) {
|
|
||||||
args->boolif = NULL;
|
|
||||||
} else if (parent->flavor == CIL_BLOCK) {
|
|
||||||
- /* pop off the stack */
|
|
||||||
- blockstack = args->blockstack;
|
|
||||||
- args->blockstack = blockstack->cl_head;
|
|
||||||
- if (blockstack->cl_head) {
|
|
||||||
- blockstack->cl_head->parent = NULL;
|
|
||||||
+ struct cil_tree_node *n = parent->parent;
|
|
||||||
+ args->block = NULL;
|
|
||||||
+ while (n && n->flavor != CIL_ROOT) {
|
|
||||||
+ if (n->flavor == CIL_BLOCK) {
|
|
||||||
+ args->block = n;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ n = n->parent;
|
|
||||||
}
|
|
||||||
- free(blockstack);
|
|
||||||
}
|
|
||||||
|
|
||||||
return SEPOL_OK;
|
|
||||||
@@ -3970,16 +3949,6 @@ exit:
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void cil_destroy_tree_node_stack(struct cil_tree_node *curr)
|
|
||||||
-{
|
|
||||||
- struct cil_tree_node *next;
|
|
||||||
- while (curr != NULL) {
|
|
||||||
- next = curr->cl_head;
|
|
||||||
- free(curr);
|
|
||||||
- curr = next;
|
|
||||||
- }
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
|
|
||||||
{
|
|
||||||
int rc = SEPOL_ERR;
|
|
||||||
@@ -3994,7 +3963,8 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
|
|
||||||
extra_args.db = db;
|
|
||||||
extra_args.pass = pass;
|
|
||||||
extra_args.changed = &changed;
|
|
||||||
- extra_args.optstack = NULL;
|
|
||||||
+ extra_args.block = NULL;
|
|
||||||
+ extra_args.optional = NULL;
|
|
||||||
extra_args.boolif= NULL;
|
|
||||||
extra_args.macro = NULL;
|
|
||||||
extra_args.sidorder_lists = NULL;
|
|
||||||
@@ -4003,7 +3973,6 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
|
|
||||||
extra_args.catorder_lists = NULL;
|
|
||||||
extra_args.sensitivityorder_lists = NULL;
|
|
||||||
extra_args.in_list = NULL;
|
|
||||||
- extra_args.blockstack = NULL;
|
|
||||||
|
|
||||||
cil_list_init(&extra_args.disabled_optionals, CIL_NODE);
|
|
||||||
cil_list_init(&extra_args.sidorder_lists, CIL_LIST_ITEM);
|
|
||||||
@@ -4107,17 +4076,7 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
|
|
||||||
}
|
|
||||||
cil_list_destroy(&extra_args.disabled_optionals, CIL_FALSE);
|
|
||||||
cil_list_init(&extra_args.disabled_optionals, CIL_NODE);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- /* reset the arguments */
|
|
||||||
- changed = 0;
|
|
||||||
- while (extra_args.optstack != NULL) {
|
|
||||||
- cil_destroy_tree_node_stack(extra_args.optstack);
|
|
||||||
- extra_args.optstack = NULL;
|
|
||||||
- }
|
|
||||||
- while (extra_args.blockstack!= NULL) {
|
|
||||||
- cil_destroy_tree_node_stack(extra_args.blockstack);
|
|
||||||
- extra_args.blockstack = NULL;
|
|
||||||
+ changed = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -4128,8 +4087,6 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
|
|
||||||
|
|
||||||
rc = SEPOL_OK;
|
|
||||||
exit:
|
|
||||||
- cil_destroy_tree_node_stack(extra_args.optstack);
|
|
||||||
- cil_destroy_tree_node_stack(extra_args.blockstack);
|
|
||||||
__cil_ordered_lists_destroy(&extra_args.sidorder_lists);
|
|
||||||
__cil_ordered_lists_destroy(&extra_args.classorder_lists);
|
|
||||||
__cil_ordered_lists_destroy(&extra_args.catorder_lists);
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
@ -1,58 +0,0 @@
|
|||||||
From 8314076cd9cd71ee7ee3c5e668c1f0472ea8b815 Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Carter <jwcart2@gmail.com>
|
|
||||||
Date: Tue, 30 Mar 2021 13:40:02 -0400
|
|
||||||
Subject: [PATCH] libsepol/cil: Use CIL_ERR for error messages in cil_compile()
|
|
||||||
|
|
||||||
In cil_compile(), CIL_INFO is being used as the priority for
|
|
||||||
error messages. This can make it difficult to tell when the error
|
|
||||||
occurred.
|
|
||||||
|
|
||||||
Instead, use CIL_ERR as the priority for the error messages in
|
|
||||||
cil_compile().
|
|
||||||
|
|
||||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil.c | 8 ++++----
|
|
||||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c
|
|
||||||
index 99c8e28..b971922 100644
|
|
||||||
--- a/libsepol/cil/src/cil.c
|
|
||||||
+++ b/libsepol/cil/src/cil.c
|
|
||||||
@@ -539,7 +539,7 @@ int cil_compile(struct cil_db *db)
|
|
||||||
cil_log(CIL_INFO, "Building AST from Parse Tree\n");
|
|
||||||
rc = cil_build_ast(db, db->parse->root, db->ast->root);
|
|
||||||
if (rc != SEPOL_OK) {
|
|
||||||
- cil_log(CIL_INFO, "Failed to build ast\n");
|
|
||||||
+ cil_log(CIL_ERR, "Failed to build AST\n");
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -549,21 +549,21 @@ int cil_compile(struct cil_db *db)
|
|
||||||
cil_log(CIL_INFO, "Resolving AST\n");
|
|
||||||
rc = cil_resolve_ast(db, db->ast->root);
|
|
||||||
if (rc != SEPOL_OK) {
|
|
||||||
- cil_log(CIL_INFO, "Failed to resolve ast\n");
|
|
||||||
+ cil_log(CIL_ERR, "Failed to resolve AST\n");
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
cil_log(CIL_INFO, "Qualifying Names\n");
|
|
||||||
rc = cil_fqn_qualify(db->ast->root);
|
|
||||||
if (rc != SEPOL_OK) {
|
|
||||||
- cil_log(CIL_INFO, "Failed to qualify names\n");
|
|
||||||
+ cil_log(CIL_ERR, "Failed to qualify names\n");
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
cil_log(CIL_INFO, "Compile post process\n");
|
|
||||||
rc = cil_post_process(db);
|
|
||||||
if (rc != SEPOL_OK ) {
|
|
||||||
- cil_log(CIL_INFO, "Post process failed\n");
|
|
||||||
+ cil_log(CIL_ERR, "Post process failed\n");
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
@ -1,101 +0,0 @@
|
|||||||
From d16a1e4647a5ef2da5238f3d7829e73ceb37e5ff Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Carter <jwcart2@gmail.com>
|
|
||||||
Date: Mon, 16 Nov 2020 17:07:02 -0500
|
|
||||||
Subject: [PATCH] libsepol/cil: Use the macro FLAVOR() whenever possible
|
|
||||||
|
|
||||||
In cil_symtab.h, the macro FLAVOR() is defined. It refers to the
|
|
||||||
flavor of the first node in the list of nodes that declare the datum.
|
|
||||||
(The flavors of every node should be the same.) While the macro was
|
|
||||||
used in many places, it was not used everywhere that it could be.
|
|
||||||
|
|
||||||
Change all the remaining places to use FLAVOR().
|
|
||||||
|
|
||||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_find.c | 8 ++++----
|
|
||||||
libsepol/cil/src/cil_post.c | 2 +-
|
|
||||||
libsepol/cil/src/cil_resolve_ast.c | 8 ++++----
|
|
||||||
3 files changed, 9 insertions(+), 9 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_find.c b/libsepol/cil/src/cil_find.c
|
|
||||||
index c182406..638b675 100644
|
|
||||||
--- a/libsepol/cil/src/cil_find.c
|
|
||||||
+++ b/libsepol/cil/src/cil_find.c
|
|
||||||
@@ -44,8 +44,8 @@ struct cil_args_find {
|
|
||||||
|
|
||||||
static int cil_type_match_any(struct cil_symtab_datum *d1, struct cil_symtab_datum *d2)
|
|
||||||
{
|
|
||||||
- enum cil_flavor f1 = ((struct cil_tree_node*)d1->nodes->head->data)->flavor;
|
|
||||||
- enum cil_flavor f2 = ((struct cil_tree_node*)d2->nodes->head->data)->flavor;
|
|
||||||
+ enum cil_flavor f1 = FLAVOR(d1);
|
|
||||||
+ enum cil_flavor f2 = FLAVOR(d2);
|
|
||||||
|
|
||||||
if (f1 != CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) {
|
|
||||||
struct cil_type *t1 = (struct cil_type *)d1;
|
|
||||||
@@ -81,8 +81,8 @@ static int cil_type_match_any(struct cil_symtab_datum *d1, struct cil_symtab_dat
|
|
||||||
static int cil_type_matches(ebitmap_t *matches, struct cil_symtab_datum *d1, struct cil_symtab_datum *d2)
|
|
||||||
{
|
|
||||||
int rc = SEPOL_OK;
|
|
||||||
- enum cil_flavor f1 = ((struct cil_tree_node*)d1->nodes->head->data)->flavor;
|
|
||||||
- enum cil_flavor f2 = ((struct cil_tree_node*)d2->nodes->head->data)->flavor;
|
|
||||||
+ enum cil_flavor f1 = FLAVOR(d1);
|
|
||||||
+ enum cil_flavor f2 = FLAVOR(d2);
|
|
||||||
|
|
||||||
if (f1 != CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) {
|
|
||||||
struct cil_type *t1 = (struct cil_type *)d1;
|
|
||||||
diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c
|
|
||||||
index a0cadfd..37a4441 100644
|
|
||||||
--- a/libsepol/cil/src/cil_post.c
|
|
||||||
+++ b/libsepol/cil/src/cil_post.c
|
|
||||||
@@ -1482,7 +1482,7 @@ static void __mark_neverallow_attrs(struct cil_list *expr_list)
|
|
||||||
|
|
||||||
cil_list_for_each(curr, expr_list) {
|
|
||||||
if (curr->flavor == CIL_DATUM) {
|
|
||||||
- if (NODE(curr->data)->flavor == CIL_TYPEATTRIBUTE) {
|
|
||||||
+ if (FLAVOR(curr->data) == CIL_TYPEATTRIBUTE) {
|
|
||||||
struct cil_typeattribute *attr = curr->data;
|
|
||||||
if (strstr(DATUM(attr)->name, TYPEATTR_INFIX)) {
|
|
||||||
__mark_neverallow_attrs(attr->expr_list);
|
|
||||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
index 060bc0d..f6deb10 100644
|
|
||||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
@@ -505,7 +505,7 @@ int cil_resolve_aliasactual(struct cil_tree_node *current, void *extra_args, enu
|
|
||||||
if (rc != SEPOL_OK) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
- if (NODE(alias_datum)->flavor != alias_flavor) {
|
|
||||||
+ if (FLAVOR(alias_datum) != alias_flavor) {
|
|
||||||
cil_log(CIL_ERR, "%s is not an alias\n",alias_datum->name);
|
|
||||||
rc = SEPOL_ERR;
|
|
||||||
goto exit;
|
|
||||||
@@ -516,7 +516,7 @@ int cil_resolve_aliasactual(struct cil_tree_node *current, void *extra_args, enu
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (NODE(actual_datum)->flavor != flavor && NODE(actual_datum)->flavor != alias_flavor) {
|
|
||||||
+ if (FLAVOR(actual_datum) != flavor && FLAVOR(actual_datum) != alias_flavor) {
|
|
||||||
cil_log(CIL_ERR, "%s is a %s, but aliases a %s\n", alias_datum->name, cil_node_to_string(NODE(alias_datum)), cil_node_to_string(NODE(actual_datum)));
|
|
||||||
rc = SEPOL_ERR;
|
|
||||||
goto exit;
|
|
||||||
@@ -2573,7 +2573,7 @@ int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil
|
|
||||||
if (rc != SEPOL_OK) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
- if (NODE(parent_datum)->flavor == attr_flavor) {
|
|
||||||
+ if (FLAVOR(parent_datum) == attr_flavor) {
|
|
||||||
cil_log(CIL_ERR, "Bounds parent %s is an attribute\n", bounds->parent_str);
|
|
||||||
rc = SEPOL_ERR;
|
|
||||||
goto exit;
|
|
||||||
@@ -2584,7 +2584,7 @@ int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil
|
|
||||||
if (rc != SEPOL_OK) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
- if (NODE(child_datum)->flavor == attr_flavor) {
|
|
||||||
+ if (FLAVOR(child_datum) == attr_flavor) {
|
|
||||||
cil_log(CIL_ERR, "Bounds child %s is an attribute\n", bounds->child_str);
|
|
||||||
rc = SEPOL_ERR;
|
|
||||||
goto exit;
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
@ -1,305 +0,0 @@
|
|||||||
From 2aac859a9542f9f7a05b3763ee2ef7071760f401 Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Carter <jwcart2@gmail.com>
|
|
||||||
Date: Mon, 16 Nov 2020 17:07:01 -0500
|
|
||||||
Subject: [PATCH] libsepol/cil: Use the macro NODE() whenever possible
|
|
||||||
|
|
||||||
In cil_symtab.h, the macro NODE() is defined. It refers to the first
|
|
||||||
node in the list of nodes that declare that datum. (It is rare for
|
|
||||||
a datum to have more than one node in this list.) While the macro was
|
|
||||||
used in many places, it was not used everywhere that it could be.
|
|
||||||
|
|
||||||
Change all the remaining places to use NODE().
|
|
||||||
|
|
||||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil.c | 2 +-
|
|
||||||
libsepol/cil/src/cil_binary.c | 12 ++++++------
|
|
||||||
libsepol/cil/src/cil_find.c | 2 +-
|
|
||||||
libsepol/cil/src/cil_resolve_ast.c | 40 +++++++++++++++++++-------------------
|
|
||||||
libsepol/cil/src/cil_tree.c | 2 +-
|
|
||||||
5 files changed, 29 insertions(+), 29 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c
|
|
||||||
index 95bdb5e..bb7f06d 100644
|
|
||||||
--- a/libsepol/cil/src/cil.c
|
|
||||||
+++ b/libsepol/cil/src/cil.c
|
|
||||||
@@ -1380,7 +1380,7 @@ static int cil_cats_to_ebitmap(struct cil_cats *cats, struct ebitmap* cats_ebitm
|
|
||||||
}
|
|
||||||
|
|
||||||
cil_list_for_each(i, cats->datum_expr) {
|
|
||||||
- node = DATUM(i->data)->nodes->head->data;
|
|
||||||
+ node = NODE(i->data);
|
|
||||||
if (node->flavor == CIL_CATSET) {
|
|
||||||
cs = (struct cil_catset*)i->data;
|
|
||||||
cil_list_for_each(j, cs->cats->datum_expr) {
|
|
||||||
diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c
|
|
||||||
index e417c5c..3b01ade 100644
|
|
||||||
--- a/libsepol/cil/src/cil_binary.c
|
|
||||||
+++ b/libsepol/cil/src/cil_binary.c
|
|
||||||
@@ -147,7 +147,7 @@ static int __cil_get_sepol_level_datum(policydb_t *pdb, struct cil_symtab_datum
|
|
||||||
|
|
||||||
static int __cil_expand_user(struct cil_symtab_datum *datum, ebitmap_t *new)
|
|
||||||
{
|
|
||||||
- struct cil_tree_node *node = datum->nodes->head->data;
|
|
||||||
+ struct cil_tree_node *node = NODE(datum);
|
|
||||||
struct cil_user *user = NULL;
|
|
||||||
struct cil_userattribute *attr = NULL;
|
|
||||||
|
|
||||||
@@ -175,7 +175,7 @@ exit:
|
|
||||||
|
|
||||||
static int __cil_expand_role(struct cil_symtab_datum *datum, ebitmap_t *new)
|
|
||||||
{
|
|
||||||
- struct cil_tree_node *node = datum->nodes->head->data;
|
|
||||||
+ struct cil_tree_node *node = NODE(datum);
|
|
||||||
|
|
||||||
if (node->flavor == CIL_ROLEATTRIBUTE) {
|
|
||||||
struct cil_roleattribute *attr = (struct cil_roleattribute *)datum;
|
|
||||||
@@ -201,7 +201,7 @@ exit:
|
|
||||||
|
|
||||||
static int __cil_expand_type(struct cil_symtab_datum *datum, ebitmap_t *new)
|
|
||||||
{
|
|
||||||
- struct cil_tree_node *node = datum->nodes->head->data;
|
|
||||||
+ struct cil_tree_node *node = NODE(datum);
|
|
||||||
|
|
||||||
if (node->flavor == CIL_TYPEATTRIBUTE) {
|
|
||||||
struct cil_typeattribute *attr = (struct cil_typeattribute *)datum;
|
|
||||||
@@ -2943,7 +2943,7 @@ int __cil_cats_to_mls_level(policydb_t *pdb, struct cil_cats *cats, mls_level_t
|
|
||||||
cat_datum_t *sepol_cat = NULL;
|
|
||||||
|
|
||||||
cil_list_for_each(i, cats->datum_expr) {
|
|
||||||
- struct cil_tree_node *node = DATUM(i->data)->nodes->head->data;
|
|
||||||
+ struct cil_tree_node *node = NODE(i->data);
|
|
||||||
if (node->flavor == CIL_CATSET) {
|
|
||||||
struct cil_list_item *j;
|
|
||||||
struct cil_catset *cs = i->data;
|
|
||||||
@@ -3701,7 +3701,7 @@ int __cil_node_to_policydb(struct cil_tree_node *node, void *extra_args)
|
|
||||||
type_value_to_cil = args->type_value_to_cil;
|
|
||||||
|
|
||||||
if (node->flavor >= CIL_MIN_DECLARATIVE) {
|
|
||||||
- if (node != DATUM(node->data)->nodes->head->data) {
|
|
||||||
+ if (node != NODE(node->data)) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4450,7 +4450,7 @@ static void __cil_init_sepol_type_set(type_set_t *t)
|
|
||||||
static int __cil_add_sepol_type(policydb_t *pdb, const struct cil_db *db, struct cil_symtab_datum *datum, ebitmap_t *map)
|
|
||||||
{
|
|
||||||
int rc = SEPOL_ERR;
|
|
||||||
- struct cil_tree_node *n = datum->nodes->head->data;
|
|
||||||
+ struct cil_tree_node *n = NODE(datum);
|
|
||||||
type_datum_t *sepol_datum = NULL;
|
|
||||||
|
|
||||||
if (n->flavor == CIL_TYPEATTRIBUTE) {
|
|
||||||
diff --git a/libsepol/cil/src/cil_find.c b/libsepol/cil/src/cil_find.c
|
|
||||||
index 4134242..c182406 100644
|
|
||||||
--- a/libsepol/cil/src/cil_find.c
|
|
||||||
+++ b/libsepol/cil/src/cil_find.c
|
|
||||||
@@ -118,7 +118,7 @@ static int cil_type_matches(ebitmap_t *matches, struct cil_symtab_datum *d1, str
|
|
||||||
static int cil_self_match_any(struct cil_symtab_datum *s1, struct cil_symtab_datum *s2, struct cil_symtab_datum *t2)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
- struct cil_tree_node *n1 = s1->nodes->head->data;
|
|
||||||
+ struct cil_tree_node *n1 = NODE(s1);
|
|
||||||
if (n1->flavor != CIL_TYPEATTRIBUTE) {
|
|
||||||
rc = cil_type_match_any(s1, t2);
|
|
||||||
} else {
|
|
||||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
index 9e6afca..060bc0d 100644
|
|
||||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
@@ -393,7 +393,7 @@ int cil_resolve_type_rule(struct cil_tree_node *current, void *extra_args)
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
- result_node = result_datum->nodes->head->data;
|
|
||||||
+ result_node = NODE(result_datum);
|
|
||||||
|
|
||||||
if (result_node->flavor != CIL_TYPE) {
|
|
||||||
cil_log(CIL_ERR, "Type rule result must be a type [%d]\n",result_node->flavor);
|
|
||||||
@@ -421,7 +421,7 @@ int cil_resolve_typeattributeset(struct cil_tree_node *current, void *extra_args
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
- attr_node = attr_datum->nodes->head->data;
|
|
||||||
+ attr_node = NODE(attr_datum);
|
|
||||||
|
|
||||||
if (attr_node->flavor != CIL_TYPEATTRIBUTE) {
|
|
||||||
rc = SEPOL_ERR;
|
|
||||||
@@ -470,7 +470,7 @@ int cil_resolve_expandtypeattribute(struct cil_tree_node *current, void *extra_a
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
- attr_node = attr_datum->nodes->head->data;
|
|
||||||
+ attr_node = NODE(attr_datum);
|
|
||||||
|
|
||||||
if (attr_node->flavor != CIL_TYPEATTRIBUTE) {
|
|
||||||
rc = SEPOL_ERR;
|
|
||||||
@@ -594,7 +594,7 @@ int cil_resolve_typepermissive(struct cil_tree_node *current, void *extra_args)
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
- type_node = type_datum->nodes->head->data;
|
|
||||||
+ type_node = NODE(type_datum);
|
|
||||||
|
|
||||||
if (type_node->flavor != CIL_TYPE && type_node->flavor != CIL_TYPEALIAS) {
|
|
||||||
cil_log(CIL_ERR, "Typepermissive must be a type or type alias\n");
|
|
||||||
@@ -654,7 +654,7 @@ int cil_resolve_nametypetransition(struct cil_tree_node *current, void *extra_ar
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
- result_node = result_datum->nodes->head->data;
|
|
||||||
+ result_node = NODE(result_datum);
|
|
||||||
|
|
||||||
if (result_node->flavor != CIL_TYPE && result_node->flavor != CIL_TYPEALIAS) {
|
|
||||||
cil_log(CIL_ERR, "typetransition result is not a type or type alias\n");
|
|
||||||
@@ -855,7 +855,7 @@ int cil_resolve_userlevel(struct cil_tree_node *current, void *extra_args)
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
- user_node = user_datum->nodes->head->data;
|
|
||||||
+ user_node = NODE(user_datum);
|
|
||||||
|
|
||||||
if (user_node->flavor != CIL_USER) {
|
|
||||||
cil_log(CIL_ERR, "Userlevel must be a user\n");
|
|
||||||
@@ -908,7 +908,7 @@ int cil_resolve_userrange(struct cil_tree_node *current, void *extra_args)
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
- user_node = user_datum->nodes->head->data;
|
|
||||||
+ user_node = NODE(user_datum);
|
|
||||||
|
|
||||||
if (user_node->flavor != CIL_USER) {
|
|
||||||
cil_log(CIL_ERR, "Userrange must be a user: %s\n", user_datum->fqn);
|
|
||||||
@@ -959,7 +959,7 @@ int cil_resolve_userprefix(struct cil_tree_node *current, void *extra_args)
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
- user_node = user_datum->nodes->head->data;
|
|
||||||
+ user_node = NODE(user_datum);
|
|
||||||
|
|
||||||
if (user_node->flavor != CIL_USER) {
|
|
||||||
cil_log(CIL_ERR, "Userprefix must be a user: %s\n", user_datum->fqn);
|
|
||||||
@@ -986,7 +986,7 @@ int cil_resolve_selinuxuser(struct cil_tree_node *current, void *extra_args)
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
- user_node = user_datum->nodes->head->data;
|
|
||||||
+ user_node = NODE(user_datum);
|
|
||||||
|
|
||||||
if (user_node->flavor != CIL_USER) {
|
|
||||||
cil_log(CIL_ERR, "Selinuxuser must be a user: %s\n", user_datum->fqn);
|
|
||||||
@@ -1079,7 +1079,7 @@ int cil_resolve_roletransition(struct cil_tree_node *current, void *extra_args)
|
|
||||||
if (rc != SEPOL_OK) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
- node = result_datum->nodes->head->data;
|
|
||||||
+ node = NODE(result_datum);
|
|
||||||
if (node->flavor != CIL_ROLE) {
|
|
||||||
rc = SEPOL_ERR;
|
|
||||||
printf("%i\n", node->flavor);
|
|
||||||
@@ -1131,7 +1131,7 @@ int cil_resolve_roleattributeset(struct cil_tree_node *current, void *extra_args
|
|
||||||
if (rc != SEPOL_OK) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
- attr_node = attr_datum->nodes->head->data;
|
|
||||||
+ attr_node = NODE(attr_datum);
|
|
||||||
|
|
||||||
if (attr_node->flavor != CIL_ROLEATTRIBUTE) {
|
|
||||||
rc = SEPOL_ERR;
|
|
||||||
@@ -1569,7 +1569,7 @@ int cil_resolve_catorder(struct cil_tree_node *current, void *extra_args)
|
|
||||||
cil_log(CIL_ERR, "Failed to resolve category %s in categoryorder\n", (char *)curr->data);
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
- node = cat_datum->nodes->head->data;
|
|
||||||
+ node = NODE(cat_datum);
|
|
||||||
if (node->flavor != CIL_CAT) {
|
|
||||||
cil_log(CIL_ERR, "%s is not a category. Only categories are allowed in categoryorder statements\n", cat_datum->name);
|
|
||||||
rc = SEPOL_ERR;
|
|
||||||
@@ -1832,7 +1832,7 @@ int cil_resolve_context(struct cil_tree_node *current, struct cil_context *conte
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
- node = user_datum->nodes->head->data;
|
|
||||||
+ node = NODE(user_datum);
|
|
||||||
|
|
||||||
if (node->flavor != CIL_USER) {
|
|
||||||
cil_log(CIL_ERR, "Context user must be a user: %s\n", user_datum->fqn);
|
|
||||||
@@ -1847,7 +1847,7 @@ int cil_resolve_context(struct cil_tree_node *current, struct cil_context *conte
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
- node = role_datum->nodes->head->data;
|
|
||||||
+ node = NODE(role_datum);
|
|
||||||
if (node->flavor != CIL_ROLE) {
|
|
||||||
rc = SEPOL_ERR;
|
|
||||||
cil_log(CIL_ERR, "Context role not a role: %s\n", role_datum->fqn);
|
|
||||||
@@ -1861,7 +1861,7 @@ int cil_resolve_context(struct cil_tree_node *current, struct cil_context *conte
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
- node = type_datum->nodes->head->data;
|
|
||||||
+ node = NODE(type_datum);
|
|
||||||
|
|
||||||
if (node->flavor != CIL_TYPE && node->flavor != CIL_TYPEALIAS) {
|
|
||||||
rc = SEPOL_ERR;
|
|
||||||
@@ -2311,7 +2311,7 @@ int cil_resolve_blockinherit_link(struct cil_tree_node *current, void *extra_arg
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
- node = block_datum->nodes->head->data;
|
|
||||||
+ node = NODE(block_datum);
|
|
||||||
|
|
||||||
if (node->flavor != CIL_BLOCK) {
|
|
||||||
cil_log(CIL_ERR, "%s is not a block\n", cil_node_to_string(node));
|
|
||||||
@@ -2450,7 +2450,7 @@ int cil_resolve_blockabstract(struct cil_tree_node *current, void *extra_args)
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
- block_node = block_datum->nodes->head->data;
|
|
||||||
+ block_node = NODE(block_datum);
|
|
||||||
if (block_node->flavor != CIL_BLOCK) {
|
|
||||||
cil_log(CIL_ERR, "Failed to resolve blockabstract to a block, rc: %d\n", rc);
|
|
||||||
goto exit;
|
|
||||||
@@ -2482,7 +2482,7 @@ int cil_resolve_in(struct cil_tree_node *current, void *extra_args)
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
- block_node = block_datum->nodes->head->data;
|
|
||||||
+ block_node = NODE(block_datum);
|
|
||||||
|
|
||||||
rc = cil_copy_ast(db, current, block_node);
|
|
||||||
if (rc != SEPOL_OK) {
|
|
||||||
@@ -2774,7 +2774,7 @@ int cil_resolve_call1(struct cil_tree_node *current, void *extra_args)
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
- macro_node = macro_datum->nodes->head->data;
|
|
||||||
+ macro_node = NODE(macro_datum);
|
|
||||||
|
|
||||||
if (macro_node->flavor != CIL_MACRO) {
|
|
||||||
printf("Failed to resolve %s to a macro\n", new_call->macro_str);
|
|
||||||
@@ -3367,7 +3367,7 @@ int cil_resolve_userattributeset(struct cil_tree_node *current, void *extra_args
|
|
||||||
if (rc != SEPOL_OK) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
- attr_node = attr_datum->nodes->head->data;
|
|
||||||
+ attr_node = NODE(attr_datum);
|
|
||||||
|
|
||||||
if (attr_node->flavor != CIL_USERATTRIBUTE) {
|
|
||||||
rc = SEPOL_ERR;
|
|
||||||
diff --git a/libsepol/cil/src/cil_tree.c b/libsepol/cil/src/cil_tree.c
|
|
||||||
index b1cbda9..3ab5e86 100644
|
|
||||||
--- a/libsepol/cil/src/cil_tree.c
|
|
||||||
+++ b/libsepol/cil/src/cil_tree.c
|
|
||||||
@@ -1688,7 +1688,7 @@ void cil_tree_print_node(struct cil_tree_node *node)
|
|
||||||
struct cil_symtab_datum *datum = ((struct cil_args*)item->data)->arg;
|
|
||||||
if (datum != NULL) {
|
|
||||||
if (datum->nodes != NULL && datum->nodes->head != NULL) {
|
|
||||||
- cil_tree_print_node((struct cil_tree_node*)datum->nodes->head->data);
|
|
||||||
+ cil_tree_print_node(NODE(datum));
|
|
||||||
}
|
|
||||||
} else if (((struct cil_args*)item->data)->arg_str != NULL) {
|
|
||||||
switch (item->flavor) {
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
@ -1,112 +0,0 @@
|
|||||||
From 90809674c13c03e324dff560654d0e686c5fc46b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Evgeny Vereshchagin <evvers@ya.ru>
|
|
||||||
Date: Sun, 6 Dec 2020 23:29:22 +0100
|
|
||||||
Subject: [PATCH] libsepol/cil: always destroy the lexer state
|
|
||||||
|
|
||||||
It was found in https://github.com/google/oss-fuzz/pull/4790:
|
|
||||||
```
|
|
||||||
Invalid token '' at line 2 of fuzz
|
|
||||||
NEW_FUNC[1/2]: 0x67fff0 in yy_get_previous_state /src/selinux/libsepol/src/../cil/src/cil_lexer.c:1143
|
|
||||||
NEW_FUNC[2/2]: 0x6803e0 in yy_try_NUL_trans /src/selinux/libsepol/src/../cil/src/cil_lexer.c:1176
|
|
||||||
=================================================================
|
|
||||||
==12==ERROR: AddressSanitizer: heap-use-after-free on address 0x602000007992 at pc 0x000000681800 bp 0x7ffccddee530 sp 0x7ffccddee528
|
|
||||||
WRITE of size 1 at 0x602000007992 thread T0
|
|
||||||
SCARINESS: 41 (1-byte-write-heap-use-after-free)
|
|
||||||
#0 0x6817ff in cil_yy_switch_to_buffer /src/selinux/libsepol/src/../cil/src/cil_lexer.c:1315:17
|
|
||||||
#1 0x6820cc in cil_yy_scan_buffer /src/selinux/libsepol/src/../cil/src/cil_lexer.c:1571:2
|
|
||||||
#2 0x682662 in cil_lexer_setup /src/selinux/libsepol/src/../cil/src/cil_lexer.l:73:6
|
|
||||||
#3 0x5cf2ae in cil_parser /src/selinux/libsepol/src/../cil/src/cil_parser.c:220:2
|
|
||||||
#4 0x56d5e2 in cil_add_file /src/selinux/libsepol/src/../cil/src/cil.c:514:7
|
|
||||||
#5 0x556e91 in LLVMFuzzerTestOneInput /src/secilc-fuzzer.c:434:7
|
|
||||||
#6 0x459ab1 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:599:15
|
|
||||||
#7 0x45a755 in fuzzer::Fuzzer::TryDetectingAMemoryLeak(unsigned char const*, unsigned long, bool) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:675:3
|
|
||||||
#8 0x45acd9 in fuzzer::Fuzzer::MutateAndTestOne() /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:747:5
|
|
||||||
#9 0x45b875 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:883:5
|
|
||||||
#10 0x4499fb in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:906:6
|
|
||||||
#11 0x473a32 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
|
|
||||||
#12 0x7f982296d83f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2083f)
|
|
||||||
#13 0x41e758 in _start (/out/secilc-fuzzer+0x41e758)
|
|
||||||
|
|
||||||
DEDUP_TOKEN: cil_yy_switch_to_buffer--cil_yy_scan_buffer--cil_lexer_setup
|
|
||||||
0x602000007992 is located 2 bytes inside of 4-byte region [0x602000007990,0x602000007994)
|
|
||||||
freed by thread T0 here:
|
|
||||||
#0 0x521ef2 in free /src/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:127:3
|
|
||||||
#1 0x56d630 in cil_add_file /src/selinux/libsepol/src/../cil/src/cil.c:526:2
|
|
||||||
#2 0x556e91 in LLVMFuzzerTestOneInput /src/secilc-fuzzer.c:434:7
|
|
||||||
#3 0x459ab1 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:599:15
|
|
||||||
#4 0x458fba in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool, bool*) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:505:3
|
|
||||||
#5 0x45acc7 in fuzzer::Fuzzer::MutateAndTestOne() /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:745:19
|
|
||||||
#6 0x45b875 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:883:5
|
|
||||||
#7 0x4499fb in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:906:6
|
|
||||||
#8 0x473a32 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
|
|
||||||
#9 0x7f982296d83f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2083f)
|
|
||||||
|
|
||||||
DEDUP_TOKEN: free--cil_add_file--LLVMFuzzerTestOneInput
|
|
||||||
previously allocated by thread T0 here:
|
|
||||||
#0 0x52215d in malloc /src/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:145:3
|
|
||||||
#1 0x5cecb8 in cil_malloc /src/selinux/libsepol/src/../cil/src/cil_mem.c:39:14
|
|
||||||
#2 0x56d584 in cil_add_file /src/selinux/libsepol/src/../cil/src/cil.c:510:11
|
|
||||||
#3 0x556e91 in LLVMFuzzerTestOneInput /src/secilc-fuzzer.c:434:7
|
|
||||||
#4 0x459ab1 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:599:15
|
|
||||||
#5 0x458fba in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool, bool*) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:505:3
|
|
||||||
#6 0x45acc7 in fuzzer::Fuzzer::MutateAndTestOne() /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:745:19
|
|
||||||
#7 0x45b875 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:883:5
|
|
||||||
#8 0x4499fb in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:906:6
|
|
||||||
#9 0x473a32 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
|
|
||||||
#10 0x7f982296d83f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2083f)
|
|
||||||
|
|
||||||
DEDUP_TOKEN: malloc--cil_malloc--cil_add_file
|
|
||||||
SUMMARY: AddressSanitizer: heap-use-after-free /src/selinux/libsepol/src/../cil/src/cil_lexer.c:1315:17 in cil_yy_switch_to_buffer
|
|
||||||
Shadow bytes around the buggy address:
|
|
||||||
0x0c047fff8ee0: fa fa fd fa fa fa fd fd fa fa fd fa fa fa fd fd
|
|
||||||
0x0c047fff8ef0: fa fa fd fa fa fa fd fd fa fa fd fa fa fa fd fd
|
|
||||||
0x0c047fff8f00: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fd
|
|
||||||
0x0c047fff8f10: fa fa fd fa fa fa fd fd fa fa fd fa fa fa fd fd
|
|
||||||
0x0c047fff8f20: fa fa fd fa fa fa fd fd fa fa fd fa fa fa fd fa
|
|
||||||
=>0x0c047fff8f30: fa fa[fd]fa fa fa fd fa fa fa fd fa fa fa fd fa
|
|
||||||
0x0c047fff8f40: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
|
|
||||||
0x0c047fff8f50: fa fa fd fa fa fa fd fd fa fa fd fa fa fa fd fa
|
|
||||||
0x0c047fff8f60: fa fa fd fd fa fa fd fa fa fa fd fd fa fa fd fa
|
|
||||||
0x0c047fff8f70: fa fa 00 00 fa fa 02 fa fa fa 02 fa fa fa 00 fa
|
|
||||||
0x0c047fff8f80: fa fa 03 fa fa fa 00 fa fa fa 03 fa fa fa 00 fa
|
|
||||||
Shadow byte legend (one shadow byte represents 8 application bytes):
|
|
||||||
Addressable: 00
|
|
||||||
Partially addressable: 01 02 03 04 05 06 07
|
|
||||||
Heap left redzone: fa
|
|
||||||
Freed heap region: fd
|
|
||||||
Stack left redzone: f1
|
|
||||||
Stack mid redzone: f2
|
|
||||||
Stack right redzone: f3
|
|
||||||
Stack after return: f5
|
|
||||||
Stack use after scope: f8
|
|
||||||
Global redzone: f9
|
|
||||||
Global init order: f6
|
|
||||||
Poisoned by user: f7
|
|
||||||
Container overflow: fc
|
|
||||||
Array cookie: ac
|
|
||||||
Intra object redzone: bb
|
|
||||||
ASan internal: fe
|
|
||||||
Left alloca redzone: ca
|
|
||||||
Right alloca redzone: cb
|
|
||||||
Shadow gap: cc
|
|
||||||
==12==ABORTING
|
|
||||||
```
|
|
||||||
|
|
||||||
Signed-off-by: Evgeny Vereshchagin <evvers@ya.ru>
|
|
||||||
Acked-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_parser.c | 1 +
|
|
||||||
1 file changed, 1 insertion(+)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_parser.c b/libsepol/cil/src/cil_parser.c
|
|
||||||
index 585ea7704..a8af1dce2 100644
|
|
||||||
--- a/libsepol/cil/src/cil_parser.c
|
|
||||||
+++ b/libsepol/cil/src/cil_parser.c
|
|
||||||
@@ -310,6 +310,7 @@ int cil_parser(char *_path, char *buffer, uint32_t size, struct cil_tree **parse
|
|
||||||
while (!cil_stack_is_empty(stack)) {
|
|
||||||
pop_hll_info(stack, &hll_lineno, &hll_expand);
|
|
||||||
}
|
|
||||||
+ cil_lexer_destroy();
|
|
||||||
cil_stack_destroy(&stack);
|
|
||||||
|
|
||||||
return SEPOL_ERR;
|
|
||||||
@ -1,53 +0,0 @@
|
|||||||
From 4662bdc11c8f505716f8da361a07ad13083b0618 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Nicolas Iooss <nicolas.iooss@m4x.org>
|
|
||||||
Date: Fri, 5 Feb 2021 10:45:38 +0100
|
|
||||||
Subject: [PATCH] libsepol/cil: be more robust when encountering <src_info>
|
|
||||||
|
|
||||||
OSS-Fuzz found a Null-dereference READ in the CIL compiler when trying
|
|
||||||
to compile the following policy:
|
|
||||||
|
|
||||||
(<src_info>)
|
|
||||||
|
|
||||||
In cil_gen_src_info(), parse_current->next is NULL even though the code
|
|
||||||
expects that both parse_current->next and parse_current->next->next
|
|
||||||
exists.
|
|
||||||
|
|
||||||
Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28457
|
|
||||||
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_build_ast.c | 5 +++++
|
|
||||||
libsepol/cil/src/cil_tree.c | 2 +-
|
|
||||||
2 files changed, 6 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
|
|
||||||
index 5094d62..726f46c 100644
|
|
||||||
--- a/libsepol/cil/src/cil_build_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_build_ast.c
|
|
||||||
@@ -6070,6 +6070,11 @@ int cil_gen_src_info(struct cil_tree_node *parse_current, struct cil_tree_node *
|
|
||||||
/* No need to check syntax, because this is auto generated */
|
|
||||||
struct cil_src_info *info = NULL;
|
|
||||||
|
|
||||||
+ if (parse_current->next == NULL || parse_current->next->next == NULL) {
|
|
||||||
+ cil_tree_log(parse_current, CIL_ERR, "Bad <src_info>");
|
|
||||||
+ return SEPOL_ERR;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
cil_src_info_init(&info);
|
|
||||||
|
|
||||||
info->is_cil = (parse_current->next->data == CIL_KEY_SRC_CIL) ? CIL_TRUE : CIL_FALSE;
|
|
||||||
diff --git a/libsepol/cil/src/cil_tree.c b/libsepol/cil/src/cil_tree.c
|
|
||||||
index 886412d..3da972e 100644
|
|
||||||
--- a/libsepol/cil/src/cil_tree.c
|
|
||||||
+++ b/libsepol/cil/src/cil_tree.c
|
|
||||||
@@ -69,7 +69,7 @@ struct cil_tree_node *cil_tree_get_next_path(struct cil_tree_node *node, char **
|
|
||||||
|
|
||||||
while (node) {
|
|
||||||
if (node->flavor == CIL_NODE && node->data == NULL) {
|
|
||||||
- if (node->cl_head->data == CIL_KEY_SRC_INFO) {
|
|
||||||
+ if (node->cl_head->data == CIL_KEY_SRC_INFO && node->cl_head->next != NULL && node->cl_head->next->next != NULL) {
|
|
||||||
/* Parse Tree */
|
|
||||||
*path = node->cl_head->next->next->data;
|
|
||||||
*is_cil = (node->cl_head->next->data == CIL_KEY_SRC_CIL);
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
From b7ea65f547c67bfbae4ae133052583b090747e5a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Nicolas Iooss <nicolas.iooss@m4x.org>
|
|
||||||
Date: Wed, 30 Dec 2020 11:07:46 +0100
|
|
||||||
Subject: [PATCH] libsepol/cil: destroy perm_datums when __cil_resolve_perms
|
|
||||||
fails
|
|
||||||
|
|
||||||
When __cil_resolve_perms fails, it does not destroy perm_datums, which
|
|
||||||
leads to a memory leak reported by OSS-Fuzz with the following CIL
|
|
||||||
policy:
|
|
||||||
|
|
||||||
(class cl01())
|
|
||||||
(classorder(cl01))
|
|
||||||
(type at02)
|
|
||||||
(type tpr3)
|
|
||||||
(allow at02 tpr3(cl01((s))))
|
|
||||||
|
|
||||||
Calling cil_list_destroy() fixes the issue.
|
|
||||||
|
|
||||||
Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28466
|
|
||||||
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_resolve_ast.c | 1 +
|
|
||||||
1 file changed, 1 insertion(+)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
index 68b590bcc..0c85eabe5 100644
|
|
||||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
@@ -146,6 +146,7 @@ static int __cil_resolve_perms(symtab_t *class_symtab, symtab_t *common_symtab,
|
|
||||||
return SEPOL_OK;
|
|
||||||
|
|
||||||
exit:
|
|
||||||
+ cil_list_destroy(perm_datums, CIL_FALSE);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
From 6c8fca10452e445edf52daffc69f2e9dfcdac54c Mon Sep 17 00:00:00 2001
|
|
||||||
From: Nicolas Iooss <nicolas.iooss@m4x.org>
|
|
||||||
Date: Wed, 30 Dec 2020 21:11:40 +0100
|
|
||||||
Subject: [PATCH] libsepol/cil: do not add a stack variable to a list
|
|
||||||
|
|
||||||
OSS-Fuzz found a heap use-after-free when the CIL compiler destroys its
|
|
||||||
database after failing to compile the following policy:
|
|
||||||
|
|
||||||
(validatetrans x (eq t3 (a)))
|
|
||||||
|
|
||||||
This is caused by the fact that the validatetrans AST object references
|
|
||||||
a stack variable local to __cil_fill_constraint_leaf_expr, when parsing
|
|
||||||
the list "(a)":
|
|
||||||
|
|
||||||
struct cil_list *sub_list;
|
|
||||||
cil_fill_list(current->next->next->cl_head, leaf_expr_flavor, &sub_list);
|
|
||||||
cil_list_append(*leaf_expr, CIL_LIST, &sub_list);
|
|
||||||
|
|
||||||
Drop the & sign to really add the list like it is supposed to be.
|
|
||||||
|
|
||||||
Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28507
|
|
||||||
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_build_ast.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
|
|
||||||
index 67801def0..d5b9977c0 100644
|
|
||||||
--- a/libsepol/cil/src/cil_build_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_build_ast.c
|
|
||||||
@@ -2714,7 +2714,7 @@ static int __cil_fill_constraint_leaf_expr(struct cil_tree_node *current, enum c
|
|
||||||
} else if (r_flavor == CIL_LIST) {
|
|
||||||
struct cil_list *sub_list;
|
|
||||||
cil_fill_list(current->next->next->cl_head, leaf_expr_flavor, &sub_list);
|
|
||||||
- cil_list_append(*leaf_expr, CIL_LIST, &sub_list);
|
|
||||||
+ cil_list_append(*leaf_expr, CIL_LIST, sub_list);
|
|
||||||
} else {
|
|
||||||
cil_list_append(*leaf_expr, CIL_CONS_OPERAND, (void *)r_flavor);
|
|
||||||
}
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
From c5e6153720e713e72a65614f625a51ad44d1fc07 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Nicolas Iooss <nicolas.iooss@m4x.org>
|
|
||||||
Date: Sun, 14 Mar 2021 19:25:58 +0100
|
|
||||||
Subject: [PATCH] libsepol/cil: fix NULL pointer dereference in
|
|
||||||
__cil_insert_name
|
|
||||||
|
|
||||||
OSS-Fuzz found a Null-dereference in __cil_insert_name when trying to
|
|
||||||
compile the following policy:
|
|
||||||
|
|
||||||
(macro MACRO ()
|
|
||||||
(classmap CLASS (PERM))
|
|
||||||
(type TYPE)
|
|
||||||
(typetransition TYPE TYPE CLASS "name" TYPE)
|
|
||||||
)
|
|
||||||
(call MACRO)
|
|
||||||
|
|
||||||
When using a macro with no argument, macro->params is NULL and
|
|
||||||
cil_list_for_each(item, macro->params) dereferenced a NULL pointer.
|
|
||||||
Fix this by checking that macro->params is not NULL before using it.
|
|
||||||
|
|
||||||
Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28565
|
|
||||||
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_resolve_ast.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
index 2ea106d..63beed9 100644
|
|
||||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
@@ -82,7 +82,7 @@ static struct cil_name * __cil_insert_name(struct cil_db *db, hashtab_key_t key,
|
|
||||||
} else if (parent->flavor == CIL_MACRO) {
|
|
||||||
macro = parent->data;
|
|
||||||
}
|
|
||||||
- if (macro != NULL) {
|
|
||||||
+ if (macro != NULL && macro->params != NULL) {
|
|
||||||
struct cil_list_item *item;
|
|
||||||
cil_list_for_each(item, macro->params) {
|
|
||||||
if (((struct cil_param*)item->data)->str == key) {
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
@ -1,33 +0,0 @@
|
|||||||
From 6238e025714b18db41354629dd40e70e27b7c37e Mon Sep 17 00:00:00 2001
|
|
||||||
From: lutianxiong <lutianxiong@huawei.com>
|
|
||||||
Date: Thu, 25 Feb 2021 18:40:02 +0800
|
|
||||||
Subject: [PATCH] libsepol/cil: fix NULL pointer dereference in cil_fill_ipaddr
|
|
||||||
|
|
||||||
Found a NULL pointer dereference by fuzzing, reproducing:
|
|
||||||
$ echo "(nodecon(())o(e()))" > tmp.cil
|
|
||||||
$ secilc tmp.cil
|
|
||||||
Segmentation fault (core dumped)
|
|
||||||
|
|
||||||
Add NULL check for addr_node->data in cil_fill_ipaddr.
|
|
||||||
|
|
||||||
Signed-off-by: lutianxiong <lutianxiong@huawei.com>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_build_ast.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
|
|
||||||
index 726f46cd..4e53f06a 100644
|
|
||||||
--- a/libsepol/cil/src/cil_build_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_build_ast.c
|
|
||||||
@@ -5660,7 +5660,7 @@ int cil_fill_ipaddr(struct cil_tree_node *addr_node, struct cil_ipaddr *addr)
|
|
||||||
{
|
|
||||||
int rc = SEPOL_ERR;
|
|
||||||
|
|
||||||
- if (addr_node == NULL || addr == NULL) {
|
|
||||||
+ if (addr_node == NULL || addr_node->data == NULL || addr == NULL) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,82 +0,0 @@
|
|||||||
From bdf4e332b41ff358b7e8539c3d6ee6277f0be762 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Nicolas Iooss <nicolas.iooss@m4x.org>
|
|
||||||
Date: Wed, 6 Jan 2021 09:13:19 +0100
|
|
||||||
Subject: [PATCH] libsepol/cil: fix NULL pointer dereference when parsing an
|
|
||||||
improper integer
|
|
||||||
|
|
||||||
OSS-Fuzz found a NULL pointer dereference when the CIL compiler tries to
|
|
||||||
compile a policy with an invalid integer:
|
|
||||||
|
|
||||||
$ echo '(ioportcon(2())n)' > tmp.cil
|
|
||||||
$ secilc tmp.cil
|
|
||||||
Segmentation fault (core dumped)
|
|
||||||
|
|
||||||
This is because strtol() is called with a NULL pointer, in
|
|
||||||
cil_fill_integer().
|
|
||||||
|
|
||||||
Fix this by checking that int_node->data is not NULL. While at it, use
|
|
||||||
strtoul() instead of strtol() to parse an unsigned integer.
|
|
||||||
|
|
||||||
When using "val > UINT32_MAX" with "unsigned long val;", it is expected
|
|
||||||
that some compilers emit a warning when the size of "unsigned long" is
|
|
||||||
32 bits. In theory gcc could be such a compiler (with warning
|
|
||||||
-Wtype-limits, which is included in -Wextra). Nevertheless this is
|
|
||||||
currently broken, according to
|
|
||||||
https://gcc.gnu.org/pipermail/gcc-help/2021-January/139755.html and
|
|
||||||
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89126 (this bug was
|
|
||||||
opened in January 2019).
|
|
||||||
|
|
||||||
In order to prevent this warning from appearing, introduce some
|
|
||||||
preprocessor macros around the bound check.
|
|
||||||
|
|
||||||
Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28456
|
|
||||||
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
|
||||||
Acked-by: James Carter <jwcart2@gmail.com>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_build_ast.c | 16 ++++++++++++----
|
|
||||||
1 file changed, 12 insertions(+), 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
|
|
||||||
index be10d61b1..02481558a 100644
|
|
||||||
--- a/libsepol/cil/src/cil_build_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_build_ast.c
|
|
||||||
@@ -5570,19 +5570,27 @@ int cil_fill_integer(struct cil_tree_node *int_node, uint32_t *integer, int base
|
|
||||||
{
|
|
||||||
int rc = SEPOL_ERR;
|
|
||||||
char *endptr = NULL;
|
|
||||||
- int val;
|
|
||||||
+ unsigned long val;
|
|
||||||
|
|
||||||
- if (int_node == NULL || integer == NULL) {
|
|
||||||
+ if (int_node == NULL || int_node->data == NULL || integer == NULL) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
- val = strtol(int_node->data, &endptr, base);
|
|
||||||
+ val = strtoul(int_node->data, &endptr, base);
|
|
||||||
if (errno != 0 || endptr == int_node->data || *endptr != '\0') {
|
|
||||||
rc = SEPOL_ERR;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ /* Ensure that the value fits a 32-bit integer without triggering -Wtype-limits */
|
|
||||||
+#if ULONG_MAX > UINT32_MAX
|
|
||||||
+ if (val > UINT32_MAX) {
|
|
||||||
+ rc = SEPOL_ERR;
|
|
||||||
+ goto exit;
|
|
||||||
+ }
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
*integer = val;
|
|
||||||
|
|
||||||
return SEPOL_OK;
|
|
||||||
@@ -5598,7 +5606,7 @@ int cil_fill_integer64(struct cil_tree_node *int_node, uint64_t *integer, int ba
|
|
||||||
char *endptr = NULL;
|
|
||||||
uint64_t val;
|
|
||||||
|
|
||||||
- if (int_node == NULL || integer == NULL) {
|
|
||||||
+ if (int_node == NULL || int_node->data == NULL || integer == NULL) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
From 38a09b74024bbe1c78639821f3cff3a5ceb73d0d Mon Sep 17 00:00:00 2001
|
|
||||||
From: Nicolas Iooss <nicolas.iooss@m4x.org>
|
|
||||||
Date: Wed, 30 Dec 2020 21:11:39 +0100
|
|
||||||
Subject: [PATCH] libsepol/cil: fix NULL pointer dereference when using an
|
|
||||||
unused alias
|
|
||||||
|
|
||||||
OSS-Fuzz found a NULL pointer dereference when the CIL compiler tries to
|
|
||||||
compile a policy where a categoryalias references an unused
|
|
||||||
categoryalias:
|
|
||||||
|
|
||||||
$ echo '(categoryalias c0)(categoryalias c1)(categoryaliasactual c0 c1)' > tmp.cil
|
|
||||||
$ secil tmp.cil
|
|
||||||
Segmentation fault (core dumped)
|
|
||||||
|
|
||||||
In such a case, a1 can become NULL in cil_resolve_alias_to_actual().
|
|
||||||
Add a check to report an error when this occurs. Now the error message
|
|
||||||
is:
|
|
||||||
|
|
||||||
Alias c0 references an unused alias c1 at tmp.cil:1
|
|
||||||
|
|
||||||
Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28471
|
|
||||||
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_resolve_ast.c | 4 ++++
|
|
||||||
1 file changed, 4 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
index f6deb1002..affa7657b 100644
|
|
||||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
@@ -555,6 +555,10 @@ int cil_resolve_alias_to_actual(struct cil_tree_node *current, enum cil_flavor f
|
|
||||||
a1_node = a1->datum.nodes->head->data;
|
|
||||||
|
|
||||||
while (flavor != a1_node->flavor) {
|
|
||||||
+ if (a1->actual == NULL) {
|
|
||||||
+ cil_tree_log(current, CIL_ERR, "Alias %s references an unused alias %s", alias->datum.name, a1->datum.name);
|
|
||||||
+ return SEPOL_ERR;
|
|
||||||
+ }
|
|
||||||
a1 = a1->actual;
|
|
||||||
a1_node = a1->datum.nodes->head->data;
|
|
||||||
steps += 1;
|
|
||||||
@ -1,57 +0,0 @@
|
|||||||
From 228c06d97a8a33b60b89ded17acbd0e92cca9cfe Mon Sep 17 00:00:00 2001
|
|
||||||
From: Nicolas Iooss <nicolas.iooss@m4x.org>
|
|
||||||
Date: Wed, 30 Dec 2020 11:07:45 +0100
|
|
||||||
Subject: [PATCH] libsepol/cil: fix out-of-bound read in
|
|
||||||
cil_print_recursive_blockinherit
|
|
||||||
|
|
||||||
OSS-Fuzz found a heap buffer overflow (out-of-bound reads) when the CIL
|
|
||||||
compiler tries to report a recursive blockinherit with an optional
|
|
||||||
block:
|
|
||||||
|
|
||||||
$ echo '(block b (optional o (blockinherit b)))' > tmp.cil
|
|
||||||
$ secilc tmp.cil
|
|
||||||
Segmentation fault (core dumped)
|
|
||||||
|
|
||||||
This is because cil_print_recursive_blockinherit() assumes that all
|
|
||||||
nodes are either CIL_BLOCK or CIL_BLOCKINHERIT. Add support for other
|
|
||||||
block kinds, using cil_node_to_string() to show them.
|
|
||||||
|
|
||||||
Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28462
|
|
||||||
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_resolve_ast.c | 10 ++++++++--
|
|
||||||
1 file changed, 8 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
index affa7657b..68b590bcc 100644
|
|
||||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
@@ -2347,11 +2347,13 @@ void cil_print_recursive_blockinherit(struct cil_tree_node *bi_node, struct cil_
|
|
||||||
for (curr = bi_node; curr != terminating_node; curr = curr->parent) {
|
|
||||||
if (curr->flavor == CIL_BLOCK) {
|
|
||||||
cil_list_prepend(trace, CIL_NODE, curr);
|
|
||||||
- } else {
|
|
||||||
+ } else if (curr->flavor == CIL_BLOCKINHERIT) {
|
|
||||||
if (curr != bi_node) {
|
|
||||||
cil_list_prepend(trace, CIL_NODE, NODE(((struct cil_blockinherit *)curr->data)->block));
|
|
||||||
}
|
|
||||||
cil_list_prepend(trace, CIL_NODE, curr);
|
|
||||||
+ } else {
|
|
||||||
+ cil_list_prepend(trace, CIL_NODE, curr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cil_list_prepend(trace, CIL_NODE, terminating_node);
|
|
||||||
@@ -2360,8 +2362,12 @@ void cil_print_recursive_blockinherit(struct cil_tree_node *bi_node, struct cil_
|
|
||||||
curr = item->data;
|
|
||||||
if (curr->flavor == CIL_BLOCK) {
|
|
||||||
cil_tree_log(curr, CIL_ERR, "block %s", DATUM(curr->data)->name);
|
|
||||||
- } else {
|
|
||||||
+ } else if (curr->flavor == CIL_BLOCKINHERIT) {
|
|
||||||
cil_tree_log(curr, CIL_ERR, "blockinherit %s", ((struct cil_blockinherit *)curr->data)->block_str);
|
|
||||||
+ } else if (curr->flavor == CIL_OPTIONAL) {
|
|
||||||
+ cil_tree_log(curr, CIL_ERR, "optional %s", DATUM(curr->data)->name);
|
|
||||||
+ } else {
|
|
||||||
+ cil_tree_log(curr, CIL_ERR, "%s", cil_node_to_string(curr));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,92 +0,0 @@
|
|||||||
From 521e6a2f478a4c7a7c198c017d4d12e8667d89e7 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Nicolas Iooss <nicolas.iooss@m4x.org>
|
|
||||||
Date: Sat, 3 Oct 2020 15:19:08 +0200
|
|
||||||
Subject: [PATCH] libsepol/cil: fix signed overflow caused by using (1 << 31) -
|
|
||||||
1
|
|
||||||
|
|
||||||
When compiling SELinux userspace tools with -ftrapv (this option
|
|
||||||
generates traps for signed overflow on addition, subtraction,
|
|
||||||
multiplication operations, instead of silently wrapping around),
|
|
||||||
semodule crashes when running the tests from
|
|
||||||
scripts/ci/fedora-test-runner.sh in a Fedora 32 virtual machine:
|
|
||||||
|
|
||||||
[root@localhost selinux-testsuite]# make test
|
|
||||||
make -C policy load
|
|
||||||
make[1]: Entering directory '/root/selinux-testsuite/policy'
|
|
||||||
# Test for "expand-check = 0" in /etc/selinux/semanage.conf
|
|
||||||
# General policy build
|
|
||||||
make[2]: Entering directory '/root/selinux-testsuite/policy/test_policy'
|
|
||||||
Compiling targeted test_policy module
|
|
||||||
Creating targeted test_policy.pp policy package
|
|
||||||
rm tmp/test_policy.mod.fc
|
|
||||||
make[2]: Leaving directory '/root/selinux-testsuite/policy/test_policy'
|
|
||||||
# General policy load
|
|
||||||
domain_fd_use --> off
|
|
||||||
/usr/sbin/semodule -i test_policy/test_policy.pp test_mlsconstrain.cil test_overlay_defaultrange.cil test_add_levels.cil test_glblub.cil
|
|
||||||
make[1]: *** [Makefile:174: load] Aborted (core dumped)
|
|
||||||
|
|
||||||
Using "coredumpctl gdb" leads to the following strack trace:
|
|
||||||
|
|
||||||
(gdb) bt
|
|
||||||
#0 0x00007f608fe4fa25 in raise () from /lib64/libc.so.6
|
|
||||||
#1 0x00007f608fe38895 in abort () from /lib64/libc.so.6
|
|
||||||
#2 0x00007f6090028aca in __addvsi3.cold () from /lib64/libsepol.so.1
|
|
||||||
#3 0x00007f6090096f59 in __avrule_xperm_setrangebits (low=30, high=30, xperms=0x8b9eea0)
|
|
||||||
at ../cil/src/cil_binary.c:1551
|
|
||||||
#4 0x00007f60900970dd in __cil_permx_bitmap_to_sepol_xperms_list (xperms=0xb650a30, xperms_list=0x7ffce2653b18)
|
|
||||||
at ../cil/src/cil_binary.c:1596
|
|
||||||
#5 0x00007f6090097286 in __cil_avrulex_ioctl_to_policydb (k=0xb8ec200 "@\023\214\022\006", datum=0xb650a30,
|
|
||||||
args=0x239a640) at ../cil/src/cil_binary.c:1649
|
|
||||||
#6 0x00007f609003f1e5 in hashtab_map (h=0x41f8710, apply=0x7f60900971da <__cil_avrulex_ioctl_to_policydb>,
|
|
||||||
args=0x239a640) at hashtab.c:234
|
|
||||||
#7 0x00007f609009ea19 in cil_binary_create_allocated_pdb (db=0x2394f10, policydb=0x239a640)
|
|
||||||
at ../cil/src/cil_binary.c:4969
|
|
||||||
#8 0x00007f609009d19d in cil_binary_create (db=0x2394f10, policydb=0x7ffce2653d30) at ../cil/src/cil_binary.c:4329
|
|
||||||
#9 0x00007f609008ec23 in cil_build_policydb_create_pdb (db=0x2394f10, sepol_db=0x7ffce2653d30)
|
|
||||||
at ../cil/src/cil.c:631
|
|
||||||
#10 0x00007f608fff4bf3 in semanage_direct_commit () from /lib64/libsemanage.so.1
|
|
||||||
#11 0x00007f608fff9fae in semanage_commit () from /lib64/libsemanage.so.1
|
|
||||||
#12 0x0000000000403e2b in main (argc=7, argv=0x7ffce2655058) at semodule.c:753
|
|
||||||
|
|
||||||
(gdb) f 3
|
|
||||||
#3 0x00007f6090096f59 in __avrule_xperm_setrangebits (low=30, high=30, xperms=0x8b9eea0)
|
|
||||||
at ../cil/src/cil_binary.c:1551
|
|
||||||
1551 xperms->perms[i] |= XPERM_SETBITS(h) - XPERM_SETBITS(low);
|
|
||||||
|
|
||||||
A signed integer overflow therefore occurs in XPERM_SETBITS(h):
|
|
||||||
|
|
||||||
#define XPERM_SETBITS(x) ((1 << (x & 0x1f)) - 1)
|
|
||||||
|
|
||||||
This macro is expanded with h=31, so "(1 << 31) - 1" is computed:
|
|
||||||
|
|
||||||
* (1 << 31) = -0x80000000 is the lowest signed 32-bit integer value
|
|
||||||
* (1 << 31) - 1 overflows the capacity of a signed 32-bit integer and
|
|
||||||
results in 0x7fffffff (which is unsigned)
|
|
||||||
|
|
||||||
Using unsigned integers (with "1U") fixes the crash, as
|
|
||||||
(1U << 31) = 0x80000000U has no overflowing issues.
|
|
||||||
|
|
||||||
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
|
||||||
Acked-by: Petr Lautrbach <plautrba@redhat.com>
|
|
||||||
|
|
||||||
Conflict:remove contents of checkpolicy/policy_define.c
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_binary.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c
|
|
||||||
index 36720ed..e417c5c 100644
|
|
||||||
--- a/libsepol/cil/src/cil_binary.c
|
|
||||||
+++ b/libsepol/cil/src/cil_binary.c
|
|
||||||
@@ -1526,7 +1526,7 @@ int cil_avrule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_
|
|
||||||
/* index of the u32 containing the permission */
|
|
||||||
#define XPERM_IDX(x) (x >> 5)
|
|
||||||
/* set bits 0 through x-1 within the u32 */
|
|
||||||
-#define XPERM_SETBITS(x) ((1 << (x & 0x1f)) - 1)
|
|
||||||
+#define XPERM_SETBITS(x) ((1U << (x & 0x1f)) - 1)
|
|
||||||
/* low value for this u32 */
|
|
||||||
#define XPERM_LOW(x) (x << 5)
|
|
||||||
/* high value for this u32 */
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
@ -1,189 +0,0 @@
|
|||||||
From 852c4398a9a227e0eb4de42d45c0c2845ed92bc7 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
|
|
||||||
Date: Tue, 8 Jun 2021 17:58:57 +0200
|
|
||||||
Subject: [PATCH] libsepol/cil: follow declaration-after-statement
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
Follow the project style of no declaration after statement.
|
|
||||||
|
|
||||||
Found by the gcc warning -Wdeclaration-after-statement
|
|
||||||
|
|
||||||
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
|
|
||||||
Acked-by: James Carter <jwcart2@gmail.com>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_binary.c | 5 +++--
|
|
||||||
libsepol/cil/src/cil_build_ast.c | 5 +++--
|
|
||||||
libsepol/cil/src/cil_fqn.c | 3 ++-
|
|
||||||
libsepol/cil/src/cil_list.c | 7 ++++---
|
|
||||||
libsepol/cil/src/cil_post.c | 2 +-
|
|
||||||
libsepol/cil/src/cil_resolve_ast.c | 6 +++---
|
|
||||||
libsepol/cil/src/cil_strpool.c | 3 ++-
|
|
||||||
7 files changed, 18 insertions(+), 13 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c
|
|
||||||
index 18532aa..85094b0 100644
|
|
||||||
--- a/libsepol/cil/src/cil_binary.c
|
|
||||||
+++ b/libsepol/cil/src/cil_binary.c
|
|
||||||
@@ -593,11 +593,11 @@ exit:
|
|
||||||
int __cil_typeattr_bitmap_init(policydb_t *pdb)
|
|
||||||
{
|
|
||||||
int rc = SEPOL_ERR;
|
|
||||||
+ uint32_t i;
|
|
||||||
|
|
||||||
pdb->type_attr_map = cil_malloc(pdb->p_types.nprim * sizeof(ebitmap_t));
|
|
||||||
pdb->attr_type_map = cil_malloc(pdb->p_types.nprim * sizeof(ebitmap_t));
|
|
||||||
|
|
||||||
- uint32_t i = 0;
|
|
||||||
for (i = 0; i < pdb->p_types.nprim; i++) {
|
|
||||||
ebitmap_init(&pdb->type_attr_map[i]);
|
|
||||||
ebitmap_init(&pdb->attr_type_map[i]);
|
|
||||||
@@ -2657,6 +2657,7 @@ int __cil_constrain_expr_to_sepol_expr_helper(policydb_t *pdb, const struct cil_
|
|
||||||
int rc = SEPOL_ERR;
|
|
||||||
struct cil_list_item *item;
|
|
||||||
enum cil_flavor flavor;
|
|
||||||
+ enum cil_flavor cil_op;
|
|
||||||
constraint_expr_t *op, *h1, *h2, *t1, *t2;
|
|
||||||
int is_leaf = CIL_FALSE;
|
|
||||||
|
|
||||||
@@ -2673,7 +2674,7 @@ int __cil_constrain_expr_to_sepol_expr_helper(policydb_t *pdb, const struct cil_
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
- enum cil_flavor cil_op = (enum cil_flavor)(uintptr_t)item->data;
|
|
||||||
+ cil_op = (enum cil_flavor)(uintptr_t)item->data;
|
|
||||||
switch (cil_op) {
|
|
||||||
case CIL_NOT:
|
|
||||||
op->expr_type = CEXPR_NOT;
|
|
||||||
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
|
|
||||||
index 96c9726..908b033 100644
|
|
||||||
--- a/libsepol/cil/src/cil_build_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_build_ast.c
|
|
||||||
@@ -5173,6 +5173,7 @@ int cil_gen_macro(struct cil_db *db, struct cil_tree_node *parse_current, struct
|
|
||||||
char *key = NULL;
|
|
||||||
struct cil_macro *macro = NULL;
|
|
||||||
struct cil_tree_node *macro_content = NULL;
|
|
||||||
+ struct cil_tree_node *current_item;
|
|
||||||
enum cil_syntax syntax[] = {
|
|
||||||
CIL_SYN_STRING,
|
|
||||||
CIL_SYN_STRING,
|
|
||||||
@@ -5195,7 +5196,7 @@ int cil_gen_macro(struct cil_db *db, struct cil_tree_node *parse_current, struct
|
|
||||||
|
|
||||||
key = parse_current->next->data;
|
|
||||||
|
|
||||||
- struct cil_tree_node *current_item = parse_current->next->next->cl_head;
|
|
||||||
+ current_item = parse_current->next->next->cl_head;
|
|
||||||
while (current_item != NULL) {
|
|
||||||
enum cil_syntax param_syntax[] = {
|
|
||||||
CIL_SYN_STRING,
|
|
||||||
@@ -5205,6 +5206,7 @@ int cil_gen_macro(struct cil_db *db, struct cil_tree_node *parse_current, struct
|
|
||||||
int param_syntax_len = sizeof(param_syntax)/sizeof(*param_syntax);
|
|
||||||
char *kind = NULL;
|
|
||||||
struct cil_param *param = NULL;
|
|
||||||
+ struct cil_list_item *curr_param;
|
|
||||||
|
|
||||||
rc =__cil_verify_syntax(current_item->cl_head, param_syntax, param_syntax_len);
|
|
||||||
if (rc != SEPOL_OK) {
|
|
||||||
@@ -5263,7 +5265,6 @@ int cil_gen_macro(struct cil_db *db, struct cil_tree_node *parse_current, struct
|
|
||||||
}
|
|
||||||
|
|
||||||
//walk current list and check for duplicate parameters
|
|
||||||
- struct cil_list_item *curr_param;
|
|
||||||
cil_list_for_each(curr_param, macro->params) {
|
|
||||||
if (param->str == ((struct cil_param*)curr_param->data)->str) {
|
|
||||||
cil_log(CIL_ERR, "Duplicate parameter\n");
|
|
||||||
diff --git a/libsepol/cil/src/cil_fqn.c b/libsepol/cil/src/cil_fqn.c
|
|
||||||
index 097222a..46db069 100644
|
|
||||||
--- a/libsepol/cil/src/cil_fqn.c
|
|
||||||
+++ b/libsepol/cil/src/cil_fqn.c
|
|
||||||
@@ -78,12 +78,13 @@ static int __cil_fqn_qualify_blocks(__attribute__((unused)) hashtab_key_t k, has
|
|
||||||
struct cil_tree_node *node = NODE(datum);
|
|
||||||
int i;
|
|
||||||
int rc = SEPOL_OK;
|
|
||||||
+ int newlen;
|
|
||||||
|
|
||||||
if (node->flavor != CIL_BLOCK) {
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
- int newlen = fqn_args->len + strlen(datum->name) + 1;
|
|
||||||
+ newlen = fqn_args->len + strlen(datum->name) + 1;
|
|
||||||
if (newlen >= CIL_MAX_NAME_LENGTH) {
|
|
||||||
cil_log(CIL_INFO, "Fully qualified name for block %s is too long\n", datum->name);
|
|
||||||
rc = SEPOL_ERR;
|
|
||||||
diff --git a/libsepol/cil/src/cil_list.c b/libsepol/cil/src/cil_list.c
|
|
||||||
index 4e7843c..8a426f1 100644
|
|
||||||
--- a/libsepol/cil/src/cil_list.c
|
|
||||||
+++ b/libsepol/cil/src/cil_list.c
|
|
||||||
@@ -55,15 +55,16 @@ void cil_list_init(struct cil_list **list, enum cil_flavor flavor)
|
|
||||||
|
|
||||||
void cil_list_destroy(struct cil_list **list, unsigned destroy_data)
|
|
||||||
{
|
|
||||||
+ struct cil_list_item *item;
|
|
||||||
+
|
|
||||||
if (*list == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
- struct cil_list_item *item = (*list)->head;
|
|
||||||
- struct cil_list_item *next = NULL;
|
|
||||||
+ item = (*list)->head;
|
|
||||||
while (item != NULL)
|
|
||||||
{
|
|
||||||
- next = item->next;
|
|
||||||
+ struct cil_list_item *next = item->next;
|
|
||||||
if (item->flavor == CIL_LIST) {
|
|
||||||
cil_list_destroy((struct cil_list**)&(item->data), destroy_data);
|
|
||||||
free(item);
|
|
||||||
diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c
|
|
||||||
index 05842b6..7bca083 100644
|
|
||||||
--- a/libsepol/cil/src/cil_post.c
|
|
||||||
+++ b/libsepol/cil/src/cil_post.c
|
|
||||||
@@ -213,8 +213,8 @@ int cil_post_filecon_compare(const void *a, const void *b)
|
|
||||||
struct fc_data *a_data = cil_malloc(sizeof(*a_data));
|
|
||||||
struct fc_data *b_data = cil_malloc(sizeof(*b_data));
|
|
||||||
char *a_path = cil_malloc(strlen(a_filecon->path_str) + 1);
|
|
||||||
- a_path[0] = '\0';
|
|
||||||
char *b_path = cil_malloc(strlen(b_filecon->path_str) + 1);
|
|
||||||
+ a_path[0] = '\0';
|
|
||||||
b_path[0] = '\0';
|
|
||||||
strcat(a_path, a_filecon->path_str);
|
|
||||||
strcat(b_path, b_filecon->path_str);
|
|
||||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
index 92a4d29..b5199ba 100644
|
|
||||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
@@ -3956,10 +3956,10 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished
|
|
||||||
enum cil_log_level lvl = CIL_ERR;
|
|
||||||
|
|
||||||
if (optional != NULL) {
|
|
||||||
- lvl = CIL_INFO;
|
|
||||||
-
|
|
||||||
struct cil_optional *opt = (struct cil_optional *)optional->data;
|
|
||||||
- struct cil_tree_node *opt_node = NODE(opt);;
|
|
||||||
+ struct cil_tree_node *opt_node = NODE(opt);
|
|
||||||
+
|
|
||||||
+ lvl = CIL_INFO;
|
|
||||||
/* disable an optional if something failed to resolve */
|
|
||||||
opt->enabled = CIL_FALSE;
|
|
||||||
cil_tree_log(node, lvl, "Failed to resolve %s statement", cil_node_to_string(node));
|
|
||||||
diff --git a/libsepol/cil/src/cil_strpool.c b/libsepol/cil/src/cil_strpool.c
|
|
||||||
index 2598bbf..70bca36 100644
|
|
||||||
--- a/libsepol/cil/src/cil_strpool.c
|
|
||||||
+++ b/libsepol/cil/src/cil_strpool.c
|
|
||||||
@@ -75,9 +75,10 @@ char *cil_strpool_add(const char *str)
|
|
||||||
|
|
||||||
strpool_ref = hashtab_search(cil_strpool_tab, (hashtab_key_t)str);
|
|
||||||
if (strpool_ref == NULL) {
|
|
||||||
+ int rc;
|
|
||||||
strpool_ref = cil_malloc(sizeof(*strpool_ref));
|
|
||||||
strpool_ref->str = cil_strdup(str);
|
|
||||||
- int rc = hashtab_insert(cil_strpool_tab, (hashtab_key_t)strpool_ref->str, strpool_ref);
|
|
||||||
+ rc = hashtab_insert(cil_strpool_tab, (hashtab_key_t)strpool_ref->str, strpool_ref);
|
|
||||||
if (rc != SEPOL_OK) {
|
|
||||||
pthread_mutex_unlock(&cil_strpool_mutex);
|
|
||||||
cil_log(CIL_ERR, "Failed to allocate memory\n");
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
@ -1,171 +0,0 @@
|
|||||||
From 32f8ed3d6b0bba44f2f211ff630f61f6a17cf578 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Nicolas Iooss <nicolas.iooss@m4x.org>
|
|
||||||
Date: Fri, 5 Feb 2021 10:45:39 +0100
|
|
||||||
Subject: [PATCH] libsepol/cil: introduce intermediate cast to silence
|
|
||||||
-Wvoid-pointer-to-enum-cast
|
|
||||||
|
|
||||||
clang 11.0.0 reports the following warning several times (when building
|
|
||||||
with "make CC=clang" from libsepol directory, in the default
|
|
||||||
configuration of the git repository):
|
|
||||||
|
|
||||||
../cil/src/cil_binary.c:1980:8: error: cast to smaller integer type
|
|
||||||
'enum cil_flavor' from 'void *' [-Werror,-Wvoid-pointer-to-enum-cast]
|
|
||||||
op = (enum cil_flavor)curr->data;
|
|
||||||
^~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Silence this warning by casting the pointer to an integer the cast to
|
|
||||||
enum cil_flavor.
|
|
||||||
|
|
||||||
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_binary.c | 12 ++++++------
|
|
||||||
libsepol/cil/src/cil_policy.c | 12 ++++++------
|
|
||||||
libsepol/cil/src/cil_post.c | 2 +-
|
|
||||||
libsepol/cil/src/cil_resolve_ast.c | 2 +-
|
|
||||||
4 files changed, 14 insertions(+), 14 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c
|
|
||||||
index 7ba2098..f80d846 100644
|
|
||||||
--- a/libsepol/cil/src/cil_binary.c
|
|
||||||
+++ b/libsepol/cil/src/cil_binary.c
|
|
||||||
@@ -1977,7 +1977,7 @@ static void __cil_expr_to_string(struct cil_list *expr, enum cil_flavor flavor,
|
|
||||||
curr = expr->head;
|
|
||||||
|
|
||||||
if (curr->flavor == CIL_OP) {
|
|
||||||
- op = (enum cil_flavor)curr->data;
|
|
||||||
+ op = (enum cil_flavor)(uintptr_t)curr->data;
|
|
||||||
|
|
||||||
if (op == CIL_ALL) {
|
|
||||||
*out = cil_strdup(CIL_KEY_ALL);
|
|
||||||
@@ -2076,7 +2076,7 @@ static int __cil_cond_expr_to_sepol_expr_helper(policydb_t *pdb, struct cil_list
|
|
||||||
if (item == NULL) {
|
|
||||||
goto exit;
|
|
||||||
} else if (item->flavor == CIL_OP) {
|
|
||||||
- enum cil_flavor cil_op = (enum cil_flavor)item->data;
|
|
||||||
+ enum cil_flavor cil_op = (enum cil_flavor)(uintptr_t)item->data;
|
|
||||||
|
|
||||||
op = cil_malloc(sizeof(*op));
|
|
||||||
op->bool = 0;
|
|
||||||
@@ -2562,7 +2562,7 @@ int __cil_constrain_expr_leaf_to_sepol_expr(policydb_t *pdb, const struct cil_db
|
|
||||||
struct cil_list_item *l_item = op_item->next;
|
|
||||||
struct cil_list_item *r_item = op_item->next->next;
|
|
||||||
|
|
||||||
- enum cil_flavor l_operand = (enum cil_flavor)l_item->data;
|
|
||||||
+ enum cil_flavor l_operand = (enum cil_flavor)(uintptr_t)l_item->data;
|
|
||||||
|
|
||||||
switch (l_operand) {
|
|
||||||
case CIL_CONS_U1:
|
|
||||||
@@ -2593,7 +2593,7 @@ int __cil_constrain_expr_leaf_to_sepol_expr(policydb_t *pdb, const struct cil_db
|
|
||||||
expr->attr = CEXPR_TYPE | CEXPR_XTARGET;
|
|
||||||
break;
|
|
||||||
case CIL_CONS_L1: {
|
|
||||||
- enum cil_flavor r_operand = (enum cil_flavor)r_item->data;
|
|
||||||
+ enum cil_flavor r_operand = (enum cil_flavor)(uintptr_t)r_item->data;
|
|
||||||
|
|
||||||
if (r_operand == CIL_CONS_L2) {
|
|
||||||
expr->attr = CEXPR_L1L2;
|
|
||||||
@@ -2608,7 +2608,7 @@ int __cil_constrain_expr_leaf_to_sepol_expr(policydb_t *pdb, const struct cil_db
|
|
||||||
expr->attr = CEXPR_L2H2;
|
|
||||||
break;
|
|
||||||
case CIL_CONS_H1: {
|
|
||||||
- enum cil_flavor r_operand = (enum cil_flavor)r_item->data;
|
|
||||||
+ enum cil_flavor r_operand = (enum cil_flavor)(uintptr_t)r_item->data;
|
|
||||||
if (r_operand == CIL_CONS_L2) {
|
|
||||||
expr->attr = CEXPR_H1L2;
|
|
||||||
} else {
|
|
||||||
@@ -2672,7 +2672,7 @@ int __cil_constrain_expr_to_sepol_expr_helper(policydb_t *pdb, const struct cil_
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
- enum cil_flavor cil_op = (enum cil_flavor)item->data;
|
|
||||||
+ enum cil_flavor cil_op = (enum cil_flavor)(uintptr_t)item->data;
|
|
||||||
switch (cil_op) {
|
|
||||||
case CIL_NOT:
|
|
||||||
op->expr_type = CEXPR_NOT;
|
|
||||||
diff --git a/libsepol/cil/src/cil_policy.c b/libsepol/cil/src/cil_policy.c
|
|
||||||
index 74edb34..30d507f 100644
|
|
||||||
--- a/libsepol/cil/src/cil_policy.c
|
|
||||||
+++ b/libsepol/cil/src/cil_policy.c
|
|
||||||
@@ -285,7 +285,7 @@ static void cil_cond_expr_to_policy(FILE *out, struct cil_list *expr, int first)
|
|
||||||
struct cil_list_item *i1 = expr->head;
|
|
||||||
|
|
||||||
if (i1->flavor == CIL_OP) {
|
|
||||||
- enum cil_flavor op = (enum cil_flavor)i1->data;
|
|
||||||
+ enum cil_flavor op = (enum cil_flavor)(uintptr_t)i1->data;
|
|
||||||
fprintf(out, "(");
|
|
||||||
switch (op) {
|
|
||||||
case CIL_NOT:
|
|
||||||
@@ -385,7 +385,7 @@ static size_t __cil_cons_leaf_operand_len(struct cil_db *db, struct cil_list_ite
|
|
||||||
|
|
||||||
static size_t __cil_cons_leaf_op_len(struct cil_list_item *op)
|
|
||||||
{
|
|
||||||
- enum cil_flavor flavor = (enum cil_flavor)op->data;
|
|
||||||
+ enum cil_flavor flavor = (enum cil_flavor)(uintptr_t)op->data;
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
switch (flavor) {
|
|
||||||
@@ -420,7 +420,7 @@ static size_t cil_cons_expr_len(struct cil_db *db, struct cil_list *cons_expr)
|
|
||||||
|
|
||||||
i1 = cons_expr->head;
|
|
||||||
|
|
||||||
- op = (enum cil_flavor)i1->data;
|
|
||||||
+ op = (enum cil_flavor)(uintptr_t)i1->data;
|
|
||||||
switch (op) {
|
|
||||||
case CIL_NOT:
|
|
||||||
len = 6; /* "(not )" */
|
|
||||||
@@ -472,7 +472,7 @@ static char *__cil_cons_leaf_operand_to_string(struct cil_db *db, struct cil_lis
|
|
||||||
size_t o_len;
|
|
||||||
|
|
||||||
if (flavor == CIL_CONS_OPERAND) {
|
|
||||||
- enum cil_flavor o_flavor = (enum cil_flavor)operand->data;
|
|
||||||
+ enum cil_flavor o_flavor = (enum cil_flavor)(uintptr_t)operand->data;
|
|
||||||
switch (o_flavor) {
|
|
||||||
case CIL_CONS_U1:
|
|
||||||
o_str = "u1";
|
|
||||||
@@ -555,7 +555,7 @@ static char *__cil_cons_leaf_operand_to_string(struct cil_db *db, struct cil_lis
|
|
||||||
|
|
||||||
static char *__cil_cons_leaf_op_to_string(struct cil_list_item *op, char *new)
|
|
||||||
{
|
|
||||||
- enum cil_flavor flavor = (enum cil_flavor)op->data;
|
|
||||||
+ enum cil_flavor flavor = (enum cil_flavor)(uintptr_t)op->data;
|
|
||||||
const char *op_str;
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
@@ -599,7 +599,7 @@ static char *__cil_cons_expr_to_string(struct cil_db *db, struct cil_list *cons_
|
|
||||||
|
|
||||||
i1 = cons_expr->head;
|
|
||||||
|
|
||||||
- op = (enum cil_flavor)i1->data;
|
|
||||||
+ op = (enum cil_flavor)(uintptr_t)i1->data;
|
|
||||||
switch (op) {
|
|
||||||
case CIL_NOT:
|
|
||||||
*new++ = '(';
|
|
||||||
diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c
|
|
||||||
index 37a4441..a55df1e 100644
|
|
||||||
--- a/libsepol/cil/src/cil_post.c
|
|
||||||
+++ b/libsepol/cil/src/cil_post.c
|
|
||||||
@@ -1301,7 +1301,7 @@ static int __cil_expr_to_bitmap(struct cil_list *expr, ebitmap_t *out, int max,
|
|
||||||
flavor = expr->flavor;
|
|
||||||
|
|
||||||
if (curr->flavor == CIL_OP) {
|
|
||||||
- enum cil_flavor op = (enum cil_flavor)curr->data;
|
|
||||||
+ enum cil_flavor op = (enum cil_flavor)(uintptr_t)curr->data;
|
|
||||||
|
|
||||||
if (op == CIL_ALL) {
|
|
||||||
ebitmap_init(&b1); /* all zeros */
|
|
||||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
index 9300cd2..208bc01 100644
|
|
||||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
@@ -3355,7 +3355,7 @@ static int __cil_evaluate_tunable_expr(struct cil_list_item *curr)
|
|
||||||
return CIL_FALSE;
|
|
||||||
} else if (curr->flavor == CIL_OP) {
|
|
||||||
uint16_t v1, v2;
|
|
||||||
- enum cil_flavor op_flavor = (enum cil_flavor)curr->data;
|
|
||||||
+ enum cil_flavor op_flavor = (enum cil_flavor)(uintptr_t)curr->data;
|
|
||||||
|
|
||||||
v1 = __cil_evaluate_tunable_expr_helper(curr->next);
|
|
||||||
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
@ -1,49 +0,0 @@
|
|||||||
From e2d018423d5910e88947bba3b96d2f301d890c62 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Nicolas Iooss <nicolas.iooss@m4x.org>
|
|
||||||
Date: Wed, 30 Dec 2020 21:11:41 +0100
|
|
||||||
Subject: [PATCH] libsepol/cil: propagate failure of cil_fill_list()
|
|
||||||
|
|
||||||
OSS-Fuzz found a Null-dereference READ in the CIL compiler when trying
|
|
||||||
to compile the following policy:
|
|
||||||
|
|
||||||
(optional o (validatetrans x (eq t3 (a ()))))
|
|
||||||
|
|
||||||
With some logs, secilc reports:
|
|
||||||
|
|
||||||
Invalid syntax
|
|
||||||
Destroying Parse Tree
|
|
||||||
Resolving AST
|
|
||||||
Failed to resolve validatetrans statement at fuzz:1
|
|
||||||
Disabling optional 'o' at tmp.cil:1
|
|
||||||
|
|
||||||
So there is an "Invalid syntax" error, but the compilation continues.
|
|
||||||
Fix this issue by stopping the compilation when cil_fill_list() reports
|
|
||||||
an error:
|
|
||||||
|
|
||||||
Invalid syntax
|
|
||||||
Bad expression tree for constraint
|
|
||||||
Bad validatetrans declaration at tmp.cil:1
|
|
||||||
|
|
||||||
Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=29061
|
|
||||||
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_build_ast.c | 6 +++++-
|
|
||||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
|
|
||||||
index d5b9977c0..be10d61b1 100644
|
|
||||||
--- a/libsepol/cil/src/cil_build_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_build_ast.c
|
|
||||||
@@ -2713,7 +2713,11 @@ static int __cil_fill_constraint_leaf_expr(struct cil_tree_node *current, enum c
|
|
||||||
cil_list_append(*leaf_expr, CIL_STRING, current->next->next->data);
|
|
||||||
} else if (r_flavor == CIL_LIST) {
|
|
||||||
struct cil_list *sub_list;
|
|
||||||
- cil_fill_list(current->next->next->cl_head, leaf_expr_flavor, &sub_list);
|
|
||||||
+ rc = cil_fill_list(current->next->next->cl_head, leaf_expr_flavor, &sub_list);
|
|
||||||
+ if (rc != SEPOL_OK) {
|
|
||||||
+ cil_list_destroy(leaf_expr, CIL_TRUE);
|
|
||||||
+ goto exit;
|
|
||||||
+ }
|
|
||||||
cil_list_append(*leaf_expr, CIL_LIST, sub_list);
|
|
||||||
} else {
|
|
||||||
cil_list_append(*leaf_expr, CIL_CONS_OPERAND, (void *)r_flavor);
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
From 68e8871cfcbe1267ff0234a0dc78b207acc26af8 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Nicolas Iooss <nicolas.iooss@m4x.org>
|
|
||||||
Date: Sun, 14 Mar 2021 18:04:04 +0100
|
|
||||||
Subject: [PATCH] libsepol/cil: replace printf with proper cil_tree_log
|
|
||||||
|
|
||||||
All functions of the CIL compiler use cil_log or cil_tree_log to report
|
|
||||||
errors, but in two places which still uses printf. Replace these printf
|
|
||||||
invocation with cil_tree_log.
|
|
||||||
|
|
||||||
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
|
||||||
---
|
|
||||||
libsepol/cil/src/cil_resolve_ast.c | 4 ++--
|
|
||||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
index 47cdf0e..2ea106d 100644
|
|
||||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
|
||||||
@@ -2497,7 +2497,7 @@ int cil_resolve_in(struct cil_tree_node *current, void *extra_args)
|
|
||||||
|
|
||||||
rc = cil_copy_ast(db, current, block_node);
|
|
||||||
if (rc != SEPOL_OK) {
|
|
||||||
- printf("Failed to copy in, rc: %d\n", rc);
|
|
||||||
+ cil_tree_log(current, CIL_ERR, "Failed to copy in-statement");
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -2788,7 +2788,7 @@ int cil_resolve_call1(struct cil_tree_node *current, void *extra_args)
|
|
||||||
macro_node = NODE(macro_datum);
|
|
||||||
|
|
||||||
if (macro_node->flavor != CIL_MACRO) {
|
|
||||||
- printf("Failed to resolve %s to a macro\n", new_call->macro_str);
|
|
||||||
+ cil_tree_log(current, CIL_ERR, "Failed to resolve %s to a macro", new_call->macro_str);
|
|
||||||
rc = SEPOL_ERR;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
Binary file not shown.
BIN
libsepol-3.3.tar.gz
Normal file
BIN
libsepol-3.3.tar.gz
Normal file
Binary file not shown.
@ -1,53 +1,12 @@
|
|||||||
Name: libsepol
|
Name: libsepol
|
||||||
Version: 3.1
|
Version: 3.3
|
||||||
Release: 6
|
Release: 1
|
||||||
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
|
||||||
Source0: https://github.com/SELinuxProject/selinux/releases/download/20200710/libsepol-3.1.tar.gz
|
Source0: https://github.com/SELinuxProject/selinux/releases/download/%{version}/%{name}-%{version}.tar.gz
|
||||||
|
|
||||||
Patch1: backport-libsepol-cil-fix-NULL-pointer-dereference-in-cil_fil.patch
|
BuildRequires: gcc flex libsepol
|
||||||
Patch2: backport-libsepol-cil-always-destroy-the-lexer-state.patch
|
|
||||||
Patch3: backport-libsepol-cil-destroy-perm_datums-when-_cil_resolve_.patch
|
|
||||||
Patch4: backport-libsepol-cil-do-not-add-a-stack-variable-to-a-list.patch
|
|
||||||
Patch5: backport-libsepol-cil-Fix-heap-use-after-free-in_class-rese.patch
|
|
||||||
Patch6: backport-libsepol-cil-fix-NULL-pointer-dereference-when-parsi.patch
|
|
||||||
Patch7: backport-libsepol-cil-fix-NULL-pointer-dereference-when-using.patch
|
|
||||||
Patch8: backport-libsepol-cil-fix-out-of-bound-read-in-cil_print_recu.patch
|
|
||||||
Patch9: backport-libsepol-cil-propagate-failure-of-cil_fill_list.patch
|
|
||||||
|
|
||||||
Patch10: backport-libsepol-cil-Use-CIL_ERR-for-error-messages-in-cil_c.patch
|
|
||||||
Patch11: backport-libsepol-cil-Detect-degenerate-inheritance-and-exit-.patch
|
|
||||||
Patch12: backport-libsepol-cil-Use-the-macro-NODE-whenever-possible.patch
|
|
||||||
Patch13: backport-libsepol-cil-Check-for-duplicate-blocks-optionals-an.patch
|
|
||||||
Patch14: backport-libsepol-cil-Refactor-helper-function-for-cil_gen_no.patch
|
|
||||||
Patch15: backport-libsepol-cil-Remove-unused-field-from-struct-cil_arg.patch
|
|
||||||
Patch16: backport-libsepol-cil-Destroy-disabled-optional-blocks-after-.patch
|
|
||||||
Patch17: backport-libsepol-cil-Use-AST-to-track-blocks-and-optionals-w.patch
|
|
||||||
Patch18: backport-libsepol-cil-Reorder-checks-for-invalid-rules-when-r.patch
|
|
||||||
Patch19: backport-libsepol-cil-replace-printf-with-proper-cil_tree_log.patch
|
|
||||||
Patch20: backport-libsepol-cil-introduce-intermediate-cast-to-silence-.patch
|
|
||||||
Patch21: backport-libsepol-cil-follow-declaration-after-statement.patch
|
|
||||||
Patch22: backport-libsepol-cil-Handle-disabled-optional-blocks-in-earl.patch
|
|
||||||
Patch23: backport-libsepol-cil-Allow-duplicate-optional-blocks-in-most.patch
|
|
||||||
Patch24: backport-libsepol-cil-Improve-degenerate-inheritance-check.patch
|
|
||||||
Patch25: backport-libsepol-cil-Improve-checking-for-bad-inheritance-pa.patch
|
|
||||||
Patch26: backport-libsepol-cil-Use-the-macro-FLAVOR-whenever-possible.patch
|
|
||||||
Patch27: backport-libsepol-cil-Check-for-empty-list-when-marking-never.patch
|
|
||||||
Patch28: backport-libsepol-cil-Fix-instances-where-an-error-returns-SE.patch
|
|
||||||
Patch29: backport-libsepol-cil-Limit-the-number-of-open-parenthesis-al.patch
|
|
||||||
Patch30: backport-libsepol-cil-Fix-syntax-checking-of-defaultrange-rul.patch
|
|
||||||
Patch31: backport-libsepol-cil-Allow-some-duplicate-macro-and-block-de.patch
|
|
||||||
Patch32: backport-libsepol-cil-fix-signed-overflow-caused-by-using-1-3.patch
|
|
||||||
Patch33: backport-libsepol-cil-Fix-potential-undefined-shifts.patch
|
|
||||||
Patch34: backport-libsepol-cil-be-more-robust-when-encountering-src_in.patch
|
|
||||||
Patch35: backport-libsepol-cil-Handle-operations-in-a-class-mapping-wh.patch
|
|
||||||
Patch36: backport-libsepol-cil-Allow-permission-expressions-when-using.patch
|
|
||||||
Patch37: backport-libsepol-cil-fix-NULL-pointer-dereference-in-__cil_i.patch
|
|
||||||
Patch38: backport-libsepol-cil-Properly-check-for-parameter-when-inser.patch
|
|
||||||
Patch39: backport-libsepol-cil-Reset-expandtypeattribute-rules-when-re.patch
|
|
||||||
|
|
||||||
BuildRequires: gcc flex
|
|
||||||
|
|
||||||
%description
|
%description
|
||||||
libsepol provides an API for the manipulation of SELinux binary
|
libsepol provides an API for the manipulation of SELinux binary
|
||||||
@ -77,6 +36,8 @@ make %{?_smp_mflags} CFLAGS="%{optflags}" LDFLAGS="%{?__global_ldflags}"
|
|||||||
rm -rf %{buildroot}
|
rm -rf %{buildroot}
|
||||||
make DESTDIR="%{buildroot}" LIBDIR="%{_libdir}" SHLIBDIR="%{_libdir}" install
|
make DESTDIR="%{buildroot}" LIBDIR="%{_libdir}" SHLIBDIR="%{_libdir}" install
|
||||||
|
|
||||||
|
cp -a %{_libdir}/libsepol.so.1* %{buildroot}%{_libdir}
|
||||||
|
|
||||||
%pre
|
%pre
|
||||||
|
|
||||||
%preun
|
%preun
|
||||||
@ -105,6 +66,9 @@ make DESTDIR="%{buildroot}" LIBDIR="%{_libdir}" SHLIBDIR="%{_libdir}" install
|
|||||||
%{_mandir}/man3/*
|
%{_mandir}/man3/*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu Jan 13 2022 panxiaohe <panxiaohe@huawei.com> - 3.3-1
|
||||||
|
- update to 3.3
|
||||||
|
|
||||||
* Fri Dec 10 2021 panxiaohe <panxiaohe@huawei.com> - 3.1-6
|
* Fri Dec 10 2021 panxiaohe <panxiaohe@huawei.com> - 3.1-6
|
||||||
- fix secilc-fuzzer issues
|
- fix secilc-fuzzer issues
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user