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
|
||||
Version: 3.1
|
||||
Release: 6
|
||||
Version: 3.3
|
||||
Release: 1
|
||||
Summary: SELinux binary policy manipulation library
|
||||
License: LGPLv2+
|
||||
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
|
||||
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
|
||||
BuildRequires: gcc flex libsepol
|
||||
|
||||
%description
|
||||
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}
|
||||
make DESTDIR="%{buildroot}" LIBDIR="%{_libdir}" SHLIBDIR="%{_libdir}" install
|
||||
|
||||
cp -a %{_libdir}/libsepol.so.1* %{buildroot}%{_libdir}
|
||||
|
||||
%pre
|
||||
|
||||
%preun
|
||||
@ -105,6 +66,9 @@ make DESTDIR="%{buildroot}" LIBDIR="%{_libdir}" SHLIBDIR="%{_libdir}" install
|
||||
%{_mandir}/man3/*
|
||||
|
||||
%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
|
||||
- fix secilc-fuzzer issues
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user