SELinux userspace 3.3-rc2 release
This commit is contained in:
parent
c59879b8aa
commit
394d26d7f2
1
.gitignore
vendored
1
.gitignore
vendored
@ -180,3 +180,4 @@ libsepol-2.0.41.tgz
|
||||
/libsepol-3.2-rc1.tar.gz
|
||||
/libsepol-3.2-rc2.tar.gz
|
||||
/libsepol-3.2.tar.gz
|
||||
/libsepol-3.3-rc2.tar.gz
|
||||
|
@ -1,79 +0,0 @@
|
||||
From f7431d0e0ed9f695a6a8af74c3f239f80649a167 Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Wed, 10 Mar 2021 14:30:12 -0500
|
||||
Subject: [PATCH] libsepol: Expand role attributes in constraint expressions
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
When creating the kernel binary policy, role attributes in constraint
|
||||
expressions are not expanded. This causes the constraint expression
|
||||
to refer to a non-existent role in the kernel policy. This can lead
|
||||
to a segfault when converting the binary policy back to conf or CIL
|
||||
source or when using policy tools such as seinfo.
|
||||
|
||||
Expand role attributes in constraint expressions when creating the
|
||||
kernel binary policy.
|
||||
|
||||
Reported-by: Christian Göttsche <cgzones@googlemail.com>
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/src/expand.c | 35 +++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 35 insertions(+)
|
||||
|
||||
diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c
|
||||
index eac7e4507d02..2d9cb566fe1e 100644
|
||||
--- a/libsepol/src/expand.c
|
||||
+++ b/libsepol/src/expand.c
|
||||
@@ -71,6 +71,38 @@ static int map_ebitmap(ebitmap_t * src, ebitmap_t * dst, uint32_t * map)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int ebitmap_expand_roles(policydb_t *p, ebitmap_t *roles)
|
||||
+{
|
||||
+ ebitmap_node_t *node;
|
||||
+ unsigned int bit;
|
||||
+ role_datum_t *role;
|
||||
+ ebitmap_t tmp;
|
||||
+
|
||||
+ ebitmap_init(&tmp);
|
||||
+ ebitmap_for_each_positive_bit(roles, node, bit) {
|
||||
+ role = p->role_val_to_struct[bit];
|
||||
+ assert(role);
|
||||
+ if (role->flavor != ROLE_ATTRIB) {
|
||||
+ if (ebitmap_set_bit(&tmp, bit, 1)) {
|
||||
+ ebitmap_destroy(&tmp);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ } else {
|
||||
+ if (ebitmap_union(&tmp, &role->roles)) {
|
||||
+ ebitmap_destroy(&tmp);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ ebitmap_destroy(roles);
|
||||
+ if (ebitmap_cpy(roles, &tmp)) {
|
||||
+ ebitmap_destroy(&tmp);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ ebitmap_destroy(&tmp);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int type_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
|
||||
void *data)
|
||||
{
|
||||
@@ -333,6 +365,9 @@ static int constraint_node_clone(constraint_node_t ** dst,
|
||||
if (map_ebitmap(&expr->names, &new_expr->names, state->rolemap)) {
|
||||
goto out_of_mem;
|
||||
}
|
||||
+ if (ebitmap_expand_roles(state->out, &new_expr->names)) {
|
||||
+ goto out_of_mem;
|
||||
+ }
|
||||
} else if (new_expr->attr & CEXPR_USER) {
|
||||
if (map_ebitmap(&expr->names, &new_expr->names, state->usermap)) {
|
||||
goto out_of_mem;
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,70 +0,0 @@
|
||||
From 6015b05d068515201f5d053910c6587fff8407d4 Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Tue, 9 Mar 2021 16:36:40 -0500
|
||||
Subject: [PATCH] libsepol: Properly handle types associated to role attributes
|
||||
|
||||
Types associated to role attributes in optional blocks are not
|
||||
associated with the roles that have that attribute. The problem
|
||||
is that role_fix_callback is called before the avrule_decls are
|
||||
walked.
|
||||
|
||||
Example/
|
||||
class CLASS1
|
||||
sid kernel
|
||||
class CLASS1 { PERM1 }
|
||||
type TYPE1;
|
||||
type TYPE1A;
|
||||
allow TYPE1 self : CLASS1 PERM1;
|
||||
attribute_role ROLE_ATTR1A;
|
||||
role ROLE1;
|
||||
role ROLE1A;
|
||||
roleattribute ROLE1A ROLE_ATTR1A;
|
||||
role ROLE1 types TYPE1;
|
||||
optional {
|
||||
require {
|
||||
class CLASS1 PERM1;
|
||||
}
|
||||
role ROLE_ATTR1A types TYPE1A;
|
||||
}
|
||||
user USER1 roles ROLE1;
|
||||
sid kernel USER1:ROLE1:TYPE1
|
||||
|
||||
In this example ROLE1A will not have TYPE1A associated to it.
|
||||
|
||||
Call role_fix_callback() after the avrule_decls are walked.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/src/expand.c | 9 +++++----
|
||||
1 file changed, 5 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c
|
||||
index 2d9cb566fe1e..a656ffad3a71 100644
|
||||
--- a/libsepol/src/expand.c
|
||||
+++ b/libsepol/src/expand.c
|
||||
@@ -3052,10 +3052,6 @@ int expand_module(sepol_handle_t * handle,
|
||||
if (hashtab_map(state.base->p_roles.table,
|
||||
role_bounds_copy_callback, &state))
|
||||
goto cleanup;
|
||||
- /* escalate the type_set_t in a role attribute to all regular roles
|
||||
- * that belongs to it. */
|
||||
- if (hashtab_map(state.base->p_roles.table, role_fix_callback, &state))
|
||||
- goto cleanup;
|
||||
|
||||
/* copy MLS's sensitivity level and categories - this needs to be done
|
||||
* before expanding users (they need to be indexed too) */
|
||||
@@ -3121,6 +3117,11 @@ int expand_module(sepol_handle_t * handle,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
+ /* escalate the type_set_t in a role attribute to all regular roles
|
||||
+ * that belongs to it. */
|
||||
+ if (hashtab_map(state.base->p_roles.table, role_fix_callback, &state))
|
||||
+ goto cleanup;
|
||||
+
|
||||
if (copy_and_expand_avrule_block(&state) < 0) {
|
||||
ERR(handle, "Error during expand");
|
||||
goto cleanup;
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,58 +0,0 @@
|
||||
From 859857def94bd6c8ad9e9ecce88c85d19dc19933 Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Thu, 11 Mar 2021 11:56:44 -0500
|
||||
Subject: [PATCH] libsepol: Remove unnecessary copying of declarations from
|
||||
link.c
|
||||
|
||||
At one point link_modules() might have needed this initial copying,
|
||||
but now it serves no purpose, so remove it.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/src/link.c | 30 ------------------------------
|
||||
1 file changed, 30 deletions(-)
|
||||
|
||||
diff --git a/libsepol/src/link.c b/libsepol/src/link.c
|
||||
index 83bbc8a5c7d1..bdc1fcbf59d3 100644
|
||||
--- a/libsepol/src/link.c
|
||||
+++ b/libsepol/src/link.c
|
||||
@@ -2573,36 +2573,6 @@ int link_modules(sepol_handle_t * handle,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
- /* copy all types, declared and required */
|
||||
- for (i = 0; i < len; i++) {
|
||||
- state.cur = modules[i];
|
||||
- state.cur_mod_name = modules[i]->policy->name;
|
||||
- ret =
|
||||
- hashtab_map(modules[i]->policy->p_types.table,
|
||||
- type_copy_callback, &state);
|
||||
- if (ret) {
|
||||
- retval = ret;
|
||||
- goto cleanup;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- /* then copy everything else, including aliases, and fixup attributes */
|
||||
- for (i = 0; i < len; i++) {
|
||||
- state.cur = modules[i];
|
||||
- state.cur_mod_name = modules[i]->policy->name;
|
||||
- ret =
|
||||
- copy_identifiers(&state, modules[i]->policy->symtab, NULL);
|
||||
- if (ret) {
|
||||
- retval = ret;
|
||||
- goto cleanup;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (policydb_index_others(state.handle, state.base, 0)) {
|
||||
- ERR(state.handle, "Error while indexing others");
|
||||
- goto cleanup;
|
||||
- }
|
||||
-
|
||||
/* copy and remap the module's data over to base */
|
||||
for (i = 0; i < len; i++) {
|
||||
state.cur = modules[i];
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,91 +0,0 @@
|
||||
From 43c5ed469c2f3bc1beed9110b72bcc29c367ecfb Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Mon, 15 Mar 2021 11:09:38 -0400
|
||||
Subject: [PATCH] libsepol: Check kernel to CIL and Conf functions for
|
||||
supported versions
|
||||
|
||||
For policy versions between 20 and 23, attributes exist in the
|
||||
policy, but only in the type_attr_map. This means that there are
|
||||
gaps in both the type_val_to_struct and p_type_val_to_name arrays
|
||||
and policy rules can refer to those gaps which can lead to NULL
|
||||
dereferences when using sepol_kernel_policydb_to_conf() and
|
||||
sepol_kernel_policydb_to_cil().
|
||||
|
||||
This can be seen with the following policy:
|
||||
class CLASS1
|
||||
sid SID1
|
||||
class CLASS1 { PERM1 }
|
||||
attribute TYPE_ATTR1;
|
||||
type TYPE1;
|
||||
typeattribute TYPE1 TYPE_ATTR1;
|
||||
allow TYPE_ATTR1 self : CLASS1 PERM1;
|
||||
role ROLE1;
|
||||
role ROLE1 types TYPE1;
|
||||
user USER1 roles ROLE1;
|
||||
sid SID1 USER1:ROLE1:TYPE1
|
||||
|
||||
Compile the policy:
|
||||
checkpolicy -c 23 -o policy.bin policy.conf
|
||||
Converting back to a policy.conf causes a segfault:
|
||||
checkpolicy -F -b -o policy.bin.conf policy.bin
|
||||
|
||||
Have both sepol_kernel_policydb_to_conf() and
|
||||
sepol_kernel_policydb_to_cil() exit with an error if the kernel
|
||||
policy version is between 20 and 23.
|
||||
|
||||
Acked-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/src/kernel_to_cil.c | 12 ++++++++++++
|
||||
libsepol/src/kernel_to_conf.c | 12 ++++++++++++
|
||||
2 files changed, 24 insertions(+)
|
||||
|
||||
diff --git a/libsepol/src/kernel_to_cil.c b/libsepol/src/kernel_to_cil.c
|
||||
index a146ac514018..edfebeafe283 100644
|
||||
--- a/libsepol/src/kernel_to_cil.c
|
||||
+++ b/libsepol/src/kernel_to_cil.c
|
||||
@@ -3164,6 +3164,18 @@ int sepol_kernel_policydb_to_cil(FILE *out, struct policydb *pdb)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
+ if (pdb->policyvers >= POLICYDB_VERSION_AVTAB && pdb->policyvers <= POLICYDB_VERSION_PERMISSIVE) {
|
||||
+ /*
|
||||
+ * For policy versions between 20 and 23, attributes exist in the policy,
|
||||
+ * but only in the type_attr_map. This means that there are gaps in both
|
||||
+ * the type_val_to_struct and p_type_val_to_name arrays and policy rules
|
||||
+ * can refer to those gaps.
|
||||
+ */
|
||||
+ sepol_log_err("Writing policy versions between 20 and 23 as CIL is not supported");
|
||||
+ rc = -1;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
rc = constraint_rules_to_strs(pdb, mls_constraints, non_mls_constraints);
|
||||
if (rc != 0) {
|
||||
goto exit;
|
||||
diff --git a/libsepol/src/kernel_to_conf.c b/libsepol/src/kernel_to_conf.c
|
||||
index a22f196df9e9..ea58a026501f 100644
|
||||
--- a/libsepol/src/kernel_to_conf.c
|
||||
+++ b/libsepol/src/kernel_to_conf.c
|
||||
@@ -3041,6 +3041,18 @@ int sepol_kernel_policydb_to_conf(FILE *out, struct policydb *pdb)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
+ if (pdb->policyvers >= POLICYDB_VERSION_AVTAB && pdb->policyvers <= POLICYDB_VERSION_PERMISSIVE) {
|
||||
+ /*
|
||||
+ * For policy versions between 20 and 23, attributes exist in the policy,
|
||||
+ * but only in the type_attr_map. This means that there are gaps in both
|
||||
+ * the type_val_to_struct and p_type_val_to_name arrays and policy rules
|
||||
+ * can refer to those gaps.
|
||||
+ */
|
||||
+ sepol_log_err("Writing policy versions between 20 and 23 as a policy.conf is not supported");
|
||||
+ rc = -1;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
rc = constraint_rules_to_strs(pdb, mls_constraints, non_mls_constraints);
|
||||
if (rc != 0) {
|
||||
goto exit;
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,77 +0,0 @@
|
||||
From ba5fb7a41bb481cb870da273dd2faea4f2343c6d Mon Sep 17 00:00:00 2001
|
||||
From: Nicolas Iooss <nicolas.iooss@m4x.org>
|
||||
Date: Sun, 14 Mar 2021 16:58:44 +0100
|
||||
Subject: [PATCH] libsepol/cil: make cil_post_fc_fill_data static
|
||||
|
||||
cil_post_fc_fill_data() is not used outside of cil_post.c, and is not
|
||||
exported in libsepol.so. Make it static, in order to ease the analysis
|
||||
of static analyzers.
|
||||
|
||||
While at it, make its path argument "const char*" and the fields of
|
||||
"struct fc_data" "unsigned int" or "size_t", in order to make the types
|
||||
better match the values.
|
||||
|
||||
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
||||
---
|
||||
libsepol/cil/src/cil_post.c | 11 +++++++++--
|
||||
libsepol/cil/src/cil_post.h | 7 -------
|
||||
2 files changed, 9 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c
|
||||
index a55df1ea5bb0..d2ecbd430aa3 100644
|
||||
--- a/libsepol/cil/src/cil_post.c
|
||||
+++ b/libsepol/cil/src/cil_post.c
|
||||
@@ -27,6 +27,7 @@
|
||||
* either expressed or implied, of Tresys Technology, LLC.
|
||||
*/
|
||||
|
||||
+#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -50,6 +51,12 @@
|
||||
#define GEN_REQUIRE_ATTR "cil_gen_require" /* Also in libsepol/src/module_to_cil.c */
|
||||
#define TYPEATTR_INFIX "_typeattr_" /* Also in libsepol/src/module_to_cil.c */
|
||||
|
||||
+struct fc_data {
|
||||
+ unsigned int meta;
|
||||
+ size_t stem_len;
|
||||
+ size_t str_len;
|
||||
+};
|
||||
+
|
||||
static int __cil_expr_to_bitmap(struct cil_list *expr, ebitmap_t *out, int max, struct cil_db *db);
|
||||
static int __cil_expr_list_to_bitmap(struct cil_list *expr_list, ebitmap_t *out, int max, struct cil_db *db);
|
||||
|
||||
@@ -156,9 +163,9 @@ static int cil_verify_is_list(struct cil_list *list, enum cil_flavor flavor)
|
||||
return CIL_TRUE;
|
||||
}
|
||||
|
||||
-void cil_post_fc_fill_data(struct fc_data *fc, char *path)
|
||||
+static void cil_post_fc_fill_data(struct fc_data *fc, const char *path)
|
||||
{
|
||||
- int c = 0;
|
||||
+ size_t c = 0;
|
||||
fc->meta = 0;
|
||||
fc->stem_len = 0;
|
||||
fc->str_len = 0;
|
||||
diff --git a/libsepol/cil/src/cil_post.h b/libsepol/cil/src/cil_post.h
|
||||
index 3d5415486b77..b1d2206f9ef6 100644
|
||||
--- a/libsepol/cil/src/cil_post.h
|
||||
+++ b/libsepol/cil/src/cil_post.h
|
||||
@@ -30,13 +30,6 @@
|
||||
#ifndef CIL_POST_H_
|
||||
#define CIL_POST_H_
|
||||
|
||||
-struct fc_data {
|
||||
- int meta;
|
||||
- int stem_len;
|
||||
- int str_len;
|
||||
-};
|
||||
-
|
||||
-void cil_post_fc_fill_data(struct fc_data *fc, char *path);
|
||||
int cil_post_filecon_compare(const void *a, const void *b);
|
||||
int cil_post_ibpkeycon_compare(const void *a, const void *b);
|
||||
int cil_post_portcon_compare(const void *a, const void *b);
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,28 +0,0 @@
|
||||
From fba672edfbe3fef4969c947eb3f7d62f5da6be2f Mon Sep 17 00:00:00 2001
|
||||
From: Nicolas Iooss <nicolas.iooss@m4x.org>
|
||||
Date: Sun, 14 Mar 2021 17:58:01 +0100
|
||||
Subject: [PATCH] libsepol/cil: remove stray printf
|
||||
|
||||
printf("%i\n", node->flavor); looks very much like a statement which was
|
||||
added for debugging purpose and was unintentionally left.
|
||||
|
||||
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
||||
---
|
||||
libsepol/cil/src/cil_resolve_ast.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
||||
index 0e07856133e5..47cdf0e7c0b9 100644
|
||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
||||
@@ -1088,7 +1088,6 @@ int cil_resolve_roletransition(struct cil_tree_node *current, void *extra_args)
|
||||
node = NODE(result_datum);
|
||||
if (node->flavor != CIL_ROLE) {
|
||||
rc = SEPOL_ERR;
|
||||
- printf("%i\n", node->flavor);
|
||||
cil_log(CIL_ERR, "roletransition must result in a role, but %s is a %s\n", roletrans->result_str, cil_node_to_string(node));
|
||||
goto exit;
|
||||
}
|
||||
--
|
||||
2.32.0
|
||||
|
@ -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 47cdf0e7c0b9..2ea106d63505 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;
|
||||
}
|
||||
--
|
||||
2.32.0
|
||||
|
@ -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 2ea106d63505..63beed9230b9 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) {
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,173 +0,0 @@
|
||||
From 78d458d16393d8f2dd2cd2a7b066222da4e87975 Mon Sep 17 00:00:00 2001
|
||||
From: Nicolas Iooss <nicolas.iooss@m4x.org>
|
||||
Date: Sun, 14 Mar 2021 19:53:25 +0100
|
||||
Subject: [PATCH] libsepol/cil: do not leak avrulex_ioctl_table memory when an
|
||||
error occurs
|
||||
|
||||
OSS-Fuzz found a memory leak when trying to compile the following
|
||||
policy:
|
||||
|
||||
(class CLASS (PERM ioctl))
|
||||
(classorder (CLASS))
|
||||
(sid SID)
|
||||
(sidorder (SID))
|
||||
(user USER)
|
||||
(role ROLE)
|
||||
(type TYPE)
|
||||
(category CAT)
|
||||
(categoryorder (CAT))
|
||||
(sensitivity SENS)
|
||||
(sensitivityorder (SENS))
|
||||
(sensitivitycategory SENS (CAT))
|
||||
(allow TYPE self (CLASS (PERM)))
|
||||
(roletype ROLE TYPE)
|
||||
(userrole USER ROLE)
|
||||
(userlevel USER (SENS))
|
||||
(userrange USER ((SENS)(SENS (CAT))))
|
||||
(sidcontext SID (USER ROLE TYPE ((SENS)(SENS))))
|
||||
|
||||
(permissionx ioctl_test (ioctl CLASS (and (range 0x1600 0x19FF) (not (range 0x1750 0x175F)))))
|
||||
(allowx TYPE TYPE ioctl_test)
|
||||
|
||||
(boolean BOOLEAN false)
|
||||
|
||||
(booleanif (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (not (xor (eq BOOLEAN BOOLEAN)
|
||||
(and (eq BOOLEAN BOOLEAN) BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
BOOLEAN ) ) )
|
||||
(true
|
||||
(allow TYPE TYPE (CLASS (PERM)))
|
||||
)
|
||||
)
|
||||
|
||||
When the CIL compiler reports "Conditional expression exceeded max
|
||||
allowable depth" because of the loooooong expression in the booleanif
|
||||
statement, cil_binary_create_allocated_pdb returns without freeing the
|
||||
memory which was allocated to store the keys and values of hash table
|
||||
avrulex_ioctl_table.
|
||||
|
||||
Fix this by moving the freeing logic to a dedicated destructor function
|
||||
and calling it in the exit block of cil_binary_create_allocated_pdb.
|
||||
|
||||
Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28618
|
||||
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
||||
---
|
||||
libsepol/cil/src/cil_binary.c | 18 ++++++++++--------
|
||||
1 file changed, 10 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c
|
||||
index f80d84679f85..18532aad9801 100644
|
||||
--- a/libsepol/cil/src/cil_binary.c
|
||||
+++ b/libsepol/cil/src/cil_binary.c
|
||||
@@ -1668,14 +1668,6 @@ exit:
|
||||
}
|
||||
cil_list_destroy(&xperms_list, CIL_FALSE);
|
||||
}
|
||||
-
|
||||
- // hashtab_t does not have a way to free keys or datum since it doesn't
|
||||
- // know what they are. We won't need the keys/datum after this function, so
|
||||
- // clean them up here.
|
||||
- free(avtab_key);
|
||||
- ebitmap_destroy(datum);
|
||||
- free(datum);
|
||||
-
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -1885,6 +1877,15 @@ exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
+static int __cil_avrulex_ioctl_destroy(hashtab_key_t k, hashtab_datum_t datum, __attribute__((unused)) void *args)
|
||||
+{
|
||||
+ free(k);
|
||||
+ ebitmap_destroy(datum);
|
||||
+ free(datum);
|
||||
+
|
||||
+ return SEPOL_OK;
|
||||
+}
|
||||
+
|
||||
int __cil_cond_to_policydb_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *extra_args)
|
||||
{
|
||||
int rc;
|
||||
@@ -5037,6 +5038,7 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p
|
||||
|
||||
exit:
|
||||
hashtab_destroy(role_trans_table);
|
||||
+ hashtab_map(avrulex_ioctl_table, __cil_avrulex_ioctl_destroy, NULL);
|
||||
hashtab_destroy(avrulex_ioctl_table);
|
||||
free(type_value_to_cil);
|
||||
free(class_value_to_cil);
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,234 +0,0 @@
|
||||
From 13eaba21ef523325f226c14c4c792ce404b58970 Mon Sep 17 00:00:00 2001
|
||||
From: Nicolas Iooss <nicolas.iooss@m4x.org>
|
||||
Date: Tue, 16 Mar 2021 23:23:13 +0100
|
||||
Subject: [PATCH] libsepol: make num_* unsigned int in module_to_cil
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Using signed integer to represent counts can troube some gcc
|
||||
optimisation passes, for example in
|
||||
https://github.com/fishilico/selinux/runs/2125501324?check_suite_focus=true#step:9:107
|
||||
|
||||
In function ‘name_list_to_string’,
|
||||
inlined from ‘constraint_expr_to_string’ at module_to_cil.c:1799:11:
|
||||
module_to_cil.c:1156:8: error: argument 1 range
|
||||
[18446744071562067968, 18446744073709551615] exceeds maximum
|
||||
object size 9223372036854775807 [-Werror=alloc-size-larger-than=]
|
||||
1156 | str = malloc(len);
|
||||
| ^~~~~~~~~~~
|
||||
In file included from module_to_cil.c:39:
|
||||
module_to_cil.c: In function ‘constraint_expr_to_string’:
|
||||
/usr/include/stdlib.h:539:14: note: in a call to allocation
|
||||
function ‘malloc’ declared here
|
||||
539 | extern void *malloc (size_t __size) __THROW __attribute_malloc__
|
||||
| ^~~~~~
|
||||
|
||||
The wide range (from 18446744071562067968 = 0xffffffff80000000 to
|
||||
18446744073709551615 = 0xffffffffffffffff) was caused by num_names being
|
||||
a signed int used in "len += num_names;", even though it should always
|
||||
be non-negative.
|
||||
|
||||
Prevent such issues from occurring by using "unsigned int" where
|
||||
appropriate.
|
||||
|
||||
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
||||
---
|
||||
libsepol/src/module_to_cil.c | 62 ++++++++++++++++++------------------
|
||||
1 file changed, 31 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c
|
||||
index a87bc15e7610..cb1069caffdf 100644
|
||||
--- a/libsepol/src/module_to_cil.c
|
||||
+++ b/libsepol/src/module_to_cil.c
|
||||
@@ -717,9 +717,9 @@ exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
-static int num_digits(int n)
|
||||
+static unsigned int num_digits(unsigned int n)
|
||||
{
|
||||
- int num = 1;
|
||||
+ unsigned int num = 1;
|
||||
while (n >= 10) {
|
||||
n /= 10;
|
||||
num++;
|
||||
@@ -945,7 +945,7 @@ static char *search_attr_list(struct list *attr_list, int is_type, void *set)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
-static int set_to_names(struct policydb *pdb, int is_type, void *set, struct list *attr_list, char ***names, int *num_names)
|
||||
+static int set_to_names(struct policydb *pdb, int is_type, void *set, struct list *attr_list, char ***names, unsigned int *num_names)
|
||||
{
|
||||
char *attr_name = NULL;
|
||||
int rc = 0;
|
||||
@@ -982,12 +982,12 @@ exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
-static int ebitmap_to_names(struct ebitmap *map, char **vals_to_names, char ***names, int *num_names)
|
||||
+static int ebitmap_to_names(struct ebitmap *map, char **vals_to_names, char ***names, unsigned int *num_names)
|
||||
{
|
||||
int rc = 0;
|
||||
struct ebitmap_node *node;
|
||||
uint32_t i;
|
||||
- uint32_t num;
|
||||
+ unsigned int num;
|
||||
char **name_arr;
|
||||
|
||||
num = 0;
|
||||
@@ -1026,7 +1026,7 @@ exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
-static int process_roleset(struct policydb *pdb, struct role_set *rs, struct list *attr_list, char ***names, int *num_names)
|
||||
+static int process_roleset(struct policydb *pdb, struct role_set *rs, struct list *attr_list, char ***names, unsigned int *num_names)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
@@ -1049,7 +1049,7 @@ exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
-static int process_typeset(struct policydb *pdb, struct type_set *ts, struct list *attr_list, char ***names, int *num_names)
|
||||
+static int process_typeset(struct policydb *pdb, struct type_set *ts, struct list *attr_list, char ***names, unsigned int *num_names)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
@@ -1072,7 +1072,7 @@ exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
-static void names_destroy(char ***names, int *num_names)
|
||||
+static void names_destroy(char ***names, unsigned int *num_names)
|
||||
{
|
||||
free(*names);
|
||||
*names = NULL;
|
||||
@@ -1083,7 +1083,7 @@ static int roletype_role_in_ancestor_to_cil(struct policydb *pdb, struct stack *
|
||||
{
|
||||
struct list_node *curr;
|
||||
char **tnames = NULL;
|
||||
- int num_tnames, i;
|
||||
+ unsigned int num_tnames, i;
|
||||
struct role_list_node *role_node = NULL;
|
||||
int rc;
|
||||
struct type_set *ts;
|
||||
@@ -1124,12 +1124,12 @@ exit:
|
||||
}
|
||||
|
||||
|
||||
-static int name_list_to_string(char **names, int num_names, char **string)
|
||||
+static int name_list_to_string(char **names, unsigned int num_names, char **string)
|
||||
{
|
||||
// create a space separated string of the names
|
||||
int rc = -1;
|
||||
size_t len = 0;
|
||||
- int i;
|
||||
+ unsigned int i;
|
||||
char *str;
|
||||
char *strpos;
|
||||
|
||||
@@ -1184,7 +1184,7 @@ static int avrule_list_to_cil(int indent, struct policydb *pdb, struct avrule *a
|
||||
struct avrule *avrule;
|
||||
char **snames = NULL;
|
||||
char **tnames = NULL;
|
||||
- int s, t, num_snames, num_tnames;
|
||||
+ unsigned int s, t, num_snames, num_tnames;
|
||||
struct type_set *ts;
|
||||
|
||||
for (avrule = avrule_list; avrule != NULL; avrule = avrule->next) {
|
||||
@@ -1257,7 +1257,7 @@ static int cond_expr_to_cil(int indent, struct policydb *pdb, struct cond_expr *
|
||||
char *new_val = NULL;
|
||||
char *val1 = NULL;
|
||||
char *val2 = NULL;
|
||||
- int num_params;
|
||||
+ unsigned int num_params;
|
||||
const char *op;
|
||||
const char *fmt_str;
|
||||
const char *type;
|
||||
@@ -1432,11 +1432,11 @@ static int role_trans_to_cil(int indent, struct policydb *pdb, struct role_trans
|
||||
int rc = 0;
|
||||
struct role_trans_rule *rule;
|
||||
char **role_names = NULL;
|
||||
- int num_role_names = 0;
|
||||
- int role;
|
||||
+ unsigned int num_role_names = 0;
|
||||
+ unsigned int role;
|
||||
char **type_names = NULL;
|
||||
- int num_type_names = 0;
|
||||
- int type;
|
||||
+ unsigned int num_type_names = 0;
|
||||
+ unsigned int type;
|
||||
uint32_t i;
|
||||
struct ebitmap_node *node;
|
||||
struct type_set *ts;
|
||||
@@ -1482,10 +1482,10 @@ static int role_allows_to_cil(int indent, struct policydb *pdb, struct role_allo
|
||||
int rc = -1;
|
||||
struct role_allow_rule *rule;
|
||||
char **roles = NULL;
|
||||
- int num_roles = 0;
|
||||
+ unsigned int num_roles = 0;
|
||||
char **new_roles = NULL;
|
||||
- int num_new_roles = 0;
|
||||
- int i,j;
|
||||
+ unsigned int num_new_roles = 0;
|
||||
+ unsigned int i, j;
|
||||
struct role_set *rs;
|
||||
|
||||
for (rule = rules; rule != NULL; rule = rule->next) {
|
||||
@@ -1525,11 +1525,11 @@ static int range_trans_to_cil(int indent, struct policydb *pdb, struct range_tra
|
||||
int rc = -1;
|
||||
struct range_trans_rule *rule;
|
||||
char **stypes = NULL;
|
||||
- int num_stypes = 0;
|
||||
- int stype;
|
||||
+ unsigned int num_stypes = 0;
|
||||
+ unsigned int stype;
|
||||
char **ttypes = NULL;
|
||||
- int num_ttypes = 0;
|
||||
- int ttype;
|
||||
+ unsigned int num_ttypes = 0;
|
||||
+ unsigned int ttype;
|
||||
struct ebitmap_node *node;
|
||||
uint32_t i;
|
||||
struct type_set *ts;
|
||||
@@ -1594,11 +1594,11 @@ static int filename_trans_to_cil(int indent, struct policydb *pdb, struct filena
|
||||
{
|
||||
int rc = -1;
|
||||
char **stypes = NULL;
|
||||
- int num_stypes = 0;
|
||||
- int stype;
|
||||
+ unsigned int num_stypes = 0;
|
||||
+ unsigned int stype;
|
||||
char **ttypes = NULL;
|
||||
- int num_ttypes = 0;
|
||||
- int ttype;
|
||||
+ unsigned int num_ttypes = 0;
|
||||
+ unsigned int ttype;
|
||||
struct type_set *ts;
|
||||
struct filename_trans_rule *rule;
|
||||
|
||||
@@ -1716,7 +1716,7 @@ static int constraint_expr_to_string(struct policydb *pdb, struct constraint_exp
|
||||
const char *attr2;
|
||||
char *names = NULL;
|
||||
char **name_list = NULL;
|
||||
- int num_names = 0;
|
||||
+ unsigned int num_names = 0;
|
||||
struct type_set *ts;
|
||||
|
||||
rc = stack_init(&stack);
|
||||
@@ -2090,9 +2090,9 @@ static int role_to_cil(int indent, struct policydb *pdb, struct avrule_block *UN
|
||||
int rc = -1;
|
||||
struct ebitmap_node *node;
|
||||
uint32_t i;
|
||||
- int j;
|
||||
+ unsigned int j;
|
||||
char **types = NULL;
|
||||
- int num_types = 0;
|
||||
+ unsigned int num_types = 0;
|
||||
struct role_datum *role = datum;
|
||||
struct type_set *ts;
|
||||
struct list *attr_list = NULL;
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,37 +0,0 @@
|
||||
From d4d0955c67f5b928ef134ee7e7e23a9c40a266ea Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Tue, 16 Mar 2021 14:30:02 -0400
|
||||
Subject: [PATCH] libsepol: Write "NO_IDENTIFIER" for empty constraint
|
||||
expression
|
||||
|
||||
If a role attribute with no roles associated with it is used in a
|
||||
constraint expression, then the role bitmap will be empty. This is
|
||||
not a problem for the kernel, but does cause problems when
|
||||
converting a kernel policy to policy.conf.
|
||||
|
||||
When creating a policy.conf from a kernel policy, if an empty bitmap
|
||||
is encountered, use the string "NO_IDENTIFIER". An error will occur
|
||||
if an attempt is made to compile the resulting policy, but this is
|
||||
better than exiting with an error without creating a policy.conf.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/src/kernel_to_conf.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libsepol/src/kernel_to_conf.c b/libsepol/src/kernel_to_conf.c
|
||||
index ea58a026501f..cd5a517abb59 100644
|
||||
--- a/libsepol/src/kernel_to_conf.c
|
||||
+++ b/libsepol/src/kernel_to_conf.c
|
||||
@@ -186,7 +186,7 @@ static char *constraint_expr_to_str(struct policydb *pdb, struct constraint_expr
|
||||
names = ebitmap_to_str(&curr->names, pdb->p_role_val_to_name, 1);
|
||||
}
|
||||
if (!names) {
|
||||
- goto exit;
|
||||
+ names = strdup("NO_IDENTIFIER");
|
||||
}
|
||||
new_val = create_str("%s %s %s", 3, attr1, op, names);
|
||||
free(names);
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,38 +0,0 @@
|
||||
From dbe890ab9f74c9514a0f8839591eb3c4c70a6e03 Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Tue, 16 Mar 2021 14:42:36 -0400
|
||||
Subject: [PATCH] libsepol: Enclose identifier lists in constraint expressions
|
||||
|
||||
When writing a policy.conf from a kernel policy, if there are
|
||||
multiple users, roles, or types, then the list needs to be enclosed
|
||||
by "{" and "}".
|
||||
|
||||
When writing a constraint expression, check to see if there are
|
||||
multiple identifiers in the names string and enclose the list
|
||||
with "{" and "}" if there are.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/src/kernel_to_conf.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libsepol/src/kernel_to_conf.c b/libsepol/src/kernel_to_conf.c
|
||||
index cd5a517abb59..5db47fe4f567 100644
|
||||
--- a/libsepol/src/kernel_to_conf.c
|
||||
+++ b/libsepol/src/kernel_to_conf.c
|
||||
@@ -188,7 +188,11 @@ static char *constraint_expr_to_str(struct policydb *pdb, struct constraint_expr
|
||||
if (!names) {
|
||||
names = strdup("NO_IDENTIFIER");
|
||||
}
|
||||
- new_val = create_str("%s %s %s", 3, attr1, op, names);
|
||||
+ if (strchr(names, ' ')) {
|
||||
+ new_val = create_str("%s %s { %s }", 3, attr1, op, names);
|
||||
+ } else {
|
||||
+ new_val = create_str("%s %s %s", 3, attr1, op, names);
|
||||
+ }
|
||||
free(names);
|
||||
}
|
||||
} else {
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,40 +0,0 @@
|
||||
From 48ca44c8bc3bffd276fae0e7cc8c5b04af4f8736 Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Tue, 16 Mar 2021 15:18:31 -0400
|
||||
Subject: [PATCH] libsepol/cil: Allow lists in constraint expressions
|
||||
|
||||
The expectation in CIL was to use user, role, or type attributes in
|
||||
constraint expressions. The problem is that neither user nor role
|
||||
attributes are part of the kernel binary policy, so when converting
|
||||
from a kernel policy to CIL, that would require the creation of a
|
||||
role or user attribute. The better solution is to just allow a list
|
||||
to be used. In fact, the only thing preventing a list to be used
|
||||
is a check in cil_verify_constraint_leaf_expr_syntax().
|
||||
|
||||
Remove the check and allow lists in constraint expressions.
|
||||
|
||||
The following is now allowed:
|
||||
(constrain (CLASS1 (PERM1)) (eq r1 (ROLE1 ROLE2 ROLE_ATTR3)))
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_verify.c | 3 ---
|
||||
1 file changed, 3 deletions(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_verify.c b/libsepol/cil/src/cil_verify.c
|
||||
index 6706e21921fe..09e3daf94cc7 100644
|
||||
--- a/libsepol/cil/src/cil_verify.c
|
||||
+++ b/libsepol/cil/src/cil_verify.c
|
||||
@@ -225,9 +225,6 @@ int cil_verify_constraint_leaf_expr_syntax(enum cil_flavor l_flavor, enum cil_fl
|
||||
cil_log(CIL_ERR, "u3, r3, and t3 can only be used with (mls)validatetrans rules\n");
|
||||
goto exit;
|
||||
}
|
||||
- } else if (r_flavor == CIL_LIST) {
|
||||
- cil_log(CIL_ERR, "t1, t2, r1, r2, u1, u2 cannot be used on the left side with a list on the right side\n");
|
||||
- goto exit;
|
||||
}
|
||||
} else {
|
||||
if (r_flavor == CIL_CONS_U2) {
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,66 +0,0 @@
|
||||
From 6758addf8592d950cba489703abedd4a3430602f Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Tue, 16 Mar 2021 15:24:14 -0400
|
||||
Subject: [PATCH] libsepol: Enclose identifier lists in CIL constraint
|
||||
expressions
|
||||
|
||||
When writing CIL policy from a kernel policy or module, if there are
|
||||
multiple users, roles, or types, then the list needs to be enclosed
|
||||
by "(" and ")".
|
||||
|
||||
When writing a constraint expression, check to see if there are
|
||||
multiple identifiers in the names string and enclose the list with
|
||||
"(" and ")" if there are.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/src/kernel_to_cil.c | 6 +++++-
|
||||
libsepol/src/module_to_cil.c | 9 ++++++++-
|
||||
2 files changed, 13 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libsepol/src/kernel_to_cil.c b/libsepol/src/kernel_to_cil.c
|
||||
index edfebeafe283..101cb61240f5 100644
|
||||
--- a/libsepol/src/kernel_to_cil.c
|
||||
+++ b/libsepol/src/kernel_to_cil.c
|
||||
@@ -191,7 +191,11 @@ static char *constraint_expr_to_str(struct policydb *pdb, struct constraint_expr
|
||||
if (!names) {
|
||||
goto exit;
|
||||
}
|
||||
- new_val = create_str("(%s %s %s)", 3, op, attr1, names);
|
||||
+ if (strchr(names, ' ')) {
|
||||
+ new_val = create_str("(%s %s (%s))", 3, op, attr1, names);
|
||||
+ } else {
|
||||
+ new_val = create_str("(%s %s %s)", 3, op, attr1, names);
|
||||
+ }
|
||||
free(names);
|
||||
}
|
||||
} else {
|
||||
diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c
|
||||
index cb1069caffdf..fdf56b701e2c 100644
|
||||
--- a/libsepol/src/module_to_cil.c
|
||||
+++ b/libsepol/src/module_to_cil.c
|
||||
@@ -1800,13 +1800,20 @@ static int constraint_expr_to_string(struct policydb *pdb, struct constraint_exp
|
||||
|
||||
// length of values/oper + 2 spaces + 2 parens + null terminator
|
||||
len = strlen(op) + strlen(attr1) + strlen(names) + 2 + 2 + 1;
|
||||
+ if (num_names > 1) {
|
||||
+ len += 2; // 2 more parens
|
||||
+ }
|
||||
new_val = malloc(len);
|
||||
if (new_val == NULL) {
|
||||
log_err("Out of memory");
|
||||
rc = -1;
|
||||
goto exit;
|
||||
}
|
||||
- rlen = snprintf(new_val, len, "(%s %s %s)", op, attr1, names);
|
||||
+ if (num_names > 1) {
|
||||
+ rlen = snprintf(new_val, len, "(%s %s (%s))", op, attr1, names);
|
||||
+ } else {
|
||||
+ rlen = snprintf(new_val, len, "(%s %s %s)", op, attr1, names);
|
||||
+ }
|
||||
if (rlen < 0 || rlen >= len) {
|
||||
log_err("Failed to generate constraint expression");
|
||||
rc = -1;
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,60 +0,0 @@
|
||||
From b839e9a1cb78d67c18df8b2e75e2fa53cca74392 Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Tue, 16 Mar 2021 15:31:06 -0400
|
||||
Subject: [PATCH] libsepol: Write "NO_IDENTIFIER" for empty CIL constraint
|
||||
expression
|
||||
|
||||
If a role or user attribute with nothing associated with it is used
|
||||
in a constraint expression, then the bitmap will be empty. This is
|
||||
not a problem for the kernel, but does cause problems when converting
|
||||
a kernel policy or module to CIL.
|
||||
|
||||
When creating a CIL policy from a kernel policy or module, if an
|
||||
empty bitmap is encountered, use the string "NO_IDENTIFIER". An
|
||||
error will occur if an attempt is made to compile the resulting
|
||||
policy, but a valid policy was not being produced before anyway.
|
||||
Treat types the same way even though empty bitmaps are not expected.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/src/kernel_to_cil.c | 2 +-
|
||||
libsepol/src/module_to_cil.c | 10 +++++++---
|
||||
2 files changed, 8 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libsepol/src/kernel_to_cil.c b/libsepol/src/kernel_to_cil.c
|
||||
index 101cb61240f5..989aacde8a12 100644
|
||||
--- a/libsepol/src/kernel_to_cil.c
|
||||
+++ b/libsepol/src/kernel_to_cil.c
|
||||
@@ -189,7 +189,7 @@ static char *constraint_expr_to_str(struct policydb *pdb, struct constraint_expr
|
||||
names = ebitmap_to_str(&curr->names, pdb->p_role_val_to_name, 1);
|
||||
}
|
||||
if (!names) {
|
||||
- goto exit;
|
||||
+ names = strdup("NO_IDENTIFIER");
|
||||
}
|
||||
if (strchr(names, ' ')) {
|
||||
new_val = create_str("(%s %s (%s))", 3, op, attr1, names);
|
||||
diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c
|
||||
index fdf56b701e2c..58df0d4f6d77 100644
|
||||
--- a/libsepol/src/module_to_cil.c
|
||||
+++ b/libsepol/src/module_to_cil.c
|
||||
@@ -1793,9 +1793,13 @@ static int constraint_expr_to_string(struct policydb *pdb, struct constraint_exp
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
- rc = name_list_to_string(name_list, num_names, &names);
|
||||
- if (rc != 0) {
|
||||
- goto exit;
|
||||
+ if (num_names == 0) {
|
||||
+ names = strdup("NO_IDENTIFIER");
|
||||
+ } else {
|
||||
+ rc = name_list_to_string(name_list, num_names, &names);
|
||||
+ if (rc != 0) {
|
||||
+ goto exit;
|
||||
+ }
|
||||
}
|
||||
|
||||
// length of values/oper + 2 spaces + 2 parens + null terminator
|
||||
--
|
||||
2.32.0
|
||||
|
@ -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 c9aada9db348..ed96786115d3 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;
|
||||
}
|
||||
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,50 +0,0 @@
|
||||
From e13c8162656665f9ec1c76a033cae5b011b8c658 Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Thu, 8 Apr 2021 13:24:29 -0400
|
||||
Subject: [PATCH] libsepol/cil: Fix out-of-bound read of file context pattern
|
||||
ending with "\"
|
||||
|
||||
Based on patch by Nicolas Iooss, who writes:
|
||||
OSS-Fuzz found a Heap-buffer-overflow in the CIL compiler when trying
|
||||
to compile the following policy:
|
||||
|
||||
(sid SID)
|
||||
(sidorder(SID))
|
||||
(filecon "\" any ())
|
||||
(filecon "" any ())
|
||||
|
||||
When cil_post_fc_fill_data() processes "\", it goes beyond the NUL
|
||||
terminator of the string. Fix this by returning when '\0' is read
|
||||
after a backslash.
|
||||
|
||||
To be consistent with the function compute_diffdata() in
|
||||
refpolicy/support/fc_sort.py, also increment str_len in this case.
|
||||
|
||||
Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28484
|
||||
Reported-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_post.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c
|
||||
index d2ecbd430aa3..fd4758dc580e 100644
|
||||
--- a/libsepol/cil/src/cil_post.c
|
||||
+++ b/libsepol/cil/src/cil_post.c
|
||||
@@ -186,6 +186,13 @@ static void cil_post_fc_fill_data(struct fc_data *fc, const char *path)
|
||||
break;
|
||||
case '\\':
|
||||
c++;
|
||||
+ if (path[c] == '\0') {
|
||||
+ if (!fc->meta) {
|
||||
+ fc->stem_len++;
|
||||
+ }
|
||||
+ fc->str_len++;
|
||||
+ return;
|
||||
+ }
|
||||
/* FALLTHRU */
|
||||
default:
|
||||
if (!fc->meta) {
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,97 +0,0 @@
|
||||
From f34d3d30c8325e4847a6b696fe7a3936a8a361f3 Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Thu, 8 Apr 2021 13:32:01 -0400
|
||||
Subject: [PATCH] libsepol/cil: Destroy classperms list when resetting
|
||||
classpermission
|
||||
|
||||
Nicolas Iooss reports:
|
||||
A few months ago, OSS-Fuzz found a crash in the CIL compiler, which
|
||||
got reported as
|
||||
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28648 (the title
|
||||
is misleading, or is caused by another issue that conflicts with the
|
||||
one I report in this message). Here is a minimized CIL policy which
|
||||
reproduces the issue:
|
||||
|
||||
(class CLASS (PERM))
|
||||
(classorder (CLASS))
|
||||
(sid SID)
|
||||
(sidorder (SID))
|
||||
(user USER)
|
||||
(role ROLE)
|
||||
(type TYPE)
|
||||
(category CAT)
|
||||
(categoryorder (CAT))
|
||||
(sensitivity SENS)
|
||||
(sensitivityorder (SENS))
|
||||
(sensitivitycategory SENS (CAT))
|
||||
(allow TYPE self (CLASS (PERM)))
|
||||
(roletype ROLE TYPE)
|
||||
(userrole USER ROLE)
|
||||
(userlevel USER (SENS))
|
||||
(userrange USER ((SENS)(SENS (CAT))))
|
||||
(sidcontext SID (USER ROLE TYPE ((SENS)(SENS))))
|
||||
|
||||
(classpermission CLAPERM)
|
||||
|
||||
(optional OPT
|
||||
(roletype nonexistingrole nonexistingtype)
|
||||
(classpermissionset CLAPERM (CLASS (PERM)))
|
||||
)
|
||||
|
||||
The CIL policy fuzzer (which mimics secilc built with clang Address
|
||||
Sanitizer) reports:
|
||||
|
||||
==36541==ERROR: AddressSanitizer: heap-use-after-free on address
|
||||
0x603000004f98 at pc 0x56445134c842 bp 0x7ffe2a256590 sp
|
||||
0x7ffe2a256588
|
||||
READ of size 8 at 0x603000004f98 thread T0
|
||||
#0 0x56445134c841 in __cil_verify_classperms
|
||||
/selinux/libsepol/src/../cil/src/cil_verify.c:1620:8
|
||||
#1 0x56445134a43e in __cil_verify_classpermission
|
||||
/selinux/libsepol/src/../cil/src/cil_verify.c:1650:9
|
||||
#2 0x56445134a43e in __cil_pre_verify_helper
|
||||
/selinux/libsepol/src/../cil/src/cil_verify.c:1715:8
|
||||
#3 0x5644513225ac in cil_tree_walk_core
|
||||
/selinux/libsepol/src/../cil/src/cil_tree.c:272:9
|
||||
#4 0x564451322ab1 in cil_tree_walk
|
||||
/selinux/libsepol/src/../cil/src/cil_tree.c:316:7
|
||||
#5 0x5644513226af in cil_tree_walk_core
|
||||
/selinux/libsepol/src/../cil/src/cil_tree.c:284:9
|
||||
#6 0x564451322ab1 in cil_tree_walk
|
||||
/selinux/libsepol/src/../cil/src/cil_tree.c:316:7
|
||||
#7 0x5644512b88fd in cil_pre_verify
|
||||
/selinux/libsepol/src/../cil/src/cil_post.c:2510:7
|
||||
#8 0x5644512b88fd in cil_post_process
|
||||
/selinux/libsepol/src/../cil/src/cil_post.c:2524:7
|
||||
#9 0x5644511856ff in cil_compile
|
||||
/selinux/libsepol/src/../cil/src/cil.c:564:7
|
||||
|
||||
The classperms list of a classpermission rule is created and filled
|
||||
in when classpermissionset rules are processed, so it doesn't own any
|
||||
part of the list and shouldn't retain any of it when it is reset.
|
||||
|
||||
Destroy the classperms list (without destroying the data in it) when
|
||||
resetting a classpermission rule.
|
||||
|
||||
Reported-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_reset_ast.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_reset_ast.c b/libsepol/cil/src/cil_reset_ast.c
|
||||
index 3da1b9a64167..db70a535bd42 100644
|
||||
--- a/libsepol/cil/src/cil_reset_ast.c
|
||||
+++ b/libsepol/cil/src/cil_reset_ast.c
|
||||
@@ -54,7 +54,7 @@ static void cil_reset_classpermission(struct cil_classpermission *cp)
|
||||
return;
|
||||
}
|
||||
|
||||
- cil_reset_classperms_list(cp->classperms);
|
||||
+ cil_list_destroy(&cp->classperms, CIL_FALSE);
|
||||
}
|
||||
|
||||
static void cil_reset_classperms_set(struct cil_classperms_set *cp_set)
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,36 +0,0 @@
|
||||
From 2d35fcc7e9e976a2346b1de20e54f8663e8a6cba Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Thu, 8 Apr 2021 13:32:04 -0400
|
||||
Subject: [PATCH] libsepol/cil: Destroy classperm list when resetting map perms
|
||||
|
||||
Map perms share the same struct as regular perms, but only the
|
||||
map perms use the classperms field. This field is a pointer to a
|
||||
list of classperms that is created and added to when resolving
|
||||
classmapping rules, so the map permission doesn't own any of the
|
||||
data in the list and this list should be destroyed when the AST is
|
||||
reset.
|
||||
|
||||
When resetting a perm, destroy the classperms list without destroying
|
||||
the data in the list.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_reset_ast.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_reset_ast.c b/libsepol/cil/src/cil_reset_ast.c
|
||||
index db70a535bd42..89f91e568d0e 100644
|
||||
--- a/libsepol/cil/src/cil_reset_ast.c
|
||||
+++ b/libsepol/cil/src/cil_reset_ast.c
|
||||
@@ -36,7 +36,7 @@ static void cil_reset_class(struct cil_class *class)
|
||||
|
||||
static void cil_reset_perm(struct cil_perm *perm)
|
||||
{
|
||||
- cil_reset_classperms_list(perm->classperms);
|
||||
+ cil_list_destroy(&perm->classperms, CIL_FALSE);
|
||||
}
|
||||
|
||||
static inline void cil_reset_classperms(struct cil_classperms *cp)
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,39 +0,0 @@
|
||||
From c49a8ea09501ad66e799ea41b8154b6770fec2c8 Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Thu, 8 Apr 2021 13:32:06 -0400
|
||||
Subject: [PATCH] libsepol/cil: cil_reset_classperms_set() should not reset
|
||||
classpermission
|
||||
|
||||
In struct cil_classperms_set, the set field is a pointer to a
|
||||
struct cil_classpermission which is looked up in the symbol table.
|
||||
Since the cil_classperms_set does not create the cil_classpermission,
|
||||
it should not reset it.
|
||||
|
||||
Set the set field to NULL instead of resetting the classpermission
|
||||
that it points to.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_reset_ast.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_reset_ast.c b/libsepol/cil/src/cil_reset_ast.c
|
||||
index 89f91e568d0e..1d9ca704e3ea 100644
|
||||
--- a/libsepol/cil/src/cil_reset_ast.c
|
||||
+++ b/libsepol/cil/src/cil_reset_ast.c
|
||||
@@ -59,7 +59,11 @@ static void cil_reset_classpermission(struct cil_classpermission *cp)
|
||||
|
||||
static void cil_reset_classperms_set(struct cil_classperms_set *cp_set)
|
||||
{
|
||||
- cil_reset_classpermission(cp_set->set);
|
||||
+ if (cp_set == NULL) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ cp_set->set = NULL;
|
||||
}
|
||||
|
||||
static inline void cil_reset_classperms_list(struct cil_list *cp_list)
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,32 +0,0 @@
|
||||
From a7a80ef51b915071f0339e5e0262f06d84112874 Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Thu, 8 Apr 2021 13:32:08 -0400
|
||||
Subject: [PATCH] libsepol/cil: Set class field to NULL when resetting struct
|
||||
cil_classperms
|
||||
|
||||
The class field of a struct cil_classperms points to the class looked
|
||||
up in the symbol table, so that field should be set to NULL when
|
||||
the cil_classperms is reset.
|
||||
|
||||
Set the class field to NULL when resetting the struct cil_classperms.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_reset_ast.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_reset_ast.c b/libsepol/cil/src/cil_reset_ast.c
|
||||
index 1d9ca704e3ea..76405aba6194 100644
|
||||
--- a/libsepol/cil/src/cil_reset_ast.c
|
||||
+++ b/libsepol/cil/src/cil_reset_ast.c
|
||||
@@ -45,6 +45,7 @@ static inline void cil_reset_classperms(struct cil_classperms *cp)
|
||||
return;
|
||||
}
|
||||
|
||||
+ cp->class = NULL;
|
||||
cil_list_destroy(&cp->perms, CIL_FALSE);
|
||||
}
|
||||
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,42 +0,0 @@
|
||||
From e978e7692e16d6d8b801700d1dc5129ca31dfbad Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Thu, 8 Apr 2021 13:32:11 -0400
|
||||
Subject: [PATCH] libsepol/cil: More strict verification of constraint leaf
|
||||
expressions
|
||||
|
||||
In constraint expressions u1, u3, r1, r3, t1, and t3 are never
|
||||
allowed on the right side of an expression, but there were no checks
|
||||
to verify that they were not used on the right side. The result was
|
||||
that the expression "(eq t1 t1)" would be silently turned into
|
||||
"(eq t1 t2)" when the binary policy was created.
|
||||
|
||||
Verify that u1, u3, r1, r3, t1, and t3 are not used on the right
|
||||
side of a constraint expression.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_verify.c | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_verify.c b/libsepol/cil/src/cil_verify.c
|
||||
index 09e3daf94cc7..2707b6c97d15 100644
|
||||
--- a/libsepol/cil/src/cil_verify.c
|
||||
+++ b/libsepol/cil/src/cil_verify.c
|
||||
@@ -227,7 +227,13 @@ int cil_verify_constraint_leaf_expr_syntax(enum cil_flavor l_flavor, enum cil_fl
|
||||
}
|
||||
}
|
||||
} else {
|
||||
- if (r_flavor == CIL_CONS_U2) {
|
||||
+ if (r_flavor == CIL_CONS_U1 || r_flavor == CIL_CONS_R1 || r_flavor == CIL_CONS_T1) {
|
||||
+ cil_log(CIL_ERR, "u1, r1, and t1 are not allowed on the right side\n");
|
||||
+ goto exit;
|
||||
+ } else if (r_flavor == CIL_CONS_U3 || r_flavor == CIL_CONS_R3 || r_flavor == CIL_CONS_T3) {
|
||||
+ cil_log(CIL_ERR, "u3, r3, and t3 are not allowed on the right side\n");
|
||||
+ goto exit;
|
||||
+ } else if (r_flavor == CIL_CONS_U2) {
|
||||
if (op != CIL_EQ && op != CIL_NEQ) {
|
||||
cil_log(CIL_ERR, "u2 on the right side must be used with eq or neq as the operator\n");
|
||||
goto exit;
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,194 +0,0 @@
|
||||
From 532469a251607cfd8bd5e9299d3bba3764345ab6 Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Thu, 8 Apr 2021 13:32:12 -0400
|
||||
Subject: [PATCH] libsepol/cil: Exit with an error if declaration name is a
|
||||
reserved word
|
||||
|
||||
When CIL parses sets or conditional expressions, any identifier that
|
||||
matches an operator name will always be taken as an operator. If a
|
||||
declaration has the same name as an operator, then there is the
|
||||
possibility of causing either confusion or a syntax error if it is
|
||||
used in an expression. The potential for problems is much greater
|
||||
than any possible advantage in allowing a declaration to share the
|
||||
name of a reserved word.
|
||||
|
||||
Create a new function, __cil_is_reserved_name() that is called when
|
||||
an identifier is declared and its name is being validated. In this
|
||||
function, check if the declaration has the same name as a reserved
|
||||
word for an expression operator that can be used with the identifer's
|
||||
flavor and exit with an error if it does.
|
||||
|
||||
Also, move the check for types, type aliases, and type attributes
|
||||
matching the reserved word "self" to this new function.
|
||||
|
||||
Finally, change the name of the function __cil_verify_name() to
|
||||
cil_verify_name(), since this function is neither static nor a
|
||||
helper function.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_build_ast.c | 28 ++---------------
|
||||
libsepol/cil/src/cil_verify.c | 52 +++++++++++++++++++++++++++++++-
|
||||
libsepol/cil/src/cil_verify.h | 2 +-
|
||||
3 files changed, 54 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
|
||||
index 4e53f06a98f4..e57de662dbd9 100644
|
||||
--- a/libsepol/cil/src/cil_build_ast.c
|
||||
+++ b/libsepol/cil/src/cil_build_ast.c
|
||||
@@ -114,7 +114,7 @@ int cil_gen_node(struct cil_db *db, struct cil_tree_node *ast_node, struct cil_s
|
||||
symtab_t *symtab = NULL;
|
||||
struct cil_symtab_datum *prev;
|
||||
|
||||
- rc = __cil_verify_name((const char*)key);
|
||||
+ rc = cil_verify_name((const char*)key, nflavor);
|
||||
if (rc != SEPOL_OK) {
|
||||
goto exit;
|
||||
}
|
||||
@@ -1953,12 +1953,6 @@ int cil_gen_roleattribute(struct cil_db *db, struct cil_tree_node *parse_current
|
||||
goto exit;
|
||||
}
|
||||
|
||||
- if (parse_current->next->data == CIL_KEY_SELF) {
|
||||
- cil_log(CIL_ERR, "The keyword '%s' is reserved\n", CIL_KEY_SELF);
|
||||
- rc = SEPOL_ERR;
|
||||
- goto exit;
|
||||
- }
|
||||
-
|
||||
cil_roleattribute_init(&attr);
|
||||
|
||||
key = parse_current->next->data;
|
||||
@@ -2337,12 +2331,6 @@ int cil_gen_type(struct cil_db *db, struct cil_tree_node *parse_current, struct
|
||||
goto exit;
|
||||
}
|
||||
|
||||
- if (parse_current->next->data == CIL_KEY_SELF) {
|
||||
- cil_log(CIL_ERR, "The keyword '%s' is reserved\n", CIL_KEY_SELF);
|
||||
- rc = SEPOL_ERR;
|
||||
- goto exit;
|
||||
- }
|
||||
-
|
||||
cil_type_init(&type);
|
||||
|
||||
key = parse_current->next->data;
|
||||
@@ -2391,12 +2379,6 @@ int cil_gen_typeattribute(struct cil_db *db, struct cil_tree_node *parse_current
|
||||
goto exit;
|
||||
}
|
||||
|
||||
- if (parse_current->next->data == CIL_KEY_SELF) {
|
||||
- cil_log(CIL_ERR, "The keyword '%s' is reserved\n", CIL_KEY_SELF);
|
||||
- rc = SEPOL_ERR;
|
||||
- goto exit;
|
||||
- }
|
||||
-
|
||||
cil_typeattribute_init(&attr);
|
||||
|
||||
key = parse_current->next->data;
|
||||
@@ -3048,12 +3030,6 @@ int cil_gen_alias(struct cil_db *db, struct cil_tree_node *parse_current, struct
|
||||
goto exit;
|
||||
}
|
||||
|
||||
- if (flavor == CIL_TYPEALIAS && parse_current->next->data == CIL_KEY_SELF) {
|
||||
- cil_log(CIL_ERR, "The keyword '%s' is reserved\n", CIL_KEY_SELF);
|
||||
- rc = SEPOL_ERR;
|
||||
- goto exit;
|
||||
- }
|
||||
-
|
||||
cil_alias_init(&alias);
|
||||
|
||||
key = parse_current->next->data;
|
||||
@@ -5278,7 +5254,7 @@ int cil_gen_macro(struct cil_db *db, struct cil_tree_node *parse_current, struct
|
||||
|
||||
param->str = current_item->cl_head->next->data;
|
||||
|
||||
- rc = __cil_verify_name(param->str);
|
||||
+ rc = cil_verify_name(param->str, param->flavor);
|
||||
if (rc != SEPOL_OK) {
|
||||
cil_destroy_param(param);
|
||||
goto exit;
|
||||
diff --git a/libsepol/cil/src/cil_verify.c b/libsepol/cil/src/cil_verify.c
|
||||
index 2707b6c97d15..8fd54360698d 100644
|
||||
--- a/libsepol/cil/src/cil_verify.c
|
||||
+++ b/libsepol/cil/src/cil_verify.c
|
||||
@@ -47,7 +47,51 @@
|
||||
|
||||
#include "cil_verify.h"
|
||||
|
||||
-int __cil_verify_name(const char *name)
|
||||
+static int __cil_is_reserved_name(const char *name, enum cil_flavor flavor)
|
||||
+{
|
||||
+ switch (flavor) {
|
||||
+ case CIL_BOOL:
|
||||
+ case CIL_TUNABLE:
|
||||
+ if ((name == CIL_KEY_EQ) || (name == CIL_KEY_NEQ))
|
||||
+ return CIL_TRUE;
|
||||
+ break;
|
||||
+ case CIL_PERM:
|
||||
+ case CIL_MAP_PERM:
|
||||
+ case CIL_USER:
|
||||
+ case CIL_USERATTRIBUTE:
|
||||
+ case CIL_ROLE:
|
||||
+ case CIL_ROLEATTRIBUTE:
|
||||
+ if (name == CIL_KEY_ALL)
|
||||
+ return CIL_TRUE;
|
||||
+ break;
|
||||
+ case CIL_TYPE:
|
||||
+ case CIL_TYPEATTRIBUTE:
|
||||
+ case CIL_TYPEALIAS:
|
||||
+ if ((name == CIL_KEY_ALL) || (name == CIL_KEY_SELF))
|
||||
+ return CIL_TRUE;
|
||||
+ break;
|
||||
+ case CIL_CAT:
|
||||
+ case CIL_CATSET:
|
||||
+ case CIL_CATALIAS:
|
||||
+ case CIL_PERMISSIONX:
|
||||
+ if ((name == CIL_KEY_ALL) || (name == CIL_KEY_RANGE))
|
||||
+ return CIL_TRUE;
|
||||
+ break;
|
||||
+ default:
|
||||
+ /* All of these are not used in expressions */
|
||||
+ return CIL_FALSE;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ /* Everything not under the default case is also checked for these */
|
||||
+ if ((name == CIL_KEY_AND) || (name == CIL_KEY_OR) || (name == CIL_KEY_NOT) || (name == CIL_KEY_XOR)) {
|
||||
+ return CIL_TRUE;
|
||||
+ }
|
||||
+
|
||||
+ return CIL_FALSE;
|
||||
+}
|
||||
+
|
||||
+int cil_verify_name(const char *name, enum cil_flavor flavor)
|
||||
{
|
||||
int rc = SEPOL_ERR;
|
||||
int len;
|
||||
@@ -77,6 +121,12 @@ int __cil_verify_name(const char *name)
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ if (__cil_is_reserved_name(name, flavor)) {
|
||||
+ cil_log(CIL_ERR, "Name %s is a reserved word\n", name);
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
return SEPOL_OK;
|
||||
|
||||
exit:
|
||||
diff --git a/libsepol/cil/src/cil_verify.h b/libsepol/cil/src/cil_verify.h
|
||||
index 905761b0a19c..1887ae3f13a1 100644
|
||||
--- a/libsepol/cil/src/cil_verify.h
|
||||
+++ b/libsepol/cil/src/cil_verify.h
|
||||
@@ -56,7 +56,7 @@ struct cil_args_verify {
|
||||
int *pass;
|
||||
};
|
||||
|
||||
-int __cil_verify_name(const char *name);
|
||||
+int cil_verify_name(const char *name, enum cil_flavor flavor);
|
||||
int __cil_verify_syntax(struct cil_tree_node *parse_current, enum cil_syntax s[], int len);
|
||||
int cil_verify_expr_syntax(struct cil_tree_node *current, enum cil_flavor op, enum cil_flavor expr_flavor);
|
||||
int cil_verify_constraint_leaf_expr_syntax(enum cil_flavor l_flavor, enum cil_flavor r_flavor, enum cil_flavor op, enum cil_flavor expr_flavor);
|
||||
--
|
||||
2.32.0
|
||||
|
@ -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 fd4758dc580e..05842b644807 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);
|
||||
--
|
||||
2.32.0
|
||||
|
@ -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 e57de662dbd9..14cdce1482a0 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",
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,141 +0,0 @@
|
||||
From 0d4e568afe5a28edc5fcdcff8e925d4ec1d0d3d0 Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Thu, 8 Apr 2021 13:32:19 -0400
|
||||
Subject: [PATCH] libsepol/cil: Create function cil_add_decl_to_symtab() and
|
||||
refactor
|
||||
|
||||
The functionality of adding a declaration to a symbol table is also
|
||||
needed in __cil_copy_node_helper() and not just cil_gen_node().
|
||||
|
||||
Create a new function called cil_add_decl_to_symtab() to add a
|
||||
declaration to a symtab and refactor cil_gen_node() and
|
||||
__cil_copy_node_helper() to use the new function.
|
||||
|
||||
By using the new function, __cil_copy_node_helper() will now allow
|
||||
duplicate declarations when appropriate.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_build_ast.c | 63 +++++++++++++++++++-------------
|
||||
libsepol/cil/src/cil_build_ast.h | 2 +
|
||||
libsepol/cil/src/cil_copy_ast.c | 6 ++-
|
||||
3 files changed, 45 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
|
||||
index 14cdce1482a0..ec81db554b22 100644
|
||||
--- a/libsepol/cil/src/cil_build_ast.c
|
||||
+++ b/libsepol/cil/src/cil_build_ast.c
|
||||
@@ -102,11 +102,45 @@ static int cil_allow_multiple_decls(struct cil_db *db, enum cil_flavor f_new, en
|
||||
return CIL_FALSE;
|
||||
}
|
||||
|
||||
+int cil_add_decl_to_symtab(struct cil_db *db, symtab_t *symtab, hashtab_key_t key, struct cil_symtab_datum *datum, struct cil_tree_node *node)
|
||||
+{
|
||||
+ int rc;
|
||||
+
|
||||
+ if (symtab == NULL || datum == NULL || node == NULL) {
|
||||
+ return SEPOL_ERR;
|
||||
+ }
|
||||
+
|
||||
+ rc = cil_symtab_insert(symtab, key, datum, node);
|
||||
+ if (rc == SEPOL_EEXIST) {
|
||||
+ struct cil_symtab_datum *prev;
|
||||
+ rc = cil_symtab_get_datum(symtab, key, &prev);
|
||||
+ if (rc != SEPOL_OK) {
|
||||
+ cil_log(CIL_ERR, "Re-declaration of %s %s, but previous declaration could not be found\n",cil_node_to_string(node), key);
|
||||
+ return SEPOL_ERR;
|
||||
+ }
|
||||
+ if (!cil_allow_multiple_decls(db, node->flavor, FLAVOR(prev))) {
|
||||
+ /* multiple_decls not ok, ret error */
|
||||
+ struct cil_tree_node *n = NODE(prev);
|
||||
+ cil_log(CIL_ERR, "Re-declaration of %s %s\n",
|
||||
+ cil_node_to_string(node), key);
|
||||
+ cil_tree_log(node, CIL_ERR, "Previous declaration of %s",
|
||||
+ cil_node_to_string(n));
|
||||
+ return SEPOL_ERR;
|
||||
+ }
|
||||
+ /* multiple_decls is enabled and works for this datum type, add node */
|
||||
+ cil_list_append(prev->nodes, CIL_NODE, node);
|
||||
+ node->data = prev;
|
||||
+ cil_symtab_datum_destroy(datum);
|
||||
+ free(datum);
|
||||
+ }
|
||||
+
|
||||
+ return SEPOL_OK;
|
||||
+}
|
||||
+
|
||||
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)
|
||||
{
|
||||
int rc = SEPOL_ERR;
|
||||
symtab_t *symtab = NULL;
|
||||
- struct cil_symtab_datum *prev;
|
||||
|
||||
rc = cil_verify_name((const char*)key, nflavor);
|
||||
if (rc != SEPOL_OK) {
|
||||
@@ -121,30 +155,9 @@ int cil_gen_node(struct cil_db *db, struct cil_tree_node *ast_node, struct cil_s
|
||||
ast_node->data = datum;
|
||||
ast_node->flavor = nflavor;
|
||||
|
||||
- if (symtab != NULL) {
|
||||
- rc = cil_symtab_insert(symtab, (hashtab_key_t)key, datum, ast_node);
|
||||
- if (rc == SEPOL_EEXIST) {
|
||||
- rc = cil_symtab_get_datum(symtab, (hashtab_key_t)key, &prev);
|
||||
- if (rc != SEPOL_OK) {
|
||||
- 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 (!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",
|
||||
- cil_node_to_string(ast_node), key);
|
||||
- cil_tree_log(node, CIL_ERR, "Previous declaration of %s",
|
||||
- cil_node_to_string(node));
|
||||
- rc = SEPOL_ERR;
|
||||
- goto exit;
|
||||
- }
|
||||
- /* multiple_decls is enabled and works for this datum type, add node */
|
||||
- cil_list_append(prev->nodes, CIL_NODE, ast_node);
|
||||
- ast_node->data = prev;
|
||||
- cil_symtab_datum_destroy(datum);
|
||||
- free(datum);
|
||||
- }
|
||||
+ rc = cil_add_decl_to_symtab(db, symtab, key, datum, ast_node);
|
||||
+ if (rc != SEPOL_OK) {
|
||||
+ goto exit;
|
||||
}
|
||||
|
||||
if (ast_node->parent->flavor == CIL_MACRO) {
|
||||
diff --git a/libsepol/cil/src/cil_build_ast.h b/libsepol/cil/src/cil_build_ast.h
|
||||
index 8153e51e3a97..fd9053ce55ca 100644
|
||||
--- a/libsepol/cil/src/cil_build_ast.h
|
||||
+++ b/libsepol/cil/src/cil_build_ast.h
|
||||
@@ -37,6 +37,8 @@
|
||||
#include "cil_tree.h"
|
||||
#include "cil_list.h"
|
||||
|
||||
+int cil_add_decl_to_symtab(struct cil_db *db, symtab_t *symtab, hashtab_key_t key, struct cil_symtab_datum *datum, struct cil_tree_node *node);
|
||||
+
|
||||
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);
|
||||
int cil_parse_to_list(struct cil_tree_node *parse_cl_head, struct cil_list *ast_cl, enum cil_flavor flavor);
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_copy_ast.c b/libsepol/cil/src/cil_copy_ast.c
|
||||
index ed96786115d3..12bc553c6594 100644
|
||||
--- a/libsepol/cil/src/cil_copy_ast.c
|
||||
+++ b/libsepol/cil/src/cil_copy_ast.c
|
||||
@@ -2031,7 +2031,11 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) u
|
||||
rc = SEPOL_ERR;
|
||||
goto exit;
|
||||
}
|
||||
- rc = cil_symtab_insert(symtab, ((struct cil_symtab_datum*)orig->data)->name, ((struct cil_symtab_datum*)data), new);
|
||||
+
|
||||
+ rc = cil_add_decl_to_symtab(db, symtab, DATUM(orig->data)->name, DATUM(data), new);
|
||||
+ if (rc != SEPOL_OK) {
|
||||
+ goto exit;
|
||||
+ }
|
||||
|
||||
namespace = new;
|
||||
while (namespace->flavor != CIL_MACRO && namespace->flavor != CIL_BLOCK && namespace->flavor != CIL_ROOT) {
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,140 +0,0 @@
|
||||
From e65cf030b784dbb1ff4415e0b63a3bdf0158ccf6 Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Thu, 8 Apr 2021 13:32:23 -0400
|
||||
Subject: [PATCH] libsepol/cil: Move check for the shadowing of macro
|
||||
parameters
|
||||
|
||||
In cil_gen_node(), after the declaration is added to the symbol
|
||||
table, if the parent is a macro, then a check is made to ensure
|
||||
the declaration does not shadow any of the macro's parameters.
|
||||
This check also needs to be done when copying the AST.
|
||||
|
||||
Move the check for the shadowing of macro parameters to its own
|
||||
function, cil_verify_decl_does_not_shadow_macro_parameter(), and
|
||||
refactor cil_gen_node() and __cil_copy_node_helper() to use the
|
||||
new function.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_build_ast.c | 16 +++-------------
|
||||
libsepol/cil/src/cil_copy_ast.c | 20 ++++----------------
|
||||
libsepol/cil/src/cil_verify.c | 18 ++++++++++++++++++
|
||||
libsepol/cil/src/cil_verify.h | 1 +
|
||||
4 files changed, 26 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
|
||||
index ec81db554b22..a4a2baa0f53b 100644
|
||||
--- a/libsepol/cil/src/cil_build_ast.c
|
||||
+++ b/libsepol/cil/src/cil_build_ast.c
|
||||
@@ -161,19 +161,9 @@ int cil_gen_node(struct cil_db *db, struct cil_tree_node *ast_node, struct cil_s
|
||||
}
|
||||
|
||||
if (ast_node->parent->flavor == CIL_MACRO) {
|
||||
- struct cil_list_item *item;
|
||||
- struct cil_list *param_list = ((struct cil_macro*)ast_node->parent->data)->params;
|
||||
- if (param_list != NULL) {
|
||||
- cil_list_for_each(item, param_list) {
|
||||
- struct cil_param *param = item->data;
|
||||
- if (param->flavor == ast_node->flavor) {
|
||||
- if (param->str == key) {
|
||||
- cil_log(CIL_ERR, "%s %s shadows a macro parameter in macro declaration\n", cil_node_to_string(ast_node), key);
|
||||
- rc = SEPOL_ERR;
|
||||
- goto exit;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
+ rc = cil_verify_decl_does_not_shadow_macro_parameter(ast_node->parent->data, ast_node, key);
|
||||
+ if (rc != SEPOL_OK) {
|
||||
+ goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_copy_ast.c b/libsepol/cil/src/cil_copy_ast.c
|
||||
index 12bc553c6594..954eab330340 100644
|
||||
--- a/libsepol/cil/src/cil_copy_ast.c
|
||||
+++ b/libsepol/cil/src/cil_copy_ast.c
|
||||
@@ -40,6 +40,7 @@
|
||||
#include "cil_copy_ast.h"
|
||||
#include "cil_build_ast.h"
|
||||
#include "cil_strpool.h"
|
||||
+#include "cil_verify.h"
|
||||
|
||||
struct cil_args_copy {
|
||||
struct cil_tree_node *dest;
|
||||
@@ -1716,7 +1717,6 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) u
|
||||
struct cil_db *db = NULL;
|
||||
struct cil_args_copy *args = NULL;
|
||||
struct cil_tree_node *namespace = NULL;
|
||||
- struct cil_param *param = NULL;
|
||||
enum cil_sym_index sym_index = CIL_SYM_UNKNOWN;
|
||||
symtab_t *symtab = NULL;
|
||||
void *data = NULL;
|
||||
@@ -2043,21 +2043,9 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) u
|
||||
}
|
||||
|
||||
if (namespace->flavor == CIL_MACRO) {
|
||||
- struct cil_macro *macro = namespace->data;
|
||||
- struct cil_list *param_list = macro->params;
|
||||
- if (param_list != NULL) {
|
||||
- struct cil_list_item *item;
|
||||
- cil_list_for_each(item, param_list) {
|
||||
- param = item->data;
|
||||
- if (param->flavor == new->flavor) {
|
||||
- if (param->str == ((struct cil_symtab_datum*)new->data)->name) {
|
||||
- cil_tree_log(orig, CIL_ERR, "%s %s shadows a macro parameter", cil_node_to_string(new), ((struct cil_symtab_datum*)orig->data)->name);
|
||||
- cil_tree_log(namespace, CIL_ERR, "Note: macro declaration");
|
||||
- rc = SEPOL_ERR;
|
||||
- goto exit;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
+ rc = cil_verify_decl_does_not_shadow_macro_parameter(namespace->data, orig, DATUM(orig->data)->name);
|
||||
+ if (rc != SEPOL_OK) {
|
||||
+ goto exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/libsepol/cil/src/cil_verify.c b/libsepol/cil/src/cil_verify.c
|
||||
index 8fd54360698d..5a37dd2f76bc 100644
|
||||
--- a/libsepol/cil/src/cil_verify.c
|
||||
+++ b/libsepol/cil/src/cil_verify.c
|
||||
@@ -412,6 +412,24 @@ int cil_verify_conditional_blocks(struct cil_tree_node *current)
|
||||
return SEPOL_OK;
|
||||
}
|
||||
|
||||
+int cil_verify_decl_does_not_shadow_macro_parameter(struct cil_macro *macro, struct cil_tree_node *node, const char *name)
|
||||
+{
|
||||
+ struct cil_list_item *item;
|
||||
+ struct cil_list *param_list = macro->params;
|
||||
+ if (param_list != NULL) {
|
||||
+ cil_list_for_each(item, param_list) {
|
||||
+ struct cil_param *param = item->data;
|
||||
+ if (param->flavor == node->flavor) {
|
||||
+ if (param->str == name) {
|
||||
+ cil_log(CIL_ERR, "%s %s shadows a macro parameter in macro declaration\n", cil_node_to_string(node), name);
|
||||
+ return SEPOL_ERR;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ return SEPOL_OK;
|
||||
+}
|
||||
+
|
||||
int cil_verify_no_self_reference(struct cil_symtab_datum *datum, struct cil_list *datum_list)
|
||||
{
|
||||
struct cil_list_item *i;
|
||||
diff --git a/libsepol/cil/src/cil_verify.h b/libsepol/cil/src/cil_verify.h
|
||||
index 1887ae3f13a1..c497018f8a95 100644
|
||||
--- a/libsepol/cil/src/cil_verify.h
|
||||
+++ b/libsepol/cil/src/cil_verify.h
|
||||
@@ -62,6 +62,7 @@ int cil_verify_expr_syntax(struct cil_tree_node *current, enum cil_flavor op, en
|
||||
int cil_verify_constraint_leaf_expr_syntax(enum cil_flavor l_flavor, enum cil_flavor r_flavor, enum cil_flavor op, enum cil_flavor expr_flavor);
|
||||
int cil_verify_constraint_expr_syntax(struct cil_tree_node *current, enum cil_flavor op);
|
||||
int cil_verify_conditional_blocks(struct cil_tree_node *current);
|
||||
+int cil_verify_decl_does_not_shadow_macro_parameter(struct cil_macro *macro, struct cil_tree_node *node, const char *name);
|
||||
int cil_verify_no_self_reference(struct cil_symtab_datum *datum, struct cil_list *datum_list);
|
||||
int __cil_verify_ranges(struct cil_list *list);
|
||||
int __cil_verify_ordered_node_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args);
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,219 +0,0 @@
|
||||
From 69bfe64cdf659cc47c544e6b376f0a653ff06f6f Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Tue, 30 Mar 2021 13:39:12 -0400
|
||||
Subject: [PATCH] libsepol/cil: Reorder checks for invalid rules when building
|
||||
AST
|
||||
|
||||
Reorder checks for invalid rules in the blocks of tunableifs,
|
||||
in-statements, macros, and booleanifs when building the AST for
|
||||
consistency.
|
||||
|
||||
Order the checks in the same order the blocks will be resolved in,
|
||||
so tuanbleif, in-statement, macro, booleanif, and then non-block
|
||||
rules.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_build_ast.c | 100 +++++++++++++++----------------
|
||||
1 file changed, 50 insertions(+), 50 deletions(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
|
||||
index a4a2baa0f53b..eee21086bba8 100644
|
||||
--- a/libsepol/cil/src/cil_build_ast.c
|
||||
+++ b/libsepol/cil/src/cil_build_ast.c
|
||||
@@ -49,10 +49,10 @@
|
||||
struct cil_args_build {
|
||||
struct cil_tree_node *ast;
|
||||
struct cil_db *db;
|
||||
- struct cil_tree_node *macro;
|
||||
- struct cil_tree_node *boolif;
|
||||
struct cil_tree_node *tunif;
|
||||
struct cil_tree_node *in;
|
||||
+ struct cil_tree_node *macro;
|
||||
+ struct cil_tree_node *boolif;
|
||||
};
|
||||
|
||||
int cil_fill_list(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **list)
|
||||
@@ -6069,10 +6069,10 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f
|
||||
struct cil_tree_node *ast_current = NULL;
|
||||
struct cil_db *db = NULL;
|
||||
struct cil_tree_node *ast_node = NULL;
|
||||
- struct cil_tree_node *macro = NULL;
|
||||
- struct cil_tree_node *boolif = NULL;
|
||||
struct cil_tree_node *tunif = NULL;
|
||||
struct cil_tree_node *in = NULL;
|
||||
+ struct cil_tree_node *macro = NULL;
|
||||
+ struct cil_tree_node *boolif = NULL;
|
||||
int rc = SEPOL_ERR;
|
||||
|
||||
if (parse_current == NULL || finished == NULL || extra_args == NULL) {
|
||||
@@ -6082,10 +6082,10 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f
|
||||
args = extra_args;
|
||||
ast_current = args->ast;
|
||||
db = args->db;
|
||||
- macro = args->macro;
|
||||
- boolif = args->boolif;
|
||||
tunif = args->tunif;
|
||||
in = args->in;
|
||||
+ macro = args->macro;
|
||||
+ boolif = args->boolif;
|
||||
|
||||
if (parse_current->parent->cl_head != parse_current) {
|
||||
/* ignore anything that isn't following a parenthesis */
|
||||
@@ -6102,13 +6102,31 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f
|
||||
goto exit;
|
||||
}
|
||||
|
||||
+ if (tunif != NULL) {
|
||||
+ if (parse_current->data == CIL_KEY_TUNABLE) {
|
||||
+ rc = SEPOL_ERR;
|
||||
+ cil_tree_log(parse_current, CIL_ERR, "Found tunable");
|
||||
+ cil_log(CIL_ERR, "Tunables cannot be defined within tunableif statement\n");
|
||||
+ goto exit;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (in != NULL) {
|
||||
+ if (parse_current->data == CIL_KEY_IN) {
|
||||
+ rc = SEPOL_ERR;
|
||||
+ cil_tree_log(parse_current, CIL_ERR, "Found in-statement");
|
||||
+ cil_log(CIL_ERR, "in-statements cannot be defined within in-statements\n");
|
||||
+ goto exit;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (macro != NULL) {
|
||||
- if (parse_current->data == CIL_KEY_MACRO ||
|
||||
- parse_current->data == CIL_KEY_TUNABLE ||
|
||||
+ if (parse_current->data == CIL_KEY_TUNABLE ||
|
||||
parse_current->data == CIL_KEY_IN ||
|
||||
parse_current->data == CIL_KEY_BLOCK ||
|
||||
parse_current->data == CIL_KEY_BLOCKINHERIT ||
|
||||
- parse_current->data == CIL_KEY_BLOCKABSTRACT) {
|
||||
+ parse_current->data == CIL_KEY_BLOCKABSTRACT ||
|
||||
+ parse_current->data == CIL_KEY_MACRO) {
|
||||
rc = SEPOL_ERR;
|
||||
cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in macros", (char *)parse_current->data);
|
||||
goto exit;
|
||||
@@ -6116,15 +6134,15 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f
|
||||
}
|
||||
|
||||
if (boolif != NULL) {
|
||||
- if (parse_current->data != CIL_KEY_CONDTRUE &&
|
||||
+ if (parse_current->data != CIL_KEY_TUNABLEIF &&
|
||||
+ parse_current->data != CIL_KEY_CALL &&
|
||||
+ parse_current->data != CIL_KEY_CONDTRUE &&
|
||||
parse_current->data != CIL_KEY_CONDFALSE &&
|
||||
- parse_current->data != CIL_KEY_AUDITALLOW &&
|
||||
- parse_current->data != CIL_KEY_TUNABLEIF &&
|
||||
parse_current->data != CIL_KEY_ALLOW &&
|
||||
parse_current->data != CIL_KEY_DONTAUDIT &&
|
||||
+ parse_current->data != CIL_KEY_AUDITALLOW &&
|
||||
parse_current->data != CIL_KEY_TYPETRANSITION &&
|
||||
- parse_current->data != CIL_KEY_TYPECHANGE &&
|
||||
- parse_current->data != CIL_KEY_CALL) {
|
||||
+ parse_current->data != CIL_KEY_TYPECHANGE) {
|
||||
rc = SEPOL_ERR;
|
||||
cil_tree_log(parse_current, CIL_ERR, "Found %s", (char*)parse_current->data);
|
||||
if (((struct cil_booleanif*)boolif->data)->preserved_tunable) {
|
||||
@@ -6138,24 +6156,6 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f
|
||||
}
|
||||
}
|
||||
|
||||
- if (tunif != NULL) {
|
||||
- if (parse_current->data == CIL_KEY_TUNABLE) {
|
||||
- rc = SEPOL_ERR;
|
||||
- cil_tree_log(parse_current, CIL_ERR, "Found tunable");
|
||||
- cil_log(CIL_ERR, "Tunables cannot be defined within tunableif statement\n");
|
||||
- goto exit;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (in != NULL) {
|
||||
- if (parse_current->data == CIL_KEY_IN) {
|
||||
- rc = SEPOL_ERR;
|
||||
- cil_tree_log(parse_current, CIL_ERR, "Found in-statement");
|
||||
- cil_log(CIL_ERR, "in-statements cannot be defined within in-statements\n");
|
||||
- goto exit;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
cil_tree_node_init(&ast_node);
|
||||
|
||||
ast_node->parent = ast_current;
|
||||
@@ -6441,14 +6441,6 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f
|
||||
|
||||
if (rc == SEPOL_OK) {
|
||||
if (ast_current->cl_head == NULL) {
|
||||
- if (ast_current->flavor == CIL_MACRO) {
|
||||
- args->macro = ast_current;
|
||||
- }
|
||||
-
|
||||
- if (ast_current->flavor == CIL_BOOLEANIF) {
|
||||
- args->boolif = ast_current;
|
||||
- }
|
||||
-
|
||||
if (ast_current->flavor == CIL_TUNABLEIF) {
|
||||
args->tunif = ast_current;
|
||||
}
|
||||
@@ -6457,6 +6449,14 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f
|
||||
args->in = ast_current;
|
||||
}
|
||||
|
||||
+ if (ast_current->flavor == CIL_MACRO) {
|
||||
+ args->macro = ast_current;
|
||||
+ }
|
||||
+
|
||||
+ if (ast_current->flavor == CIL_BOOLEANIF) {
|
||||
+ args->boolif = ast_current;
|
||||
+ }
|
||||
+
|
||||
ast_current->cl_head = ast_node;
|
||||
} else {
|
||||
ast_current->cl_tail->next = ast_node;
|
||||
@@ -6492,14 +6492,6 @@ int __cil_build_ast_last_child_helper(struct cil_tree_node *parse_current, void
|
||||
|
||||
args->ast = ast->parent;
|
||||
|
||||
- if (ast->flavor == CIL_MACRO) {
|
||||
- args->macro = NULL;
|
||||
- }
|
||||
-
|
||||
- if (ast->flavor == CIL_BOOLEANIF) {
|
||||
- args->boolif = NULL;
|
||||
- }
|
||||
-
|
||||
if (ast->flavor == CIL_TUNABLEIF) {
|
||||
args->tunif = NULL;
|
||||
}
|
||||
@@ -6508,6 +6500,14 @@ int __cil_build_ast_last_child_helper(struct cil_tree_node *parse_current, void
|
||||
args->in = NULL;
|
||||
}
|
||||
|
||||
+ if (ast->flavor == CIL_MACRO) {
|
||||
+ args->macro = NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (ast->flavor == CIL_BOOLEANIF) {
|
||||
+ args->boolif = NULL;
|
||||
+ }
|
||||
+
|
||||
// At this point we no longer have any need for parse_current or any of its
|
||||
// siblings; they have all been converted to the appropriate AST node. The
|
||||
// full parse tree will get deleted elsewhere, but in an attempt to
|
||||
@@ -6532,10 +6532,10 @@ int cil_build_ast(struct cil_db *db, struct cil_tree_node *parse_tree, struct ci
|
||||
|
||||
extra_args.ast = ast;
|
||||
extra_args.db = db;
|
||||
- extra_args.macro = NULL;
|
||||
- extra_args.boolif = NULL;
|
||||
extra_args.tunif = NULL;
|
||||
extra_args.in = NULL;
|
||||
+ extra_args.macro = NULL;
|
||||
+ extra_args.boolif = NULL;
|
||||
|
||||
rc = cil_tree_walk(parse_tree, __cil_build_ast_node_helper, NULL, __cil_build_ast_last_child_helper, &extra_args);
|
||||
if (rc != SEPOL_OK) {
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,91 +0,0 @@
|
||||
From f043078f1debeb1c84d4f6943aa689c33dd9cefc Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Tue, 30 Mar 2021 13:39:13 -0400
|
||||
Subject: [PATCH] libsepol/cil: Cleanup build AST helper functions
|
||||
|
||||
Since parse_current, finished, and extra_args can never be NULL,
|
||||
remove the useless check and directly assign local variables from
|
||||
extra_args.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_build_ast.c | 44 ++++++++------------------------
|
||||
1 file changed, 10 insertions(+), 34 deletions(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
|
||||
index eee21086bba8..0d6d91a7dc34 100644
|
||||
--- a/libsepol/cil/src/cil_build_ast.c
|
||||
+++ b/libsepol/cil/src/cil_build_ast.c
|
||||
@@ -6065,28 +6065,16 @@ void cil_destroy_src_info(struct cil_src_info *info)
|
||||
|
||||
int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *finished, void *extra_args)
|
||||
{
|
||||
- struct cil_args_build *args = NULL;
|
||||
- struct cil_tree_node *ast_current = NULL;
|
||||
- struct cil_db *db = NULL;
|
||||
+ struct cil_args_build *args = extra_args;
|
||||
+ struct cil_db *db = args->db;
|
||||
+ struct cil_tree_node *ast_current = args->ast;
|
||||
+ struct cil_tree_node *tunif = args->tunif;
|
||||
+ struct cil_tree_node *in = args->in;
|
||||
+ struct cil_tree_node *macro = args->macro;
|
||||
+ struct cil_tree_node *boolif = args->boolif;
|
||||
struct cil_tree_node *ast_node = NULL;
|
||||
- struct cil_tree_node *tunif = NULL;
|
||||
- struct cil_tree_node *in = NULL;
|
||||
- struct cil_tree_node *macro = NULL;
|
||||
- struct cil_tree_node *boolif = NULL;
|
||||
int rc = SEPOL_ERR;
|
||||
|
||||
- if (parse_current == NULL || finished == NULL || extra_args == NULL) {
|
||||
- goto exit;
|
||||
- }
|
||||
-
|
||||
- args = extra_args;
|
||||
- ast_current = args->ast;
|
||||
- db = args->db;
|
||||
- tunif = args->tunif;
|
||||
- in = args->in;
|
||||
- macro = args->macro;
|
||||
- boolif = args->boolif;
|
||||
-
|
||||
if (parse_current->parent->cl_head != parse_current) {
|
||||
/* ignore anything that isn't following a parenthesis */
|
||||
rc = SEPOL_OK;
|
||||
@@ -6474,20 +6462,11 @@ exit:
|
||||
|
||||
int __cil_build_ast_last_child_helper(struct cil_tree_node *parse_current, void *extra_args)
|
||||
{
|
||||
- int rc = SEPOL_ERR;
|
||||
- struct cil_tree_node *ast = NULL;
|
||||
- struct cil_args_build *args = NULL;
|
||||
-
|
||||
- if (extra_args == NULL) {
|
||||
- goto exit;
|
||||
- }
|
||||
-
|
||||
- args = extra_args;
|
||||
- ast = args->ast;
|
||||
+ struct cil_args_build *args = extra_args;
|
||||
+ struct cil_tree_node *ast = args->ast;
|
||||
|
||||
if (ast->flavor == CIL_ROOT) {
|
||||
- rc = SEPOL_OK;
|
||||
- goto exit;
|
||||
+ return SEPOL_OK;
|
||||
}
|
||||
|
||||
args->ast = ast->parent;
|
||||
@@ -6516,9 +6495,6 @@ int __cil_build_ast_last_child_helper(struct cil_tree_node *parse_current, void
|
||||
cil_tree_children_destroy(parse_current->parent);
|
||||
|
||||
return SEPOL_OK;
|
||||
-
|
||||
-exit:
|
||||
- return rc;
|
||||
}
|
||||
|
||||
int cil_build_ast(struct cil_db *db, struct cil_tree_node *parse_tree, struct cil_tree_node *ast)
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,98 +0,0 @@
|
||||
From ab90cb46abd4cfc5927f48c7b61782aa97e2561f Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Tue, 30 Mar 2021 13:39:14 -0400
|
||||
Subject: [PATCH] libsepol/cil: Create new first child helper function for
|
||||
building AST
|
||||
|
||||
In order to find statements not allowed in tunableifs, in-statements,
|
||||
macros, and booleanifs, there are tree node pointers that point to
|
||||
each of these kinds of statements when its block is being parsed.
|
||||
If the pointer is non-NULL, then the rule being parsed is in the block
|
||||
of that kind of statement.
|
||||
|
||||
The tree node pointers were being updated at the wrong point which
|
||||
prevented an invalid statement from being found if it was the first
|
||||
statement in the block of a tunableif, in-statement, macro, or
|
||||
booleanif.
|
||||
|
||||
Create a first child helper function for walking the parse tree and
|
||||
in that function set the appropriate tree node pointer if the
|
||||
current AST node is a tunableif, in-statement, macro, or booleanif.
|
||||
This also makes the code symmetrical with the last child helper
|
||||
where the tree node pointers are set to NULL.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_build_ast.c | 42 +++++++++++++++++++-------------
|
||||
1 file changed, 25 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
|
||||
index 0d6d91a7dc34..9836f044553c 100644
|
||||
--- a/libsepol/cil/src/cil_build_ast.c
|
||||
+++ b/libsepol/cil/src/cil_build_ast.c
|
||||
@@ -6429,22 +6429,6 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f
|
||||
|
||||
if (rc == SEPOL_OK) {
|
||||
if (ast_current->cl_head == NULL) {
|
||||
- if (ast_current->flavor == CIL_TUNABLEIF) {
|
||||
- args->tunif = ast_current;
|
||||
- }
|
||||
-
|
||||
- if (ast_current->flavor == CIL_IN) {
|
||||
- args->in = ast_current;
|
||||
- }
|
||||
-
|
||||
- if (ast_current->flavor == CIL_MACRO) {
|
||||
- args->macro = ast_current;
|
||||
- }
|
||||
-
|
||||
- if (ast_current->flavor == CIL_BOOLEANIF) {
|
||||
- args->boolif = ast_current;
|
||||
- }
|
||||
-
|
||||
ast_current->cl_head = ast_node;
|
||||
} else {
|
||||
ast_current->cl_tail->next = ast_node;
|
||||
@@ -6460,6 +6444,30 @@ exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
+int __cil_build_ast_first_child_helper(__attribute__((unused)) struct cil_tree_node *parse_current, void *extra_args)
|
||||
+{
|
||||
+ struct cil_args_build *args = extra_args;
|
||||
+ struct cil_tree_node *ast = args->ast;
|
||||
+
|
||||
+ if (ast->flavor == CIL_TUNABLEIF) {
|
||||
+ args->tunif = ast;
|
||||
+ }
|
||||
+
|
||||
+ if (ast->flavor == CIL_IN) {
|
||||
+ args->in = ast;
|
||||
+ }
|
||||
+
|
||||
+ if (ast->flavor == CIL_MACRO) {
|
||||
+ args->macro = ast;
|
||||
+ }
|
||||
+
|
||||
+ if (ast->flavor == CIL_BOOLEANIF) {
|
||||
+ args->boolif = ast;
|
||||
+ }
|
||||
+
|
||||
+ return SEPOL_OK;
|
||||
+}
|
||||
+
|
||||
int __cil_build_ast_last_child_helper(struct cil_tree_node *parse_current, void *extra_args)
|
||||
{
|
||||
struct cil_args_build *args = extra_args;
|
||||
@@ -6513,7 +6521,7 @@ int cil_build_ast(struct cil_db *db, struct cil_tree_node *parse_tree, struct ci
|
||||
extra_args.macro = NULL;
|
||||
extra_args.boolif = NULL;
|
||||
|
||||
- rc = cil_tree_walk(parse_tree, __cil_build_ast_node_helper, NULL, __cil_build_ast_last_child_helper, &extra_args);
|
||||
+ rc = cil_tree_walk(parse_tree, __cil_build_ast_node_helper, __cil_build_ast_first_child_helper, __cil_build_ast_last_child_helper, &extra_args);
|
||||
if (rc != SEPOL_OK) {
|
||||
goto exit;
|
||||
}
|
||||
--
|
||||
2.32.0
|
||||
|
@ -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 63beed9230b9..a61462d0eb31 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);
|
||||
--
|
||||
2.32.0
|
||||
|
@ -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 a61462d0eb31..93fc0d633cc7 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;
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,86 +0,0 @@
|
||||
From 8a74c05b97050bd226d61fc162e04dcdf8e91247 Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Tue, 30 Mar 2021 13:39:17 -0400
|
||||
Subject: [PATCH] libsepol/cil: Sync checks for invalid rules in booleanifs
|
||||
|
||||
When building the AST, typemember rules in a booleanif block will
|
||||
be incorrectly called invalid. They are allowed in the kernel
|
||||
policy and should be allowed in CIL.
|
||||
|
||||
When resolving the AST, if a neverallow rule is copied into a
|
||||
booleanif block, it will not be considered an invalid rule, even
|
||||
though this is not allowed in the kernel policy.
|
||||
|
||||
Update the booleanif checks to allow typemember rules and to not
|
||||
allow neverallow rules in booleanifs. Also use the same form of
|
||||
conditional for the checks when building and resolving the AST.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_build_ast.c | 3 ++-
|
||||
libsepol/cil/src/cil_resolve_ast.c | 23 +++++++++++++++--------
|
||||
2 files changed, 17 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
|
||||
index 9836f044553c..96c944975def 100644
|
||||
--- a/libsepol/cil/src/cil_build_ast.c
|
||||
+++ b/libsepol/cil/src/cil_build_ast.c
|
||||
@@ -6130,7 +6130,8 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f
|
||||
parse_current->data != CIL_KEY_DONTAUDIT &&
|
||||
parse_current->data != CIL_KEY_AUDITALLOW &&
|
||||
parse_current->data != CIL_KEY_TYPETRANSITION &&
|
||||
- parse_current->data != CIL_KEY_TYPECHANGE) {
|
||||
+ parse_current->data != CIL_KEY_TYPECHANGE &&
|
||||
+ parse_current->data != CIL_KEY_TYPEMEMBER) {
|
||||
rc = SEPOL_ERR;
|
||||
cil_tree_log(parse_current, CIL_ERR, "Found %s", (char*)parse_current->data);
|
||||
if (((struct cil_booleanif*)boolif->data)->preserved_tunable) {
|
||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
||||
index 93fc0d633cc7..56295a047ba2 100644
|
||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
||||
@@ -3774,7 +3774,7 @@ exit:
|
||||
|
||||
int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args)
|
||||
{
|
||||
- int rc = SEPOL_ERR;
|
||||
+ int rc = SEPOL_OK;
|
||||
struct cil_args_resolve *args = extra_args;
|
||||
enum cil_pass pass = args->pass;
|
||||
struct cil_tree_node *block = args->block;
|
||||
@@ -3817,18 +3817,25 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished
|
||||
}
|
||||
|
||||
if (boolif != NULL) {
|
||||
- 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 (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) {
|
||||
+ rc = SEPOL_ERR;
|
||||
+ } else if (node->flavor == CIL_AVRULE) {
|
||||
+ struct cil_avrule *rule = node->data;
|
||||
+ if (rule->rule_kind == CIL_AVRULE_NEVERALLOW) {
|
||||
+ rc = SEPOL_ERR;
|
||||
+ }
|
||||
+ }
|
||||
+ if (rc == SEPOL_ERR) {
|
||||
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 {
|
||||
cil_tree_log(node, CIL_ERR, "%s statement is not allowed in booleanifs", cil_node_to_string(node));
|
||||
}
|
||||
- rc = SEPOL_ERR;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,151 +0,0 @@
|
||||
From 340f0eb7f3673e8aacaf0a96cbfcd4d12a405521 Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Tue, 30 Mar 2021 13:39:18 -0400
|
||||
Subject: [PATCH] libsepol/cil: Check for statements not allowed in optional
|
||||
blocks
|
||||
|
||||
While there are some checks for invalid statements in an optional
|
||||
block when resolving the AST, there are no checks when building the
|
||||
AST.
|
||||
|
||||
OSS-Fuzz found the following policy which caused a null dereference
|
||||
in cil_tree_get_next_path().
|
||||
(blockinherit b3)
|
||||
(sid SID)
|
||||
(sidorder(SID))
|
||||
(optional o
|
||||
(ibpkeycon :(1 0)s)
|
||||
(block b3
|
||||
(filecon""block())
|
||||
(filecon""block())))
|
||||
|
||||
The problem is that the blockinherit copies block b3 before
|
||||
the optional block is disabled. When the optional is disabled,
|
||||
block b3 is deleted along with everything else in the optional.
|
||||
Later, when filecon statements with the same path are found an
|
||||
error message is produced and in trying to find out where the block
|
||||
was copied from, the reference to the deleted block is used. The
|
||||
error handling code assumes (rightly) that if something was copied
|
||||
from a block then that block should still exist.
|
||||
|
||||
It is clear that in-statements, blocks, and macros cannot be in an
|
||||
optional, because that allows nodes to be copied from the optional
|
||||
block to somewhere outside even though the optional could be disabled
|
||||
later. When optionals are disabled the AST is reset and the
|
||||
resolution is restarted at the point of resolving macro calls, so
|
||||
anything resolved before macro calls will never be re-resolved.
|
||||
This includes tunableifs, in-statements, blockinherits,
|
||||
blockabstracts, and macro definitions. Tunable declarations also
|
||||
cannot be in an optional block because they are needed to resolve
|
||||
tunableifs. It should be fine to allow blockinherit statements in
|
||||
an optional, because that is copying nodes from outside the optional
|
||||
to the optional and if the optional is later disabled, everything
|
||||
will be deleted anyway.
|
||||
|
||||
Check and quit with an error if a tunable declaration, in-statement,
|
||||
block, blockabstract, or macro definition is found within an
|
||||
optional when either building or resolving the AST.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_build_ast.c | 32 ++++++++++++++++++++++++++++++
|
||||
libsepol/cil/src/cil_resolve_ast.c | 4 +++-
|
||||
2 files changed, 35 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
|
||||
index 96c944975def..8825485855f6 100644
|
||||
--- a/libsepol/cil/src/cil_build_ast.c
|
||||
+++ b/libsepol/cil/src/cil_build_ast.c
|
||||
@@ -52,6 +52,7 @@ struct cil_args_build {
|
||||
struct cil_tree_node *tunif;
|
||||
struct cil_tree_node *in;
|
||||
struct cil_tree_node *macro;
|
||||
+ struct cil_tree_node *optional;
|
||||
struct cil_tree_node *boolif;
|
||||
};
|
||||
|
||||
@@ -6071,6 +6072,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f
|
||||
struct cil_tree_node *tunif = args->tunif;
|
||||
struct cil_tree_node *in = args->in;
|
||||
struct cil_tree_node *macro = args->macro;
|
||||
+ struct cil_tree_node *optional = args->optional;
|
||||
struct cil_tree_node *boolif = args->boolif;
|
||||
struct cil_tree_node *ast_node = NULL;
|
||||
int rc = SEPOL_ERR;
|
||||
@@ -6121,6 +6123,18 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f
|
||||
}
|
||||
}
|
||||
|
||||
+ if (optional != NULL) {
|
||||
+ if (parse_current->data == CIL_KEY_TUNABLE ||
|
||||
+ parse_current->data == CIL_KEY_IN ||
|
||||
+ parse_current->data == CIL_KEY_BLOCK ||
|
||||
+ parse_current->data == CIL_KEY_BLOCKABSTRACT ||
|
||||
+ parse_current->data == CIL_KEY_MACRO) {
|
||||
+ rc = SEPOL_ERR;
|
||||
+ cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in optionals", (char *)parse_current->data);
|
||||
+ goto exit;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (boolif != NULL) {
|
||||
if (parse_current->data != CIL_KEY_TUNABLEIF &&
|
||||
parse_current->data != CIL_KEY_CALL &&
|
||||
@@ -6462,6 +6476,10 @@ int __cil_build_ast_first_child_helper(__attribute__((unused)) struct cil_tree_n
|
||||
args->macro = ast;
|
||||
}
|
||||
|
||||
+ if (ast->flavor == CIL_OPTIONAL) {
|
||||
+ args->optional = ast;
|
||||
+ }
|
||||
+
|
||||
if (ast->flavor == CIL_BOOLEANIF) {
|
||||
args->boolif = ast;
|
||||
}
|
||||
@@ -6492,6 +6510,19 @@ int __cil_build_ast_last_child_helper(struct cil_tree_node *parse_current, void
|
||||
args->macro = NULL;
|
||||
}
|
||||
|
||||
+ if (ast->flavor == CIL_OPTIONAL) {
|
||||
+ struct cil_tree_node *n = ast->parent;
|
||||
+ args->optional = NULL;
|
||||
+ /* Optionals can be nested */
|
||||
+ while (n && n->flavor != CIL_ROOT) {
|
||||
+ if (n->flavor == CIL_OPTIONAL) {
|
||||
+ args->optional = n;
|
||||
+ break;
|
||||
+ }
|
||||
+ n = n->parent;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (ast->flavor == CIL_BOOLEANIF) {
|
||||
args->boolif = NULL;
|
||||
}
|
||||
@@ -6520,6 +6551,7 @@ int cil_build_ast(struct cil_db *db, struct cil_tree_node *parse_tree, struct ci
|
||||
extra_args.tunif = NULL;
|
||||
extra_args.in = NULL;
|
||||
extra_args.macro = NULL;
|
||||
+ extra_args.optional = NULL;
|
||||
extra_args.boolif = NULL;
|
||||
|
||||
rc = cil_tree_walk(parse_tree, __cil_build_ast_node_helper, __cil_build_ast_first_child_helper, __cil_build_ast_last_child_helper, &extra_args);
|
||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
||||
index 56295a047ba2..efff0f2ec49d 100644
|
||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
||||
@@ -3808,8 +3808,10 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished
|
||||
|
||||
if (optional != NULL) {
|
||||
if (node->flavor == CIL_TUNABLE ||
|
||||
+ node->flavor == CIL_IN ||
|
||||
+ node->flavor == CIL_BLOCK ||
|
||||
+ node->flavor == CIL_BLOCKABSTRACT ||
|
||||
node->flavor == CIL_MACRO) {
|
||||
- /* tuanbles and macros are not allowed in optionals*/
|
||||
cil_tree_log(node, CIL_ERR, "%s statement is not allowed in optionals", cil_node_to_string(node));
|
||||
rc = SEPOL_ERR;
|
||||
goto exit;
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,35 +0,0 @@
|
||||
From f38b7ea300e83d4b14d817c35f4ff24071e4990e Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Tue, 30 Mar 2021 13:39:19 -0400
|
||||
Subject: [PATCH] libsepol/cil: Sync checks for invalid rules in macros
|
||||
|
||||
When resolving the AST, tunable and in-statements are not considered
|
||||
to be invalid in macros. This is inconsistent with the checks when
|
||||
building the AST.
|
||||
|
||||
Add checks to make tunable and in-statments invalid in macros when
|
||||
resolving the AST.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_resolve_ast.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
||||
index efff0f2ec49d..7229a3b4e990 100644
|
||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
||||
@@ -3796,7 +3796,9 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished
|
||||
}
|
||||
|
||||
if (macro != NULL) {
|
||||
- if (node->flavor == CIL_BLOCK ||
|
||||
+ if (node->flavor == CIL_TUNABLE ||
|
||||
+ node->flavor == CIL_IN ||
|
||||
+ node->flavor == CIL_BLOCK ||
|
||||
node->flavor == CIL_BLOCKINHERIT ||
|
||||
node->flavor == CIL_BLOCKABSTRACT ||
|
||||
node->flavor == CIL_MACRO) {
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,35 +0,0 @@
|
||||
From ea34dbf041f0c75f2b0261ddf6fa014121d69a1a Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Tue, 30 Mar 2021 13:39:20 -0400
|
||||
Subject: [PATCH] libsepol/cil: Do not allow tunable declarations in
|
||||
in-statements
|
||||
|
||||
Since tunableifs are resolved before in-statements, do not allow
|
||||
tuanble declarations in in-statements.
|
||||
|
||||
Since in-statements are the first flavor of statement that causes
|
||||
part of the AST to be copied to another part, there is no need to
|
||||
check the in-statements when resolving the AST.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_build_ast.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
|
||||
index 8825485855f6..3f83c228fec1 100644
|
||||
--- a/libsepol/cil/src/cil_build_ast.c
|
||||
+++ b/libsepol/cil/src/cil_build_ast.c
|
||||
@@ -6102,7 +6102,8 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f
|
||||
}
|
||||
|
||||
if (in != NULL) {
|
||||
- if (parse_current->data == CIL_KEY_IN) {
|
||||
+ if (parse_current->data == CIL_KEY_TUNABLE ||
|
||||
+ parse_current->data == CIL_KEY_IN) {
|
||||
rc = SEPOL_ERR;
|
||||
cil_tree_log(parse_current, CIL_ERR, "Found in-statement");
|
||||
cil_log(CIL_ERR, "in-statements cannot be defined within in-statements\n");
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,120 +0,0 @@
|
||||
From ca339eb49da6fe5b191de5c3ee7196453fa14e23 Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Tue, 30 Mar 2021 13:40:01 -0400
|
||||
Subject: [PATCH] libsepol/cil: Make invalid statement error messages
|
||||
consistent
|
||||
|
||||
Use a consistent style for the error messages when an invalid
|
||||
statement is found within tunableif, in-statement, block, macro,
|
||||
optional, and booleanif blocks.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_build_ast.c | 17 ++++++-----------
|
||||
libsepol/cil/src/cil_resolve_ast.c | 10 +++++-----
|
||||
2 files changed, 11 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
|
||||
index 3f83c228fec1..5b1e28246b2e 100644
|
||||
--- a/libsepol/cil/src/cil_build_ast.c
|
||||
+++ b/libsepol/cil/src/cil_build_ast.c
|
||||
@@ -6095,8 +6095,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f
|
||||
if (tunif != NULL) {
|
||||
if (parse_current->data == CIL_KEY_TUNABLE) {
|
||||
rc = SEPOL_ERR;
|
||||
- cil_tree_log(parse_current, CIL_ERR, "Found tunable");
|
||||
- cil_log(CIL_ERR, "Tunables cannot be defined within tunableif statement\n");
|
||||
+ cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in tunableif", (char *)parse_current->data);
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
@@ -6105,8 +6104,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f
|
||||
if (parse_current->data == CIL_KEY_TUNABLE ||
|
||||
parse_current->data == CIL_KEY_IN) {
|
||||
rc = SEPOL_ERR;
|
||||
- cil_tree_log(parse_current, CIL_ERR, "Found in-statement");
|
||||
- cil_log(CIL_ERR, "in-statements cannot be defined within in-statements\n");
|
||||
+ cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in in-statement", (char *)parse_current->data);
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
@@ -6119,7 +6117,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f
|
||||
parse_current->data == CIL_KEY_BLOCKABSTRACT ||
|
||||
parse_current->data == CIL_KEY_MACRO) {
|
||||
rc = SEPOL_ERR;
|
||||
- cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in macros", (char *)parse_current->data);
|
||||
+ cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in macro", (char *)parse_current->data);
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
@@ -6131,7 +6129,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f
|
||||
parse_current->data == CIL_KEY_BLOCKABSTRACT ||
|
||||
parse_current->data == CIL_KEY_MACRO) {
|
||||
rc = SEPOL_ERR;
|
||||
- cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in optionals", (char *)parse_current->data);
|
||||
+ cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in optional", (char *)parse_current->data);
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
@@ -6148,13 +6146,10 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f
|
||||
parse_current->data != CIL_KEY_TYPECHANGE &&
|
||||
parse_current->data != CIL_KEY_TYPEMEMBER) {
|
||||
rc = SEPOL_ERR;
|
||||
- cil_tree_log(parse_current, CIL_ERR, "Found %s", (char*)parse_current->data);
|
||||
if (((struct cil_booleanif*)boolif->data)->preserved_tunable) {
|
||||
- cil_log(CIL_ERR, "%s cannot be defined within tunableif statement (treated as a booleanif due to preserve-tunables)\n",
|
||||
- (char*)parse_current->data);
|
||||
+ cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in tunableif being treated as a booleanif", (char *)parse_current->data);
|
||||
} else {
|
||||
- cil_log(CIL_ERR, "%s cannot be defined within booleanif statement\n",
|
||||
- (char*)parse_current->data);
|
||||
+ cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in booleanif", (char *)parse_current->data);
|
||||
}
|
||||
goto exit;
|
||||
}
|
||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
||||
index 7229a3b4e990..872b6799b0bf 100644
|
||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
||||
@@ -3789,7 +3789,7 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished
|
||||
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));
|
||||
+ cil_tree_log(node, CIL_ERR, "%s is not allowed in block", cil_node_to_string(node));
|
||||
rc = SEPOL_ERR;
|
||||
goto exit;
|
||||
}
|
||||
@@ -3802,7 +3802,7 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished
|
||||
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));
|
||||
+ cil_tree_log(node, CIL_ERR, "%s is not allowed in macro", cil_node_to_string(node));
|
||||
rc = SEPOL_ERR;
|
||||
goto exit;
|
||||
}
|
||||
@@ -3814,7 +3814,7 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished
|
||||
node->flavor == CIL_BLOCK ||
|
||||
node->flavor == CIL_BLOCKABSTRACT ||
|
||||
node->flavor == CIL_MACRO) {
|
||||
- cil_tree_log(node, CIL_ERR, "%s statement is not allowed in optionals", cil_node_to_string(node));
|
||||
+ cil_tree_log(node, CIL_ERR, "%s is not allowed in optional", cil_node_to_string(node));
|
||||
rc = SEPOL_ERR;
|
||||
goto exit;
|
||||
}
|
||||
@@ -3836,9 +3836,9 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished
|
||||
}
|
||||
if (rc == SEPOL_ERR) {
|
||||
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));
|
||||
+ cil_tree_log(node, CIL_ERR, "%s is not allowed in tunableif being treated as a booleanif", cil_node_to_string(node));
|
||||
} else {
|
||||
- cil_tree_log(node, CIL_ERR, "%s statement is not allowed in booleanifs", cil_node_to_string(node));
|
||||
+ cil_tree_log(node, CIL_ERR, "%s is not allowed in booleanif", cil_node_to_string(node));
|
||||
}
|
||||
goto exit;
|
||||
}
|
||||
--
|
||||
2.32.0
|
||||
|
@ -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 99c8e288912c..b971922c70b5 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;
|
||||
}
|
||||
|
||||
--
|
||||
2.32.0
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,158 +0,0 @@
|
||||
From 86ec04cfded8b2a76953ca2682d2a32bf6b24721 Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Wed, 21 Apr 2021 13:21:11 -0400
|
||||
Subject: [PATCH] libsepol/cil: Add functions to make use of cil_write_ast()
|
||||
|
||||
Add the functions cil_write_parse_ast(), cil_write_build_ast(),
|
||||
and cil_write_resolve_ast() that can be used outside of libsepol.
|
||||
|
||||
These functions take a FILE pointer and CIL db, do the CIL build
|
||||
through the desired phase, and then call cil_write_ast() to write
|
||||
the CIL AST at that point.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/include/cil/cil.h | 3 ++
|
||||
libsepol/cil/src/cil.c | 92 ++++++++++++++++++++++++++++++++++
|
||||
libsepol/src/libsepol.map.in | 3 ++
|
||||
3 files changed, 98 insertions(+)
|
||||
|
||||
diff --git a/libsepol/cil/include/cil/cil.h b/libsepol/cil/include/cil/cil.h
|
||||
index e6f4503eb33a..92fac6e1619a 100644
|
||||
--- a/libsepol/cil/include/cil/cil.h
|
||||
+++ b/libsepol/cil/include/cil/cil.h
|
||||
@@ -60,6 +60,9 @@ extern void cil_set_attrs_expand_size(struct cil_db *db, unsigned attrs_expand_s
|
||||
extern void cil_set_target_platform(cil_db_t *db, int target_platform);
|
||||
extern void cil_set_policy_version(cil_db_t *db, int policy_version);
|
||||
extern void cil_write_policy_conf(FILE *out, struct cil_db *db);
|
||||
+extern int cil_write_parse_ast(FILE *out, cil_db_t *db);
|
||||
+extern int cil_write_build_ast(FILE *out, cil_db_t *db);
|
||||
+extern int cil_write_resolve_ast(FILE *out, cil_db_t *db);
|
||||
|
||||
enum cil_log_level {
|
||||
CIL_ERR = 1,
|
||||
diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c
|
||||
index b971922c70b5..0d351b491c2c 100644
|
||||
--- a/libsepol/cil/src/cil.c
|
||||
+++ b/libsepol/cil/src/cil.c
|
||||
@@ -50,6 +50,7 @@
|
||||
#include "cil_binary.h"
|
||||
#include "cil_policy.h"
|
||||
#include "cil_strpool.h"
|
||||
+#include "cil_write_ast.h"
|
||||
|
||||
int cil_sym_sizes[CIL_SYM_ARRAY_NUM][CIL_SYM_NUM] = {
|
||||
{64, 64, 64, 1 << 13, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64},
|
||||
@@ -572,6 +573,97 @@ exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
+int cil_write_parse_ast(FILE *out, cil_db_t *db)
|
||||
+{
|
||||
+ int rc = SEPOL_ERR;
|
||||
+
|
||||
+ if (db == NULL) {
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ cil_log(CIL_INFO, "Writing Parse AST\n");
|
||||
+ rc = cil_write_ast(out, CIL_WRITE_AST_PHASE_PARSE, db->parse->root);
|
||||
+ if (rc != SEPOL_OK) {
|
||||
+ cil_log(CIL_ERR, "Failed to write parse ast\n");
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+exit:
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+int cil_write_build_ast(FILE *out, cil_db_t *db)
|
||||
+{
|
||||
+ int rc = SEPOL_ERR;
|
||||
+
|
||||
+ if (db == NULL) {
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ 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_ERR, "Failed to build ast\n");
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ cil_log(CIL_INFO, "Destroying Parse Tree\n");
|
||||
+ cil_tree_destroy(&db->parse);
|
||||
+
|
||||
+ cil_log(CIL_INFO, "Writing Build AST\n");
|
||||
+ rc = cil_write_ast(out, CIL_WRITE_AST_PHASE_BUILD, db->ast->root);
|
||||
+ if (rc != SEPOL_OK) {
|
||||
+ cil_log(CIL_ERR, "Failed to write build ast\n");
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+exit:
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+int cil_write_resolve_ast(FILE *out, cil_db_t *db)
|
||||
+{
|
||||
+ int rc = SEPOL_ERR;
|
||||
+
|
||||
+ if (db == NULL) {
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ 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_ERR, "Failed to build ast\n");
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ cil_log(CIL_INFO, "Destroying Parse Tree\n");
|
||||
+ cil_tree_destroy(&db->parse);
|
||||
+
|
||||
+ cil_log(CIL_INFO, "Resolving AST\n");
|
||||
+ rc = cil_resolve_ast(db, db->ast->root);
|
||||
+ if (rc != SEPOL_OK) {
|
||||
+ 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_ERR, "Failed to qualify names\n");
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ cil_log(CIL_INFO, "Writing Resolve AST\n");
|
||||
+ rc = cil_write_ast(out, CIL_WRITE_AST_PHASE_RESOLVE, db->ast->root);
|
||||
+ if (rc != SEPOL_OK) {
|
||||
+ cil_log(CIL_ERR, "Failed to write resolve ast\n");
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+exit:
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
int cil_build_policydb(cil_db_t *db, sepol_policydb_t **sepol_db)
|
||||
{
|
||||
int rc;
|
||||
diff --git a/libsepol/src/libsepol.map.in b/libsepol/src/libsepol.map.in
|
||||
index eb5721257638..2e503bd1b453 100644
|
||||
--- a/libsepol/src/libsepol.map.in
|
||||
+++ b/libsepol/src/libsepol.map.in
|
||||
@@ -269,4 +269,7 @@ LIBSEPOL_1.1 {
|
||||
LIBSEPOL_3.0 {
|
||||
global:
|
||||
sepol_policydb_optimize;
|
||||
+ cil_write_parse_ast;
|
||||
+ cil_write_build_ast;
|
||||
+ cil_write_resolve_ast;
|
||||
} LIBSEPOL_1.1;
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,103 +0,0 @@
|
||||
From 0744fa4f533c765d0a704fe8aa7174a0f93eb7bc Mon Sep 17 00:00:00 2001
|
||||
From: Nicolas Iooss <nicolas.iooss@m4x.org>
|
||||
Date: Thu, 22 Apr 2021 08:46:04 +0200
|
||||
Subject: [PATCH] libsepol: use checked arithmetic builtin to perform safe
|
||||
addition
|
||||
|
||||
Checking whether an overflow occurred after adding two values can be
|
||||
achieved using checked arithmetic builtin functions such as:
|
||||
|
||||
bool __builtin_add_overflow(type1 x, type2 y, type3 *sum);
|
||||
|
||||
This function is available at least in clang
|
||||
(at least since clang 3.8.0,
|
||||
https://releases.llvm.org/3.8.0/tools/clang/docs/LanguageExtensions.html#checked-arithmetic-builtins)
|
||||
and gcc
|
||||
(https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html,
|
||||
since gcc 5 according to https://gcc.gnu.org/gcc-5/changes.html)
|
||||
|
||||
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
||||
---
|
||||
libsepol/src/context_record.c | 29 ++++++-----------------------
|
||||
libsepol/src/module_to_cil.c | 6 ++----
|
||||
2 files changed, 8 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/libsepol/src/context_record.c b/libsepol/src/context_record.c
|
||||
index 317a42133884..435f788058c4 100644
|
||||
--- a/libsepol/src/context_record.c
|
||||
+++ b/libsepol/src/context_record.c
|
||||
@@ -267,31 +267,13 @@ int sepol_context_from_string(sepol_handle_t * handle,
|
||||
return STATUS_ERR;
|
||||
}
|
||||
|
||||
-
|
||||
-static inline int safe_sum(size_t *sum, const size_t augends[], const size_t cnt) {
|
||||
-
|
||||
- size_t a, i;
|
||||
-
|
||||
- *sum = 0;
|
||||
- for(i=0; i < cnt; i++) {
|
||||
- /* sum should not be smaller than the addend */
|
||||
- a = augends[i];
|
||||
- *sum += a;
|
||||
- if (*sum < a) {
|
||||
- return i;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
int sepol_context_to_string(sepol_handle_t * handle,
|
||||
const sepol_context_t * con, char **str_ptr)
|
||||
{
|
||||
|
||||
int rc;
|
||||
char *str = NULL;
|
||||
- size_t total_sz, err;
|
||||
+ size_t total_sz = 0, i;
|
||||
const size_t sizes[] = {
|
||||
strlen(con->user), /* user length */
|
||||
strlen(con->role), /* role length */
|
||||
@@ -300,10 +282,11 @@ int sepol_context_to_string(sepol_handle_t * handle,
|
||||
((con->mls) ? 3 : 2) + 1 /* mls has extra ":" also null byte */
|
||||
};
|
||||
|
||||
- err = safe_sum(&total_sz, sizes, ARRAY_SIZE(sizes));
|
||||
- if (err) {
|
||||
- ERR(handle, "invalid size, overflow at position: %zu", err);
|
||||
- goto err;
|
||||
+ for (i = 0; i < ARRAY_SIZE(sizes); i++) {
|
||||
+ if (__builtin_add_overflow(total_sz, sizes[i], &total_sz)) {
|
||||
+ ERR(handle, "invalid size, overflow at position: %zu", i);
|
||||
+ goto err;
|
||||
+ }
|
||||
}
|
||||
|
||||
str = (char *)malloc(total_sz);
|
||||
diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c
|
||||
index 58df0d4f6d77..496693f4616e 100644
|
||||
--- a/libsepol/src/module_to_cil.c
|
||||
+++ b/libsepol/src/module_to_cil.c
|
||||
@@ -1134,16 +1134,14 @@ static int name_list_to_string(char **names, unsigned int num_names, char **stri
|
||||
char *strpos;
|
||||
|
||||
for (i = 0; i < num_names; i++) {
|
||||
- len += strlen(names[i]);
|
||||
- if (len < strlen(names[i])) {
|
||||
+ if (__builtin_add_overflow(len, strlen(names[i]), &len)) {
|
||||
log_err("Overflow");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// add spaces + null terminator
|
||||
- len += num_names;
|
||||
- if (len < (size_t)num_names) {
|
||||
+ if (__builtin_add_overflow(len, (size_t)num_names, &len)) {
|
||||
log_err("Overflow");
|
||||
return -1;
|
||||
}
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,51 +0,0 @@
|
||||
From 2d2c76fc613ba338476a3a1741c2a3af5e04d154 Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Mon, 26 Apr 2021 15:22:05 -0400
|
||||
Subject: [PATCH] libsepol/cil: Properly reset an anonymous classperm set
|
||||
|
||||
In struct cil_classperms_set, the "set" field is a pointer to a
|
||||
struct cil_classpermission. Normally the classpermission is created
|
||||
in a classpermissionset rule with a name declared in a
|
||||
classpermission rule and stored in a symbol table. Commit c49a8ea0
|
||||
("libsepol/cil: cil_reset_classperms_set() should not reset
|
||||
classpermission") fixed the resetting of classperms sets by setting
|
||||
the "set" field to NULL rather than resetting the classpermission
|
||||
that it pointed to.
|
||||
|
||||
But this fix mixed the special case where an anonymous classperm
|
||||
set is passed as an argument to a call. In this case the
|
||||
classpermission is not named and not stored in a symtab, it is
|
||||
created just for the classperms set and its classperms list needs
|
||||
to be reset.
|
||||
|
||||
Reset the classperms list if the classperms set is anonymous (which
|
||||
is when the datum name is NULL).
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_reset_ast.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_reset_ast.c b/libsepol/cil/src/cil_reset_ast.c
|
||||
index 76405aba6194..d24d4f8159a3 100644
|
||||
--- a/libsepol/cil/src/cil_reset_ast.c
|
||||
+++ b/libsepol/cil/src/cil_reset_ast.c
|
||||
@@ -60,10 +60,14 @@ static void cil_reset_classpermission(struct cil_classpermission *cp)
|
||||
|
||||
static void cil_reset_classperms_set(struct cil_classperms_set *cp_set)
|
||||
{
|
||||
- if (cp_set == NULL) {
|
||||
+ if (cp_set == NULL || cp_set->set == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
+ if (cp_set->set->datum.name == NULL) {
|
||||
+ cil_reset_classperms_list(cp_set->set->classperms);
|
||||
+ }
|
||||
+
|
||||
cp_set->set = NULL;
|
||||
}
|
||||
|
||||
--
|
||||
2.32.0
|
||||
|
@ -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 5b1e28246b2e..87043a8fa183 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 872b6799b0bf..5389df43fed7 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;
|
||||
}
|
||||
|
||||
--
|
||||
2.32.0
|
||||
|
@ -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 9bdcbdd013c0..74e0b34d6cbd 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 5389df43fed7..6890964728cb 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;
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,69 +0,0 @@
|
||||
From d438b6cfb3d4b60cd9ced49be817f67902910912 Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Wed, 28 Apr 2021 16:07:03 -0400
|
||||
Subject: [PATCH] libsepol/cil: Check datum in ordered list for expected flavor
|
||||
|
||||
The secilc-fuzzer found an out of bounds memory access occurs
|
||||
when building the binary policy if a map class is included in a
|
||||
classorder statement.
|
||||
|
||||
The order statements in CIL (sidorder, classorder, categoryorder,
|
||||
and sensitivityorder) are used to specify an ordering for sids,
|
||||
classes, categories, and sensitivities. When the order statments
|
||||
are resolved and merged, only in the case of the category order
|
||||
list is the datum resolved checked to see if it is the expected
|
||||
flavor.
|
||||
|
||||
When resolving the sid, class, and sensitivity order statements,
|
||||
check that each name resolved to a datum of the expected flavor
|
||||
and return an error if it does not.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_resolve_ast.c | 16 ++++++++++++++++
|
||||
1 file changed, 16 insertions(+)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
||||
index 6890964728cb..b081d45d4cb5 100644
|
||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
||||
@@ -1488,6 +1488,11 @@ int cil_resolve_classorder(struct cil_tree_node *current, void *extra_args)
|
||||
rc = SEPOL_ERR;
|
||||
goto exit;
|
||||
}
|
||||
+ if (FLAVOR(datum) != CIL_CLASS) {
|
||||
+ cil_log(CIL_ERR, "%s is not a class. Only classes are allowed in classorder statements\n", datum->name);
|
||||
+ rc = SEPOL_ERR;
|
||||
+ goto exit;
|
||||
+ }
|
||||
cil_list_append(new, CIL_CLASS, datum);
|
||||
}
|
||||
|
||||
@@ -1526,6 +1531,12 @@ int cil_resolve_sidorder(struct cil_tree_node *current, void *extra_args)
|
||||
cil_log(CIL_ERR, "Failed to resolve sid %s in sidorder\n", (char *)curr->data);
|
||||
goto exit;
|
||||
}
|
||||
+ if (FLAVOR(datum) != CIL_SID) {
|
||||
+ cil_log(CIL_ERR, "%s is not a sid. Only sids are allowed in sidorder statements\n", datum->name);
|
||||
+ rc = SEPOL_ERR;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
cil_list_append(new, CIL_SID, datum);
|
||||
}
|
||||
|
||||
@@ -1617,6 +1628,11 @@ int cil_resolve_sensitivityorder(struct cil_tree_node *current, void *extra_args
|
||||
cil_log(CIL_ERR, "Failed to resolve sensitivty %s in sensitivityorder\n", (char *)curr->data);
|
||||
goto exit;
|
||||
}
|
||||
+ if (FLAVOR(datum) != CIL_SENS) {
|
||||
+ cil_log(CIL_ERR, "%s is not a sensitivity. Only sensitivities are allowed in sensitivityorder statements\n", datum->name);
|
||||
+ rc = SEPOL_ERR;
|
||||
+ goto exit;
|
||||
+ }
|
||||
cil_list_append(new, CIL_SENS, datum);
|
||||
}
|
||||
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,40 +0,0 @@
|
||||
From d9433692c782b65e5397234950c6d9993fbcaa70 Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Wed, 28 Apr 2021 16:07:09 -0400
|
||||
Subject: [PATCH] libsepol/cil: Return an error if a call argument fails to
|
||||
resolve
|
||||
|
||||
Return an error if a call argument fails to resolve so that
|
||||
the resolution phase stops and returns an error.
|
||||
|
||||
This problem 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 b081d45d4cb5..f251ed1582fc 100644
|
||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
||||
@@ -3277,6 +3277,7 @@ int cil_resolve_call2(struct cil_tree_node *current, void *extra_args)
|
||||
if (sym_index != CIL_SYM_UNKNOWN) {
|
||||
rc = cil_resolve_name(current, arg->arg_str, sym_index, extra_args, &(arg->arg));
|
||||
if (rc != SEPOL_OK) {
|
||||
+ cil_tree_log(current, CIL_ERR, "Failed to resolve %s in call argument list", arg->arg_str);
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
@@ -3308,7 +3309,7 @@ int cil_resolve_name_call_args(struct cil_call *call, char *name, enum cil_sym_i
|
||||
if (param_index == sym_index) {
|
||||
if (name == arg->param_str) {
|
||||
*datum = arg->arg;
|
||||
- rc = SEPOL_OK;
|
||||
+ rc = *datum ? SEPOL_OK : SEPOL_ERR;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,244 +0,0 @@
|
||||
From 61fbdce666f24c4a118b249ece6b014d54b65074 Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Tue, 4 May 2021 16:14:55 -0400
|
||||
Subject: [PATCH] libsepol/cil: Check for self-referential loops in sets
|
||||
|
||||
The secilc-fuzzer found a self-referential loop using category sets.
|
||||
Any set declaration in CIL that allows sets in it is susceptible to
|
||||
the creation of a self-referential loop. There is a check, but only
|
||||
for the name of the set being declared being used in the set
|
||||
declaration.
|
||||
|
||||
Check for self-refential loops in user, role, and type attributes
|
||||
and in category sets. Since all of the sets need to be declared,
|
||||
this check has to be done when verifying the CIL db before doing
|
||||
the post phase.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_resolve_ast.c | 31 +---------
|
||||
libsepol/cil/src/cil_verify.c | 97 +++++++++++++++++++++---------
|
||||
libsepol/cil/src/cil_verify.h | 1 -
|
||||
3 files changed, 71 insertions(+), 58 deletions(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
||||
index f251ed1582fc..5368ae80ede9 100644
|
||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
||||
@@ -438,11 +438,6 @@ int cil_resolve_typeattributeset(struct cil_tree_node *current, void *extra_args
|
||||
goto exit;
|
||||
}
|
||||
|
||||
- rc = cil_verify_no_self_reference(attr_datum, attrtypes->datum_expr);
|
||||
- if (rc != SEPOL_OK) {
|
||||
- goto exit;
|
||||
- }
|
||||
-
|
||||
if (attr->expr_list == NULL) {
|
||||
cil_list_init(&attr->expr_list, CIL_TYPEATTRIBUTE);
|
||||
}
|
||||
@@ -1151,11 +1146,6 @@ int cil_resolve_roleattributeset(struct cil_tree_node *current, void *extra_args
|
||||
goto exit;
|
||||
}
|
||||
|
||||
- rc = cil_verify_no_self_reference(attr_datum, attrroles->datum_expr);
|
||||
- if (rc != SEPOL_OK) {
|
||||
- goto exit;
|
||||
- }
|
||||
-
|
||||
if (attr->expr_list == NULL) {
|
||||
cil_list_init(&attr->expr_list, CIL_ROLEATTRIBUTE);
|
||||
}
|
||||
@@ -1666,21 +1656,7 @@ exit:
|
||||
|
||||
int cil_resolve_catset(struct cil_tree_node *current, struct cil_catset *catset, void *extra_args)
|
||||
{
|
||||
- int rc = SEPOL_ERR;
|
||||
-
|
||||
- rc = cil_resolve_cats(current, catset->cats, extra_args);
|
||||
- if (rc != SEPOL_OK) {
|
||||
- goto exit;
|
||||
- }
|
||||
-
|
||||
- rc = cil_verify_no_self_reference((struct cil_symtab_datum *)catset, catset->cats->datum_expr);
|
||||
- if (rc != SEPOL_OK) {
|
||||
- cil_list_destroy(&catset->cats->datum_expr, CIL_FALSE);
|
||||
- goto exit;
|
||||
- }
|
||||
-
|
||||
-exit:
|
||||
- return rc;
|
||||
+ return cil_resolve_cats(current, catset->cats, extra_args);
|
||||
}
|
||||
|
||||
int cil_resolve_senscat(struct cil_tree_node *current, void *extra_args)
|
||||
@@ -3545,11 +3521,6 @@ int cil_resolve_userattributeset(struct cil_tree_node *current, void *extra_args
|
||||
goto exit;
|
||||
}
|
||||
|
||||
- rc = cil_verify_no_self_reference(attr_datum, attrusers->datum_expr);
|
||||
- if (rc != SEPOL_OK) {
|
||||
- goto exit;
|
||||
- }
|
||||
-
|
||||
if (attr->expr_list == NULL) {
|
||||
cil_list_init(&attr->expr_list, CIL_USERATTRIBUTE);
|
||||
}
|
||||
diff --git a/libsepol/cil/src/cil_verify.c b/libsepol/cil/src/cil_verify.c
|
||||
index 5a37dd2f76bc..8e15a0e68a69 100644
|
||||
--- a/libsepol/cil/src/cil_verify.c
|
||||
+++ b/libsepol/cil/src/cil_verify.c
|
||||
@@ -430,28 +430,71 @@ int cil_verify_decl_does_not_shadow_macro_parameter(struct cil_macro *macro, str
|
||||
return SEPOL_OK;
|
||||
}
|
||||
|
||||
-int cil_verify_no_self_reference(struct cil_symtab_datum *datum, struct cil_list *datum_list)
|
||||
+static int cil_verify_no_self_reference(enum cil_flavor flavor, struct cil_symtab_datum *datum, struct cil_symtab_datum *orig);
|
||||
+
|
||||
+static int __verify_no_self_reference_in_expr(struct cil_list *expr, struct cil_symtab_datum *orig)
|
||||
{
|
||||
- struct cil_list_item *i;
|
||||
+ struct cil_list_item *item;
|
||||
+ int rc = SEPOL_OK;
|
||||
|
||||
- cil_list_for_each(i, datum_list) {
|
||||
- if (i->flavor == CIL_DATUM) {
|
||||
- struct cil_symtab_datum *d = i->data;
|
||||
- if (d == datum) {
|
||||
- cil_log(CIL_ERR,"Self-reference found for %s\n",datum->name);
|
||||
- return SEPOL_ERR;
|
||||
- }
|
||||
- } else if (i->flavor == CIL_LIST) {
|
||||
- int rc = cil_verify_no_self_reference(datum, i->data);
|
||||
- if (rc != SEPOL_OK) {
|
||||
- return SEPOL_ERR;
|
||||
- }
|
||||
+ if (!expr) {
|
||||
+ return SEPOL_OK;
|
||||
+ }
|
||||
+
|
||||
+ cil_list_for_each(item, expr) {
|
||||
+ if (item->flavor == CIL_DATUM) {
|
||||
+ struct cil_symtab_datum* datum = item->data;
|
||||
+ rc = cil_verify_no_self_reference(FLAVOR(datum), datum, orig);
|
||||
+ } else if (item->flavor == CIL_LIST) {
|
||||
+ rc = __verify_no_self_reference_in_expr(item->data, orig);
|
||||
+ }
|
||||
+ if (rc != SEPOL_OK) {
|
||||
+ return SEPOL_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
return SEPOL_OK;
|
||||
}
|
||||
|
||||
+static int cil_verify_no_self_reference(enum cil_flavor flavor, struct cil_symtab_datum *datum, struct cil_symtab_datum *orig)
|
||||
+{
|
||||
+ int rc = SEPOL_OK;
|
||||
+
|
||||
+ if (datum == orig) {
|
||||
+ cil_tree_log(NODE(orig), CIL_ERR, "Self-reference found for %s", orig->name);
|
||||
+ return SEPOL_ERR;
|
||||
+ } else if (orig == NULL) {
|
||||
+ orig = datum;
|
||||
+ }
|
||||
+
|
||||
+ switch (flavor) {
|
||||
+ case CIL_USERATTRIBUTE: {
|
||||
+ struct cil_userattribute *attr = (struct cil_userattribute *)datum;
|
||||
+ rc = __verify_no_self_reference_in_expr(attr->expr_list, orig);
|
||||
+ break;
|
||||
+ }
|
||||
+ case CIL_ROLEATTRIBUTE: {
|
||||
+ struct cil_roleattribute *attr = (struct cil_roleattribute *)datum;
|
||||
+ rc = __verify_no_self_reference_in_expr(attr->expr_list, orig);
|
||||
+ break;
|
||||
+ }
|
||||
+ case CIL_TYPEATTRIBUTE: {
|
||||
+ struct cil_typeattribute *attr = (struct cil_typeattribute *)datum;
|
||||
+ rc = __verify_no_self_reference_in_expr(attr->expr_list, orig);
|
||||
+ break;
|
||||
+ }
|
||||
+ case CIL_CATSET: {
|
||||
+ struct cil_catset *set = (struct cil_catset *)datum;
|
||||
+ rc = __verify_no_self_reference_in_expr(set->cats->datum_expr, orig);
|
||||
+ break;
|
||||
+ }
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
int __cil_verify_ranges(struct cil_list *list)
|
||||
{
|
||||
int rc = SEPOL_ERR;
|
||||
@@ -1757,27 +1800,22 @@ static int __cil_verify_map_class(struct cil_tree_node *node)
|
||||
|
||||
int __cil_pre_verify_helper(struct cil_tree_node *node, uint32_t *finished, __attribute__((unused)) void *extra_args)
|
||||
{
|
||||
- int rc = SEPOL_ERR;
|
||||
+ int rc = SEPOL_OK;
|
||||
|
||||
- if (node->flavor == CIL_MACRO) {
|
||||
+ switch (node->flavor) {
|
||||
+ case CIL_MACRO: {
|
||||
*finished = CIL_TREE_SKIP_HEAD;
|
||||
- rc = SEPOL_OK;
|
||||
- goto exit;
|
||||
- } else if (node->flavor == CIL_BLOCK) {
|
||||
+ break;
|
||||
+ }
|
||||
+ case CIL_BLOCK: {
|
||||
struct cil_block *blk = node->data;
|
||||
if (blk->is_abstract == CIL_TRUE) {
|
||||
*finished = CIL_TREE_SKIP_HEAD;
|
||||
}
|
||||
- rc = SEPOL_OK;
|
||||
- goto exit;
|
||||
+ break;
|
||||
}
|
||||
-
|
||||
- switch (node->flavor) {
|
||||
case CIL_USER:
|
||||
rc = __cil_verify_user_pre_eval(node);
|
||||
- if (rc != SEPOL_OK) {
|
||||
- goto exit;
|
||||
- }
|
||||
break;
|
||||
case CIL_MAP_CLASS:
|
||||
rc = __cil_verify_map_class(node);
|
||||
@@ -1785,11 +1823,16 @@ int __cil_pre_verify_helper(struct cil_tree_node *node, uint32_t *finished, __at
|
||||
case CIL_CLASSPERMISSION:
|
||||
rc = __cil_verify_classpermission(node);
|
||||
break;
|
||||
+ case CIL_USERATTRIBUTE:
|
||||
+ case CIL_ROLEATTRIBUTE:
|
||||
+ case CIL_TYPEATTRIBUTE:
|
||||
+ case CIL_CATSET:
|
||||
+ rc = cil_verify_no_self_reference(node->flavor, node->data, NULL);
|
||||
+ break;
|
||||
default:
|
||||
rc = SEPOL_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
-exit:
|
||||
return rc;
|
||||
}
|
||||
diff --git a/libsepol/cil/src/cil_verify.h b/libsepol/cil/src/cil_verify.h
|
||||
index c497018f8a95..4ea14f5b0a9a 100644
|
||||
--- a/libsepol/cil/src/cil_verify.h
|
||||
+++ b/libsepol/cil/src/cil_verify.h
|
||||
@@ -63,7 +63,6 @@ int cil_verify_constraint_leaf_expr_syntax(enum cil_flavor l_flavor, enum cil_fl
|
||||
int cil_verify_constraint_expr_syntax(struct cil_tree_node *current, enum cil_flavor op);
|
||||
int cil_verify_conditional_blocks(struct cil_tree_node *current);
|
||||
int cil_verify_decl_does_not_shadow_macro_parameter(struct cil_macro *macro, struct cil_tree_node *node, const char *name);
|
||||
-int cil_verify_no_self_reference(struct cil_symtab_datum *datum, struct cil_list *datum_list);
|
||||
int __cil_verify_ranges(struct cil_list *list);
|
||||
int __cil_verify_ordered_node_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args);
|
||||
int __cil_verify_ordered(struct cil_tree_node *current, enum cil_flavor flavor);
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,74 +0,0 @@
|
||||
From 0d6e95cfb24fd0bc5405ecea0b3ebac3462b5312 Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Thu, 6 May 2021 13:05:36 -0400
|
||||
Subject: [PATCH] libsepol/cil: Fix name resolution involving inherited blocks
|
||||
|
||||
When resolving a name in a block that has been inherited. First,
|
||||
a search is done in the parent namespaces (if any) of the
|
||||
blockinherit rule with the exception of the global namespace. If
|
||||
the name is not found, then a search is done in the namespaces of
|
||||
the original block (starting with that block's namespace) with
|
||||
the exception of the global namespace. Finally, if it still has
|
||||
not been found, the global namespace is searched.
|
||||
|
||||
This does not work if a declaration is in the block being
|
||||
inherited.
|
||||
|
||||
For example:
|
||||
(block b
|
||||
(typeattribute a)
|
||||
(allow a self (CLASS (PERM)))
|
||||
)
|
||||
(blockinherit b)
|
||||
|
||||
This will result in a policy with the following identical allow
|
||||
rules:
|
||||
(allow b.a self (CLASS (PERM)))
|
||||
(allow b.a self (CLASS (PERM)))
|
||||
rather than the expected:
|
||||
(allow b.a self (CLASS (PERM)))
|
||||
(allow a self (CLASS (PERM)))
|
||||
This is because when the typeattribute is copied while resolving
|
||||
the inheritance, the new datum is added to the global namespace
|
||||
and, since that is searched last, the typeattribute in block b is
|
||||
found first.
|
||||
|
||||
This behavior means that no declaration that is inherited into the
|
||||
global namespace will actually be used.
|
||||
|
||||
Instead, if the name is not found in the parent namespaces (if any)
|
||||
where the blockinherit is located with the exception of the global
|
||||
namespace, start the next search in the namespace of the parent of
|
||||
the original block (instead of the original block itself). Now if
|
||||
a declaration is inherited from the original block, the new
|
||||
declaration will be used. This behavior seems to be the originally
|
||||
intended behavior because there is a comment in the code that says,
|
||||
"Continue search in original block's parent".
|
||||
|
||||
This issue was found by secilc-fuzzer. If the original block
|
||||
is made to be abstract, then the type attribute declaration
|
||||
in the original block is not in the policy and a segfault
|
||||
occurs when creating the binary because the copied allow rule
|
||||
refers to a non-existent type attribute.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
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 5368ae80ede9..5684b8da0f76 100644
|
||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
||||
@@ -4182,7 +4182,7 @@ static int __cil_resolve_name_with_parents(struct cil_tree_node *node, char *nam
|
||||
rc = __cil_resolve_name_with_parents(node->parent, name, sym_index, datum);
|
||||
if (rc != SEPOL_OK) {
|
||||
/* Continue search in original block's parent */
|
||||
- rc = __cil_resolve_name_with_parents(NODE(inherit->block), name, sym_index, datum);
|
||||
+ rc = __cil_resolve_name_with_parents(NODE(inherit->block)->parent, name, sym_index, datum);
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,75 +0,0 @@
|
||||
From 788d40b0e61f352524660d0965d5e86f6e1e0718 Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Tue, 11 May 2021 09:43:22 -0400
|
||||
Subject: [PATCH] libsepol/cil: Make name resolution in macros work as
|
||||
documented
|
||||
|
||||
The CIL Reference Guide specifies how name resolution is suppose
|
||||
to work within an expanded macro.
|
||||
1. Items defined inside the macro
|
||||
2. Items passed into the macro as arguments
|
||||
3. Items defined in the same namespace of the macro
|
||||
4. Items defined in the caller's namespace
|
||||
5. Items defined in the global namespace
|
||||
|
||||
But Lorenzo Ceragioli <lorenzo.ceragioli@phd.unipi.it> found
|
||||
that the first step is not done.
|
||||
|
||||
So the following policy:
|
||||
(block A
|
||||
(type a)
|
||||
(macro m ()
|
||||
(type a)
|
||||
(allow a self (CLASS (PERM)))
|
||||
)
|
||||
)
|
||||
(block B
|
||||
(call A.m)
|
||||
)
|
||||
will result in:
|
||||
(allow A.a self (CLASS (PERM)))
|
||||
instead of the expected:
|
||||
(allow B.a self (CLASS (PERM)))
|
||||
|
||||
Now when an expanded call is found, the macro's namespace is
|
||||
checked first. If the name is found, then the name was declared
|
||||
in the macro and it is declared in the expanded call, so only the
|
||||
namespace of the call up to and including the global namespace
|
||||
will be searched. If the name is not found in the macro's namespace
|
||||
then name resolution continues with steps 2-5 above.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_resolve_ast.c | 16 ++++++++++++----
|
||||
1 file changed, 12 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
||||
index 5684b8da0f76..ae6743f92f4c 100644
|
||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
||||
@@ -4195,10 +4195,18 @@ static int __cil_resolve_name_with_parents(struct cil_tree_node *node, char *nam
|
||||
break;
|
||||
case CIL_CALL: {
|
||||
struct cil_call *call = node->data;
|
||||
- rc = cil_resolve_name_call_args(call, name, sym_index, datum);
|
||||
- if (rc != SEPOL_OK) {
|
||||
- /* Continue search in macro's parent */
|
||||
- rc = __cil_resolve_name_with_parents(NODE(call->macro)->parent, name, sym_index, datum);
|
||||
+ struct cil_macro *macro = call->macro;
|
||||
+ symtab = ¯o->symtab[sym_index];
|
||||
+ rc = cil_symtab_get_datum(symtab, name, datum);
|
||||
+ if (rc == SEPOL_OK) {
|
||||
+ /* If the name was declared in the macro, just look on the call side */
|
||||
+ rc = SEPOL_ERR;
|
||||
+ } else {
|
||||
+ rc = cil_resolve_name_call_args(call, name, sym_index, datum);
|
||||
+ if (rc != SEPOL_OK) {
|
||||
+ /* Continue search in macro's parent */
|
||||
+ rc = __cil_resolve_name_with_parents(NODE(call->macro)->parent, name, sym_index, datum);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
break;
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,45 +0,0 @@
|
||||
From a1952af7c0346f3cd60a362e43fc90a7d799cffe Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Tue, 11 May 2021 09:43:43 -0400
|
||||
Subject: [PATCH] libsepol/cil: Do not add NULL node when inserting key into
|
||||
symtab
|
||||
|
||||
Allow inserting a key without providing a node.
|
||||
|
||||
This will make it easier to properly resolve call arguments where
|
||||
a key might need to be temporarily removed to search for a datum
|
||||
that is not declared within the call. Since the node is already
|
||||
in the node list, re-inserting the key without this option would
|
||||
add another link to the node and cause problems.
|
||||
|
||||
Also, do not add the node to the datum's node list if the result
|
||||
of the call to hashtab_insert() is SEPOL_EEXIST because the datum
|
||||
is a duplicate and will be destroyed.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_symtab.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_symtab.c b/libsepol/cil/src/cil_symtab.c
|
||||
index 579a888e5785..c195156071e1 100644
|
||||
--- a/libsepol/cil/src/cil_symtab.c
|
||||
+++ b/libsepol/cil/src/cil_symtab.c
|
||||
@@ -93,10 +93,10 @@ int cil_symtab_insert(symtab_t *symtab, hashtab_key_t key, struct cil_symtab_dat
|
||||
datum->fqn = key;
|
||||
datum->symtab = symtab;
|
||||
symtab->nprim++;
|
||||
- cil_list_append(datum->nodes, CIL_NODE, node);
|
||||
- } else if (rc == SEPOL_EEXIST) {
|
||||
- cil_list_append(datum->nodes, CIL_NODE, node);
|
||||
- } else {
|
||||
+ if (node) {
|
||||
+ cil_list_append(datum->nodes, CIL_NODE, node);
|
||||
+ }
|
||||
+ } else if (rc != SEPOL_EEXIST) {
|
||||
cil_symtab_error("Failed to insert datum into hashtab\n");
|
||||
}
|
||||
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,738 +0,0 @@
|
||||
From bccec36a7694e8eee03ab0d592c3b0d8ddfff36e Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Tue, 11 May 2021 12:34:27 -0400
|
||||
Subject: [PATCH] libsepo/cil: Refactor macro call resolution
|
||||
|
||||
Rename cil_resolve_call1() as cil resolve_call() and rename
|
||||
cil_resolve_call2() as cil_resolve_call_args() to make it clearer
|
||||
what is being done in each function.
|
||||
|
||||
Move code to build call arguments out of cil_resolve_call() and into
|
||||
the new function called cil_build_call_args() so that the logic of
|
||||
cil_resolve_call() can be seen.
|
||||
|
||||
Exit cil_resolve_call() immediately if the call has already been
|
||||
copied.
|
||||
|
||||
In __cil_resolve_ast_node(), only resolve calls outside of macros.
|
||||
This results in more calls to cil_copy_ast(), but slightly less
|
||||
rules copied overall (since no rules are copied into a macro). This
|
||||
also means that the CIL_PASS_MACRO pass is not needed and can be
|
||||
eliminated.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_internal.h | 1 -
|
||||
libsepol/cil/src/cil_resolve_ast.c | 599 +++++++++++++++--------------
|
||||
2 files changed, 303 insertions(+), 297 deletions(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_internal.h b/libsepol/cil/src/cil_internal.h
|
||||
index 74e0b34d6cbd..a77c95201fb7 100644
|
||||
--- a/libsepol/cil/src/cil_internal.h
|
||||
+++ b/libsepol/cil/src/cil_internal.h
|
||||
@@ -59,7 +59,6 @@ enum cil_pass {
|
||||
CIL_PASS_BLKIN_LINK,
|
||||
CIL_PASS_BLKIN_COPY,
|
||||
CIL_PASS_BLKABS,
|
||||
- CIL_PASS_MACRO,
|
||||
CIL_PASS_CALL1,
|
||||
CIL_PASS_CALL2,
|
||||
CIL_PASS_ALIAS1,
|
||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
||||
index ae6743f92f4c..258fdb1bb69f 100644
|
||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
||||
@@ -2816,359 +2816,371 @@ exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
-int cil_resolve_call1(struct cil_tree_node *current, void *extra_args)
|
||||
+static int cil_build_call_args(struct cil_tree_node *call_node, struct cil_call *call, struct cil_macro *macro, void *extra_args)
|
||||
{
|
||||
- struct cil_call *new_call = current->data;
|
||||
struct cil_args_resolve *args = extra_args;
|
||||
- struct cil_db *db = NULL;
|
||||
- struct cil_tree_node *macro_node = NULL;
|
||||
- struct cil_symtab_datum *macro_datum = NULL;
|
||||
+ struct cil_list_item *item;
|
||||
+ struct cil_args *arg = NULL;
|
||||
+ struct cil_tree_node *arg_node = NULL;
|
||||
int rc = SEPOL_ERR;
|
||||
|
||||
- if (args != NULL) {
|
||||
- db = args->db;
|
||||
+ if (macro->params == NULL) {
|
||||
+ if (call->args_tree == NULL) {
|
||||
+ return SEPOL_OK;
|
||||
+ } else {
|
||||
+ cil_tree_log(call_node, CIL_ERR, "Unexpected arguments");
|
||||
+ return SEPOL_ERR;;
|
||||
+ }
|
||||
}
|
||||
-
|
||||
- rc = cil_resolve_name(current, new_call->macro_str, CIL_SYM_BLOCKS, extra_args, ¯o_datum);
|
||||
- if (rc != SEPOL_OK) {
|
||||
- goto exit;
|
||||
+ if (call->args_tree == NULL) {
|
||||
+ cil_tree_log(call_node, CIL_ERR, "Missing arguments");
|
||||
+ return SEPOL_ERR;
|
||||
}
|
||||
|
||||
- macro_node = NODE(macro_datum);
|
||||
+ arg_node = call->args_tree->root->cl_head;
|
||||
|
||||
- if (macro_node->flavor != CIL_MACRO) {
|
||||
- cil_tree_log(current, CIL_ERR, "Failed to resolve %s to a macro", new_call->macro_str);
|
||||
- rc = SEPOL_ERR;
|
||||
- goto exit;
|
||||
- }
|
||||
- new_call->macro = (struct cil_macro*)macro_datum;
|
||||
+ cil_list_init(&call->args, CIL_LIST_ITEM);
|
||||
|
||||
- if (new_call->macro->params != NULL ) {
|
||||
+ cil_list_for_each(item, macro->params) {
|
||||
+ enum cil_flavor flavor = ((struct cil_param*)item->data)->flavor;
|
||||
|
||||
- struct cil_list_item *item;
|
||||
- struct cil_args *new_arg = NULL;
|
||||
- struct cil_tree_node *pc = NULL;
|
||||
-
|
||||
- if (new_call->args_tree == NULL) {
|
||||
- cil_tree_log(current, CIL_ERR, "Missing arguments");
|
||||
+ if (arg_node == NULL) {
|
||||
+ cil_tree_log(call_node, CIL_ERR, "Missing arguments");
|
||||
+ rc = SEPOL_ERR;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+ if (item->flavor != CIL_PARAM) {
|
||||
rc = SEPOL_ERR;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
- pc = new_call->args_tree->root->cl_head;
|
||||
-
|
||||
- cil_list_init(&new_call->args, CIL_LIST_ITEM);
|
||||
-
|
||||
- cil_list_for_each(item, new_call->macro->params) {
|
||||
- enum cil_flavor flavor = ((struct cil_param*)item->data)->flavor;
|
||||
+ cil_args_init(&arg);
|
||||
|
||||
- if (pc == NULL) {
|
||||
- cil_tree_log(current, CIL_ERR, "Missing arguments");
|
||||
+ switch (flavor) {
|
||||
+ case CIL_NAME: {
|
||||
+ struct cil_name *name;
|
||||
+ if (arg_node->data == NULL) {
|
||||
+ cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
|
||||
+ cil_destroy_args(arg);
|
||||
rc = SEPOL_ERR;
|
||||
goto exit;
|
||||
}
|
||||
- if (item->flavor != CIL_PARAM) {
|
||||
+ name = __cil_insert_name(args->db, arg_node->data, call_node);
|
||||
+ if (name != NULL) {
|
||||
+ arg->arg = (struct cil_symtab_datum *)name;
|
||||
+ } else {
|
||||
+ arg->arg_str = arg_node->data;
|
||||
+ }
|
||||
+ }
|
||||
+ break;
|
||||
+ case CIL_TYPE:
|
||||
+ if (arg_node->data == NULL) {
|
||||
+ cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
|
||||
+ cil_destroy_args(arg);
|
||||
rc = SEPOL_ERR;
|
||||
goto exit;
|
||||
}
|
||||
-
|
||||
- cil_args_init(&new_arg);
|
||||
-
|
||||
- switch (flavor) {
|
||||
- case CIL_NAME: {
|
||||
- struct cil_name *name;
|
||||
- if (pc->data == NULL) {
|
||||
- cil_tree_log(current, CIL_ERR, "Invalid macro parameter");
|
||||
- cil_destroy_args(new_arg);
|
||||
- rc = SEPOL_ERR;
|
||||
- goto exit;
|
||||
- }
|
||||
- name = __cil_insert_name(args->db, pc->data, current);
|
||||
- if (name != NULL) {
|
||||
- new_arg->arg = (struct cil_symtab_datum *)name;
|
||||
- } else {
|
||||
- new_arg->arg_str = pc->data;
|
||||
- }
|
||||
+ arg->arg_str = arg_node->data;
|
||||
+ break;
|
||||
+ case CIL_ROLE:
|
||||
+ if (arg_node->data == NULL) {
|
||||
+ cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
|
||||
+ cil_destroy_args(arg);
|
||||
+ rc = SEPOL_ERR;
|
||||
+ goto exit;
|
||||
}
|
||||
- break;
|
||||
- case CIL_TYPE:
|
||||
- if (pc->data == NULL) {
|
||||
- cil_tree_log(current, CIL_ERR, "Invalid macro parameter");
|
||||
- cil_destroy_args(new_arg);
|
||||
- rc = SEPOL_ERR;
|
||||
- goto exit;
|
||||
- }
|
||||
- new_arg->arg_str = pc->data;
|
||||
- break;
|
||||
- case CIL_ROLE:
|
||||
- if (pc->data == NULL) {
|
||||
- cil_tree_log(current, CIL_ERR, "Invalid macro parameter");
|
||||
- cil_destroy_args(new_arg);
|
||||
- rc = SEPOL_ERR;
|
||||
- goto exit;
|
||||
- }
|
||||
- new_arg->arg_str = pc->data;
|
||||
- break;
|
||||
- case CIL_USER:
|
||||
- if (pc->data == NULL) {
|
||||
- cil_tree_log(current, CIL_ERR, "Invalid macro parameter");
|
||||
- cil_destroy_args(new_arg);
|
||||
- rc = SEPOL_ERR;
|
||||
- goto exit;
|
||||
- }
|
||||
- new_arg->arg_str = pc->data;
|
||||
- break;
|
||||
- case CIL_SENS:
|
||||
- if (pc->data == NULL) {
|
||||
- cil_tree_log(current, CIL_ERR, "Invalid macro parameter");
|
||||
- cil_destroy_args(new_arg);
|
||||
- rc = SEPOL_ERR;
|
||||
- goto exit;
|
||||
- }
|
||||
- new_arg->arg_str = pc->data;
|
||||
- break;
|
||||
- case CIL_CAT:
|
||||
- if (pc->data == NULL) {
|
||||
- cil_tree_log(current, CIL_ERR, "Invalid macro parameter");
|
||||
- cil_destroy_args(new_arg);
|
||||
- rc = SEPOL_ERR;
|
||||
- goto exit;
|
||||
- }
|
||||
- new_arg->arg_str = pc->data;
|
||||
- break;
|
||||
- case CIL_BOOL:
|
||||
- if (pc->data == NULL) {
|
||||
- cil_tree_log(current, CIL_ERR, "Invalid macro parameter");
|
||||
- cil_destroy_args(new_arg);
|
||||
- rc = SEPOL_ERR;
|
||||
- goto exit;
|
||||
- }
|
||||
- new_arg->arg_str = pc->data;
|
||||
- break;
|
||||
- case CIL_CATSET: {
|
||||
- if (pc->cl_head != NULL) {
|
||||
- struct cil_catset *catset = NULL;
|
||||
- struct cil_tree_node *cat_node = NULL;
|
||||
- cil_catset_init(&catset);
|
||||
- rc = cil_fill_cats(pc, &catset->cats);
|
||||
- if (rc != SEPOL_OK) {
|
||||
- cil_destroy_catset(catset);
|
||||
- cil_destroy_args(new_arg);
|
||||
- goto exit;
|
||||
- }
|
||||
- cil_tree_node_init(&cat_node);
|
||||
- cat_node->flavor = CIL_CATSET;
|
||||
- cat_node->data = catset;
|
||||
- cil_list_append(((struct cil_symtab_datum*)catset)->nodes,
|
||||
- CIL_LIST_ITEM, cat_node);
|
||||
- new_arg->arg = (struct cil_symtab_datum*)catset;
|
||||
- } else if (pc->data == NULL) {
|
||||
- cil_tree_log(current, CIL_ERR, "Invalid macro parameter");
|
||||
- cil_destroy_args(new_arg);
|
||||
- rc = SEPOL_ERR;
|
||||
+ arg->arg_str = arg_node->data;
|
||||
+ break;
|
||||
+ case CIL_USER:
|
||||
+ if (arg_node->data == NULL) {
|
||||
+ cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
|
||||
+ cil_destroy_args(arg);
|
||||
+ rc = SEPOL_ERR;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+ arg->arg_str = arg_node->data;
|
||||
+ break;
|
||||
+ case CIL_SENS:
|
||||
+ if (arg_node->data == NULL) {
|
||||
+ cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
|
||||
+ cil_destroy_args(arg);
|
||||
+ rc = SEPOL_ERR;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+ arg->arg_str = arg_node->data;
|
||||
+ break;
|
||||
+ case CIL_CAT:
|
||||
+ if (arg_node->data == NULL) {
|
||||
+ cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
|
||||
+ cil_destroy_args(arg);
|
||||
+ rc = SEPOL_ERR;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+ arg->arg_str = arg_node->data;
|
||||
+ break;
|
||||
+ case CIL_BOOL:
|
||||
+ if (arg_node->data == NULL) {
|
||||
+ cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
|
||||
+ cil_destroy_args(arg);
|
||||
+ rc = SEPOL_ERR;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+ arg->arg_str = arg_node->data;
|
||||
+ break;
|
||||
+ case CIL_CATSET: {
|
||||
+ if (arg_node->cl_head != NULL) {
|
||||
+ struct cil_catset *catset = NULL;
|
||||
+ struct cil_tree_node *cat_node = NULL;
|
||||
+ cil_catset_init(&catset);
|
||||
+ rc = cil_fill_cats(arg_node, &catset->cats);
|
||||
+ if (rc != SEPOL_OK) {
|
||||
+ cil_destroy_catset(catset);
|
||||
+ cil_destroy_args(arg);
|
||||
goto exit;
|
||||
- } else {
|
||||
- new_arg->arg_str = pc->data;
|
||||
}
|
||||
-
|
||||
- break;
|
||||
+ cil_tree_node_init(&cat_node);
|
||||
+ cat_node->flavor = CIL_CATSET;
|
||||
+ cat_node->data = catset;
|
||||
+ cil_list_append(((struct cil_symtab_datum*)catset)->nodes,
|
||||
+ CIL_LIST_ITEM, cat_node);
|
||||
+ arg->arg = (struct cil_symtab_datum*)catset;
|
||||
+ } else if (arg_node->data == NULL) {
|
||||
+ cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
|
||||
+ cil_destroy_args(arg);
|
||||
+ rc = SEPOL_ERR;
|
||||
+ goto exit;
|
||||
+ } else {
|
||||
+ arg->arg_str = arg_node->data;
|
||||
}
|
||||
- case CIL_LEVEL: {
|
||||
- if (pc->cl_head != NULL) {
|
||||
- struct cil_level *level = NULL;
|
||||
- struct cil_tree_node *lvl_node = NULL;
|
||||
- cil_level_init(&level);
|
||||
-
|
||||
- rc = cil_fill_level(pc->cl_head, level);
|
||||
- if (rc != SEPOL_OK) {
|
||||
- cil_log(CIL_ERR, "Failed to create anonymous level, rc: %d\n", rc);
|
||||
- cil_destroy_level(level);
|
||||
- cil_destroy_args(new_arg);
|
||||
- goto exit;
|
||||
- }
|
||||
- cil_tree_node_init(&lvl_node);
|
||||
- lvl_node->flavor = CIL_LEVEL;
|
||||
- lvl_node->data = level;
|
||||
- cil_list_append(((struct cil_symtab_datum*)level)->nodes,
|
||||
- CIL_LIST_ITEM, lvl_node);
|
||||
- new_arg->arg = (struct cil_symtab_datum*)level;
|
||||
- } else if (pc->data == NULL) {
|
||||
- cil_tree_log(current, CIL_ERR, "Invalid macro parameter");
|
||||
- cil_destroy_args(new_arg);
|
||||
- rc = SEPOL_ERR;
|
||||
+
|
||||
+ break;
|
||||
+ }
|
||||
+ case CIL_LEVEL: {
|
||||
+ if (arg_node->cl_head != NULL) {
|
||||
+ struct cil_level *level = NULL;
|
||||
+ struct cil_tree_node *lvl_node = NULL;
|
||||
+ cil_level_init(&level);
|
||||
+
|
||||
+ rc = cil_fill_level(arg_node->cl_head, level);
|
||||
+ if (rc != SEPOL_OK) {
|
||||
+ cil_log(CIL_ERR, "Failed to create anonymous level, rc: %d\n", rc);
|
||||
+ cil_destroy_level(level);
|
||||
+ cil_destroy_args(arg);
|
||||
goto exit;
|
||||
- } else {
|
||||
- new_arg->arg_str = pc->data;
|
||||
}
|
||||
-
|
||||
- break;
|
||||
+ cil_tree_node_init(&lvl_node);
|
||||
+ lvl_node->flavor = CIL_LEVEL;
|
||||
+ lvl_node->data = level;
|
||||
+ cil_list_append(((struct cil_symtab_datum*)level)->nodes,
|
||||
+ CIL_LIST_ITEM, lvl_node);
|
||||
+ arg->arg = (struct cil_symtab_datum*)level;
|
||||
+ } else if (arg_node->data == NULL) {
|
||||
+ cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
|
||||
+ cil_destroy_args(arg);
|
||||
+ rc = SEPOL_ERR;
|
||||
+ goto exit;
|
||||
+ } else {
|
||||
+ arg->arg_str = arg_node->data;
|
||||
}
|
||||
- case CIL_LEVELRANGE: {
|
||||
- if (pc->cl_head != NULL) {
|
||||
- struct cil_levelrange *range = NULL;
|
||||
- struct cil_tree_node *range_node = NULL;
|
||||
- cil_levelrange_init(&range);
|
||||
-
|
||||
- rc = cil_fill_levelrange(pc->cl_head, range);
|
||||
- if (rc != SEPOL_OK) {
|
||||
- cil_log(CIL_ERR, "Failed to create anonymous levelrange, rc: %d\n", rc);
|
||||
- cil_destroy_levelrange(range);
|
||||
- cil_destroy_args(new_arg);
|
||||
- goto exit;
|
||||
- }
|
||||
- cil_tree_node_init(&range_node);
|
||||
- range_node->flavor = CIL_LEVELRANGE;
|
||||
- range_node->data = range;
|
||||
- cil_list_append(((struct cil_symtab_datum*)range)->nodes,
|
||||
- CIL_LIST_ITEM, range_node);
|
||||
- new_arg->arg = (struct cil_symtab_datum*)range;
|
||||
- } else if (pc->data == NULL) {
|
||||
- cil_tree_log(current, CIL_ERR, "Invalid macro parameter");
|
||||
- cil_destroy_args(new_arg);
|
||||
- rc = SEPOL_ERR;
|
||||
+
|
||||
+ break;
|
||||
+ }
|
||||
+ case CIL_LEVELRANGE: {
|
||||
+ if (arg_node->cl_head != NULL) {
|
||||
+ struct cil_levelrange *range = NULL;
|
||||
+ struct cil_tree_node *range_node = NULL;
|
||||
+ cil_levelrange_init(&range);
|
||||
+
|
||||
+ rc = cil_fill_levelrange(arg_node->cl_head, range);
|
||||
+ if (rc != SEPOL_OK) {
|
||||
+ cil_log(CIL_ERR, "Failed to create anonymous levelrange, rc: %d\n", rc);
|
||||
+ cil_destroy_levelrange(range);
|
||||
+ cil_destroy_args(arg);
|
||||
goto exit;
|
||||
- } else {
|
||||
- new_arg->arg_str = pc->data;
|
||||
}
|
||||
-
|
||||
- break;
|
||||
+ cil_tree_node_init(&range_node);
|
||||
+ range_node->flavor = CIL_LEVELRANGE;
|
||||
+ range_node->data = range;
|
||||
+ cil_list_append(((struct cil_symtab_datum*)range)->nodes,
|
||||
+ CIL_LIST_ITEM, range_node);
|
||||
+ arg->arg = (struct cil_symtab_datum*)range;
|
||||
+ } else if (arg_node->data == NULL) {
|
||||
+ cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
|
||||
+ cil_destroy_args(arg);
|
||||
+ rc = SEPOL_ERR;
|
||||
+ goto exit;
|
||||
+ } else {
|
||||
+ arg->arg_str = arg_node->data;
|
||||
}
|
||||
- case CIL_IPADDR: {
|
||||
- if (pc->cl_head != NULL) {
|
||||
- struct cil_ipaddr *ipaddr = NULL;
|
||||
- struct cil_tree_node *addr_node = NULL;
|
||||
- cil_ipaddr_init(&ipaddr);
|
||||
-
|
||||
- rc = cil_fill_ipaddr(pc->cl_head, ipaddr);
|
||||
- if (rc != SEPOL_OK) {
|
||||
- cil_log(CIL_ERR, "Failed to create anonymous ip address, rc: %d\n", rc);
|
||||
- cil_destroy_ipaddr(ipaddr);
|
||||
- cil_destroy_args(new_arg);
|
||||
- goto exit;
|
||||
- }
|
||||
- cil_tree_node_init(&addr_node);
|
||||
- addr_node->flavor = CIL_IPADDR;
|
||||
- addr_node->data = ipaddr;
|
||||
- cil_list_append(((struct cil_symtab_datum*)ipaddr)->nodes,
|
||||
- CIL_LIST_ITEM, addr_node);
|
||||
- new_arg->arg = (struct cil_symtab_datum*)ipaddr;
|
||||
- } else if (pc->data == NULL) {
|
||||
- cil_tree_log(current, CIL_ERR, "Invalid macro parameter");
|
||||
- cil_destroy_args(new_arg);
|
||||
- rc = SEPOL_ERR;
|
||||
+
|
||||
+ break;
|
||||
+ }
|
||||
+ case CIL_IPADDR: {
|
||||
+ if (arg_node->cl_head != NULL) {
|
||||
+ struct cil_ipaddr *ipaddr = NULL;
|
||||
+ struct cil_tree_node *addr_node = NULL;
|
||||
+ cil_ipaddr_init(&ipaddr);
|
||||
+
|
||||
+ rc = cil_fill_ipaddr(arg_node->cl_head, ipaddr);
|
||||
+ if (rc != SEPOL_OK) {
|
||||
+ cil_log(CIL_ERR, "Failed to create anonymous ip address, rc: %d\n", rc);
|
||||
+ cil_destroy_ipaddr(ipaddr);
|
||||
+ cil_destroy_args(arg);
|
||||
goto exit;
|
||||
- } else {
|
||||
- new_arg->arg_str = pc->data;
|
||||
}
|
||||
+ cil_tree_node_init(&addr_node);
|
||||
+ addr_node->flavor = CIL_IPADDR;
|
||||
+ addr_node->data = ipaddr;
|
||||
+ cil_list_append(((struct cil_symtab_datum*)ipaddr)->nodes,
|
||||
+ CIL_LIST_ITEM, addr_node);
|
||||
+ arg->arg = (struct cil_symtab_datum*)ipaddr;
|
||||
+ } else if (arg_node->data == NULL) {
|
||||
+ cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
|
||||
+ cil_destroy_args(arg);
|
||||
+ rc = SEPOL_ERR;
|
||||
+ goto exit;
|
||||
+ } else {
|
||||
+ arg->arg_str = arg_node->data;
|
||||
+ }
|
||||
|
||||
- break;
|
||||
+ break;
|
||||
+ }
|
||||
+ case CIL_CLASS:
|
||||
+ if (arg_node->data == NULL) {
|
||||
+ cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
|
||||
+ cil_destroy_args(arg);
|
||||
+ rc = SEPOL_ERR;
|
||||
+ goto exit;
|
||||
}
|
||||
- case CIL_CLASS:
|
||||
- if (pc->data == NULL) {
|
||||
- cil_tree_log(current, CIL_ERR, "Invalid macro parameter");
|
||||
- cil_destroy_args(new_arg);
|
||||
- rc = SEPOL_ERR;
|
||||
- goto exit;
|
||||
- }
|
||||
- new_arg->arg_str = pc->data;
|
||||
- break;
|
||||
- case CIL_MAP_CLASS:
|
||||
- if (pc->data == NULL) {
|
||||
- cil_tree_log(current, CIL_ERR, "Invalid macro parameter");
|
||||
- cil_destroy_args(new_arg);
|
||||
- rc = SEPOL_ERR;
|
||||
- goto exit;
|
||||
- }
|
||||
- new_arg->arg_str = pc->data;
|
||||
- break;
|
||||
- case CIL_CLASSPERMISSION: {
|
||||
- if (pc->cl_head != NULL) {
|
||||
- struct cil_classpermission *cp = NULL;
|
||||
- struct cil_tree_node *cp_node = NULL;
|
||||
-
|
||||
- cil_classpermission_init(&cp);
|
||||
- rc = cil_fill_classperms_list(pc, &cp->classperms);
|
||||
- if (rc != SEPOL_OK) {
|
||||
- cil_log(CIL_ERR, "Failed to create anonymous classpermission\n");
|
||||
- cil_destroy_classpermission(cp);
|
||||
- cil_destroy_args(new_arg);
|
||||
- goto exit;
|
||||
- }
|
||||
- cil_tree_node_init(&cp_node);
|
||||
- cp_node->flavor = CIL_CLASSPERMISSION;
|
||||
- cp_node->data = cp;
|
||||
- cil_list_append(cp->datum.nodes, CIL_LIST_ITEM, cp_node);
|
||||
- new_arg->arg = (struct cil_symtab_datum*)cp;
|
||||
- } else if (pc->data == NULL) {
|
||||
- cil_tree_log(current, CIL_ERR, "Invalid macro parameter");
|
||||
- cil_destroy_args(new_arg);
|
||||
- rc = SEPOL_ERR;
|
||||
+ arg->arg_str = arg_node->data;
|
||||
+ break;
|
||||
+ case CIL_MAP_CLASS:
|
||||
+ if (arg_node->data == NULL) {
|
||||
+ cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
|
||||
+ cil_destroy_args(arg);
|
||||
+ rc = SEPOL_ERR;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+ arg->arg_str = arg_node->data;
|
||||
+ break;
|
||||
+ case CIL_CLASSPERMISSION: {
|
||||
+ if (arg_node->cl_head != NULL) {
|
||||
+ struct cil_classpermission *cp = NULL;
|
||||
+ struct cil_tree_node *cp_node = NULL;
|
||||
+
|
||||
+ cil_classpermission_init(&cp);
|
||||
+ rc = cil_fill_classperms_list(arg_node, &cp->classperms);
|
||||
+ if (rc != SEPOL_OK) {
|
||||
+ cil_log(CIL_ERR, "Failed to create anonymous classpermission\n");
|
||||
+ cil_destroy_classpermission(cp);
|
||||
+ cil_destroy_args(arg);
|
||||
goto exit;
|
||||
- } else {
|
||||
- new_arg->arg_str = pc->data;
|
||||
}
|
||||
- break;
|
||||
- }
|
||||
- default:
|
||||
- cil_log(CIL_ERR, "Unexpected flavor: %d\n",
|
||||
- (((struct cil_param*)item->data)->flavor));
|
||||
- cil_destroy_args(new_arg);
|
||||
+ cil_tree_node_init(&cp_node);
|
||||
+ cp_node->flavor = CIL_CLASSPERMISSION;
|
||||
+ cp_node->data = cp;
|
||||
+ cil_list_append(cp->datum.nodes, CIL_LIST_ITEM, cp_node);
|
||||
+ arg->arg = (struct cil_symtab_datum*)cp;
|
||||
+ } else if (arg_node->data == NULL) {
|
||||
+ cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
|
||||
+ cil_destroy_args(arg);
|
||||
rc = SEPOL_ERR;
|
||||
goto exit;
|
||||
+ } else {
|
||||
+ arg->arg_str = arg_node->data;
|
||||
}
|
||||
- new_arg->param_str = ((struct cil_param*)item->data)->str;
|
||||
- new_arg->flavor = flavor;
|
||||
-
|
||||
- cil_list_append(new_call->args, CIL_ARGS, new_arg);
|
||||
-
|
||||
- pc = pc->next;
|
||||
+ break;
|
||||
}
|
||||
-
|
||||
- if (pc != NULL) {
|
||||
- cil_tree_log(current, CIL_ERR, "Unexpected arguments");
|
||||
+ default:
|
||||
+ cil_log(CIL_ERR, "Unexpected flavor: %d\n",
|
||||
+ (((struct cil_param*)item->data)->flavor));
|
||||
+ cil_destroy_args(arg);
|
||||
rc = SEPOL_ERR;
|
||||
goto exit;
|
||||
}
|
||||
- } else if (new_call->args_tree != NULL) {
|
||||
- cil_tree_log(current, CIL_ERR, "Unexpected arguments");
|
||||
+ arg->param_str = ((struct cil_param*)item->data)->str;
|
||||
+ arg->flavor = flavor;
|
||||
+
|
||||
+ cil_list_append(call->args, CIL_ARGS, arg);
|
||||
+
|
||||
+ arg_node = arg_node->next;
|
||||
+ }
|
||||
+
|
||||
+ if (arg_node != NULL) {
|
||||
+ cil_tree_log(call_node, CIL_ERR, "Unexpected arguments");
|
||||
rc = SEPOL_ERR;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
- if (new_call->copied == 0) {
|
||||
- new_call->copied = 1;
|
||||
+ return SEPOL_OK;
|
||||
|
||||
- rc = cil_check_recursive_call(current, macro_node);
|
||||
- if (rc != SEPOL_OK) {
|
||||
- goto exit;
|
||||
- }
|
||||
+exit:
|
||||
+ return rc;
|
||||
+}
|
||||
|
||||
- rc = cil_copy_ast(db, macro_node, current);
|
||||
- if (rc != SEPOL_OK) {
|
||||
- cil_log(CIL_ERR, "Failed to copy macro, rc: %d\n", rc);
|
||||
- goto exit;
|
||||
- }
|
||||
+int cil_resolve_call(struct cil_tree_node *current, void *extra_args)
|
||||
+{
|
||||
+ struct cil_call *call = current->data;
|
||||
+ struct cil_args_resolve *args = extra_args;
|
||||
+ struct cil_tree_node *macro_node = NULL;
|
||||
+ struct cil_symtab_datum *macro_datum = NULL;
|
||||
+ int rc = SEPOL_ERR;
|
||||
+
|
||||
+ if (call->copied) {
|
||||
+ return SEPOL_OK;
|
||||
+ }
|
||||
+
|
||||
+ rc = cil_resolve_name(current, call->macro_str, CIL_SYM_BLOCKS, extra_args, ¯o_datum);
|
||||
+ if (rc != SEPOL_OK) {
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ macro_node = NODE(macro_datum);
|
||||
+
|
||||
+ if (macro_node->flavor != CIL_MACRO) {
|
||||
+ cil_tree_log(current, CIL_ERR, "Failed to resolve %s to a macro", call->macro_str);
|
||||
+ rc = SEPOL_ERR;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+ call->macro = (struct cil_macro*)macro_datum;
|
||||
+
|
||||
+ rc = cil_build_call_args(current, call, call->macro, extra_args);
|
||||
+ if (rc != SEPOL_OK) {
|
||||
+ goto exit;
|
||||
}
|
||||
|
||||
+ rc = cil_check_recursive_call(current, macro_node);
|
||||
+ if (rc != SEPOL_OK) {
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ rc = cil_copy_ast(args->db, macro_node, current);
|
||||
+ if (rc != SEPOL_OK) {
|
||||
+ cil_tree_log(current, CIL_ERR, "Failed to copy macro %s to call", macro_datum->name);
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ call->copied = 1;
|
||||
+
|
||||
return SEPOL_OK;
|
||||
|
||||
exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
-int cil_resolve_call2(struct cil_tree_node *current, void *extra_args)
|
||||
+int cil_resolve_call_args(struct cil_tree_node *current, void *extra_args)
|
||||
{
|
||||
- struct cil_call *new_call = current->data;
|
||||
+ struct cil_call *call = current->data;
|
||||
int rc = SEPOL_ERR;
|
||||
enum cil_sym_index sym_index = CIL_SYM_UNKNOWN;
|
||||
struct cil_list_item *item;
|
||||
|
||||
- if (new_call->args == NULL) {
|
||||
+ if (call->args == NULL) {
|
||||
rc = SEPOL_OK;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
- cil_list_for_each(item, new_call->args) {
|
||||
+ cil_list_for_each(item, call->args) {
|
||||
struct cil_args *arg = item->data;
|
||||
if (arg->arg == NULL && arg->arg_str == NULL) {
|
||||
cil_log(CIL_ERR, "Arguments not created correctly\n");
|
||||
@@ -3574,19 +3586,14 @@ int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args)
|
||||
rc = cil_resolve_blockabstract(node, args);
|
||||
}
|
||||
break;
|
||||
- case CIL_PASS_MACRO:
|
||||
- if (node->flavor == CIL_CALL && args->macro != NULL) {
|
||||
- rc = cil_resolve_call1(node, args);
|
||||
- }
|
||||
- break;
|
||||
case CIL_PASS_CALL1:
|
||||
- if (node->flavor == CIL_CALL) {
|
||||
- rc = cil_resolve_call1(node, args);
|
||||
+ if (node->flavor == CIL_CALL && args->macro == NULL) {
|
||||
+ rc = cil_resolve_call(node, args);
|
||||
}
|
||||
break;
|
||||
case CIL_PASS_CALL2:
|
||||
- if (node->flavor == CIL_CALL) {
|
||||
- rc = cil_resolve_call2(node, args);
|
||||
+ if (node->flavor == CIL_CALL && args->macro == NULL) {
|
||||
+ rc = cil_resolve_call_args(node, args);
|
||||
}
|
||||
break;
|
||||
case CIL_PASS_ALIAS1:
|
||||
@@ -3890,7 +3897,7 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished
|
||||
}
|
||||
|
||||
if (node->flavor == CIL_MACRO) {
|
||||
- if (pass != CIL_PASS_TIF && pass != CIL_PASS_MACRO) {
|
||||
+ if (pass != CIL_PASS_TIF) {
|
||||
*finished = CIL_TREE_SKIP_HEAD;
|
||||
rc = SEPOL_OK;
|
||||
goto exit;
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,83 +0,0 @@
|
||||
From aa8ac8ffafb9e4121b95a721341371042a3b2994 Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Tue, 11 May 2021 14:22:53 -0400
|
||||
Subject: [PATCH] libsepol/cil: Do not resolve arguments to declarations in the
|
||||
call
|
||||
|
||||
Lorenzo Ceragioli <lorenzo.ceragioli@phd.unipi.it> noted that the
|
||||
following policy:
|
||||
(type a)
|
||||
(block A
|
||||
(macro m ((type x))
|
||||
(type a)
|
||||
(allow x x (file (read))))
|
||||
)
|
||||
(block B
|
||||
(call A.m(a))
|
||||
)
|
||||
results in the allow rule (allow B.a B.a (file(read))). This makes
|
||||
no sense because the "a" being passed as an argument has to be the
|
||||
global "a" and not the "a" defined in the macro.
|
||||
|
||||
This behavior occurs because the call arguments are resolved AFTER
|
||||
the macro body has been copied and the declaration of "a" in the
|
||||
macro has been added to block B's namespace, so this is the "a"
|
||||
that the call argument resolves to, rather than the one in the
|
||||
global namespace.
|
||||
|
||||
When resolving call arguments, check if the datum found belongs to
|
||||
a declaration in the call. If it does, then remove the datum from
|
||||
the symbol table, re-resolve the argument, and add the datum back
|
||||
into the symbol table.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_resolve_ast.c | 28 +++++++++++++++++++++++++++-
|
||||
1 file changed, 27 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
||||
index 258fdb1bb69f..74e5b78f9325 100644
|
||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
||||
@@ -3263,11 +3263,37 @@ int cil_resolve_call_args(struct cil_tree_node *current, void *extra_args)
|
||||
}
|
||||
|
||||
if (sym_index != CIL_SYM_UNKNOWN) {
|
||||
- rc = cil_resolve_name(current, arg->arg_str, sym_index, extra_args, &(arg->arg));
|
||||
+ struct cil_symtab_datum *datum;
|
||||
+ struct cil_tree_node *n;
|
||||
+ rc = cil_resolve_name(current, arg->arg_str, sym_index, extra_args, &datum);
|
||||
if (rc != SEPOL_OK) {
|
||||
cil_tree_log(current, CIL_ERR, "Failed to resolve %s in call argument list", arg->arg_str);
|
||||
goto exit;
|
||||
}
|
||||
+ arg->arg = datum;
|
||||
+ n = NODE(datum);
|
||||
+ while (n && n->flavor != CIL_ROOT) {
|
||||
+ if (n == current) {
|
||||
+ symtab_t *s = datum->symtab;
|
||||
+ /* Call arg should not resolve to declaration in the call
|
||||
+ * Need to remove datum temporarily to resolve to a datum outside
|
||||
+ * the call.
|
||||
+ */
|
||||
+ cil_symtab_remove_datum(datum);
|
||||
+ rc = cil_resolve_name(current, arg->arg_str, sym_index, extra_args, &(arg->arg));
|
||||
+ if (rc != SEPOL_OK) {
|
||||
+ cil_tree_log(current, CIL_ERR, "Failed to resolve %s in call argument list", arg->arg_str);
|
||||
+ goto exit;
|
||||
+ }
|
||||
+ rc = cil_symtab_insert(s, datum->name, datum, NULL);
|
||||
+ if (rc != SEPOL_OK) {
|
||||
+ cil_tree_log(current, CIL_ERR, "Failed to re-insert datum while resolving %s in call argument list", arg->arg_str);
|
||||
+ goto exit;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+ n = n->parent;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.32.0
|
||||
|
@ -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 74e5b78f9325..328add0421c5 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);
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,39 +0,0 @@
|
||||
From 29d6a3ee4a958607fdf7c01a78b6d389ba6e8612 Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Thu, 13 May 2021 12:36:44 -0400
|
||||
Subject: [PATCH] libsepol/cil: Destroy the permission nodes when exiting with
|
||||
an error
|
||||
|
||||
When exiting with an error because a class or common has too many
|
||||
permissions, destroy the permission nodes.
|
||||
|
||||
This bug was found by the secilc-fuzzer.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_build_ast.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
|
||||
index 87043a8fa183..71f14e20e25e 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);
|
||||
+ cil_tree_children_destroy(ast_node);
|
||||
rc = SEPOL_ERR;
|
||||
goto exit;
|
||||
}
|
||||
@@ -1019,6 +1020,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);
|
||||
+ cil_tree_children_destroy(ast_node);
|
||||
rc = SEPOL_ERR;
|
||||
goto exit;
|
||||
}
|
||||
--
|
||||
2.32.0
|
||||
|
@ -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 a93062180ff8..fb95f401f1c7 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;
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,44 +0,0 @@
|
||||
From a8dcf4d57bad3e531e44855ccfa22d234a2a7e56 Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Thu, 13 May 2021 12:51:44 -0400
|
||||
Subject: [PATCH] libsepol/cil: Resolve anonymous class permission sets only
|
||||
once
|
||||
|
||||
Anonymous class permission sets can be passed as call arguments.
|
||||
Anonymous call arguments are resolved when they are used in a
|
||||
rule. [This is because all the information might not be present
|
||||
(like common permissions being added to a class) when the call
|
||||
itself is resolved.] If there is more than one rule using an
|
||||
anonymous class permission set, then a memory leak will occur
|
||||
when a new list for the permission datum expression is created
|
||||
without destroying the old one.
|
||||
|
||||
When resolving the class and permissions, check if the class has
|
||||
already been resolved. If it has, then the permissions have been
|
||||
as well.
|
||||
|
||||
This bug was found by the secilc-fuzzer.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
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 328add0421c5..c504e60b7c58 100644
|
||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
||||
@@ -158,6 +158,10 @@ int cil_resolve_classperms(struct cil_tree_node *current, struct cil_classperms
|
||||
symtab_t *common_symtab = NULL;
|
||||
struct cil_class *class;
|
||||
|
||||
+ if (cp->class) {
|
||||
+ return SEPOL_OK;
|
||||
+ }
|
||||
+
|
||||
rc = cil_resolve_name(current, cp->class_str, CIL_SYM_CLASSES, extra_args, &datum);
|
||||
if (rc != SEPOL_OK) {
|
||||
goto exit;
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,232 +0,0 @@
|
||||
From 73d991abdc41b8e1380bfe05f031c822bfa0b515 Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Thu, 13 May 2021 12:53:54 -0400
|
||||
Subject: [PATCH] libsepol/cil: Pointers to datums should be set to NULL when
|
||||
resetting
|
||||
|
||||
Set the pointer to the sensitivity in levels, the pointers to the low
|
||||
and high levels in levelranges, the pointer to the level in userlevels,
|
||||
the pointer to the range in userranges, and the pointers to contexts
|
||||
in ocontexts to NULL.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_reset_ast.c | 56 ++++++++++++++++++++++++++++++--
|
||||
1 file changed, 53 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_reset_ast.c b/libsepol/cil/src/cil_reset_ast.c
|
||||
index d24d4f8159a3..6d1d2da77c89 100644
|
||||
--- a/libsepol/cil/src/cil_reset_ast.c
|
||||
+++ b/libsepol/cil/src/cil_reset_ast.c
|
||||
@@ -140,8 +140,11 @@ static void cil_reset_userattributeset(struct cil_userattributeset *uas)
|
||||
|
||||
static void cil_reset_selinuxuser(struct cil_selinuxuser *selinuxuser)
|
||||
{
|
||||
+ selinuxuser->user = NULL;
|
||||
if (selinuxuser->range_str == NULL) {
|
||||
cil_reset_levelrange(selinuxuser->range);
|
||||
+ } else {
|
||||
+ selinuxuser->range = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,6 +217,8 @@ static void cil_reset_rangetransition(struct cil_rangetransition *rangetrans)
|
||||
{
|
||||
if (rangetrans->range_str == NULL) {
|
||||
cil_reset_levelrange(rangetrans->range);
|
||||
+ } else {
|
||||
+ rangetrans->range = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,6 +256,7 @@ static void cil_reset_catset(struct cil_catset *catset)
|
||||
|
||||
static inline void cil_reset_level(struct cil_level *level)
|
||||
{
|
||||
+ level->sens = NULL;
|
||||
cil_reset_cats(level->cats);
|
||||
}
|
||||
|
||||
@@ -258,10 +264,14 @@ static inline void cil_reset_levelrange(struct cil_levelrange *levelrange)
|
||||
{
|
||||
if (levelrange->low_str == NULL) {
|
||||
cil_reset_level(levelrange->low);
|
||||
+ } else {
|
||||
+ levelrange->low = NULL;
|
||||
}
|
||||
|
||||
if (levelrange->high_str == NULL) {
|
||||
cil_reset_level(levelrange->high);
|
||||
+ } else {
|
||||
+ levelrange->high = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,6 +279,8 @@ static inline void cil_reset_userlevel(struct cil_userlevel *userlevel)
|
||||
{
|
||||
if (userlevel->level_str == NULL) {
|
||||
cil_reset_level(userlevel->level);
|
||||
+ } else {
|
||||
+ userlevel->level = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -276,13 +288,20 @@ static inline void cil_reset_userrange(struct cil_userrange *userrange)
|
||||
{
|
||||
if (userrange->range_str == NULL) {
|
||||
cil_reset_levelrange(userrange->range);
|
||||
+ } else {
|
||||
+ userrange->range = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void cil_reset_context(struct cil_context *context)
|
||||
{
|
||||
+ if (!context) {
|
||||
+ return;
|
||||
+ }
|
||||
if (context->range_str == NULL) {
|
||||
cil_reset_levelrange(context->range);
|
||||
+ } else {
|
||||
+ context->range = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,26 +309,35 @@ static void cil_reset_sidcontext(struct cil_sidcontext *sidcontext)
|
||||
{
|
||||
if (sidcontext->context_str == NULL) {
|
||||
cil_reset_context(sidcontext->context);
|
||||
+ } else {
|
||||
+ sidcontext->context = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void cil_reset_filecon(struct cil_filecon *filecon)
|
||||
{
|
||||
- if (filecon->context_str == NULL && filecon->context != NULL) {
|
||||
+ if (filecon->context_str == NULL) {
|
||||
cil_reset_context(filecon->context);
|
||||
+ } else {
|
||||
+ filecon->context = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void cil_reset_ibpkeycon(struct cil_ibpkeycon *ibpkeycon)
|
||||
{
|
||||
- if (!ibpkeycon->context_str)
|
||||
+ if (ibpkeycon->context_str == NULL) {
|
||||
cil_reset_context(ibpkeycon->context);
|
||||
+ } else {
|
||||
+ ibpkeycon->context = NULL;
|
||||
+ }
|
||||
}
|
||||
|
||||
static void cil_reset_portcon(struct cil_portcon *portcon)
|
||||
{
|
||||
if (portcon->context_str == NULL) {
|
||||
cil_reset_context(portcon->context);
|
||||
+ } else {
|
||||
+ portcon->context = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -317,6 +345,8 @@ static void cil_reset_nodecon(struct cil_nodecon *nodecon)
|
||||
{
|
||||
if (nodecon->context_str == NULL) {
|
||||
cil_reset_context(nodecon->context);
|
||||
+ } else {
|
||||
+ nodecon->context = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -324,6 +354,8 @@ static void cil_reset_genfscon(struct cil_genfscon *genfscon)
|
||||
{
|
||||
if (genfscon->context_str == NULL) {
|
||||
cil_reset_context(genfscon->context);
|
||||
+ } else {
|
||||
+ genfscon->context = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -331,17 +363,23 @@ static void cil_reset_netifcon(struct cil_netifcon *netifcon)
|
||||
{
|
||||
if (netifcon->if_context_str == NULL) {
|
||||
cil_reset_context(netifcon->if_context);
|
||||
+ } else {
|
||||
+ netifcon->if_context = NULL;
|
||||
}
|
||||
|
||||
if (netifcon->packet_context_str == NULL) {
|
||||
cil_reset_context(netifcon->packet_context);
|
||||
+ } else {
|
||||
+ netifcon->packet_context = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void cil_reset_ibendportcon(struct cil_ibendportcon *ibendportcon)
|
||||
{
|
||||
- if (!ibendportcon->context_str) {
|
||||
+ if (ibendportcon->context_str == NULL) {
|
||||
cil_reset_context(ibendportcon->context);
|
||||
+ } else {
|
||||
+ ibendportcon->context = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,6 +387,8 @@ static void cil_reset_pirqcon(struct cil_pirqcon *pirqcon)
|
||||
{
|
||||
if (pirqcon->context_str == NULL) {
|
||||
cil_reset_context(pirqcon->context);
|
||||
+ } else {
|
||||
+ pirqcon->context = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,6 +396,8 @@ static void cil_reset_iomemcon(struct cil_iomemcon *iomemcon)
|
||||
{
|
||||
if (iomemcon->context_str == NULL) {
|
||||
cil_reset_context(iomemcon->context);
|
||||
+ } else {
|
||||
+ iomemcon->context = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -363,6 +405,8 @@ static void cil_reset_ioportcon(struct cil_ioportcon *ioportcon)
|
||||
{
|
||||
if (ioportcon->context_str == NULL) {
|
||||
cil_reset_context(ioportcon->context);
|
||||
+ } else {
|
||||
+ ioportcon->context = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -370,6 +414,8 @@ static void cil_reset_pcidevicecon(struct cil_pcidevicecon *pcidevicecon)
|
||||
{
|
||||
if (pcidevicecon->context_str == NULL) {
|
||||
cil_reset_context(pcidevicecon->context);
|
||||
+ } else {
|
||||
+ pcidevicecon->context = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,6 +423,8 @@ static void cil_reset_devicetreecon(struct cil_devicetreecon *devicetreecon)
|
||||
{
|
||||
if (devicetreecon->context_str == NULL) {
|
||||
cil_reset_context(devicetreecon->context);
|
||||
+ } else {
|
||||
+ devicetreecon->context = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -384,6 +432,8 @@ static void cil_reset_fsuse(struct cil_fsuse *fsuse)
|
||||
{
|
||||
if (fsuse->context_str == NULL) {
|
||||
cil_reset_context(fsuse->context);
|
||||
+ } else {
|
||||
+ fsuse->context = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,39 +0,0 @@
|
||||
From d8b90f8ad1bc9dbff09312e628b48ac439ef4ef0 Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Thu, 13 May 2021 13:23:57 -0400
|
||||
Subject: [PATCH] libsepol/cil: Resolve anonymous levels only once
|
||||
|
||||
Anonymous levels can be passed as call arguments and they can
|
||||
appear in anonymous levelranges as well.
|
||||
|
||||
Anonymous call arguments are resolved when they are used in a rule.
|
||||
If more than one rule uses the anonymous level, then a memory leak
|
||||
will occur when a new list for the category datum expression is
|
||||
created without destroying the old one.
|
||||
|
||||
When resolving a level, check if the sensitivity datum has already
|
||||
been resolved. If it has, then the categories have been as well.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
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 c504e60b7c58..77ffe0ffd22b 100644
|
||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
||||
@@ -1700,6 +1700,10 @@ int cil_resolve_level(struct cil_tree_node *current, struct cil_level *level, vo
|
||||
struct cil_symtab_datum *sens_datum = NULL;
|
||||
int rc = SEPOL_ERR;
|
||||
|
||||
+ if (level->sens) {
|
||||
+ return SEPOL_OK;
|
||||
+ }
|
||||
+
|
||||
rc = cil_resolve_name(current, (char*)level->sens_str, CIL_SYM_SENS, extra_args, &sens_datum);
|
||||
if (rc != SEPOL_OK) {
|
||||
cil_log(CIL_ERR, "Failed to find sensitivity\n");
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,58 +0,0 @@
|
||||
From 644c5bbbc4c71f6636c939cb7748dd2dfa50e638 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
|
||||
Date: Tue, 8 Jun 2021 21:39:02 +0200
|
||||
Subject: [PATCH] libsepol: quote paths in CIL conversion
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
When generating CIL policy from kernel or module policy quote paths,
|
||||
which are allowed to contain spaces, in the statements `genfscon` and
|
||||
`devicetreecon`.
|
||||
|
||||
Reported by LuK1337 while building policy for Android via IRC.
|
||||
|
||||
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
|
||||
---
|
||||
libsepol/src/kernel_to_cil.c | 4 ++--
|
||||
libsepol/src/module_to_cil.c | 2 +-
|
||||
2 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/libsepol/src/kernel_to_cil.c b/libsepol/src/kernel_to_cil.c
|
||||
index 989aacde8a12..30a27bf527d5 100644
|
||||
--- a/libsepol/src/kernel_to_cil.c
|
||||
+++ b/libsepol/src/kernel_to_cil.c
|
||||
@@ -2654,7 +2654,7 @@ static int write_genfscon_rules_to_cil(FILE *out, struct policydb *pdb)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
- rc = strs_create_and_add(strs, "(genfscon %s %s %s)", 3,
|
||||
+ rc = strs_create_and_add(strs, "(genfscon %s \"%s\" %s)", 3,
|
||||
fstype, name, ctx);
|
||||
free(ctx);
|
||||
if (rc != 0) {
|
||||
@@ -3115,7 +3115,7 @@ static int write_xen_devicetree_rules_to_cil(FILE *out, struct policydb *pdb)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
- sepol_printf(out, "(devicetreecon %s %s)\n", name, ctx);
|
||||
+ sepol_printf(out, "(devicetreecon \"%s\" %s)\n", name, ctx);
|
||||
|
||||
free(ctx);
|
||||
}
|
||||
diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c
|
||||
index 496693f4616e..19c7c65c6382 100644
|
||||
--- a/libsepol/src/module_to_cil.c
|
||||
+++ b/libsepol/src/module_to_cil.c
|
||||
@@ -2963,7 +2963,7 @@ static int genfscon_to_cil(struct policydb *pdb)
|
||||
|
||||
for (genfs = pdb->genfs; genfs != NULL; genfs = genfs->next) {
|
||||
for (ocon = genfs->head; ocon != NULL; ocon = ocon->next) {
|
||||
- cil_printf("(genfscon %s %s ", genfs->fstype, ocon->u.name);
|
||||
+ cil_printf("(genfscon %s \"%s\" ", genfs->fstype, ocon->u.name);
|
||||
context_to_cil(pdb, &ocon->context[0]);
|
||||
cil_printf(")\n");
|
||||
}
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,93 +0,0 @@
|
||||
From 9ac9d2dab40826abe049fd07d21a20386fe5b38b Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Mon, 14 Jun 2021 12:53:25 -0400
|
||||
Subject: [PATCH] libsepol/cil: Fix anonymous IP address call arguments
|
||||
|
||||
A named IP address (using an ipaddr rule) could be passed as an
|
||||
argument, but trying to pass an actual IP address caused an error.
|
||||
|
||||
As an exmample, consider the following portion of a policy.
|
||||
(macro m4 ((ipaddr ip)(ipaddr nm))
|
||||
(nodecon ip nm (USER ROLE TYPE ((s0) (s0))))
|
||||
)
|
||||
(ipaddr nm1 255.255.255.0)
|
||||
(ipaddr ip1 1.2.3.4)
|
||||
(call m4 (ip1 nm1)) ; This works
|
||||
(call m4 (1.2.3.4 255.255.255.0)) ; This doesn't
|
||||
|
||||
Allow actual IP addresses to be passed as a call argument. Now the
|
||||
second call works as well.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
Acked-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
||||
---
|
||||
libsepol/cil/src/cil_build_ast.c | 4 ----
|
||||
libsepol/cil/src/cil_resolve_ast.c | 23 ++++++++++-------------
|
||||
2 files changed, 10 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
|
||||
index 71f14e20e25e..538df2794ade 100644
|
||||
--- a/libsepol/cil/src/cil_build_ast.c
|
||||
+++ b/libsepol/cil/src/cil_build_ast.c
|
||||
@@ -5642,10 +5642,6 @@ int cil_fill_ipaddr(struct cil_tree_node *addr_node, struct cil_ipaddr *addr)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
- if (addr_node->cl_head != NULL || addr_node->next != NULL) {
|
||||
- goto exit;
|
||||
- }
|
||||
-
|
||||
if (strchr(addr_node->data, '.') != NULL) {
|
||||
addr->family = AF_INET;
|
||||
} else {
|
||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
||||
index 77ffe0ffd22b..16c8c7533ce3 100644
|
||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
||||
@@ -3024,14 +3024,18 @@ static int cil_build_call_args(struct cil_tree_node *call_node, struct cil_call
|
||||
break;
|
||||
}
|
||||
case CIL_IPADDR: {
|
||||
- if (arg_node->cl_head != NULL) {
|
||||
+ if (arg_node->data == NULL) {
|
||||
+ cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
|
||||
+ cil_destroy_args(arg);
|
||||
+ rc = SEPOL_ERR;
|
||||
+ goto exit;
|
||||
+ } else if (strchr(arg_node->data, '.') || strchr(arg_node->data, ':')) {
|
||||
struct cil_ipaddr *ipaddr = NULL;
|
||||
struct cil_tree_node *addr_node = NULL;
|
||||
cil_ipaddr_init(&ipaddr);
|
||||
-
|
||||
- rc = cil_fill_ipaddr(arg_node->cl_head, ipaddr);
|
||||
+ rc = cil_fill_ipaddr(arg_node, ipaddr);
|
||||
if (rc != SEPOL_OK) {
|
||||
- cil_log(CIL_ERR, "Failed to create anonymous ip address, rc: %d\n", rc);
|
||||
+ cil_tree_log(call_node, CIL_ERR, "Failed to create anonymous ip address");
|
||||
cil_destroy_ipaddr(ipaddr);
|
||||
cil_destroy_args(arg);
|
||||
goto exit;
|
||||
@@ -3039,18 +3043,11 @@ static int cil_build_call_args(struct cil_tree_node *call_node, struct cil_call
|
||||
cil_tree_node_init(&addr_node);
|
||||
addr_node->flavor = CIL_IPADDR;
|
||||
addr_node->data = ipaddr;
|
||||
- cil_list_append(((struct cil_symtab_datum*)ipaddr)->nodes,
|
||||
- CIL_LIST_ITEM, addr_node);
|
||||
- arg->arg = (struct cil_symtab_datum*)ipaddr;
|
||||
- } else if (arg_node->data == NULL) {
|
||||
- cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
|
||||
- cil_destroy_args(arg);
|
||||
- rc = SEPOL_ERR;
|
||||
- goto exit;
|
||||
+ cil_list_append(DATUM(ipaddr)->nodes, CIL_LIST_ITEM, addr_node);
|
||||
+ arg->arg = DATUM(ipaddr);
|
||||
} else {
|
||||
arg->arg_str = arg_node->data;
|
||||
}
|
||||
-
|
||||
break;
|
||||
}
|
||||
case CIL_CLASS:
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,90 +0,0 @@
|
||||
From 982ec302b67f3c7f8df667dadb67352b1e4a6d18 Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Tue, 15 Jun 2021 10:40:20 -0400
|
||||
Subject: [PATCH] libsepol/cil: Account for anonymous category sets in an
|
||||
expression
|
||||
|
||||
It is possible for anonymous category sets to be in a category
|
||||
expression if the expression has a macro parameter in it.
|
||||
Unfortunately, anonymous category sets are not looked for when
|
||||
resolving category expressions and a segfault will occur during
|
||||
later processing if there was one.
|
||||
|
||||
As an example, consider the following portion of a policy.
|
||||
(macro m1 ((categoryset cs))
|
||||
(userlevel USER (s0 (cs)))
|
||||
)
|
||||
(call m1 ((c0 c1)))
|
||||
This policy will cause a segault, because the categoryset datum
|
||||
for the parameter cs is not seen as a categoryset and is treated
|
||||
as a plain category.
|
||||
|
||||
When resolving an expression, check whether or not the datum that
|
||||
is found is actually an anonymous category set associated with a
|
||||
macro parameter. If it is, then resolve the category set if it
|
||||
has not already been resolved and treat its categories as a sub
|
||||
expression.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
Acked-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
||||
---
|
||||
libsepol/cil/src/cil_resolve_ast.c | 24 +++++++++++++++++-------
|
||||
1 file changed, 17 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
||||
index 16c8c7533ce3..42a58468ed36 100644
|
||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
||||
@@ -3346,6 +3346,7 @@ int cil_resolve_expr(enum cil_flavor expr_type, struct cil_list *str_expr, struc
|
||||
struct cil_list_item *curr;
|
||||
struct cil_symtab_datum *res_datum = NULL;
|
||||
enum cil_sym_index sym_index = CIL_SYM_UNKNOWN;
|
||||
+ struct cil_list *datum_sub_expr;
|
||||
|
||||
switch (str_expr->flavor) {
|
||||
case CIL_BOOL:
|
||||
@@ -3379,18 +3380,26 @@ int cil_resolve_expr(enum cil_flavor expr_type, struct cil_list *str_expr, struc
|
||||
if (rc != SEPOL_OK) {
|
||||
goto exit;
|
||||
}
|
||||
-
|
||||
- if (sym_index == CIL_SYM_TYPES && (expr_type == CIL_CONSTRAIN || expr_type == CIL_VALIDATETRANS)) {
|
||||
- cil_type_used(res_datum, CIL_ATTR_CONSTRAINT);
|
||||
+ if (sym_index == CIL_SYM_CATS && NODE(res_datum)->flavor == CIL_CATSET) {
|
||||
+ struct cil_catset *catset = (struct cil_catset *)res_datum;
|
||||
+ if (!catset->cats->datum_expr) {
|
||||
+ rc = cil_resolve_expr(expr_type, catset->cats->str_expr, &catset->cats->datum_expr, parent, extra_args);
|
||||
+ if (rc != SEPOL_OK) {
|
||||
+ goto exit;
|
||||
+ }
|
||||
+ }
|
||||
+ cil_copy_list(catset->cats->datum_expr, &datum_sub_expr);
|
||||
+ cil_list_append(*datum_expr, CIL_LIST, datum_sub_expr);
|
||||
+ } else {
|
||||
+ if (sym_index == CIL_SYM_TYPES && (expr_type == CIL_CONSTRAIN || expr_type == CIL_VALIDATETRANS)) {
|
||||
+ cil_type_used(res_datum, CIL_ATTR_CONSTRAINT);
|
||||
+ }
|
||||
+ cil_list_append(*datum_expr, CIL_DATUM, res_datum);
|
||||
}
|
||||
-
|
||||
- cil_list_append(*datum_expr, CIL_DATUM, res_datum);
|
||||
break;
|
||||
case CIL_LIST: {
|
||||
- struct cil_list *datum_sub_expr;
|
||||
rc = cil_resolve_expr(expr_type, curr->data, &datum_sub_expr, parent, extra_args);
|
||||
if (rc != SEPOL_OK) {
|
||||
- cil_list_destroy(&datum_sub_expr, CIL_TRUE);
|
||||
goto exit;
|
||||
}
|
||||
cil_list_append(*datum_expr, CIL_LIST, datum_sub_expr);
|
||||
@@ -3404,6 +3413,7 @@ int cil_resolve_expr(enum cil_flavor expr_type, struct cil_list *str_expr, struc
|
||||
return SEPOL_OK;
|
||||
|
||||
exit:
|
||||
+ cil_list_destroy(datum_expr, CIL_FALSE);
|
||||
return rc;
|
||||
}
|
||||
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,46 +0,0 @@
|
||||
From ce1025bf9ccd2e34a0c12d9a1d8eee19eb415573 Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Tue, 15 Jun 2021 16:31:01 -0400
|
||||
Subject: [PATCH] libsepol: Quote paths when generating policy.conf from binary
|
||||
policy
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Christian Göttsche <cgzones@googlemail.com> submitted a similar patch
|
||||
to quote paths when generating CIL policy from a binary policy.
|
||||
|
||||
Since genfscon and devicetreecon rules have paths which are allowed
|
||||
to contain spaces, always quote the path when writing out these rules.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
Acked-by: Petr Lautrbach <plautrba@redhat.com>
|
||||
---
|
||||
libsepol/src/kernel_to_conf.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libsepol/src/kernel_to_conf.c b/libsepol/src/kernel_to_conf.c
|
||||
index 5db47fe4f567..ffdf179a71f3 100644
|
||||
--- a/libsepol/src/kernel_to_conf.c
|
||||
+++ b/libsepol/src/kernel_to_conf.c
|
||||
@@ -2527,7 +2527,7 @@ static int write_genfscon_rules_to_conf(FILE *out, struct policydb *pdb)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
- rc = strs_create_and_add(strs, "genfscon %s %s %s", 3,
|
||||
+ rc = strs_create_and_add(strs, "genfscon %s \"%s\" %s", 3,
|
||||
fstype, name, ctx);
|
||||
free(ctx);
|
||||
if (rc != 0) {
|
||||
@@ -2992,7 +2992,7 @@ static int write_xen_devicetree_rules_to_conf(FILE *out, struct policydb *pdb)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
- sepol_printf(out, "devicetreecon %s %s\n", name, ctx);
|
||||
+ sepol_printf(out, "devicetreecon \"%s\" %s\n", name, ctx);
|
||||
|
||||
free(ctx);
|
||||
}
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,72 +0,0 @@
|
||||
From 2cb6bacddcd6957a8f28ce51a089e8514af3d574 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:50 +0200
|
||||
Subject: [PATCH] libsepol: fix typos
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
|
||||
Acked-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_build_ast.c | 2 +-
|
||||
libsepol/cil/src/cil_resolve_ast.c | 2 +-
|
||||
libsepol/src/module_to_cil.c | 2 +-
|
||||
libsepol/src/policydb_validate.c | 2 +-
|
||||
4 files changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
|
||||
index 538df2794ade..96c97263d8c8 100644
|
||||
--- a/libsepol/cil/src/cil_build_ast.c
|
||||
+++ b/libsepol/cil/src/cil_build_ast.c
|
||||
@@ -3692,7 +3692,7 @@ int cil_gen_sensitivityorder(struct cil_db *db, struct cil_tree_node *parse_curr
|
||||
|
||||
cil_list_for_each(curr, sensorder->sens_list_str) {
|
||||
if (curr->data == CIL_KEY_UNORDERED) {
|
||||
- cil_log(CIL_ERR, "Sensitivy order cannot be unordered.\n");
|
||||
+ cil_log(CIL_ERR, "Sensitivity order cannot be unordered.\n");
|
||||
rc = SEPOL_ERR;
|
||||
goto exit;
|
||||
}
|
||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
||||
index 42a58468ed36..92a4d29700e9 100644
|
||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
||||
@@ -1619,7 +1619,7 @@ int cil_resolve_sensitivityorder(struct cil_tree_node *current, void *extra_args
|
||||
cil_list_for_each(curr, sensorder->sens_list_str) {
|
||||
rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_SENS, extra_args, &datum);
|
||||
if (rc != SEPOL_OK) {
|
||||
- cil_log(CIL_ERR, "Failed to resolve sensitivty %s in sensitivityorder\n", (char *)curr->data);
|
||||
+ cil_log(CIL_ERR, "Failed to resolve sensitivity %s in sensitivityorder\n", (char *)curr->data);
|
||||
goto exit;
|
||||
}
|
||||
if (FLAVOR(datum) != CIL_SENS) {
|
||||
diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c
|
||||
index 19c7c65c6382..60290da2a75f 100644
|
||||
--- a/libsepol/src/module_to_cil.c
|
||||
+++ b/libsepol/src/module_to_cil.c
|
||||
@@ -3972,7 +3972,7 @@ int sepol_module_policydb_to_cil(FILE *fp, struct policydb *pdb, int linked)
|
||||
|
||||
if (pdb->policy_type != SEPOL_POLICY_BASE &&
|
||||
pdb->policy_type != SEPOL_POLICY_MOD) {
|
||||
- log_err("Policy pakcage is not a base or module");
|
||||
+ log_err("Policy package is not a base or module");
|
||||
rc = -1;
|
||||
goto exit;
|
||||
}
|
||||
diff --git a/libsepol/src/policydb_validate.c b/libsepol/src/policydb_validate.c
|
||||
index b2891ddd64f3..246aa6e398f3 100644
|
||||
--- a/libsepol/src/policydb_validate.c
|
||||
+++ b/libsepol/src/policydb_validate.c
|
||||
@@ -641,7 +641,7 @@ static int validate_scope_index(sepol_handle_t *handle, scope_index_t *scope_ind
|
||||
return 0;
|
||||
|
||||
bad:
|
||||
- ERR(handle, "Invalide scope");
|
||||
+ ERR(handle, "Invalid scope");
|
||||
return -1;
|
||||
}
|
||||
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,203 +0,0 @@
|
||||
From 9ec061b61c97878ac4d2626803dfbdd3fcbe0c87 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:51 +0200
|
||||
Subject: [PATCH] libsepol: resolve missing prototypes
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Declare the functions as static or include the corresponding header
|
||||
file.
|
||||
|
||||
assertion.c:294:5: error: no previous prototype for function 'report_assertion_failures' [-Werror,-Wmissing-prototypes]
|
||||
int report_assertion_failures(sepol_handle_t *handle, policydb_t *p, avrule_t *avrule)
|
||||
^
|
||||
|
||||
context.c:23:5: error: no previous prototype for function 'sepol_check_context' [-Werror,-Wmissing-prototypes]
|
||||
int sepol_check_context(const char *context)
|
||||
^
|
||||
|
||||
expand.c:3377:5: error: no previous prototype for function 'expand_cond_av_node' [-Werror,-Wmissing-prototypes]
|
||||
int expand_cond_av_node(policydb_t * p,
|
||||
^
|
||||
|
||||
policydb.c:638:6: error: no previous prototype for function 'role_trans_rule_destroy' [-Werror,-Wmissing-prototypes]
|
||||
void role_trans_rule_destroy(role_trans_rule_t * x)
|
||||
^
|
||||
|
||||
policydb.c:1169:5: error: no previous prototype for function 'policydb_index_decls' [-Werror,-Wmissing-prototypes]
|
||||
int policydb_index_decls(sepol_handle_t * handle, policydb_t * p)
|
||||
^
|
||||
|
||||
policydb.c:1429:6: error: no previous prototype for function 'ocontext_selinux_free' [-Werror,-Wmissing-prototypes]
|
||||
void ocontext_selinux_free(ocontext_t **ocontexts)
|
||||
^
|
||||
|
||||
policydb.c:1451:6: error: no previous prototype for function 'ocontext_xen_free' [-Werror,-Wmissing-prototypes]
|
||||
void ocontext_xen_free(ocontext_t **ocontexts)
|
||||
^
|
||||
|
||||
policydb.c:1750:5: error: no previous prototype for function 'type_set_or' [-Werror,-Wmissing-prototypes]
|
||||
int type_set_or(type_set_t * dst, type_set_t * a, type_set_t * b)
|
||||
^
|
||||
|
||||
policydb.c:2524:5: error: no previous prototype for function 'role_trans_read' [-Werror,-Wmissing-prototypes]
|
||||
int role_trans_read(policydb_t *p, struct policy_file *fp)
|
||||
^
|
||||
|
||||
policydb.c:2567:5: error: no previous prototype for function 'role_allow_read' [-Werror,-Wmissing-prototypes]
|
||||
int role_allow_read(role_allow_t ** r, struct policy_file *fp)
|
||||
^
|
||||
|
||||
policydb.c:2842:5: error: no previous prototype for function 'filename_trans_read' [-Werror,-Wmissing-prototypes]
|
||||
int filename_trans_read(policydb_t *p, struct policy_file *fp)
|
||||
^
|
||||
|
||||
services.c:1027:5: error: no previous prototype for function 'sepol_validate_transition' [-Werror,-Wmissing-prototypes]
|
||||
int sepol_validate_transition(sepol_security_id_t oldsid,
|
||||
^
|
||||
|
||||
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
|
||||
Acked-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/src/assertion.c | 2 +-
|
||||
libsepol/src/context_internal.h | 1 +
|
||||
libsepol/src/expand.c | 6 +++---
|
||||
libsepol/src/policydb.c | 16 ++++++++--------
|
||||
libsepol/src/services.c | 2 +-
|
||||
5 files changed, 14 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/libsepol/src/assertion.c b/libsepol/src/assertion.c
|
||||
index 266f67d74c56..dd2749a09dc0 100644
|
||||
--- a/libsepol/src/assertion.c
|
||||
+++ b/libsepol/src/assertion.c
|
||||
@@ -291,7 +291,7 @@ exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
-int report_assertion_failures(sepol_handle_t *handle, policydb_t *p, avrule_t *avrule)
|
||||
+static int report_assertion_failures(sepol_handle_t *handle, policydb_t *p, avrule_t *avrule)
|
||||
{
|
||||
int rc;
|
||||
struct avtab_match_args args;
|
||||
diff --git a/libsepol/src/context_internal.h b/libsepol/src/context_internal.h
|
||||
index 3cae28cc1c67..3dc9cd156a9c 100644
|
||||
--- a/libsepol/src/context_internal.h
|
||||
+++ b/libsepol/src/context_internal.h
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef _SEPOL_CONTEXT_INTERNAL_H_
|
||||
#define _SEPOL_CONTEXT_INTERNAL_H_
|
||||
|
||||
+#include <sepol/context.h>
|
||||
#include <sepol/context_record.h>
|
||||
|
||||
#endif
|
||||
diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c
|
||||
index a656ffad3a71..84bfcfa36d0a 100644
|
||||
--- a/libsepol/src/expand.c
|
||||
+++ b/libsepol/src/expand.c
|
||||
@@ -3374,9 +3374,9 @@ static int expand_cond_insert(cond_av_list_t ** l,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int expand_cond_av_node(policydb_t * p,
|
||||
- avtab_ptr_t node,
|
||||
- cond_av_list_t ** newl, avtab_t * expa)
|
||||
+static int expand_cond_av_node(policydb_t * p,
|
||||
+ avtab_ptr_t node,
|
||||
+ cond_av_list_t ** newl, avtab_t * expa)
|
||||
{
|
||||
avtab_key_t *k = &node->key;
|
||||
avtab_datum_t *d = &node->datum;
|
||||
diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
|
||||
index ffa279715686..3f7ddb11a236 100644
|
||||
--- a/libsepol/src/policydb.c
|
||||
+++ b/libsepol/src/policydb.c
|
||||
@@ -635,7 +635,7 @@ void role_trans_rule_init(role_trans_rule_t * x)
|
||||
ebitmap_init(&x->classes);
|
||||
}
|
||||
|
||||
-void role_trans_rule_destroy(role_trans_rule_t * x)
|
||||
+static void role_trans_rule_destroy(role_trans_rule_t * x)
|
||||
{
|
||||
if (x != NULL) {
|
||||
role_set_destroy(&x->roles);
|
||||
@@ -1166,7 +1166,7 @@ int policydb_index_bools(policydb_t * p)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int policydb_index_decls(sepol_handle_t * handle, policydb_t * p)
|
||||
+static int policydb_index_decls(sepol_handle_t * handle, policydb_t * p)
|
||||
{
|
||||
avrule_block_t *curblock;
|
||||
avrule_decl_t *decl;
|
||||
@@ -1426,7 +1426,7 @@ static int range_tr_destroy(hashtab_key_t key, hashtab_datum_t datum,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-void ocontext_selinux_free(ocontext_t **ocontexts)
|
||||
+static void ocontext_selinux_free(ocontext_t **ocontexts)
|
||||
{
|
||||
ocontext_t *c, *ctmp;
|
||||
int i;
|
||||
@@ -1448,7 +1448,7 @@ void ocontext_selinux_free(ocontext_t **ocontexts)
|
||||
}
|
||||
}
|
||||
|
||||
-void ocontext_xen_free(ocontext_t **ocontexts)
|
||||
+static void ocontext_xen_free(ocontext_t **ocontexts)
|
||||
{
|
||||
ocontext_t *c, *ctmp;
|
||||
int i;
|
||||
@@ -1747,7 +1747,7 @@ int symtab_insert(policydb_t * pol, uint32_t sym,
|
||||
return retval;
|
||||
}
|
||||
|
||||
-int type_set_or(type_set_t * dst, type_set_t * a, type_set_t * b)
|
||||
+static int type_set_or(type_set_t * dst, type_set_t * a, type_set_t * b)
|
||||
{
|
||||
type_set_init(dst);
|
||||
|
||||
@@ -2521,7 +2521,7 @@ static int type_read(policydb_t * p, hashtab_t h, struct policy_file *fp)
|
||||
return -1;
|
||||
}
|
||||
|
||||
-int role_trans_read(policydb_t *p, struct policy_file *fp)
|
||||
+static int role_trans_read(policydb_t *p, struct policy_file *fp)
|
||||
{
|
||||
role_trans_t **t = &p->role_tr;
|
||||
unsigned int i;
|
||||
@@ -2564,7 +2564,7 @@ int role_trans_read(policydb_t *p, struct policy_file *fp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int role_allow_read(role_allow_t ** r, struct policy_file *fp)
|
||||
+static int role_allow_read(role_allow_t ** r, struct policy_file *fp)
|
||||
{
|
||||
unsigned int i;
|
||||
uint32_t buf[2], nel;
|
||||
@@ -2839,7 +2839,7 @@ err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
-int filename_trans_read(policydb_t *p, struct policy_file *fp)
|
||||
+static int filename_trans_read(policydb_t *p, struct policy_file *fp)
|
||||
{
|
||||
unsigned int i;
|
||||
uint32_t buf[1], nel;
|
||||
diff --git a/libsepol/src/services.c b/libsepol/src/services.c
|
||||
index 6596431c38e2..39fbd979b095 100644
|
||||
--- a/libsepol/src/services.c
|
||||
+++ b/libsepol/src/services.c
|
||||
@@ -1024,7 +1024,7 @@ static int context_struct_compute_av(context_struct_t * scontext,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int sepol_validate_transition(sepol_security_id_t oldsid,
|
||||
+static int sepol_validate_transition(sepol_security_id_t oldsid,
|
||||
sepol_security_id_t newsid,
|
||||
sepol_security_id_t tasksid,
|
||||
sepol_security_class_t tclass)
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,151 +0,0 @@
|
||||
From 42f3d7cceb1e15f10eb8e886e6f07ee3c3c6130f 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:52 +0200
|
||||
Subject: [PATCH] libsepol: remove unused functions
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The functions `role_set_get_role`, `sepol_validate_transition` and
|
||||
`sepol_sidtab_remove` seem to be unused since the initial import.
|
||||
|
||||
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
|
||||
Acked-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/src/policydb.c | 18 ----------------
|
||||
libsepol/src/services.c | 47 -----------------------------------------
|
||||
libsepol/src/sidtab.c | 31 ---------------------------
|
||||
3 files changed, 96 deletions(-)
|
||||
|
||||
diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
|
||||
index 3f7ddb11a236..fc1d07112efb 100644
|
||||
--- a/libsepol/src/policydb.c
|
||||
+++ b/libsepol/src/policydb.c
|
||||
@@ -1791,24 +1791,6 @@ int type_set_or_eq(type_set_t * dst, type_set_t * other)
|
||||
return ret;
|
||||
}
|
||||
|
||||
-int role_set_get_role(role_set_t * x, uint32_t role)
|
||||
-{
|
||||
- if (x->flags & ROLE_STAR)
|
||||
- return 1;
|
||||
-
|
||||
- if (ebitmap_get_bit(&x->roles, role - 1)) {
|
||||
- if (x->flags & ROLE_COMP)
|
||||
- return 0;
|
||||
- else
|
||||
- return 1;
|
||||
- } else {
|
||||
- if (x->flags & ROLE_COMP)
|
||||
- return 1;
|
||||
- else
|
||||
- return 0;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
/***********************************************************************/
|
||||
/* everything below is for policy reads */
|
||||
|
||||
diff --git a/libsepol/src/services.c b/libsepol/src/services.c
|
||||
index 39fbd979b095..ff91f7d2fdfc 100644
|
||||
--- a/libsepol/src/services.c
|
||||
+++ b/libsepol/src/services.c
|
||||
@@ -1024,53 +1024,6 @@ static int context_struct_compute_av(context_struct_t * scontext,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int sepol_validate_transition(sepol_security_id_t oldsid,
|
||||
- sepol_security_id_t newsid,
|
||||
- sepol_security_id_t tasksid,
|
||||
- sepol_security_class_t tclass)
|
||||
-{
|
||||
- context_struct_t *ocontext;
|
||||
- context_struct_t *ncontext;
|
||||
- context_struct_t *tcontext;
|
||||
- class_datum_t *tclass_datum;
|
||||
- constraint_node_t *constraint;
|
||||
-
|
||||
- if (!tclass || tclass > policydb->p_classes.nprim) {
|
||||
- ERR(NULL, "unrecognized class %d", tclass);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
- tclass_datum = policydb->class_val_to_struct[tclass - 1];
|
||||
-
|
||||
- ocontext = sepol_sidtab_search(sidtab, oldsid);
|
||||
- if (!ocontext) {
|
||||
- ERR(NULL, "unrecognized SID %d", oldsid);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- ncontext = sepol_sidtab_search(sidtab, newsid);
|
||||
- if (!ncontext) {
|
||||
- ERR(NULL, "unrecognized SID %d", newsid);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- tcontext = sepol_sidtab_search(sidtab, tasksid);
|
||||
- if (!tcontext) {
|
||||
- ERR(NULL, "unrecognized SID %d", tasksid);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- constraint = tclass_datum->validatetrans;
|
||||
- while (constraint) {
|
||||
- if (!constraint_expr_eval_reason(ocontext, ncontext, tcontext,
|
||||
- 0, constraint, NULL, 0)) {
|
||||
- return -EPERM;
|
||||
- }
|
||||
- constraint = constraint->next;
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
/*
|
||||
* sepol_validate_transition_reason_buffer - the reason buffer is realloc'd
|
||||
* in the constraint_expr_eval_reason() function.
|
||||
diff --git a/libsepol/src/sidtab.c b/libsepol/src/sidtab.c
|
||||
index e6bf57161e52..255e07252412 100644
|
||||
--- a/libsepol/src/sidtab.c
|
||||
+++ b/libsepol/src/sidtab.c
|
||||
@@ -84,37 +84,6 @@ int sepol_sidtab_insert(sidtab_t * s, sepol_security_id_t sid,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int sepol_sidtab_remove(sidtab_t * s, sepol_security_id_t sid)
|
||||
-{
|
||||
- int hvalue;
|
||||
- sidtab_node_t *cur, *last;
|
||||
-
|
||||
- if (!s || !s->htable)
|
||||
- return -ENOENT;
|
||||
-
|
||||
- hvalue = SIDTAB_HASH(sid);
|
||||
- last = NULL;
|
||||
- cur = s->htable[hvalue];
|
||||
- while (cur != NULL && sid > cur->sid) {
|
||||
- last = cur;
|
||||
- cur = cur->next;
|
||||
- }
|
||||
-
|
||||
- if (cur == NULL || sid != cur->sid)
|
||||
- return -ENOENT;
|
||||
-
|
||||
- if (last == NULL)
|
||||
- s->htable[hvalue] = cur->next;
|
||||
- else
|
||||
- last->next = cur->next;
|
||||
-
|
||||
- context_destroy(&cur->context);
|
||||
-
|
||||
- free(cur);
|
||||
- s->nel--;
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
context_struct_t *sepol_sidtab_search(sidtab_t * s, sepol_security_id_t sid)
|
||||
{
|
||||
int hvalue;
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,47 +0,0 @@
|
||||
From 1537ea8412e4af832b53ac48b7d85eac00426a92 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:55 +0200
|
||||
Subject: [PATCH] libsepol: avoid unsigned integer overflow
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Unsigned integer overflow is well-defined and not undefined behavior.
|
||||
But it is still useful to enable undefined behavior sanitizer checks on
|
||||
unsigned arithmetic to detect possible issues on counters or variables
|
||||
with similar purpose.
|
||||
|
||||
Use a spaceship operator like comparison instead of subtraction.
|
||||
|
||||
Modern compilers will generate a single comparison instruction instead
|
||||
of actually perform the subtraction.
|
||||
|
||||
policydb.c:826:17: runtime error: unsigned integer overflow: 24 - 1699 cannot be represented in type 'unsigned int'
|
||||
|
||||
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
|
||||
Acked-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/src/policydb.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
|
||||
index fc1d07112efb..e0b072e1938f 100644
|
||||
--- a/libsepol/src/policydb.c
|
||||
+++ b/libsepol/src/policydb.c
|
||||
@@ -817,11 +817,11 @@ static int filenametr_cmp(hashtab_t h __attribute__ ((unused)),
|
||||
const filename_trans_key_t *ft2 = (const filename_trans_key_t *)k2;
|
||||
int v;
|
||||
|
||||
- v = ft1->ttype - ft2->ttype;
|
||||
+ v = (ft1->ttype > ft2->ttype) - (ft1->ttype < ft2->ttype);
|
||||
if (v)
|
||||
return v;
|
||||
|
||||
- v = ft1->tclass - ft2->tclass;
|
||||
+ v = (ft1->tclass > ft2->tclass) - (ft1->tclass < ft2->tclass);
|
||||
if (v)
|
||||
return v;
|
||||
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,335 +0,0 @@
|
||||
From 8f50b45320f715aa7ab883fe3540017bdc097e20 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:56 +0200
|
||||
Subject: [PATCH] libsepol: 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/src/booleans.c | 6 ++--
|
||||
libsepol/src/debug.c | 2 +-
|
||||
libsepol/src/ebitmap.c | 11 ++++---
|
||||
libsepol/src/module_to_cil.c | 10 +++---
|
||||
libsepol/src/nodes.c | 6 ++--
|
||||
libsepol/src/services.c | 59 ++++++++++++++++++------------------
|
||||
libsepol/src/util.c | 2 +-
|
||||
7 files changed, 50 insertions(+), 46 deletions(-)
|
||||
|
||||
diff --git a/libsepol/src/booleans.c b/libsepol/src/booleans.c
|
||||
index 30fcf29d892b..716da6b487a9 100644
|
||||
--- a/libsepol/src/booleans.c
|
||||
+++ b/libsepol/src/booleans.c
|
||||
@@ -19,6 +19,7 @@ static int bool_update(sepol_handle_t * handle,
|
||||
const char *cname;
|
||||
char *name;
|
||||
int value;
|
||||
+ cond_bool_datum_t *datum;
|
||||
|
||||
sepol_bool_key_unpack(key, &cname);
|
||||
name = strdup(cname);
|
||||
@@ -27,8 +28,7 @@ static int bool_update(sepol_handle_t * handle,
|
||||
if (!name)
|
||||
goto omem;
|
||||
|
||||
- cond_bool_datum_t *datum =
|
||||
- hashtab_search(policydb->p_bools.table, name);
|
||||
+ datum = hashtab_search(policydb->p_bools.table, name);
|
||||
if (!datum) {
|
||||
ERR(handle, "boolean %s no longer in policy", name);
|
||||
goto err;
|
||||
@@ -84,10 +84,10 @@ int sepol_bool_set(sepol_handle_t * handle,
|
||||
const sepol_bool_key_t * key, const sepol_bool_t * data)
|
||||
{
|
||||
|
||||
+ policydb_t *policydb = &p->p;
|
||||
const char *name;
|
||||
sepol_bool_key_unpack(key, &name);
|
||||
|
||||
- policydb_t *policydb = &p->p;
|
||||
if (bool_update(handle, policydb, key, data) < 0)
|
||||
goto err;
|
||||
|
||||
diff --git a/libsepol/src/debug.c b/libsepol/src/debug.c
|
||||
index 0458e3538884..f6a59ae701ed 100644
|
||||
--- a/libsepol/src/debug.c
|
||||
+++ b/libsepol/src/debug.c
|
||||
@@ -44,6 +44,7 @@ void sepol_msg_default_handler(void *varg __attribute__ ((unused)),
|
||||
{
|
||||
|
||||
FILE *stream = NULL;
|
||||
+ va_list ap;
|
||||
|
||||
switch (sepol_msg_get_level(handle)) {
|
||||
|
||||
@@ -60,7 +61,6 @@ void sepol_msg_default_handler(void *varg __attribute__ ((unused)),
|
||||
fprintf(stream, "%s.%s: ",
|
||||
sepol_msg_get_channel(handle), sepol_msg_get_fname(handle));
|
||||
|
||||
- va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stream, fmt, ap);
|
||||
va_end(ap);
|
||||
diff --git a/libsepol/src/ebitmap.c b/libsepol/src/ebitmap.c
|
||||
index 7f425349c229..522e14a68a94 100644
|
||||
--- a/libsepol/src/ebitmap.c
|
||||
+++ b/libsepol/src/ebitmap.c
|
||||
@@ -113,9 +113,10 @@ int ebitmap_not(ebitmap_t *dst, ebitmap_t *e1, unsigned int maxbit)
|
||||
|
||||
int ebitmap_andnot(ebitmap_t *dst, ebitmap_t *e1, ebitmap_t *e2, unsigned int maxbit)
|
||||
{
|
||||
+ int rc;
|
||||
ebitmap_t e3;
|
||||
ebitmap_init(dst);
|
||||
- int rc = ebitmap_not(&e3, e2, maxbit);
|
||||
+ rc = ebitmap_not(&e3, e2, maxbit);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
rc = ebitmap_and(dst, e1, &e3);
|
||||
@@ -138,13 +139,15 @@ unsigned int ebitmap_cardinality(ebitmap_t *e1)
|
||||
|
||||
int ebitmap_hamming_distance(ebitmap_t * e1, ebitmap_t * e2)
|
||||
{
|
||||
+ int rc;
|
||||
+ ebitmap_t tmp;
|
||||
+ int distance;
|
||||
if (ebitmap_cmp(e1, e2))
|
||||
return 0;
|
||||
- ebitmap_t tmp;
|
||||
- int rc = ebitmap_xor(&tmp, e1, e2);
|
||||
+ rc = ebitmap_xor(&tmp, e1, e2);
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
- int distance = ebitmap_cardinality(&tmp);
|
||||
+ distance = ebitmap_cardinality(&tmp);
|
||||
ebitmap_destroy(&tmp);
|
||||
return distance;
|
||||
}
|
||||
diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c
|
||||
index 60290da2a75f..580ba06a95b0 100644
|
||||
--- a/libsepol/src/module_to_cil.c
|
||||
+++ b/libsepol/src/module_to_cil.c
|
||||
@@ -107,8 +107,8 @@ static void cil_printf(const char *fmt, ...) {
|
||||
__attribute__ ((format(printf, 2, 3)))
|
||||
static void cil_println(int indent, const char *fmt, ...)
|
||||
{
|
||||
- cil_indent(indent);
|
||||
va_list argptr;
|
||||
+ cil_indent(indent);
|
||||
va_start(argptr, fmt);
|
||||
if (vfprintf(out_file, fmt, argptr) < 0) {
|
||||
log_err("Failed to write to output");
|
||||
@@ -235,12 +235,14 @@ static void role_list_destroy(void)
|
||||
|
||||
static void attr_list_destroy(struct list **attr_list)
|
||||
{
|
||||
+ struct list_node *curr;
|
||||
+ struct attr_list_node *attr;
|
||||
+
|
||||
if (attr_list == NULL || *attr_list == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
- struct list_node *curr = (*attr_list)->head;
|
||||
- struct attr_list_node *attr;
|
||||
+ curr = (*attr_list)->head;
|
||||
|
||||
while (curr != NULL) {
|
||||
attr = curr->data;
|
||||
@@ -3525,12 +3527,12 @@ exit:
|
||||
static int additive_scopes_to_cil(int indent, struct policydb *pdb, struct avrule_block *block, struct stack *decl_stack)
|
||||
{
|
||||
int rc = -1;
|
||||
+ struct avrule_decl *decl = stack_peek(decl_stack);
|
||||
struct map_args args;
|
||||
args.pdb = pdb;
|
||||
args.block = block;
|
||||
args.decl_stack = decl_stack;
|
||||
args.indent = indent;
|
||||
- struct avrule_decl *decl = stack_peek(decl_stack);
|
||||
|
||||
for (args.sym_index = 0; args.sym_index < SYM_NUM; args.sym_index++) {
|
||||
if (func_to_cil[args.sym_index] == NULL) {
|
||||
diff --git a/libsepol/src/nodes.c b/libsepol/src/nodes.c
|
||||
index 820346d0f5df..97a0f959c7ca 100644
|
||||
--- a/libsepol/src/nodes.c
|
||||
+++ b/libsepol/src/nodes.c
|
||||
@@ -19,20 +19,20 @@ static int node_from_record(sepol_handle_t * handle,
|
||||
ocontext_t *tmp_node = NULL;
|
||||
context_struct_t *tmp_con = NULL;
|
||||
char *addr_buf = NULL, *mask_buf = NULL;
|
||||
+ size_t addr_bsize, mask_bsize;
|
||||
+ int proto;
|
||||
|
||||
tmp_node = (ocontext_t *) calloc(1, sizeof(ocontext_t));
|
||||
if (!tmp_node)
|
||||
goto omem;
|
||||
|
||||
- size_t addr_bsize, mask_bsize;
|
||||
-
|
||||
/* Address and netmask */
|
||||
if (sepol_node_get_addr_bytes(handle, data, &addr_buf, &addr_bsize) < 0)
|
||||
goto err;
|
||||
if (sepol_node_get_mask_bytes(handle, data, &mask_buf, &mask_bsize) < 0)
|
||||
goto err;
|
||||
|
||||
- int proto = sepol_node_get_proto(data);
|
||||
+ proto = sepol_node_get_proto(data);
|
||||
|
||||
switch (proto) {
|
||||
case SEPOL_PROTO_IP4:
|
||||
diff --git a/libsepol/src/services.c b/libsepol/src/services.c
|
||||
index ff91f7d2fdfc..d647c8f57300 100644
|
||||
--- a/libsepol/src/services.c
|
||||
+++ b/libsepol/src/services.c
|
||||
@@ -290,6 +290,19 @@ static char *get_class_info(sepol_security_class_t tclass,
|
||||
{
|
||||
constraint_expr_t *e;
|
||||
int mls, state_num;
|
||||
+ /* Determine statement type */
|
||||
+ const char *statements[] = {
|
||||
+ "constrain ", /* 0 */
|
||||
+ "mlsconstrain ", /* 1 */
|
||||
+ "validatetrans ", /* 2 */
|
||||
+ "mlsvalidatetrans ", /* 3 */
|
||||
+ 0 };
|
||||
+ size_t class_buf_len = 0;
|
||||
+ size_t new_class_buf_len;
|
||||
+ size_t buf_used;
|
||||
+ int len;
|
||||
+ char *class_buf = NULL, *p;
|
||||
+ char *new_class_buf = NULL;
|
||||
|
||||
/* Find if MLS statement or not */
|
||||
mls = 0;
|
||||
@@ -300,26 +313,11 @@ static char *get_class_info(sepol_security_class_t tclass,
|
||||
}
|
||||
}
|
||||
|
||||
- /* Determine statement type */
|
||||
- const char *statements[] = {
|
||||
- "constrain ", /* 0 */
|
||||
- "mlsconstrain ", /* 1 */
|
||||
- "validatetrans ", /* 2 */
|
||||
- "mlsvalidatetrans ", /* 3 */
|
||||
- 0 };
|
||||
-
|
||||
if (xcontext == NULL)
|
||||
state_num = mls + 0;
|
||||
else
|
||||
state_num = mls + 2;
|
||||
|
||||
- size_t class_buf_len = 0;
|
||||
- size_t new_class_buf_len;
|
||||
- size_t buf_used;
|
||||
- int len;
|
||||
- char *class_buf = NULL, *p;
|
||||
- char *new_class_buf = NULL;
|
||||
-
|
||||
while (1) {
|
||||
new_class_buf_len = class_buf_len + EXPR_BUF_SIZE;
|
||||
new_class_buf = realloc(class_buf, new_class_buf_len);
|
||||
@@ -417,6 +415,8 @@ static int constraint_expr_eval_reason(context_struct_t *scontext,
|
||||
char *tgt = NULL;
|
||||
int rc = 0, x;
|
||||
char *class_buf = NULL;
|
||||
+ int expr_list_len = 0;
|
||||
+ int expr_count;
|
||||
|
||||
/*
|
||||
* The array of expression answer buffer pointers and counter.
|
||||
@@ -424,6 +424,11 @@ static int constraint_expr_eval_reason(context_struct_t *scontext,
|
||||
char **answer_list = NULL;
|
||||
int answer_counter = 0;
|
||||
|
||||
+ /* The pop operands */
|
||||
+ char *a;
|
||||
+ char *b;
|
||||
+ int a_len, b_len;
|
||||
+
|
||||
class_buf = get_class_info(tclass, constraint, xcontext);
|
||||
if (!class_buf) {
|
||||
ERR(NULL, "failed to allocate class buffer");
|
||||
@@ -431,7 +436,6 @@ static int constraint_expr_eval_reason(context_struct_t *scontext,
|
||||
}
|
||||
|
||||
/* Original function but with buffer support */
|
||||
- int expr_list_len = 0;
|
||||
expr_counter = 0;
|
||||
expr_list = NULL;
|
||||
for (e = constraint->expr; e; e = e->next) {
|
||||
@@ -701,7 +705,7 @@ mls_ops:
|
||||
* expr_list malloc's. Normally they are released by the RPN to
|
||||
* infix code.
|
||||
*/
|
||||
- int expr_count = expr_counter;
|
||||
+ expr_count = expr_counter;
|
||||
expr_counter = 0;
|
||||
|
||||
/*
|
||||
@@ -715,11 +719,6 @@ mls_ops:
|
||||
goto out;
|
||||
}
|
||||
|
||||
- /* The pop operands */
|
||||
- char *a;
|
||||
- char *b;
|
||||
- int a_len, b_len;
|
||||
-
|
||||
/* Convert constraint from RPN to infix notation. */
|
||||
for (x = 0; x != expr_count; x++) {
|
||||
if (strncmp(expr_list[x], "and", 3) == 0 || strncmp(expr_list[x],
|
||||
@@ -778,14 +777,6 @@ mls_ops:
|
||||
xcontext ? "Validatetrans" : "Constraint",
|
||||
s[0] ? "GRANTED" : "DENIED");
|
||||
|
||||
- int len, new_buf_len;
|
||||
- char *p, **new_buf = r_buf;
|
||||
- /*
|
||||
- * These contain the constraint components that are added to the
|
||||
- * callers reason buffer.
|
||||
- */
|
||||
- const char *buffers[] = { class_buf, a, "); ", tmp_buf, 0 };
|
||||
-
|
||||
/*
|
||||
* This will add the constraints to the callers reason buffer (who is
|
||||
* responsible for freeing the memory). It will handle any realloc's
|
||||
@@ -796,6 +787,14 @@ mls_ops:
|
||||
|
||||
if (r_buf && ((s[0] == 0) || ((s[0] == 1 &&
|
||||
(flags & SHOW_GRANTED) == SHOW_GRANTED)))) {
|
||||
+ int len, new_buf_len;
|
||||
+ char *p, **new_buf = r_buf;
|
||||
+ /*
|
||||
+ * These contain the constraint components that are added to the
|
||||
+ * callers reason buffer.
|
||||
+ */
|
||||
+ const char *buffers[] = { class_buf, a, "); ", tmp_buf, 0 };
|
||||
+
|
||||
for (x = 0; buffers[x] != NULL; x++) {
|
||||
while (1) {
|
||||
p = *r_buf + reason_buf_used;
|
||||
diff --git a/libsepol/src/util.c b/libsepol/src/util.c
|
||||
index d51750af3fa1..a47cae87bfed 100644
|
||||
--- a/libsepol/src/util.c
|
||||
+++ b/libsepol/src/util.c
|
||||
@@ -129,9 +129,9 @@ char *sepol_extended_perms_to_string(avtab_extended_perms_t *xperms)
|
||||
unsigned int bit;
|
||||
unsigned int in_range = 0;
|
||||
static char xpermsbuf[2048];
|
||||
- xpermsbuf[0] = '\0';
|
||||
char *p;
|
||||
int len, xpermslen = 0;
|
||||
+ xpermsbuf[0] = '\0';
|
||||
p = xpermsbuf;
|
||||
|
||||
if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
|
||||
--
|
||||
2.32.0
|
||||
|
@ -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 18532aad9801..85094b01ef9d 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 96c97263d8c8..908b0336d1dd 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 097222a83da9..46db069b254a 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 4e7843cb01ef..8a426f1f5950 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 05842b644807..7bca0834ad39 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 92a4d29700e9..b5199bad35e2 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 2598bbf3d80e..70bca3630220 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");
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,92 +0,0 @@
|
||||
From a53a845b76f674f2a11cd178222042bc9c3fdae6 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:58 +0200
|
||||
Subject: [PATCH] libsepol: remove dead stores
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
conditional.c:391:4: warning: Value stored to 'i' is never read [deadcode.DeadStores]
|
||||
i = 0;
|
||||
^ ~
|
||||
conditional.c:718:2: warning: Value stored to 'len' is never read [deadcode.DeadStores]
|
||||
len = 0;
|
||||
^ ~
|
||||
conditional.c:772:2: warning: Value stored to 'len' is never read [deadcode.DeadStores]
|
||||
len = 0;
|
||||
^ ~
|
||||
|
||||
services.c:89:10: warning: Value stored to 'new_stack' during its initialization is never read [deadcode.DeadStores]
|
||||
char **new_stack = stack;
|
||||
^~~~~~~~~ ~~~~~
|
||||
|
||||
services.c:440:11: warning: Value stored to 'new_expr_list' during its initialization is never read [deadcode.DeadStores]
|
||||
char **new_expr_list = expr_list;
|
||||
^~~~~~~~~~~~~ ~~~~~~~~~
|
||||
|
||||
../cil/src/cil_binary.c:2230:24: warning: Value stored to 'cb_node' during its initialization is never read [deadcode.DeadStores]
|
||||
struct cil_tree_node *cb_node = node->cl_head;
|
||||
^~~~~~~ ~~~~~~~~~~~~~
|
||||
|
||||
Found by clang-analyzer
|
||||
|
||||
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
|
||||
Acked-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/src/conditional.c | 3 ---
|
||||
libsepol/src/services.c | 4 ++--
|
||||
2 files changed, 2 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/libsepol/src/conditional.c b/libsepol/src/conditional.c
|
||||
index 823b649a9163..e3ede694e59f 100644
|
||||
--- a/libsepol/src/conditional.c
|
||||
+++ b/libsepol/src/conditional.c
|
||||
@@ -388,7 +388,6 @@ int cond_normalize_expr(policydb_t * p, cond_node_t * cn)
|
||||
for (e = cn->expr; e != NULL; e = e->next) {
|
||||
switch (e->expr_type) {
|
||||
case COND_BOOL:
|
||||
- i = 0;
|
||||
/* see if we've already seen this bool */
|
||||
if (!bool_present(e->bool, cn->bool_ids, cn->nbools)) {
|
||||
/* count em all but only record up to COND_MAX_BOOLS */
|
||||
@@ -715,7 +714,6 @@ static int cond_read_av_list(policydb_t * p, void *fp,
|
||||
|
||||
*ret_list = NULL;
|
||||
|
||||
- len = 0;
|
||||
rc = next_entry(buf, fp, sizeof(uint32_t));
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
@@ -769,7 +767,6 @@ static int cond_read_node(policydb_t * p, cond_node_t * node, void *fp)
|
||||
|
||||
node->cur_state = le32_to_cpu(buf[0]);
|
||||
|
||||
- len = 0;
|
||||
rc = next_entry(buf, fp, sizeof(uint32_t));
|
||||
if (rc < 0)
|
||||
goto err;
|
||||
diff --git a/libsepol/src/services.c b/libsepol/src/services.c
|
||||
index d647c8f57300..c34bb9667fbc 100644
|
||||
--- a/libsepol/src/services.c
|
||||
+++ b/libsepol/src/services.c
|
||||
@@ -86,7 +86,7 @@ static int next_stack_entry;
|
||||
static void push(char *expr_ptr)
|
||||
{
|
||||
if (next_stack_entry >= stack_len) {
|
||||
- char **new_stack = stack;
|
||||
+ char **new_stack;
|
||||
int new_stack_len;
|
||||
|
||||
if (stack_len == 0)
|
||||
@@ -441,7 +441,7 @@ static int constraint_expr_eval_reason(context_struct_t *scontext,
|
||||
for (e = constraint->expr; e; e = e->next) {
|
||||
/* Allocate a stack to hold expression buffer entries */
|
||||
if (expr_counter >= expr_list_len) {
|
||||
- char **new_expr_list = expr_list;
|
||||
+ char **new_expr_list;
|
||||
int new_expr_list_len;
|
||||
|
||||
if (expr_list_len == 0)
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,135 +0,0 @@
|
||||
From 390ec54d278a14d9c29b80cc4fc5cb9ba504ed13 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:59 +0200
|
||||
Subject: [PATCH] libsepol: mark read-only parameters of ebitmap interfaces
|
||||
const
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Make it more obvious which parameters are read-only and not being
|
||||
modified and allow callers to pass const pointers.
|
||||
|
||||
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
|
||||
Acked-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/include/sepol/policydb/ebitmap.h | 16 ++++++++--------
|
||||
libsepol/src/ebitmap.c | 18 +++++++++---------
|
||||
2 files changed, 17 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/libsepol/include/sepol/policydb/ebitmap.h b/libsepol/include/sepol/policydb/ebitmap.h
|
||||
index 634436f6c30b..81d0c7a67347 100644
|
||||
--- a/libsepol/include/sepol/policydb/ebitmap.h
|
||||
+++ b/libsepol/include/sepol/policydb/ebitmap.h
|
||||
@@ -67,7 +67,7 @@ static inline unsigned int ebitmap_next(ebitmap_node_t ** n, unsigned int bit)
|
||||
return (bit + 1);
|
||||
}
|
||||
|
||||
-static inline int ebitmap_node_get_bit(ebitmap_node_t * n, unsigned int bit)
|
||||
+static inline int ebitmap_node_get_bit(const ebitmap_node_t * n, unsigned int bit)
|
||||
{
|
||||
if (n->map & (MAPBIT << (bit - n->startbit)))
|
||||
return 1;
|
||||
@@ -83,18 +83,18 @@ static inline int ebitmap_node_get_bit(ebitmap_node_t * n, unsigned int bit)
|
||||
extern int ebitmap_cmp(const ebitmap_t * e1, const ebitmap_t * e2);
|
||||
extern int ebitmap_or(ebitmap_t * dst, const ebitmap_t * e1, const ebitmap_t * e2);
|
||||
extern int ebitmap_union(ebitmap_t * dst, const ebitmap_t * e1);
|
||||
-extern int ebitmap_and(ebitmap_t *dst, ebitmap_t *e1, ebitmap_t *e2);
|
||||
-extern int ebitmap_xor(ebitmap_t *dst, ebitmap_t *e1, ebitmap_t *e2);
|
||||
-extern int ebitmap_not(ebitmap_t *dst, ebitmap_t *e1, unsigned int maxbit);
|
||||
-extern int ebitmap_andnot(ebitmap_t *dst, ebitmap_t *e1, ebitmap_t *e2, unsigned int maxbit);
|
||||
-extern unsigned int ebitmap_cardinality(ebitmap_t *e1);
|
||||
-extern int ebitmap_hamming_distance(ebitmap_t * e1, ebitmap_t * e2);
|
||||
+extern int ebitmap_and(ebitmap_t *dst, const ebitmap_t *e1, const ebitmap_t *e2);
|
||||
+extern int ebitmap_xor(ebitmap_t *dst, const ebitmap_t *e1, const ebitmap_t *e2);
|
||||
+extern int ebitmap_not(ebitmap_t *dst, const ebitmap_t *e1, unsigned int maxbit);
|
||||
+extern int ebitmap_andnot(ebitmap_t *dst, const ebitmap_t *e1, const ebitmap_t *e2, unsigned int maxbit);
|
||||
+extern unsigned int ebitmap_cardinality(const ebitmap_t *e1);
|
||||
+extern int ebitmap_hamming_distance(const ebitmap_t * e1, const ebitmap_t * e2);
|
||||
extern int ebitmap_cpy(ebitmap_t * dst, const ebitmap_t * src);
|
||||
extern int ebitmap_contains(const ebitmap_t * e1, const ebitmap_t * e2);
|
||||
extern int ebitmap_match_any(const ebitmap_t *e1, const ebitmap_t *e2);
|
||||
extern int ebitmap_get_bit(const ebitmap_t * e, unsigned int bit);
|
||||
extern int ebitmap_set_bit(ebitmap_t * e, unsigned int bit, int value);
|
||||
-extern unsigned int ebitmap_highest_set_bit(ebitmap_t * e);
|
||||
+extern unsigned int ebitmap_highest_set_bit(const ebitmap_t * e);
|
||||
extern void ebitmap_destroy(ebitmap_t * e);
|
||||
extern int ebitmap_read(ebitmap_t * e, void *fp);
|
||||
|
||||
diff --git a/libsepol/src/ebitmap.c b/libsepol/src/ebitmap.c
|
||||
index 522e14a68a94..4e9acdf868a2 100644
|
||||
--- a/libsepol/src/ebitmap.c
|
||||
+++ b/libsepol/src/ebitmap.c
|
||||
@@ -71,7 +71,7 @@ int ebitmap_union(ebitmap_t * dst, const ebitmap_t * e1)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int ebitmap_and(ebitmap_t *dst, ebitmap_t *e1, ebitmap_t *e2)
|
||||
+int ebitmap_and(ebitmap_t *dst, const ebitmap_t *e1, const ebitmap_t *e2)
|
||||
{
|
||||
unsigned int i, length = min(ebitmap_length(e1), ebitmap_length(e2));
|
||||
ebitmap_init(dst);
|
||||
@@ -85,7 +85,7 @@ int ebitmap_and(ebitmap_t *dst, ebitmap_t *e1, ebitmap_t *e2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int ebitmap_xor(ebitmap_t *dst, ebitmap_t *e1, ebitmap_t *e2)
|
||||
+int ebitmap_xor(ebitmap_t *dst, const ebitmap_t *e1, const ebitmap_t *e2)
|
||||
{
|
||||
unsigned int i, length = max(ebitmap_length(e1), ebitmap_length(e2));
|
||||
ebitmap_init(dst);
|
||||
@@ -98,7 +98,7 @@ int ebitmap_xor(ebitmap_t *dst, ebitmap_t *e1, ebitmap_t *e2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int ebitmap_not(ebitmap_t *dst, ebitmap_t *e1, unsigned int maxbit)
|
||||
+int ebitmap_not(ebitmap_t *dst, const ebitmap_t *e1, unsigned int maxbit)
|
||||
{
|
||||
unsigned int i;
|
||||
ebitmap_init(dst);
|
||||
@@ -111,7 +111,7 @@ int ebitmap_not(ebitmap_t *dst, ebitmap_t *e1, unsigned int maxbit)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int ebitmap_andnot(ebitmap_t *dst, ebitmap_t *e1, ebitmap_t *e2, unsigned int maxbit)
|
||||
+int ebitmap_andnot(ebitmap_t *dst, const ebitmap_t *e1, const ebitmap_t *e2, unsigned int maxbit)
|
||||
{
|
||||
int rc;
|
||||
ebitmap_t e3;
|
||||
@@ -126,10 +126,10 @@ int ebitmap_andnot(ebitmap_t *dst, ebitmap_t *e1, ebitmap_t *e2, unsigned int ma
|
||||
return 0;
|
||||
}
|
||||
|
||||
-unsigned int ebitmap_cardinality(ebitmap_t *e1)
|
||||
+unsigned int ebitmap_cardinality(const ebitmap_t *e1)
|
||||
{
|
||||
unsigned int count = 0;
|
||||
- ebitmap_node_t *n;
|
||||
+ const ebitmap_node_t *n;
|
||||
|
||||
for (n = e1->node; n; n = n->next) {
|
||||
count += __builtin_popcountll(n->map);
|
||||
@@ -137,7 +137,7 @@ unsigned int ebitmap_cardinality(ebitmap_t *e1)
|
||||
return count;
|
||||
}
|
||||
|
||||
-int ebitmap_hamming_distance(ebitmap_t * e1, ebitmap_t * e2)
|
||||
+int ebitmap_hamming_distance(const ebitmap_t * e1, const ebitmap_t * e2)
|
||||
{
|
||||
int rc;
|
||||
ebitmap_t tmp;
|
||||
@@ -347,9 +347,9 @@ int ebitmap_set_bit(ebitmap_t * e, unsigned int bit, int value)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-unsigned int ebitmap_highest_set_bit(ebitmap_t * e)
|
||||
+unsigned int ebitmap_highest_set_bit(const ebitmap_t * e)
|
||||
{
|
||||
- ebitmap_node_t *n;
|
||||
+ const ebitmap_node_t *n;
|
||||
MAPTYPE map;
|
||||
unsigned int pos = 0;
|
||||
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,68 +0,0 @@
|
||||
From 8eec1bb50230c78faaeb9ccc0decb83cad205bf2 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
|
||||
Date: Tue, 8 Jun 2021 17:59:00 +0200
|
||||
Subject: [PATCH] libsepol: mark read-only parameters of type_set_ interfaces
|
||||
const
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Make it more obvious which parameters are read-only and not being
|
||||
modified and allow callers to pass const pointers.
|
||||
|
||||
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
|
||||
Acked-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/include/sepol/policydb/policydb.h | 4 ++--
|
||||
libsepol/src/policydb.c | 6 +++---
|
||||
2 files changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h
|
||||
index 9ef43abc2f12..6976ef4831ef 100644
|
||||
--- a/libsepol/include/sepol/policydb/policydb.h
|
||||
+++ b/libsepol/include/sepol/policydb/policydb.h
|
||||
@@ -667,8 +667,8 @@ extern int scope_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p);
|
||||
extern void class_perm_node_init(class_perm_node_t * x);
|
||||
extern void type_set_init(type_set_t * x);
|
||||
extern void type_set_destroy(type_set_t * x);
|
||||
-extern int type_set_cpy(type_set_t * dst, type_set_t * src);
|
||||
-extern int type_set_or_eq(type_set_t * dst, type_set_t * other);
|
||||
+extern int type_set_cpy(type_set_t * dst, const type_set_t * src);
|
||||
+extern int type_set_or_eq(type_set_t * dst, const type_set_t * other);
|
||||
extern void role_set_init(role_set_t * x);
|
||||
extern void role_set_destroy(role_set_t * x);
|
||||
extern void avrule_init(avrule_t * x);
|
||||
diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
|
||||
index e0b072e1938f..b4e427af05c8 100644
|
||||
--- a/libsepol/src/policydb.c
|
||||
+++ b/libsepol/src/policydb.c
|
||||
@@ -1747,7 +1747,7 @@ int symtab_insert(policydb_t * pol, uint32_t sym,
|
||||
return retval;
|
||||
}
|
||||
|
||||
-static int type_set_or(type_set_t * dst, type_set_t * a, type_set_t * b)
|
||||
+static int type_set_or(type_set_t * dst, const type_set_t * a, const type_set_t * b)
|
||||
{
|
||||
type_set_init(dst);
|
||||
|
||||
@@ -1764,7 +1764,7 @@ static int type_set_or(type_set_t * dst, type_set_t * a, type_set_t * b)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int type_set_cpy(type_set_t * dst, type_set_t * src)
|
||||
+int type_set_cpy(type_set_t * dst, const type_set_t * src)
|
||||
{
|
||||
type_set_init(dst);
|
||||
|
||||
@@ -1777,7 +1777,7 @@ int type_set_cpy(type_set_t * dst, type_set_t * src)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int type_set_or_eq(type_set_t * dst, type_set_t * other)
|
||||
+int type_set_or_eq(type_set_t * dst, const type_set_t * other)
|
||||
{
|
||||
int ret;
|
||||
type_set_t tmp;
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,63 +0,0 @@
|
||||
From 19a6ebfa895ce3baa6bd07cb5227556c82f20cb6 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
|
||||
Date: Tue, 8 Jun 2021 17:59:01 +0200
|
||||
Subject: [PATCH] libsepol: do not allocate memory of size 0
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
In case cats_ebitmap_len() returns 0, do not allocate but quit.
|
||||
|
||||
Found by clang-analyzer
|
||||
|
||||
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
|
||||
Acked-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/src/kernel_to_cil.c | 5 ++++-
|
||||
libsepol/src/kernel_to_conf.c | 5 ++++-
|
||||
2 files changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libsepol/src/kernel_to_cil.c b/libsepol/src/kernel_to_cil.c
|
||||
index 30a27bf527d5..5aaee6288565 100644
|
||||
--- a/libsepol/src/kernel_to_cil.c
|
||||
+++ b/libsepol/src/kernel_to_cil.c
|
||||
@@ -1034,11 +1034,14 @@ static char *cats_ebitmap_to_str(struct ebitmap *cats, char **val_to_name)
|
||||
{
|
||||
struct ebitmap_node *node;
|
||||
uint32_t i, start, range;
|
||||
- char *catsbuf, *p;
|
||||
+ char *catsbuf = NULL, *p;
|
||||
const char *fmt;
|
||||
int len, remaining;
|
||||
|
||||
remaining = (int)cats_ebitmap_len(cats, val_to_name);
|
||||
+ if (remaining == 0) {
|
||||
+ goto exit;
|
||||
+ }
|
||||
catsbuf = malloc(remaining);
|
||||
if (!catsbuf) {
|
||||
goto exit;
|
||||
diff --git a/libsepol/src/kernel_to_conf.c b/libsepol/src/kernel_to_conf.c
|
||||
index ffdf179a71f3..cb8e13809d52 100644
|
||||
--- a/libsepol/src/kernel_to_conf.c
|
||||
+++ b/libsepol/src/kernel_to_conf.c
|
||||
@@ -1025,12 +1025,15 @@ static char *cats_ebitmap_to_str(struct ebitmap *cats, char **val_to_name)
|
||||
{
|
||||
struct ebitmap_node *node;
|
||||
uint32_t i, start, range, first;
|
||||
- char *catsbuf, *p;
|
||||
+ char *catsbuf = NULL, *p;
|
||||
const char *fmt;
|
||||
char sep;
|
||||
int len, remaining;
|
||||
|
||||
remaining = (int)cats_ebitmap_len(cats, val_to_name);
|
||||
+ if (remaining == 0) {
|
||||
+ goto exit;
|
||||
+ }
|
||||
catsbuf = malloc(remaining);
|
||||
if (!catsbuf) {
|
||||
goto exit;
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,41 +0,0 @@
|
||||
From 1076a07288f527ac64dcd421ec01e424ee85474d Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
|
||||
Date: Tue, 8 Jun 2021 17:59:03 +0200
|
||||
Subject: [PATCH] libsepol: remove dead stores
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Found by Infer
|
||||
|
||||
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
|
||||
Acked-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/src/services.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libsepol/src/services.c b/libsepol/src/services.c
|
||||
index c34bb9667fbc..f7c31d80f954 100644
|
||||
--- a/libsepol/src/services.c
|
||||
+++ b/libsepol/src/services.c
|
||||
@@ -175,7 +175,7 @@ static int expr_buf_len;
|
||||
static void cat_expr_buf(char *e_buf, const char *string)
|
||||
{
|
||||
int len, new_buf_len;
|
||||
- char *p, *new_buf = e_buf;
|
||||
+ char *p, *new_buf;
|
||||
|
||||
while (1) {
|
||||
p = e_buf + expr_buf_used;
|
||||
@@ -406,7 +406,7 @@ static int constraint_expr_eval_reason(context_struct_t *scontext,
|
||||
#define TARGET 2
|
||||
#define XTARGET 3
|
||||
|
||||
- int s_t_x_num = SOURCE;
|
||||
+ int s_t_x_num;
|
||||
|
||||
/* Set 0 = fail, u = CEXPR_USER, r = CEXPR_ROLE, t = CEXPR_TYPE */
|
||||
int u_r_t = 0;
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,51 +0,0 @@
|
||||
From de3b96a158c60147703dc5d49c227a596d4ae165 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
|
||||
Date: Tue, 8 Jun 2021 17:59:04 +0200
|
||||
Subject: [PATCH] libsepol/cil: silence cast warning
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
../cil/src/cil_write_ast.c:86:32: error: cast to smaller integer type 'enum cil_flavor' from 'void *' [-Werror,-Wvoid-pointer-to-enum-cast]
|
||||
enum cil_flavor op_flavor = (enum cil_flavor)curr->data;
|
||||
^~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
../cil/src/cil_write_ast.c:130:37: error: cast to smaller integer type 'enum cil_flavor' from 'void *' [-Werror,-Wvoid-pointer-to-enum-cast]
|
||||
enum cil_flavor operand_flavor = (enum cil_flavor)curr->data;
|
||||
^~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Silence this warning by casting the pointer to an integer the cast to
|
||||
enum cil_flavor.
|
||||
|
||||
See 32f8ed3d6b0b ("libsepol/cil: introduce intermediate cast to silence -Wvoid-pointer-to-enum-cast")
|
||||
|
||||
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
|
||||
Acked-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_write_ast.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_write_ast.c b/libsepol/cil/src/cil_write_ast.c
|
||||
index 4871f7045e19..186070c1783a 100644
|
||||
--- a/libsepol/cil/src/cil_write_ast.c
|
||||
+++ b/libsepol/cil/src/cil_write_ast.c
|
||||
@@ -83,7 +83,7 @@ static void write_expr(FILE *out, struct cil_list *expr)
|
||||
break;
|
||||
case CIL_OP: {
|
||||
const char *op_str;
|
||||
- enum cil_flavor op_flavor = (enum cil_flavor)curr->data;
|
||||
+ enum cil_flavor op_flavor = (enum cil_flavor)(uintptr_t)curr->data;
|
||||
switch (op_flavor) {
|
||||
case CIL_AND:
|
||||
op_str = CIL_KEY_AND;
|
||||
@@ -127,7 +127,7 @@ static void write_expr(FILE *out, struct cil_list *expr)
|
||||
}
|
||||
case CIL_CONS_OPERAND: {
|
||||
const char *operand_str;
|
||||
- enum cil_flavor operand_flavor = (enum cil_flavor)curr->data;
|
||||
+ enum cil_flavor operand_flavor = (enum cil_flavor)(uintptr_t)curr->data;
|
||||
switch (operand_flavor) {
|
||||
case CIL_CONS_U1:
|
||||
operand_str = CIL_KEY_CONS_U1;
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,30 +0,0 @@
|
||||
From 261b655ac20e8a4d21cd420ef70468309dedb097 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
|
||||
Date: Tue, 8 Jun 2021 17:59:05 +0200
|
||||
Subject: [PATCH] libsepol/cil: drop extra semicolon
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
|
||||
Acked-by: James Carter <jwcart2@gmail.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 908b0336d1dd..71ddada226df 100644
|
||||
--- a/libsepol/cil/src/cil_build_ast.c
|
||||
+++ b/libsepol/cil/src/cil_build_ast.c
|
||||
@@ -4153,7 +4153,7 @@ void cil_destroy_context(struct cil_context *context)
|
||||
return;
|
||||
}
|
||||
|
||||
- cil_symtab_datum_destroy(&context->datum);;
|
||||
+ cil_symtab_datum_destroy(&context->datum);
|
||||
|
||||
if (context->range_str == NULL && context->range != NULL) {
|
||||
cil_destroy_levelrange(context->range);
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,36 +0,0 @@
|
||||
From 0bb89514eba0f34685c87278d600b152b28ea76e Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
|
||||
Date: Tue, 8 Jun 2021 17:59:06 +0200
|
||||
Subject: [PATCH] libsepol/cil: drop dead store
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
../cil/src/cil_binary.c:2230:24: warning: Value stored to 'cb_node' during its initialization is never read [deadcode.DeadStores]
|
||||
struct cil_tree_node *cb_node = node->cl_head;
|
||||
^~~~~~~ ~~~~~~~~~~~~~
|
||||
|
||||
Found by clang-analyzer
|
||||
|
||||
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
|
||||
Acked-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
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 85094b01ef9d..601fe8d10ab1 100644
|
||||
--- a/libsepol/cil/src/cil_binary.c
|
||||
+++ b/libsepol/cil/src/cil_binary.c
|
||||
@@ -2227,7 +2227,7 @@ int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct c
|
||||
int rc = SEPOL_ERR;
|
||||
struct cil_args_booleanif bool_args;
|
||||
struct cil_booleanif *cil_boolif = (struct cil_booleanif*)node->data;
|
||||
- struct cil_tree_node *cb_node = node->cl_head;
|
||||
+ struct cil_tree_node *cb_node;
|
||||
struct cil_tree_node *true_node = NULL;
|
||||
struct cil_tree_node *false_node = NULL;
|
||||
struct cil_tree_node *tmp_node = NULL;
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,68 +0,0 @@
|
||||
From 2723b8ec2a84488f00199687d27d1aae5a76c33b Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
|
||||
Date: Tue, 8 Jun 2021 17:59:07 +0200
|
||||
Subject: [PATCH] libsepol/cil: drop unnecessary casts
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
`const_hashtab_key_t` is a typedef of `const char *`, so these casts are
|
||||
not needed.
|
||||
|
||||
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
|
||||
Acked-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_strpool.c | 15 ++++++---------
|
||||
1 file changed, 6 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_strpool.c b/libsepol/cil/src/cil_strpool.c
|
||||
index 70bca3630220..e32ee4e90f34 100644
|
||||
--- a/libsepol/cil/src/cil_strpool.c
|
||||
+++ b/libsepol/cil/src/cil_strpool.c
|
||||
@@ -47,14 +47,13 @@ static hashtab_t cil_strpool_tab = NULL;
|
||||
|
||||
static unsigned int cil_strpool_hash(hashtab_t h, const_hashtab_key_t key)
|
||||
{
|
||||
- const char *p, *keyp;
|
||||
+ const char *p;
|
||||
size_t size;
|
||||
unsigned int val;
|
||||
|
||||
val = 0;
|
||||
- keyp = (const char*)key;
|
||||
- size = strlen(keyp);
|
||||
- for (p = keyp; ((size_t) (p - keyp)) < size; p++)
|
||||
+ size = strlen(key);
|
||||
+ for (p = key; ((size_t) (p - key)) < size; p++)
|
||||
val =
|
||||
(val << 4 | (val >> (8 * sizeof(unsigned int) - 4))) ^ (*p);
|
||||
return val & (h->size - 1);
|
||||
@@ -62,9 +61,7 @@ static unsigned int cil_strpool_hash(hashtab_t h, const_hashtab_key_t key)
|
||||
|
||||
static int cil_strpool_compare(hashtab_t h __attribute__ ((unused)), const_hashtab_key_t key1, const_hashtab_key_t key2)
|
||||
{
|
||||
- const char *keyp1 = (const char*)key1;
|
||||
- const char *keyp2 = (const char*)key2;
|
||||
- return strcmp(keyp1, keyp2);
|
||||
+ return strcmp(key1, key2);
|
||||
}
|
||||
|
||||
char *cil_strpool_add(const char *str)
|
||||
@@ -73,12 +70,12 @@ char *cil_strpool_add(const char *str)
|
||||
|
||||
pthread_mutex_lock(&cil_strpool_mutex);
|
||||
|
||||
- strpool_ref = hashtab_search(cil_strpool_tab, (hashtab_key_t)str);
|
||||
+ strpool_ref = hashtab_search(cil_strpool_tab, str);
|
||||
if (strpool_ref == NULL) {
|
||||
int rc;
|
||||
strpool_ref = cil_malloc(sizeof(*strpool_ref));
|
||||
strpool_ref->str = cil_strdup(str);
|
||||
- rc = hashtab_insert(cil_strpool_tab, (hashtab_key_t)strpool_ref->str, strpool_ref);
|
||||
+ rc = hashtab_insert(cil_strpool_tab, strpool_ref->str, strpool_ref);
|
||||
if (rc != SEPOL_OK) {
|
||||
pthread_mutex_unlock(&cil_strpool_mutex);
|
||||
cil_log(CIL_ERR, "Failed to allocate memory\n");
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,78 +0,0 @@
|
||||
From 5324a9ab1bf5e6d0dd931ee2342f32193341c601 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
|
||||
Date: Tue, 8 Jun 2021 17:59:08 +0200
|
||||
Subject: [PATCH] libsepol/cil: avoid using maybe uninitialized variables
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Initialize variables, as they are set after goto statements, which jump
|
||||
to cleanup code using them.
|
||||
|
||||
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
|
||||
Acked-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_binary.c | 12 ++++++------
|
||||
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c
|
||||
index 601fe8d10ab1..54d13f2f3945 100644
|
||||
--- a/libsepol/cil/src/cil_binary.c
|
||||
+++ b/libsepol/cil/src/cil_binary.c
|
||||
@@ -1073,7 +1073,7 @@ int __cil_type_rule_to_avtab(policydb_t *pdb, const struct cil_db *db, struct ci
|
||||
type_datum_t *sepol_src = NULL;
|
||||
type_datum_t *sepol_tgt = NULL;
|
||||
class_datum_t *sepol_obj = NULL;
|
||||
- struct cil_list *class_list;
|
||||
+ struct cil_list *class_list = NULL;
|
||||
type_datum_t *sepol_result = NULL;
|
||||
ebitmap_t src_bitmap, tgt_bitmap;
|
||||
ebitmap_node_t *node1, *node2;
|
||||
@@ -1129,7 +1129,7 @@ int __cil_typetransition_to_avtab(policydb_t *pdb, const struct cil_db *db, stru
|
||||
type_datum_t *sepol_src = NULL;
|
||||
type_datum_t *sepol_tgt = NULL;
|
||||
class_datum_t *sepol_obj = NULL;
|
||||
- struct cil_list *class_list;
|
||||
+ struct cil_list *class_list = NULL;
|
||||
type_datum_t *sepol_result = NULL;
|
||||
ebitmap_t src_bitmap, tgt_bitmap;
|
||||
ebitmap_node_t *node1, *node2;
|
||||
@@ -2338,7 +2338,7 @@ int cil_roletrans_to_policydb(policydb_t *pdb, const struct cil_db *db, struct c
|
||||
role_datum_t *sepol_src = NULL;
|
||||
type_datum_t *sepol_tgt = NULL;
|
||||
class_datum_t *sepol_obj = NULL;
|
||||
- struct cil_list *class_list;
|
||||
+ struct cil_list *class_list = NULL;
|
||||
role_datum_t *sepol_result = NULL;
|
||||
role_trans_t *new = NULL;
|
||||
uint32_t *new_role = NULL;
|
||||
@@ -3166,7 +3166,7 @@ int cil_rangetransition_to_policydb(policydb_t *pdb, const struct cil_db *db, st
|
||||
type_datum_t *sepol_src = NULL;
|
||||
type_datum_t *sepol_tgt = NULL;
|
||||
class_datum_t *sepol_class = NULL;
|
||||
- struct cil_list *class_list;
|
||||
+ struct cil_list *class_list = NULL;
|
||||
range_trans_t *newkey = NULL;
|
||||
struct mls_range *newdatum = NULL;
|
||||
ebitmap_t src_bitmap, tgt_bitmap;
|
||||
@@ -3603,7 +3603,7 @@ int cil_default_to_policydb(policydb_t *pdb, struct cil_default *def)
|
||||
{
|
||||
struct cil_list_item *curr;
|
||||
class_datum_t *sepol_class;
|
||||
- struct cil_list *class_list;
|
||||
+ struct cil_list *class_list = NULL;
|
||||
|
||||
cil_list_for_each(curr, def->class_datums) {
|
||||
struct cil_list_item *c;
|
||||
@@ -3658,7 +3658,7 @@ int cil_defaultrange_to_policydb(policydb_t *pdb, struct cil_defaultrange *def)
|
||||
{
|
||||
struct cil_list_item *curr;
|
||||
class_datum_t *sepol_class;
|
||||
- struct cil_list *class_list;
|
||||
+ struct cil_list *class_list = NULL;
|
||||
|
||||
cil_list_for_each(curr, def->class_datums) {
|
||||
struct cil_list_item *c;
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,44 +0,0 @@
|
||||
From 811185648af2ec8a6b11b54484cbe9d19ba452fa Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
|
||||
Date: Tue, 8 Jun 2021 17:59:09 +0200
|
||||
Subject: [PATCH] libsepol: drop repeated semicolons
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
|
||||
Acked-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/src/kernel_to_cil.c | 2 +-
|
||||
libsepol/src/module.c | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libsepol/src/kernel_to_cil.c b/libsepol/src/kernel_to_cil.c
|
||||
index 5aaee6288565..336d53b09ff9 100644
|
||||
--- a/libsepol/src/kernel_to_cil.c
|
||||
+++ b/libsepol/src/kernel_to_cil.c
|
||||
@@ -1050,7 +1050,7 @@ static char *cats_ebitmap_to_str(struct ebitmap *cats, char **val_to_name)
|
||||
p = catsbuf;
|
||||
|
||||
*p++ = '(';
|
||||
- remaining--;;
|
||||
+ remaining--;
|
||||
|
||||
range = 0;
|
||||
ebitmap_for_each_positive_bit(cats, node, i) {
|
||||
diff --git a/libsepol/src/module.c b/libsepol/src/module.c
|
||||
index 836da308f8d3..9b53bc470952 100644
|
||||
--- a/libsepol/src/module.c
|
||||
+++ b/libsepol/src/module.c
|
||||
@@ -82,7 +82,7 @@ static int policy_file_length(struct policy_file *fp, size_t *out)
|
||||
break;
|
||||
case PF_USE_MEMORY:
|
||||
*out = fp->size;
|
||||
- break;;
|
||||
+ break;
|
||||
default:
|
||||
*out = 0;
|
||||
break;
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,52 +0,0 @@
|
||||
From 4fbc018a279a39160f17e257017b503194a7f44d Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
|
||||
Date: Tue, 8 Jun 2021 17:59:10 +0200
|
||||
Subject: [PATCH] libsepol: drop unnecessary casts
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
`hashtab_search()` does take `const_hashtab_key_t` as second parameter,
|
||||
which is a typedef for `const char *`.
|
||||
Drop the unnecessary and const-violating cast.
|
||||
|
||||
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
|
||||
Acked-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/src/services.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/libsepol/src/services.c b/libsepol/src/services.c
|
||||
index f7c31d80f954..47a3dc1419db 100644
|
||||
--- a/libsepol/src/services.c
|
||||
+++ b/libsepol/src/services.c
|
||||
@@ -1182,7 +1182,7 @@ int sepol_string_to_security_class(const char *class_name,
|
||||
class_datum_t *tclass_datum;
|
||||
|
||||
tclass_datum = hashtab_search(policydb->p_classes.table,
|
||||
- (hashtab_key_t) class_name);
|
||||
+ class_name);
|
||||
if (!tclass_datum) {
|
||||
ERR(NULL, "unrecognized class %s", class_name);
|
||||
return STATUS_ERR;
|
||||
@@ -1211,7 +1211,7 @@ int sepol_string_to_av_perm(sepol_security_class_t tclass,
|
||||
/* Check for unique perms then the common ones (if any) */
|
||||
perm_datum = (perm_datum_t *)
|
||||
hashtab_search(tclass_datum->permissions.table,
|
||||
- (hashtab_key_t)perm_name);
|
||||
+ perm_name);
|
||||
if (perm_datum != NULL) {
|
||||
*av = 0x1 << (perm_datum->s.value - 1);
|
||||
return STATUS_SUCCESS;
|
||||
@@ -1222,7 +1222,7 @@ int sepol_string_to_av_perm(sepol_security_class_t tclass,
|
||||
|
||||
perm_datum = (perm_datum_t *)
|
||||
hashtab_search(tclass_datum->comdatum->permissions.table,
|
||||
- (hashtab_key_t)perm_name);
|
||||
+ perm_name);
|
||||
|
||||
if (perm_datum != NULL) {
|
||||
*av = 0x1 << (perm_datum->s.value - 1);
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,36 +0,0 @@
|
||||
From 4572bf254a8242898467a41811c8e235209ebdfa Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
|
||||
Date: Tue, 8 Jun 2021 17:59:11 +0200
|
||||
Subject: [PATCH] libsepol: declare file local variable static
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Clang issues:
|
||||
|
||||
module_to_cil.c:65:7: warning: no previous extern declaration for non-static variable 'out_file' [-Wmissing-variable-declarations]
|
||||
FILE *out_file;
|
||||
^
|
||||
|
||||
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
|
||||
Acked-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/src/module_to_cil.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c
|
||||
index 580ba06a95b0..21d8e5dbcc39 100644
|
||||
--- a/libsepol/src/module_to_cil.c
|
||||
+++ b/libsepol/src/module_to_cil.c
|
||||
@@ -62,7 +62,7 @@
|
||||
# define UNUSED(x) UNUSED_ ## x
|
||||
#endif
|
||||
|
||||
-FILE *out_file;
|
||||
+static FILE *out_file;
|
||||
|
||||
#define STACK_SIZE 16
|
||||
#define DEFAULT_LEVEL "systemlow"
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,225 +0,0 @@
|
||||
From 9fb8df7f1675cef89f32e3dd1a187cc5d53e08e4 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
|
||||
Date: Tue, 8 Jun 2021 17:59:12 +0200
|
||||
Subject: [PATCH] libsepol: declare read-only arrays const
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Make it more apparent that those data does not change and enforce it.
|
||||
|
||||
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
|
||||
Acked-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/src/avrule_block.c | 2 +-
|
||||
libsepol/src/avtab.c | 2 +-
|
||||
libsepol/src/link.c | 2 +-
|
||||
libsepol/src/polcaps.c | 2 +-
|
||||
libsepol/src/policydb.c | 22 +++++++++++-----------
|
||||
libsepol/src/policydb_internal.h | 2 +-
|
||||
libsepol/src/private.h | 6 +++---
|
||||
libsepol/src/write.c | 8 ++++----
|
||||
8 files changed, 23 insertions(+), 23 deletions(-)
|
||||
|
||||
diff --git a/libsepol/src/avrule_block.c b/libsepol/src/avrule_block.c
|
||||
index a9832d0d118f..dcfce8b8492c 100644
|
||||
--- a/libsepol/src/avrule_block.c
|
||||
+++ b/libsepol/src/avrule_block.c
|
||||
@@ -30,7 +30,7 @@
|
||||
/* It is anticipated that there be less declarations within an avrule
|
||||
* block than the global policy. Thus the symbol table sizes are
|
||||
* smaller than those listed in policydb.c */
|
||||
-static unsigned int symtab_sizes[SYM_NUM] = {
|
||||
+static const unsigned int symtab_sizes[SYM_NUM] = {
|
||||
2,
|
||||
4,
|
||||
8,
|
||||
diff --git a/libsepol/src/avtab.c b/libsepol/src/avtab.c
|
||||
index 257f051a86ec..88e9d510f981 100644
|
||||
--- a/libsepol/src/avtab.c
|
||||
+++ b/libsepol/src/avtab.c
|
||||
@@ -418,7 +418,7 @@ void avtab_hash_eval(avtab_t * h, char *tag)
|
||||
}
|
||||
|
||||
/* Ordering of datums in the original avtab format in the policy file. */
|
||||
-static uint16_t spec_order[] = {
|
||||
+static const uint16_t spec_order[] = {
|
||||
AVTAB_ALLOWED,
|
||||
AVTAB_AUDITDENY,
|
||||
AVTAB_AUDITALLOW,
|
||||
diff --git a/libsepol/src/link.c b/libsepol/src/link.c
|
||||
index bdc1fcbf59d3..461d2feb8190 100644
|
||||
--- a/libsepol/src/link.c
|
||||
+++ b/libsepol/src/link.c
|
||||
@@ -78,7 +78,7 @@ typedef struct missing_requirement {
|
||||
uint32_t perm_value;
|
||||
} missing_requirement_t;
|
||||
|
||||
-static const char *symtab_names[SYM_NUM] = {
|
||||
+static const char * const symtab_names[SYM_NUM] = {
|
||||
"common", "class", "role", "type/attribute", "user",
|
||||
"bool", "level", "category"
|
||||
};
|
||||
diff --git a/libsepol/src/polcaps.c b/libsepol/src/polcaps.c
|
||||
index 67ed5786db16..6a74ec7d3c3a 100644
|
||||
--- a/libsepol/src/polcaps.c
|
||||
+++ b/libsepol/src/polcaps.c
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <string.h>
|
||||
#include <sepol/policydb/polcaps.h>
|
||||
|
||||
-static const char *polcap_names[] = {
|
||||
+static const char * const polcap_names[] = {
|
||||
"network_peer_controls", /* POLICYDB_CAPABILITY_NETPEER */
|
||||
"open_perms", /* POLICYDB_CAPABILITY_OPENPERM */
|
||||
"extended_socket_class", /* POLICYDB_CAPABILITY_EXTSOCKCLASS */
|
||||
diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
|
||||
index b4e427af05c8..ef2217c28c91 100644
|
||||
--- a/libsepol/src/policydb.c
|
||||
+++ b/libsepol/src/policydb.c
|
||||
@@ -57,10 +57,10 @@
|
||||
#include "policydb_validate.h"
|
||||
|
||||
#define POLICYDB_TARGET_SZ ARRAY_SIZE(policydb_target_strings)
|
||||
-const char *policydb_target_strings[] = { POLICYDB_STRING, POLICYDB_XEN_STRING };
|
||||
+const char * const policydb_target_strings[] = { POLICYDB_STRING, POLICYDB_XEN_STRING };
|
||||
|
||||
/* These need to be updated if SYM_NUM or OCON_NUM changes */
|
||||
-static struct policydb_compat_info policydb_compat[] = {
|
||||
+static const struct policydb_compat_info policydb_compat[] = {
|
||||
{
|
||||
.type = POLICY_KERN,
|
||||
.version = POLICYDB_VERSION_BOUNDARY,
|
||||
@@ -460,7 +460,7 @@ static char *symtab_name[SYM_NUM] = {
|
||||
};
|
||||
#endif
|
||||
|
||||
-static unsigned int symtab_sizes[SYM_NUM] = {
|
||||
+static const unsigned int symtab_sizes[SYM_NUM] = {
|
||||
2,
|
||||
32,
|
||||
16,
|
||||
@@ -471,12 +471,12 @@ static unsigned int symtab_sizes[SYM_NUM] = {
|
||||
16,
|
||||
};
|
||||
|
||||
-struct policydb_compat_info *policydb_lookup_compat(unsigned int version,
|
||||
- unsigned int type,
|
||||
- unsigned int target_platform)
|
||||
+const struct policydb_compat_info *policydb_lookup_compat(unsigned int version,
|
||||
+ unsigned int type,
|
||||
+ unsigned int target_platform)
|
||||
{
|
||||
unsigned int i;
|
||||
- struct policydb_compat_info *info = NULL;
|
||||
+ const struct policydb_compat_info *info = NULL;
|
||||
|
||||
for (i = 0; i < sizeof(policydb_compat) / sizeof(*info); i++) {
|
||||
if (policydb_compat[i].version == version &&
|
||||
@@ -2848,7 +2848,7 @@ static int filename_trans_read(policydb_t *p, struct policy_file *fp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int ocontext_read_xen(struct policydb_compat_info *info,
|
||||
+static int ocontext_read_xen(const struct policydb_compat_info *info,
|
||||
policydb_t *p, struct policy_file *fp)
|
||||
{
|
||||
unsigned int i, j;
|
||||
@@ -2957,7 +2957,7 @@ static int ocontext_read_xen(struct policydb_compat_info *info,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
-static int ocontext_read_selinux(struct policydb_compat_info *info,
|
||||
+static int ocontext_read_selinux(const struct policydb_compat_info *info,
|
||||
policydb_t * p, struct policy_file *fp)
|
||||
{
|
||||
unsigned int i, j;
|
||||
@@ -3135,7 +3135,7 @@ static int ocontext_read_selinux(struct policydb_compat_info *info,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int ocontext_read(struct policydb_compat_info *info,
|
||||
+static int ocontext_read(const struct policydb_compat_info *info,
|
||||
policydb_t *p, struct policy_file *fp)
|
||||
{
|
||||
int rc = -1;
|
||||
@@ -4192,7 +4192,7 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose)
|
||||
uint32_t buf[5];
|
||||
size_t len, nprim, nel;
|
||||
char *policydb_str;
|
||||
- struct policydb_compat_info *info;
|
||||
+ const struct policydb_compat_info *info;
|
||||
unsigned int policy_type, bufindex;
|
||||
ebitmap_node_t *tnode;
|
||||
int rc;
|
||||
diff --git a/libsepol/src/policydb_internal.h b/libsepol/src/policydb_internal.h
|
||||
index 06ba5c8be144..dd8f25d0fc74 100644
|
||||
--- a/libsepol/src/policydb_internal.h
|
||||
+++ b/libsepol/src/policydb_internal.h
|
||||
@@ -3,5 +3,5 @@
|
||||
|
||||
#include <sepol/policydb.h>
|
||||
|
||||
-extern const char *policydb_target_strings[];
|
||||
+extern const char * const policydb_target_strings[];
|
||||
#endif
|
||||
diff --git a/libsepol/src/private.h b/libsepol/src/private.h
|
||||
index f5b5277f183a..72f212628314 100644
|
||||
--- a/libsepol/src/private.h
|
||||
+++ b/libsepol/src/private.h
|
||||
@@ -56,9 +56,9 @@ struct policydb_compat_info {
|
||||
unsigned int target_platform;
|
||||
};
|
||||
|
||||
-extern struct policydb_compat_info *policydb_lookup_compat(unsigned int version,
|
||||
- unsigned int type,
|
||||
- unsigned int target_platform);
|
||||
+extern const struct policydb_compat_info *policydb_lookup_compat(unsigned int version,
|
||||
+ unsigned int type,
|
||||
+ unsigned int target_platform);
|
||||
|
||||
/* Reading from a policy "file". */
|
||||
extern int next_entry(void *buf, struct policy_file *fp, size_t bytes);
|
||||
diff --git a/libsepol/src/write.c b/libsepol/src/write.c
|
||||
index 84bcaf3f57ca..3bd034d65cb1 100644
|
||||
--- a/libsepol/src/write.c
|
||||
+++ b/libsepol/src/write.c
|
||||
@@ -1345,7 +1345,7 @@ static int (*write_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum,
|
||||
common_write, class_write, role_write, type_write, user_write,
|
||||
cond_write_bool, sens_write, cat_write,};
|
||||
|
||||
-static int ocontext_write_xen(struct policydb_compat_info *info, policydb_t *p,
|
||||
+static int ocontext_write_xen(const struct policydb_compat_info *info, policydb_t *p,
|
||||
struct policy_file *fp)
|
||||
{
|
||||
unsigned int i, j;
|
||||
@@ -1453,7 +1453,7 @@ static int ocontext_write_xen(struct policydb_compat_info *info, policydb_t *p,
|
||||
return POLICYDB_SUCCESS;
|
||||
}
|
||||
|
||||
-static int ocontext_write_selinux(struct policydb_compat_info *info,
|
||||
+static int ocontext_write_selinux(const struct policydb_compat_info *info,
|
||||
policydb_t *p, struct policy_file *fp)
|
||||
{
|
||||
unsigned int i, j;
|
||||
@@ -1583,7 +1583,7 @@ static int ocontext_write_selinux(struct policydb_compat_info *info,
|
||||
return POLICYDB_SUCCESS;
|
||||
}
|
||||
|
||||
-static int ocontext_write(struct policydb_compat_info *info, policydb_t * p,
|
||||
+static int ocontext_write(const struct policydb_compat_info *info, policydb_t * p,
|
||||
struct policy_file *fp)
|
||||
{
|
||||
int rc = POLICYDB_ERROR;
|
||||
@@ -2179,7 +2179,7 @@ int policydb_write(policydb_t * p, struct policy_file *fp)
|
||||
unsigned int i, num_syms;
|
||||
uint32_t buf[32], config;
|
||||
size_t items, items2, len;
|
||||
- struct policydb_compat_info *info;
|
||||
+ const struct policydb_compat_info *info;
|
||||
struct policy_data pd;
|
||||
const char *policydb_str;
|
||||
|
||||
--
|
||||
2.32.0
|
||||
|
@ -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 0d351b491c2c..671b5ec6e183 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 71ddada226df..ea665a323f78 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 954eab330340..9c0231f294e3 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 a77c95201fb7..24be09aa33d8 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 b5199bad35e2..6d13544c80f7 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;
|
||||
}
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,136 +0,0 @@
|
||||
From c28525a26fa145cb5fd911fd2a3b9125a275677f Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Mon, 21 Jun 2021 10:34:30 -0400
|
||||
Subject: [PATCH] libsepol/cil: Properly check for loops in sets
|
||||
|
||||
Commit 61fbdce666f24c4a118b249ece6b014d54b65074 (ibsepol/cil: Check
|
||||
for self-referential loops in sets) added checks for self-referential
|
||||
loops in user, role, type, and category sets. Unfortunately, this
|
||||
check ends up in an infinite loop if the set with the self-referential
|
||||
loop is used in a different set that is checked before the bad set.
|
||||
|
||||
The problem with the old check is that only the initial datum is used
|
||||
for the check. Instead, use a stack to track all of the set datums
|
||||
that are currently involved as the check is made. A self-referential
|
||||
loop occurs if a duplicate datum is found for any of the datums in the
|
||||
stack.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
Acked-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
||||
---
|
||||
libsepol/cil/src/cil_verify.c | 48 +++++++++++++++++++++++------------
|
||||
1 file changed, 32 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_verify.c b/libsepol/cil/src/cil_verify.c
|
||||
index 8e15a0e68a69..59397f70f2ea 100644
|
||||
--- a/libsepol/cil/src/cil_verify.c
|
||||
+++ b/libsepol/cil/src/cil_verify.c
|
||||
@@ -44,6 +44,7 @@
|
||||
#include "cil_tree.h"
|
||||
#include "cil_list.h"
|
||||
#include "cil_find.h"
|
||||
+#include "cil_stack.h"
|
||||
|
||||
#include "cil_verify.h"
|
||||
|
||||
@@ -430,9 +431,9 @@ int cil_verify_decl_does_not_shadow_macro_parameter(struct cil_macro *macro, str
|
||||
return SEPOL_OK;
|
||||
}
|
||||
|
||||
-static int cil_verify_no_self_reference(enum cil_flavor flavor, struct cil_symtab_datum *datum, struct cil_symtab_datum *orig);
|
||||
+static int cil_verify_no_self_reference(enum cil_flavor flavor, struct cil_symtab_datum *datum, struct cil_stack *stack);
|
||||
|
||||
-static int __verify_no_self_reference_in_expr(struct cil_list *expr, struct cil_symtab_datum *orig)
|
||||
+static int __verify_no_self_reference_in_expr(struct cil_list *expr, struct cil_stack *stack)
|
||||
{
|
||||
struct cil_list_item *item;
|
||||
int rc = SEPOL_OK;
|
||||
@@ -444,9 +445,9 @@ static int __verify_no_self_reference_in_expr(struct cil_list *expr, struct cil_
|
||||
cil_list_for_each(item, expr) {
|
||||
if (item->flavor == CIL_DATUM) {
|
||||
struct cil_symtab_datum* datum = item->data;
|
||||
- rc = cil_verify_no_self_reference(FLAVOR(datum), datum, orig);
|
||||
+ rc = cil_verify_no_self_reference(FLAVOR(datum), datum, stack);
|
||||
} else if (item->flavor == CIL_LIST) {
|
||||
- rc = __verify_no_self_reference_in_expr(item->data, orig);
|
||||
+ rc = __verify_no_self_reference_in_expr(item->data, stack);
|
||||
}
|
||||
if (rc != SEPOL_OK) {
|
||||
return SEPOL_ERR;
|
||||
@@ -456,36 +457,47 @@ static int __verify_no_self_reference_in_expr(struct cil_list *expr, struct cil_
|
||||
return SEPOL_OK;
|
||||
}
|
||||
|
||||
-static int cil_verify_no_self_reference(enum cil_flavor flavor, struct cil_symtab_datum *datum, struct cil_symtab_datum *orig)
|
||||
+static int cil_verify_no_self_reference(enum cil_flavor flavor, struct cil_symtab_datum *datum, struct cil_stack *stack)
|
||||
{
|
||||
+ struct cil_stack_item *item;
|
||||
+ int i = 0;
|
||||
int rc = SEPOL_OK;
|
||||
|
||||
- if (datum == orig) {
|
||||
- cil_tree_log(NODE(orig), CIL_ERR, "Self-reference found for %s", orig->name);
|
||||
- return SEPOL_ERR;
|
||||
- } else if (orig == NULL) {
|
||||
- orig = datum;
|
||||
+ cil_stack_for_each(stack, i, item) {
|
||||
+ struct cil_symtab_datum *prev = item->data;
|
||||
+ if (datum == prev) {
|
||||
+ cil_tree_log(NODE(datum), CIL_ERR, "Self-reference found for %s", datum->name);
|
||||
+ return SEPOL_ERR;
|
||||
+ }
|
||||
}
|
||||
|
||||
switch (flavor) {
|
||||
case CIL_USERATTRIBUTE: {
|
||||
struct cil_userattribute *attr = (struct cil_userattribute *)datum;
|
||||
- rc = __verify_no_self_reference_in_expr(attr->expr_list, orig);
|
||||
+ cil_stack_push(stack, CIL_DATUM, datum);
|
||||
+ rc = __verify_no_self_reference_in_expr(attr->expr_list, stack);
|
||||
+ cil_stack_pop(stack);
|
||||
break;
|
||||
}
|
||||
case CIL_ROLEATTRIBUTE: {
|
||||
struct cil_roleattribute *attr = (struct cil_roleattribute *)datum;
|
||||
- rc = __verify_no_self_reference_in_expr(attr->expr_list, orig);
|
||||
+ cil_stack_push(stack, CIL_DATUM, datum);
|
||||
+ rc = __verify_no_self_reference_in_expr(attr->expr_list, stack);
|
||||
+ cil_stack_pop(stack);
|
||||
break;
|
||||
}
|
||||
case CIL_TYPEATTRIBUTE: {
|
||||
struct cil_typeattribute *attr = (struct cil_typeattribute *)datum;
|
||||
- rc = __verify_no_self_reference_in_expr(attr->expr_list, orig);
|
||||
+ cil_stack_push(stack, CIL_DATUM, datum);
|
||||
+ rc = __verify_no_self_reference_in_expr(attr->expr_list, stack);
|
||||
+ cil_stack_pop(stack);
|
||||
break;
|
||||
}
|
||||
case CIL_CATSET: {
|
||||
struct cil_catset *set = (struct cil_catset *)datum;
|
||||
- rc = __verify_no_self_reference_in_expr(set->cats->datum_expr, orig);
|
||||
+ cil_stack_push(stack, CIL_DATUM, datum);
|
||||
+ rc = __verify_no_self_reference_in_expr(set->cats->datum_expr, stack);
|
||||
+ cil_stack_pop(stack);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -1826,9 +1838,13 @@ int __cil_pre_verify_helper(struct cil_tree_node *node, uint32_t *finished, __at
|
||||
case CIL_USERATTRIBUTE:
|
||||
case CIL_ROLEATTRIBUTE:
|
||||
case CIL_TYPEATTRIBUTE:
|
||||
- case CIL_CATSET:
|
||||
- rc = cil_verify_no_self_reference(node->flavor, node->data, NULL);
|
||||
+ case CIL_CATSET: {
|
||||
+ struct cil_stack *stack;
|
||||
+ cil_stack_init(&stack);
|
||||
+ rc = cil_verify_no_self_reference(node->flavor, node->data, stack);
|
||||
+ cil_stack_destroy(&stack);
|
||||
break;
|
||||
+ }
|
||||
default:
|
||||
rc = SEPOL_OK;
|
||||
break;
|
||||
--
|
||||
2.32.0
|
||||
|
@ -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 ea665a323f78..baed3e581be4 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;
|
||||
--
|
||||
2.32.0
|
||||
|
@ -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 7bca0834ad39..7e2c2b9a85c3 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) {
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,36 +0,0 @@
|
||||
From 36e494573d7071f9b56670b4777ed14637025d9e Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Mon, 21 Jun 2021 10:56:49 -0400
|
||||
Subject: [PATCH] libsepol/cil: Reduce the initial symtab sizes for blocks
|
||||
|
||||
It is possible to create bad behaving policy that can consume all
|
||||
of a system's memory (one way is through the use of inheritance).
|
||||
Analyzing these policies shows that most of the memory usage is for
|
||||
the block symtabs.
|
||||
|
||||
Most of the nineteen symtabs will most likely never be used, so give
|
||||
these symtabs an initial size of 1. The others are given more
|
||||
appropriate sizes.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
Acked-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
||||
---
|
||||
libsepol/cil/src/cil.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c
|
||||
index 671b5ec6e183..9d5038d91add 100644
|
||||
--- a/libsepol/cil/src/cil.c
|
||||
+++ b/libsepol/cil/src/cil.c
|
||||
@@ -54,7 +54,7 @@
|
||||
|
||||
int cil_sym_sizes[CIL_SYM_ARRAY_NUM][CIL_SYM_NUM] = {
|
||||
{64, 64, 64, 1 << 13, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64},
|
||||
- {64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64},
|
||||
+ {8, 8, 8, 32, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
|
||||
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
|
||||
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
|
||||
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
|
||||
--
|
||||
2.32.0
|
||||
|
@ -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 24be09aa33d8..8b9aeabf66e4 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 6d13544c80f7..5245cc1556bd 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) {
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,58 +0,0 @@
|
||||
From 20271849d5e16fd3a3dd9c0db7d19fae18cf1f4c Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Thu, 24 Jun 2021 15:58:14 -0400
|
||||
Subject: [PATCH] libsepol/cil: Add function to determine if a subtree has a
|
||||
declaration
|
||||
|
||||
Create the function cil_tree_subtree_has_decl() that returns CIL_TRUE
|
||||
if the subtree has a declaration in it and CIL_FALSE otherwise.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_tree.c | 16 ++++++++++++++++
|
||||
libsepol/cil/src/cil_tree.h | 2 ++
|
||||
2 files changed, 18 insertions(+)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_tree.c b/libsepol/cil/src/cil_tree.c
|
||||
index 067268eb897c..4cf8dcc8b280 100644
|
||||
--- a/libsepol/cil/src/cil_tree.c
|
||||
+++ b/libsepol/cil/src/cil_tree.c
|
||||
@@ -136,6 +136,22 @@ __attribute__((format (printf, 3, 4))) void cil_tree_log(struct cil_tree_node *n
|
||||
cil_log(lvl,"\n");
|
||||
}
|
||||
|
||||
+int cil_tree_subtree_has_decl(struct cil_tree_node *node)
|
||||
+{
|
||||
+ while (node) {
|
||||
+ if (node->flavor >= CIL_MIN_DECLARATIVE) {
|
||||
+ return CIL_TRUE;
|
||||
+ }
|
||||
+ if (node->cl_head != NULL) {
|
||||
+ if (cil_tree_subtree_has_decl(node->cl_head))
|
||||
+ return CIL_TRUE;
|
||||
+ }
|
||||
+ node = node->next;
|
||||
+ }
|
||||
+
|
||||
+ return CIL_FALSE;
|
||||
+}
|
||||
+
|
||||
int cil_tree_init(struct cil_tree **tree)
|
||||
{
|
||||
struct cil_tree *new_tree = cil_malloc(sizeof(*new_tree));
|
||||
diff --git a/libsepol/cil/src/cil_tree.h b/libsepol/cil/src/cil_tree.h
|
||||
index bac9f1e47f2c..f4d2207153ce 100644
|
||||
--- a/libsepol/cil/src/cil_tree.h
|
||||
+++ b/libsepol/cil/src/cil_tree.h
|
||||
@@ -54,6 +54,8 @@ struct cil_tree_node *cil_tree_get_next_path(struct cil_tree_node *node, char **
|
||||
char *cil_tree_get_cil_path(struct cil_tree_node *node);
|
||||
__attribute__((format (printf, 3, 4))) void cil_tree_log(struct cil_tree_node *node, enum cil_log_level lvl, const char* msg, ...);
|
||||
|
||||
+int cil_tree_subtree_has_decl(struct cil_tree_node *node);
|
||||
+
|
||||
int cil_tree_init(struct cil_tree **tree);
|
||||
void cil_tree_destroy(struct cil_tree **tree);
|
||||
void cil_tree_subtree_destroy(struct cil_tree_node *node);
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,92 +0,0 @@
|
||||
From 4ff514a33e2442ba7dac7e96fc7e371898eed316 Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Thu, 24 Jun 2021 15:58:15 -0400
|
||||
Subject: [PATCH] libsepol/cil: Only reset AST if optional has a declaration
|
||||
|
||||
When disabling optionals, the AST needs to be reset only if one
|
||||
of the optional blocks being disabled contains a declaration.
|
||||
|
||||
Call the function cil_tree_subtree_has_decl() for each optional
|
||||
block being disabled and only reset the AST if one of them has
|
||||
a declaration in it.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/src/cil_resolve_ast.c | 58 +++++++++++++++++-------------
|
||||
1 file changed, 34 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
||||
index 5245cc1556bd..0ea5b1697dd2 100644
|
||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
||||
@@ -4230,33 +4230,43 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
|
||||
if (changed) {
|
||||
struct cil_list_item *item;
|
||||
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);
|
||||
+ int has_decls = CIL_FALSE;
|
||||
+
|
||||
+ cil_list_for_each(item, extra_args.to_destroy) {
|
||||
+ has_decls = cil_tree_subtree_has_decl(item->data);
|
||||
+ if (has_decls) {
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
|
||||
- pass = CIL_PASS_CALL1;
|
||||
+ if (has_decls) {
|
||||
+ /* Need to re-resolve because an optional was disabled that
|
||||
+ * contained one or more declarations.
|
||||
+ * Everything that needs to be reset comes after the
|
||||
+ * CIL_PASS_CALL2 pass. We 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);
|
||||
+ }
|
||||
|
||||
- rc = cil_reset_ast(current);
|
||||
- if (rc != SEPOL_OK) {
|
||||
- cil_log(CIL_ERR, "Failed to reset declarations\n");
|
||||
- goto exit;
|
||||
+ pass = CIL_PASS_CALL1;
|
||||
+
|
||||
+ 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.to_destroy) {
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,60 +0,0 @@
|
||||
From af75f64194c0f81c61f84305ddc8eb494de30e95 Mon Sep 17 00:00:00 2001
|
||||
From: Nicolas Iooss <nicolas.iooss@m4x.org>
|
||||
Date: Sat, 26 Jun 2021 14:34:43 +0200
|
||||
Subject: [PATCH] libsepol/cil: make array cil_sym_sizes const
|
||||
|
||||
The values of this table are never modified.
|
||||
|
||||
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
||||
---
|
||||
libsepol/cil/src/cil.c | 4 ++--
|
||||
libsepol/cil/src/cil_internal.h | 4 ++--
|
||||
2 files changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c
|
||||
index 9d5038d91add..32e8b3cf419e 100644
|
||||
--- a/libsepol/cil/src/cil.c
|
||||
+++ b/libsepol/cil/src/cil.c
|
||||
@@ -52,7 +52,7 @@
|
||||
#include "cil_strpool.h"
|
||||
#include "cil_write_ast.h"
|
||||
|
||||
-int cil_sym_sizes[CIL_SYM_ARRAY_NUM][CIL_SYM_NUM] = {
|
||||
+const int cil_sym_sizes[CIL_SYM_ARRAY_NUM][CIL_SYM_NUM] = {
|
||||
{64, 64, 64, 1 << 13, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64},
|
||||
{8, 8, 8, 32, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
|
||||
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
|
||||
@@ -1882,7 +1882,7 @@ void cil_set_policy_version(struct cil_db *db, int policy_version)
|
||||
db->policy_version = policy_version;
|
||||
}
|
||||
|
||||
-void cil_symtab_array_init(symtab_t symtab[], int symtab_sizes[CIL_SYM_NUM])
|
||||
+void cil_symtab_array_init(symtab_t symtab[], const int symtab_sizes[CIL_SYM_NUM])
|
||||
{
|
||||
uint32_t i = 0;
|
||||
for (i = 0; i < CIL_SYM_NUM; i++) {
|
||||
diff --git a/libsepol/cil/src/cil_internal.h b/libsepol/cil/src/cil_internal.h
|
||||
index 8b9aeabf66e4..3211fc355ec9 100644
|
||||
--- a/libsepol/cil/src/cil_internal.h
|
||||
+++ b/libsepol/cil/src/cil_internal.h
|
||||
@@ -275,7 +275,7 @@ enum cil_sym_array {
|
||||
CIL_SYM_ARRAY_NUM
|
||||
};
|
||||
|
||||
-extern int cil_sym_sizes[CIL_SYM_ARRAY_NUM][CIL_SYM_NUM];
|
||||
+extern const int cil_sym_sizes[CIL_SYM_ARRAY_NUM][CIL_SYM_NUM];
|
||||
|
||||
#define CIL_CLASS_SYM_SIZE 256
|
||||
#define CIL_PERMS_PER_CLASS (sizeof(sepol_access_vector_t) * 8)
|
||||
@@ -981,7 +981,7 @@ int cil_userprefixes_to_string(struct cil_db *db, char **out, size_t *size);
|
||||
int cil_selinuxusers_to_string(struct cil_db *db, char **out, size_t *size);
|
||||
int cil_filecons_to_string(struct cil_db *db, char **out, size_t *size);
|
||||
|
||||
-void cil_symtab_array_init(symtab_t symtab[], int symtab_sizes[CIL_SYM_NUM]);
|
||||
+void cil_symtab_array_init(symtab_t symtab[], const int symtab_sizes[CIL_SYM_NUM]);
|
||||
void cil_symtab_array_destroy(symtab_t symtab[]);
|
||||
void cil_destroy_ast_symtabs(struct cil_tree_node *root);
|
||||
int cil_get_symtab(struct cil_tree_node *ast_node, symtab_t **symtab, enum cil_sym_index sym_index);
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,244 +0,0 @@
|
||||
From a0914acf2a128bdfd30ca0ee964a1e88ddb6439e Mon Sep 17 00:00:00 2001
|
||||
From: James Carter <jwcart2@gmail.com>
|
||||
Date: Tue, 29 Jun 2021 11:13:59 -0400
|
||||
Subject: [PATCH] libsepol/cil: Provide option to allow qualified names in
|
||||
declarations
|
||||
|
||||
Qualified names have "dots" in them. They are generated when a CIL
|
||||
policy is compiled and come from declarations in blocks. If a kernel
|
||||
policy is decompiled into a CIL policy, the resulting policy could
|
||||
have declarations that use qualified names. Compiling this policy would
|
||||
result in an error because "dots" in declarations are not allowed.
|
||||
|
||||
Qualified names in a policy are normally used to refer to the name of
|
||||
identifiers, blocks, macros, or optionals that are declared in a
|
||||
different block (that is not a parent). Name resolution is based on
|
||||
splitting a name based on the "dots", searching the parents up to the
|
||||
global namespace for the first block using the first part of the name,
|
||||
using the second part of the name to lookup the next block using the
|
||||
first block's symbol tables, looking up the third block in the second's
|
||||
symbol tables, and so on.
|
||||
|
||||
To allow the option of using qualified names in declarations:
|
||||
|
||||
1) Create a field in the struct cil_db called "qualified_names" which
|
||||
is set to CIL_TRUE when qualified names are to be used. This field is
|
||||
checked in cil_verify_name() and "dots" are allowed if qualified names
|
||||
are being allowed.
|
||||
|
||||
2) Only allow the direct lookup of the whole name in the global symbol
|
||||
table. This means that blocks, blockinherits, blockabstracts, and in-
|
||||
statements cannot be allowed. Use the "qualified_names" field of the
|
||||
cil_db to know when using one of these should result in an error.
|
||||
|
||||
3) Create the function cil_set_qualified_names() that is used to set
|
||||
the "qualified_names" field. Export the function in libsepol.
|
||||
|
||||
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||
---
|
||||
libsepol/cil/include/cil/cil.h | 1 +
|
||||
libsepol/cil/src/cil.c | 6 ++++++
|
||||
libsepol/cil/src/cil_build_ast.c | 24 ++++++++++++++++++++++--
|
||||
libsepol/cil/src/cil_internal.h | 1 +
|
||||
libsepol/cil/src/cil_resolve_ast.c | 4 ++--
|
||||
libsepol/cil/src/cil_verify.c | 19 ++++++++++++++-----
|
||||
libsepol/cil/src/cil_verify.h | 2 +-
|
||||
libsepol/src/libsepol.map.in | 1 +
|
||||
8 files changed, 48 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/libsepol/cil/include/cil/cil.h b/libsepol/cil/include/cil/cil.h
|
||||
index 92fac6e1619a..482ca522277b 100644
|
||||
--- a/libsepol/cil/include/cil/cil.h
|
||||
+++ b/libsepol/cil/include/cil/cil.h
|
||||
@@ -51,6 +51,7 @@ extern int cil_selinuxusers_to_string(cil_db_t *db, char **out, size_t *size);
|
||||
extern int cil_filecons_to_string(cil_db_t *db, char **out, size_t *size);
|
||||
extern void cil_set_disable_dontaudit(cil_db_t *db, int disable_dontaudit);
|
||||
extern void cil_set_multiple_decls(cil_db_t *db, int multiple_decls);
|
||||
+extern void cil_set_qualified_names(struct cil_db *db, int qualified_names);
|
||||
extern void cil_set_disable_neverallow(cil_db_t *db, int disable_neverallow);
|
||||
extern void cil_set_preserve_tunables(cil_db_t *db, int preserve_tunables);
|
||||
extern int cil_set_handle_unknown(cil_db_t *db, int handle_unknown);
|
||||
diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c
|
||||
index 32e8b3cf419e..d24c81c89337 100644
|
||||
--- a/libsepol/cil/src/cil.c
|
||||
+++ b/libsepol/cil/src/cil.c
|
||||
@@ -440,6 +440,7 @@ void cil_db_init(struct cil_db **db)
|
||||
(*db)->handle_unknown = -1;
|
||||
(*db)->mls = -1;
|
||||
(*db)->multiple_decls = CIL_FALSE;
|
||||
+ (*db)->qualified_names = CIL_FALSE;
|
||||
(*db)->target_platform = SEPOL_TARGET_SELINUX;
|
||||
(*db)->policy_version = POLICYDB_VERSION_MAX;
|
||||
}
|
||||
@@ -1872,6 +1873,11 @@ void cil_set_multiple_decls(struct cil_db *db, int multiple_decls)
|
||||
db->multiple_decls = multiple_decls;
|
||||
}
|
||||
|
||||
+void cil_set_qualified_names(struct cil_db *db, int qualified_names)
|
||||
+{
|
||||
+ db->qualified_names = qualified_names;
|
||||
+}
|
||||
+
|
||||
void cil_set_target_platform(struct cil_db *db, int target_platform)
|
||||
{
|
||||
db->target_platform = target_platform;
|
||||
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
|
||||
index baed3e581be4..9da90883e85a 100644
|
||||
--- a/libsepol/cil/src/cil_build_ast.c
|
||||
+++ b/libsepol/cil/src/cil_build_ast.c
|
||||
@@ -146,7 +146,7 @@ int cil_gen_node(struct cil_db *db, struct cil_tree_node *ast_node, struct cil_s
|
||||
int rc = SEPOL_ERR;
|
||||
symtab_t *symtab = NULL;
|
||||
|
||||
- rc = cil_verify_name((const char*)key, nflavor);
|
||||
+ rc = cil_verify_name(db, (const char*)key, nflavor);
|
||||
if (rc != SEPOL_OK) {
|
||||
goto exit;
|
||||
}
|
||||
@@ -204,6 +204,11 @@ int cil_gen_block(struct cil_db *db, struct cil_tree_node *parse_current, struct
|
||||
goto exit;
|
||||
}
|
||||
|
||||
+ if (db->qualified_names) {
|
||||
+ cil_log(CIL_ERR, "Blocks are not allowed when the option for qualified names is used\n");
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
rc = __cil_verify_syntax(parse_current, syntax, syntax_len);
|
||||
if (rc != SEPOL_OK) {
|
||||
goto exit;
|
||||
@@ -274,6 +279,11 @@ int cil_gen_blockinherit(struct cil_db *db, struct cil_tree_node *parse_current,
|
||||
goto exit;
|
||||
}
|
||||
|
||||
+ if (db->qualified_names) {
|
||||
+ cil_log(CIL_ERR, "Block inherit rules are not allowed when the option for qualified names is used\n");
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
rc = __cil_verify_syntax(parse_current, syntax, syntax_len);
|
||||
if (rc != SEPOL_OK) {
|
||||
goto exit;
|
||||
@@ -331,6 +341,11 @@ int cil_gen_blockabstract(struct cil_db *db, struct cil_tree_node *parse_current
|
||||
goto exit;
|
||||
}
|
||||
|
||||
+ if (db->qualified_names) {
|
||||
+ cil_log(CIL_ERR, "Block abstract rules are not allowed when the option for qualified names is used\n");
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
rc = __cil_verify_syntax(parse_current, syntax, syntax_len);
|
||||
if (rc != SEPOL_OK) {
|
||||
goto exit;
|
||||
@@ -376,6 +391,11 @@ int cil_gen_in(struct cil_db *db, struct cil_tree_node *parse_current, struct ci
|
||||
goto exit;
|
||||
}
|
||||
|
||||
+ if (db->qualified_names) {
|
||||
+ cil_log(CIL_ERR, "In-statements are not allowed when the option for qualified names is used\n");
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
rc = __cil_verify_syntax(parse_current, syntax, syntax_len);
|
||||
if (rc != SEPOL_OK) {
|
||||
goto exit;
|
||||
@@ -5261,7 +5281,7 @@ int cil_gen_macro(struct cil_db *db, struct cil_tree_node *parse_current, struct
|
||||
|
||||
param->str = current_item->cl_head->next->data;
|
||||
|
||||
- rc = cil_verify_name(param->str, param->flavor);
|
||||
+ rc = cil_verify_name(db, param->str, param->flavor);
|
||||
if (rc != SEPOL_OK) {
|
||||
cil_destroy_param(param);
|
||||
goto exit;
|
||||
diff --git a/libsepol/cil/src/cil_internal.h b/libsepol/cil/src/cil_internal.h
|
||||
index 3211fc355ec9..98e303d14e84 100644
|
||||
--- a/libsepol/cil/src/cil_internal.h
|
||||
+++ b/libsepol/cil/src/cil_internal.h
|
||||
@@ -321,6 +321,7 @@ struct cil_db {
|
||||
int handle_unknown;
|
||||
int mls;
|
||||
int multiple_decls;
|
||||
+ int qualified_names;
|
||||
int target_platform;
|
||||
int policy_version;
|
||||
};
|
||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
||||
index 0ea5b1697dd2..32ea64e39b21 100644
|
||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
||||
@@ -4419,8 +4419,8 @@ int cil_resolve_name_keep_aliases(struct cil_tree_node *ast_node, char *name, en
|
||||
|
||||
*datum = NULL;
|
||||
|
||||
- if (strchr(name,'.') == NULL) {
|
||||
- /* No '.' in name */
|
||||
+ if (db->qualified_names || strchr(name,'.') == NULL) {
|
||||
+ /* Using qualified names or No '.' in name */
|
||||
rc = __cil_resolve_name_helper(db, ast_node->parent, name, sym_index, datum);
|
||||
if (rc != SEPOL_OK) {
|
||||
goto exit;
|
||||
diff --git a/libsepol/cil/src/cil_verify.c b/libsepol/cil/src/cil_verify.c
|
||||
index 59397f70f2ea..ce3fcd8c81c9 100644
|
||||
--- a/libsepol/cil/src/cil_verify.c
|
||||
+++ b/libsepol/cil/src/cil_verify.c
|
||||
@@ -92,7 +92,7 @@ static int __cil_is_reserved_name(const char *name, enum cil_flavor flavor)
|
||||
return CIL_FALSE;
|
||||
}
|
||||
|
||||
-int cil_verify_name(const char *name, enum cil_flavor flavor)
|
||||
+int cil_verify_name(const struct cil_db *db, const char *name, enum cil_flavor flavor)
|
||||
{
|
||||
int rc = SEPOL_ERR;
|
||||
int len;
|
||||
@@ -116,10 +116,19 @@ int cil_verify_name(const char *name, enum cil_flavor flavor)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
- for (i = 1; i < len; i++) {
|
||||
- if (!isalnum(name[i]) && name[i] != '_' && name[i] != '-') {
|
||||
- cil_log(CIL_ERR, "Invalid character \"%c\" in %s\n", name[i], name);
|
||||
- goto exit;
|
||||
+ if (db->qualified_names == CIL_FALSE) {
|
||||
+ for (i = 1; i < len; i++) {
|
||||
+ if (!isalnum(name[i]) && name[i] != '_' && name[i] != '-') {
|
||||
+ cil_log(CIL_ERR, "Invalid character \"%c\" in %s\n", name[i], name);
|
||||
+ goto exit;
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
+ for (i = 1; i < len; i++) {
|
||||
+ if (!isalnum(name[i]) && name[i] != '_' && name[i] != '-' && name[i] != '.') {
|
||||
+ cil_log(CIL_ERR, "Invalid character \"%c\" in %s\n", name[i], name);
|
||||
+ goto exit;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_verify.h b/libsepol/cil/src/cil_verify.h
|
||||
index 4ea14f5b0a9a..26e195a94c7e 100644
|
||||
--- a/libsepol/cil/src/cil_verify.h
|
||||
+++ b/libsepol/cil/src/cil_verify.h
|
||||
@@ -56,7 +56,7 @@ struct cil_args_verify {
|
||||
int *pass;
|
||||
};
|
||||
|
||||
-int cil_verify_name(const char *name, enum cil_flavor flavor);
|
||||
+int cil_verify_name(const struct cil_db *db, const char *name, enum cil_flavor flavor);
|
||||
int __cil_verify_syntax(struct cil_tree_node *parse_current, enum cil_syntax s[], int len);
|
||||
int cil_verify_expr_syntax(struct cil_tree_node *current, enum cil_flavor op, enum cil_flavor expr_flavor);
|
||||
int cil_verify_constraint_leaf_expr_syntax(enum cil_flavor l_flavor, enum cil_flavor r_flavor, enum cil_flavor op, enum cil_flavor expr_flavor);
|
||||
diff --git a/libsepol/src/libsepol.map.in b/libsepol/src/libsepol.map.in
|
||||
index 2e503bd1b453..0e05d6064789 100644
|
||||
--- a/libsepol/src/libsepol.map.in
|
||||
+++ b/libsepol/src/libsepol.map.in
|
||||
@@ -272,4 +272,5 @@ LIBSEPOL_3.0 {
|
||||
cil_write_parse_ast;
|
||||
cil_write_build_ast;
|
||||
cil_write_resolve_ast;
|
||||
+ cil_set_qualified_names;
|
||||
} LIBSEPOL_1.1;
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,51 +0,0 @@
|
||||
From fd705df050f916add396954218a67fb8a4fd7cad Mon Sep 17 00:00:00 2001
|
||||
From: Nicolas Iooss <nicolas.iooss@m4x.org>
|
||||
Date: Fri, 2 Jul 2021 13:07:05 +0200
|
||||
Subject: [PATCH] libsepol/cil: do not override previous results of
|
||||
__cil_verify_classperms
|
||||
|
||||
When __cil_verify_map_class() verifies a classpermission, it calls
|
||||
__verify_map_perm_classperms() on each item. If the first item reports a
|
||||
failure and the next one succeeds, the failure is overwritten in
|
||||
map_args->rc. This is a bug which causes a NULL pointer dereference in
|
||||
the CIL compiler when compiling the following policy:
|
||||
|
||||
(sid SID)
|
||||
(sidorder (SID))
|
||||
|
||||
(class CLASS (PERM1))
|
||||
(classorder (CLASS))
|
||||
|
||||
(classpermission CLSPERM)
|
||||
(classpermissionset CLSPERM (CLASS (PERM1)))
|
||||
(classmap files (CLAMAPxx x))
|
||||
(classmapping files CLAMAPxx CLSPERM)
|
||||
|
||||
Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=30286
|
||||
|
||||
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
||||
---
|
||||
libsepol/cil/src/cil_verify.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_verify.c b/libsepol/cil/src/cil_verify.c
|
||||
index ce3fcd8c81c9..fc8a8a406a15 100644
|
||||
--- a/libsepol/cil/src/cil_verify.c
|
||||
+++ b/libsepol/cil/src/cil_verify.c
|
||||
@@ -1795,8 +1795,12 @@ static int __verify_map_perm_classperms(__attribute__((unused)) hashtab_key_t k,
|
||||
{
|
||||
struct cil_verify_map_args *map_args = args;
|
||||
struct cil_perm *cmp = (struct cil_perm *)d;
|
||||
+ int rc;
|
||||
|
||||
- map_args->rc = __cil_verify_classperms(cmp->classperms, &cmp->datum, &map_args->class->datum, &cmp->datum, CIL_MAP_PERM, 0, 2);
|
||||
+ rc = __cil_verify_classperms(cmp->classperms, &cmp->datum, &map_args->class->datum, &cmp->datum, CIL_MAP_PERM, 0, 2);
|
||||
+ if (rc != SEPOL_OK) {
|
||||
+ map_args->rc = rc;
|
||||
+ }
|
||||
|
||||
return SEPOL_OK;
|
||||
}
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,132 +0,0 @@
|
||||
From 9d85aa60d12e468e7fd510c2b5475b5299b71622 Mon Sep 17 00:00:00 2001
|
||||
From: Nicolas Iooss <nicolas.iooss@m4x.org>
|
||||
Date: Sat, 3 Jul 2021 16:31:17 +0200
|
||||
Subject: [PATCH] libsepol: silence -Wextra-semi-stmt warning
|
||||
|
||||
On Ubuntu 20.04, when building with clang -Werror -Wextra-semi-stmt
|
||||
(which is not the default build configuration), the compiler reports:
|
||||
|
||||
../cil/src/cil_binary.c:4293:22: error: empty expression statement
|
||||
has no effect; remove unnecessary ';' to silence this warning
|
||||
[-Werror,-Wextra-semi-stmt]
|
||||
mix(k->target_class);
|
||||
^
|
||||
../cil/src/cil_binary.c:4294:21: error: empty expression statement
|
||||
has no effect; remove unnecessary ';' to silence this warning
|
||||
[-Werror,-Wextra-semi-stmt]
|
||||
mix(k->target_type);
|
||||
^
|
||||
../cil/src/cil_binary.c:4295:21: error: empty expression statement
|
||||
has no effect; remove unnecessary ';' to silence this warning
|
||||
[-Werror,-Wextra-semi-stmt]
|
||||
mix(k->source_type);
|
||||
^
|
||||
../cil/src/cil_binary.c:4296:19: error: empty expression statement
|
||||
has no effect; remove unnecessary ';' to silence this warning
|
||||
[-Werror,-Wextra-semi-stmt]
|
||||
mix(k->specified);
|
||||
^
|
||||
|
||||
Use a do { ... } while (0) construction to silence this warning.
|
||||
|
||||
Moreover the same warning appears when using two semicolons to end a
|
||||
statement. Remove such occurrences, like what was already done in commit
|
||||
811185648af2 ("libsepol: drop repeated semicolons").
|
||||
|
||||
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
||||
---
|
||||
libsepol/cil/src/cil_binary.c | 4 ++--
|
||||
libsepol/cil/src/cil_resolve_ast.c | 2 +-
|
||||
libsepol/src/avtab.c | 4 ++--
|
||||
libsepol/tests/libsepol-tests.c | 18 +++++++++++-------
|
||||
4 files changed, 16 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c
|
||||
index 54d13f2f3945..41105c122bc3 100644
|
||||
--- a/libsepol/cil/src/cil_binary.c
|
||||
+++ b/libsepol/cil/src/cil_binary.c
|
||||
@@ -4277,7 +4277,7 @@ static unsigned int avrulex_hash(__attribute__((unused)) hashtab_t h, const_hash
|
||||
|
||||
uint32_t hash = 0;
|
||||
|
||||
-#define mix(input) { \
|
||||
+#define mix(input) do { \
|
||||
uint32_t v = input; \
|
||||
v *= c1; \
|
||||
v = (v << r1) | (v >> (32 - r1)); \
|
||||
@@ -4285,7 +4285,7 @@ static unsigned int avrulex_hash(__attribute__((unused)) hashtab_t h, const_hash
|
||||
hash ^= v; \
|
||||
hash = (hash << r2) | (hash >> (32 - r2)); \
|
||||
hash = hash * m + n; \
|
||||
-}
|
||||
+} while (0)
|
||||
|
||||
mix(k->target_class);
|
||||
mix(k->target_type);
|
||||
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
||||
index 32ea64e39b21..9a02e3867659 100644
|
||||
--- a/libsepol/cil/src/cil_resolve_ast.c
|
||||
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
||||
@@ -2825,7 +2825,7 @@ static int cil_build_call_args(struct cil_tree_node *call_node, struct cil_call
|
||||
return SEPOL_OK;
|
||||
} else {
|
||||
cil_tree_log(call_node, CIL_ERR, "Unexpected arguments");
|
||||
- return SEPOL_ERR;;
|
||||
+ return SEPOL_ERR;
|
||||
}
|
||||
}
|
||||
if (call->args_tree == NULL) {
|
||||
diff --git a/libsepol/src/avtab.c b/libsepol/src/avtab.c
|
||||
index 88e9d510f981..5e16a0e9899e 100644
|
||||
--- a/libsepol/src/avtab.c
|
||||
+++ b/libsepol/src/avtab.c
|
||||
@@ -63,7 +63,7 @@ static inline int avtab_hash(struct avtab_key *keyp, uint32_t mask)
|
||||
|
||||
uint32_t hash = 0;
|
||||
|
||||
-#define mix(input) { \
|
||||
+#define mix(input) do { \
|
||||
uint32_t v = input; \
|
||||
v *= c1; \
|
||||
v = (v << r1) | (v >> (32 - r1)); \
|
||||
@@ -71,7 +71,7 @@ static inline int avtab_hash(struct avtab_key *keyp, uint32_t mask)
|
||||
hash ^= v; \
|
||||
hash = (hash << r2) | (hash >> (32 - r2)); \
|
||||
hash = hash * m + n; \
|
||||
-}
|
||||
+} while (0)
|
||||
|
||||
mix(keyp->target_class);
|
||||
mix(keyp->target_type);
|
||||
diff --git a/libsepol/tests/libsepol-tests.c b/libsepol/tests/libsepol-tests.c
|
||||
index 544c792d2ab5..dc8fd5ce5f6c 100644
|
||||
--- a/libsepol/tests/libsepol-tests.c
|
||||
+++ b/libsepol/tests/libsepol-tests.c
|
||||
@@ -36,13 +36,17 @@
|
||||
int mls;
|
||||
|
||||
#define DECLARE_SUITE(name) \
|
||||
- suite = CU_add_suite(#name, name##_test_init, name##_test_cleanup); \
|
||||
- if (NULL == suite) { \
|
||||
- CU_cleanup_registry(); \
|
||||
- return CU_get_error(); } \
|
||||
- if (name##_add_tests(suite)) { \
|
||||
- CU_cleanup_registry(); \
|
||||
- return CU_get_error(); }
|
||||
+ do { \
|
||||
+ suite = CU_add_suite(#name, name##_test_init, name##_test_cleanup); \
|
||||
+ if (NULL == suite) { \
|
||||
+ CU_cleanup_registry(); \
|
||||
+ return CU_get_error(); \
|
||||
+ } \
|
||||
+ if (name##_add_tests(suite)) { \
|
||||
+ CU_cleanup_registry(); \
|
||||
+ return CU_get_error(); \
|
||||
+ } \
|
||||
+ } while (0)
|
||||
|
||||
static void usage(char *progname)
|
||||
{
|
||||
--
|
||||
2.32.0
|
||||
|
@ -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 9a02e3867659..145d4e7452dd 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;
|
||||
}
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,79 +0,0 @@
|
||||
From 44d56761bed0a394cceb4b0c57fee4fc0e4d9a85 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
|
||||
Date: Tue, 6 Jul 2021 19:36:29 +0200
|
||||
Subject: [PATCH] libsepol: avoid unsigned integer overflow
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Unsigned integer overflow is well-defined and not undefined behavior.
|
||||
It is commonly used for hashing or pseudo random number generation.
|
||||
But it is still useful to enable undefined behavior sanitizer checks on
|
||||
unsigned arithmetic to detect possible issues on counters or variables
|
||||
with similar purpose or missed overflow checks on user input.
|
||||
|
||||
Use a spaceship operator like comparison instead of subtraction.
|
||||
|
||||
policydb.c:851:24: runtime error: unsigned integer overflow: 801 - 929 cannot be represented in type 'unsigned int'
|
||||
|
||||
Follow-up of: 1537ea8412e4 ("libsepol: avoid unsigned integer overflow")
|
||||
|
||||
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
|
||||
---
|
||||
libsepol/src/policydb.c | 10 +++++-----
|
||||
libsepol/src/private.h | 2 ++
|
||||
2 files changed, 7 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
|
||||
index ef2217c28c91..0398ceed2574 100644
|
||||
--- a/libsepol/src/policydb.c
|
||||
+++ b/libsepol/src/policydb.c
|
||||
@@ -817,11 +817,11 @@ static int filenametr_cmp(hashtab_t h __attribute__ ((unused)),
|
||||
const filename_trans_key_t *ft2 = (const filename_trans_key_t *)k2;
|
||||
int v;
|
||||
|
||||
- v = (ft1->ttype > ft2->ttype) - (ft1->ttype < ft2->ttype);
|
||||
+ v = spaceship_cmp(ft1->ttype, ft2->ttype);
|
||||
if (v)
|
||||
return v;
|
||||
|
||||
- v = (ft1->tclass > ft2->tclass) - (ft1->tclass < ft2->tclass);
|
||||
+ v = spaceship_cmp(ft1->tclass, ft2->tclass);
|
||||
if (v)
|
||||
return v;
|
||||
|
||||
@@ -843,15 +843,15 @@ static int rangetr_cmp(hashtab_t h __attribute__ ((unused)),
|
||||
const struct range_trans *key2 = (const struct range_trans *)k2;
|
||||
int v;
|
||||
|
||||
- v = key1->source_type - key2->source_type;
|
||||
+ v = spaceship_cmp(key1->source_type, key2->source_type);
|
||||
if (v)
|
||||
return v;
|
||||
|
||||
- v = key1->target_type - key2->target_type;
|
||||
+ v = spaceship_cmp(key1->target_type, key2->target_type);
|
||||
if (v)
|
||||
return v;
|
||||
|
||||
- v = key1->target_class - key2->target_class;
|
||||
+ v = spaceship_cmp(key1->target_class, key2->target_class);
|
||||
|
||||
return v;
|
||||
}
|
||||
diff --git a/libsepol/src/private.h b/libsepol/src/private.h
|
||||
index 72f212628314..c63238abe5f3 100644
|
||||
--- a/libsepol/src/private.h
|
||||
+++ b/libsepol/src/private.h
|
||||
@@ -47,6 +47,8 @@
|
||||
#define is_saturated(x) (x == (typeof(x))-1)
|
||||
#define zero_or_saturated(x) ((x == 0) || is_saturated(x))
|
||||
|
||||
+#define spaceship_cmp(a, b) (((a) > (b)) - ((a) < (b)))
|
||||
+
|
||||
/* Policy compatibility information. */
|
||||
struct policydb_compat_info {
|
||||
unsigned int type;
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,99 +0,0 @@
|
||||
From 09405ba91c40e4e08f2212c946a432fa001d04bb Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
|
||||
Date: Thu, 1 Jul 2021 20:06:22 +0200
|
||||
Subject: [PATCH] libsepol: ignore UBSAN false-positives
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Unsigned integer overflow is well-defined and not undefined behavior.
|
||||
But it is still useful to enable undefined behavior sanitizer checks on
|
||||
unsigned arithmetic to detect possible issues on counters or variables
|
||||
with similar purpose.
|
||||
|
||||
Annotate functions, in which unsigned overflows are expected to happen,
|
||||
with the respective Clang function attribute[1].
|
||||
GCC does not support sanitizing unsigned integer arithmetic[2].
|
||||
|
||||
avtab.c:76:2: runtime error: unsigned integer overflow: 6 * 3432918353 cannot be represented in type 'unsigned int'
|
||||
policydb.c:795:42: runtime error: unsigned integer overflow: 8160943042179512010 * 11 cannot be represented in type 'unsigned long'
|
||||
symtab.c:25:12: runtime error: left shift of 1766601759 by 4 places cannot be represented in type 'unsigned int'
|
||||
|
||||
[1]: https://clang.llvm.org/docs/AttributeReference.html#no-sanitize
|
||||
[2]: https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html
|
||||
|
||||
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
|
||||
---
|
||||
libsepol/src/avtab.c | 1 +
|
||||
libsepol/src/policydb.c | 1 +
|
||||
libsepol/src/private.h | 11 +++++++++++
|
||||
libsepol/src/symtab.c | 4 ++++
|
||||
4 files changed, 17 insertions(+)
|
||||
|
||||
diff --git a/libsepol/src/avtab.c b/libsepol/src/avtab.c
|
||||
index 5e16a0e9899e..93505b20e4c0 100644
|
||||
--- a/libsepol/src/avtab.c
|
||||
+++ b/libsepol/src/avtab.c
|
||||
@@ -52,6 +52,7 @@
|
||||
/* Based on MurmurHash3, written by Austin Appleby and placed in the
|
||||
* public domain.
|
||||
*/
|
||||
+ignore_unsigned_overflow_
|
||||
static inline int avtab_hash(struct avtab_key *keyp, uint32_t mask)
|
||||
{
|
||||
static const uint32_t c1 = 0xcc9e2d51;
|
||||
diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
|
||||
index 0398ceed2574..7093d9b7028a 100644
|
||||
--- a/libsepol/src/policydb.c
|
||||
+++ b/libsepol/src/policydb.c
|
||||
@@ -789,6 +789,7 @@ static int roles_init(policydb_t * p)
|
||||
goto out;
|
||||
}
|
||||
|
||||
+ignore_unsigned_overflow_
|
||||
static inline unsigned long
|
||||
partial_name_hash(unsigned long c, unsigned long prevhash)
|
||||
{
|
||||
diff --git a/libsepol/src/private.h b/libsepol/src/private.h
|
||||
index c63238abe5f3..71287282fbc0 100644
|
||||
--- a/libsepol/src/private.h
|
||||
+++ b/libsepol/src/private.h
|
||||
@@ -49,6 +49,17 @@
|
||||
|
||||
#define spaceship_cmp(a, b) (((a) > (b)) - ((a) < (b)))
|
||||
|
||||
+/* Use to ignore intentional unsigned under- and overflows while running under UBSAN. */
|
||||
+#if defined(__clang__) && defined(__clang_major__) && (__clang_major__ >= 4)
|
||||
+#if (__clang_major__ >= 12)
|
||||
+#define ignore_unsigned_overflow_ __attribute__((no_sanitize("unsigned-integer-overflow", "unsigned-shift-base")))
|
||||
+#else
|
||||
+#define ignore_unsigned_overflow_ __attribute__((no_sanitize("unsigned-integer-overflow")))
|
||||
+#endif
|
||||
+#else
|
||||
+#define ignore_unsigned_overflow_
|
||||
+#endif
|
||||
+
|
||||
/* Policy compatibility information. */
|
||||
struct policydb_compat_info {
|
||||
unsigned int type;
|
||||
diff --git a/libsepol/src/symtab.c b/libsepol/src/symtab.c
|
||||
index 9a417ca24b53..a60618510bd3 100644
|
||||
--- a/libsepol/src/symtab.c
|
||||
+++ b/libsepol/src/symtab.c
|
||||
@@ -8,9 +8,13 @@
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
+
|
||||
+#include "private.h"
|
||||
+
|
||||
#include <sepol/policydb/hashtab.h>
|
||||
#include <sepol/policydb/symtab.h>
|
||||
|
||||
+ignore_unsigned_overflow_
|
||||
static unsigned int symhash(hashtab_t h, const_hashtab_key_t key)
|
||||
{
|
||||
const char *p, *keyp;
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,70 +0,0 @@
|
||||
From e1491388d570a83f6b005d7dc1906765a02b922e Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
|
||||
Date: Thu, 1 Jul 2021 20:06:45 +0200
|
||||
Subject: [PATCH] libsepol: avoid implicit conversions
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Avoid implicit conversions from signed to unsigned values, found by
|
||||
UB sanitizers, by using unsigned values in the first place.
|
||||
|
||||
expand.c:1644:18: runtime error: implicit conversion from type 'int' of value -1 (32-bit, signed) to type 'uint32_t' (aka 'unsigned int') changed the value to 4294967295 (32-bit, unsigned)
|
||||
|
||||
expand.c:2892:24: runtime error: implicit conversion from type 'int' of value -2 (32-bit, signed) to type 'unsigned int' changed the value to 4294967294 (32-bit, unsigned)
|
||||
|
||||
policy_define.c:2344:4: runtime error: implicit conversion from type 'int' of value -1048577 (32-bit, signed) to type 'unsigned int' changed the value to 4293918719 (32-bit, unsigned)
|
||||
|
||||
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
|
||||
---
|
||||
libsepol/include/sepol/policydb/conditional.h | 2 +-
|
||||
libsepol/include/sepol/policydb/policydb.h | 6 +++---
|
||||
libsepol/src/expand.c | 2 +-
|
||||
3 files changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/libsepol/include/sepol/policydb/conditional.h b/libsepol/include/sepol/policydb/conditional.h
|
||||
index 9c3df3ef488e..49c0d76631c4 100644
|
||||
--- a/libsepol/include/sepol/policydb/conditional.h
|
||||
+++ b/libsepol/include/sepol/policydb/conditional.h
|
||||
@@ -90,7 +90,7 @@ typedef struct cond_node {
|
||||
uint32_t expr_pre_comp;
|
||||
struct cond_node *next;
|
||||
/* a tunable conditional, calculated and used at expansion */
|
||||
-#define COND_NODE_FLAGS_TUNABLE 0x01
|
||||
+#define COND_NODE_FLAGS_TUNABLE UINT32_C(0x01)
|
||||
uint32_t flags;
|
||||
} cond_node_t;
|
||||
|
||||
diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h
|
||||
index 6976ef4831ef..4bf9f05ddd0a 100644
|
||||
--- a/libsepol/include/sepol/policydb/policydb.h
|
||||
+++ b/libsepol/include/sepol/policydb/policydb.h
|
||||
@@ -251,9 +251,9 @@ typedef struct class_perm_node {
|
||||
struct class_perm_node *next;
|
||||
} class_perm_node_t;
|
||||
|
||||
-#define xperm_test(x, p) (1 & (p[x >> 5] >> (x & 0x1f)))
|
||||
-#define xperm_set(x, p) (p[x >> 5] |= (1 << (x & 0x1f)))
|
||||
-#define xperm_clear(x, p) (p[x >> 5] &= ~(1 << (x & 0x1f)))
|
||||
+#define xperm_test(x, p) (UINT32_C(1) & (p[x >> 5] >> (x & 0x1f)))
|
||||
+#define xperm_set(x, p) (p[x >> 5] |= (UINT32_C(1) << (x & 0x1f)))
|
||||
+#define xperm_clear(x, p) (p[x >> 5] &= ~(UINT32_C(1) << (x & 0x1f)))
|
||||
#define EXTENDED_PERMS_LEN 8
|
||||
|
||||
typedef struct av_extended_perms {
|
||||
diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c
|
||||
index 84bfcfa36d0a..aac5b35f7bd1 100644
|
||||
--- a/libsepol/src/expand.c
|
||||
+++ b/libsepol/src/expand.c
|
||||
@@ -1641,7 +1641,7 @@ static avtab_ptr_t find_avtab_node(sepol_handle_t * handle,
|
||||
* AUDITDENY, aka DONTAUDIT, are &= assigned, versus |= for
|
||||
* others. Initialize the data accordingly.
|
||||
*/
|
||||
- avdatum.data = key->specified == AVTAB_AUDITDENY ? ~0 : 0;
|
||||
+ avdatum.data = key->specified == AVTAB_AUDITDENY ? ~UINT32_C(0) : UINT32_C(0);
|
||||
/* this is used to get the node - insertion is actually unique */
|
||||
node = avtab_insert_nonunique(avtab, key, &avdatum);
|
||||
if (!node) {
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,89 +0,0 @@
|
||||
From 07d6f1cea5a8ec0251606636189bc519d80b0729 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
|
||||
Date: Thu, 1 Jul 2021 20:07:07 +0200
|
||||
Subject: [PATCH] libsepol: assure string NUL-termination of ibdev_name
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Clang complains:
|
||||
|
||||
ibendport_record.c: In function ‘sepol_ibendport_get_ibdev_name’:
|
||||
ibendport_record.c:169:2: error: ‘strncpy’ specified bound 64 equals destination size [-Werror=stringop-truncation]
|
||||
169 | strncpy(tmp_ibdev_name, ibendport->ibdev_name, IB_DEVICE_NAME_MAX);
|
||||
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
ibendport_record.c: In function ‘sepol_ibendport_set_ibdev_name’:
|
||||
ibendport_record.c:189:2: error: ‘strncpy’ specified bound 64 equals destination size [-Werror=stringop-truncation]
|
||||
189 | strncpy(tmp, ibdev_name, IB_DEVICE_NAME_MAX);
|
||||
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
strncpy(3) does not NUL-terminate the destination if the source is of
|
||||
the same length or longer then the specified size.
|
||||
The source of these copies are retrieved from
|
||||
sepol_ibendport_alloc_ibdev_name(), which allocates a fixed amount of
|
||||
IB_DEVICE_NAME_MAX bytes.
|
||||
Reduce the size to copy by 1 of all memory regions allocated by
|
||||
sepol_ibendport_alloc_ibdev_name().
|
||||
|
||||
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
|
||||
---
|
||||
libsepol/src/ibendport_record.c | 8 ++++----
|
||||
libsepol/src/ibendports.c | 2 +-
|
||||
2 files changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/libsepol/src/ibendport_record.c b/libsepol/src/ibendport_record.c
|
||||
index adf671615e5c..1eb50914b8c0 100644
|
||||
--- a/libsepol/src/ibendport_record.c
|
||||
+++ b/libsepol/src/ibendport_record.c
|
||||
@@ -62,7 +62,7 @@ int sepol_ibendport_key_create(sepol_handle_t *handle,
|
||||
if (sepol_ibendport_alloc_ibdev_name(handle, &tmp_key->ibdev_name) < 0)
|
||||
goto err;
|
||||
|
||||
- strncpy(tmp_key->ibdev_name, ibdev_name, IB_DEVICE_NAME_MAX);
|
||||
+ strncpy(tmp_key->ibdev_name, ibdev_name, IB_DEVICE_NAME_MAX - 1);
|
||||
tmp_key->port = port;
|
||||
|
||||
*key_ptr = tmp_key;
|
||||
@@ -166,7 +166,7 @@ int sepol_ibendport_get_ibdev_name(sepol_handle_t *handle,
|
||||
if (sepol_ibendport_alloc_ibdev_name(handle, &tmp_ibdev_name) < 0)
|
||||
goto err;
|
||||
|
||||
- strncpy(tmp_ibdev_name, ibendport->ibdev_name, IB_DEVICE_NAME_MAX);
|
||||
+ strncpy(tmp_ibdev_name, ibendport->ibdev_name, IB_DEVICE_NAME_MAX - 1);
|
||||
*ibdev_name = tmp_ibdev_name;
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
@@ -186,7 +186,7 @@ int sepol_ibendport_set_ibdev_name(sepol_handle_t *handle,
|
||||
if (sepol_ibendport_alloc_ibdev_name(handle, &tmp) < 0)
|
||||
goto err;
|
||||
|
||||
- strncpy(tmp, ibdev_name, IB_DEVICE_NAME_MAX);
|
||||
+ strncpy(tmp, ibdev_name, IB_DEVICE_NAME_MAX - 1);
|
||||
free(ibendport->ibdev_name);
|
||||
ibendport->ibdev_name = tmp;
|
||||
return STATUS_SUCCESS;
|
||||
@@ -230,7 +230,7 @@ int sepol_ibendport_clone(sepol_handle_t *handle,
|
||||
if (sepol_ibendport_alloc_ibdev_name(handle, &new_ibendport->ibdev_name) < 0)
|
||||
goto omem;
|
||||
|
||||
- strncpy(new_ibendport->ibdev_name, ibendport->ibdev_name, IB_DEVICE_NAME_MAX);
|
||||
+ strncpy(new_ibendport->ibdev_name, ibendport->ibdev_name, IB_DEVICE_NAME_MAX - 1);
|
||||
new_ibendport->port = ibendport->port;
|
||||
|
||||
if (ibendport->con &&
|
||||
diff --git a/libsepol/src/ibendports.c b/libsepol/src/ibendports.c
|
||||
index 6d56c9a1793f..ee5cb1930f31 100644
|
||||
--- a/libsepol/src/ibendports.c
|
||||
+++ b/libsepol/src/ibendports.c
|
||||
@@ -34,7 +34,7 @@ static int ibendport_from_record(sepol_handle_t *handle,
|
||||
&ibdev_name) < 0)
|
||||
goto err;
|
||||
|
||||
- strncpy(tmp_ibendport->u.ibendport.dev_name, ibdev_name, IB_DEVICE_NAME_MAX);
|
||||
+ strncpy(tmp_ibendport->u.ibendport.dev_name, ibdev_name, IB_DEVICE_NAME_MAX - 1);
|
||||
|
||||
free(ibdev_name);
|
||||
ibdev_name = NULL;
|
||||
--
|
||||
2.32.0
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user