| |
@@ -0,0 +1,170 @@
|
| |
+ From 3b26f0566698926ba38cbf3fa702f3ff78862c5e Mon Sep 17 00:00:00 2001
|
| |
+ From: James Carter <jwcart2@gmail.com>
|
| |
+ Date: Tue, 20 Oct 2020 09:28:56 -0400
|
| |
+ Subject: [PATCH] libsepol/cil: Give error for more than one true or false
|
| |
+ block
|
| |
+
|
| |
+ Both tunableif and booleanif use conditional blocks (either true or
|
| |
+ false). No ordering is imposed, so a false block can be first (or even
|
| |
+ the only) block. Checks are made to ensure that the first and second
|
| |
+ (if it exists) blocks are either true or false, but no checks are made
|
| |
+ to ensure that there is only one true and/or one false block. If there
|
| |
+ are more than one true or false block, only the first will be used and
|
| |
+ the other will be ignored.
|
| |
+
|
| |
+ Create a function, cil_verify_conditional_blocks(), that gives an error
|
| |
+ along with a message if more than one true or false block is specified
|
| |
+ and call that function when building tunableif and booleanif blocks in
|
| |
+ the AST.
|
| |
+
|
| |
+ Signed-off-by: James Carter <jwcart2@gmail.com>
|
| |
+ Acked-by: Ondrej Mosnacek <omosnace@redhat.com>
|
| |
+ ---
|
| |
+ libsepol/cil/src/cil_build_ast.c | 44 +++++---------------------------
|
| |
+ libsepol/cil/src/cil_verify.c | 35 +++++++++++++++++++++++++
|
| |
+ libsepol/cil/src/cil_verify.h | 1 +
|
| |
+ 3 files changed, 42 insertions(+), 38 deletions(-)
|
| |
+
|
| |
+ diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
|
| |
+ index 3aabb05ec534..a895583404a7 100644
|
| |
+ --- a/libsepol/cil/src/cil_build_ast.c
|
| |
+ +++ b/libsepol/cil/src/cil_build_ast.c
|
| |
+ @@ -2821,7 +2821,6 @@ int cil_gen_boolif(struct cil_db *db, struct cil_tree_node *parse_current, struc
|
| |
+ int syntax_len = sizeof(syntax)/sizeof(*syntax);
|
| |
+ struct cil_booleanif *bif = NULL;
|
| |
+ struct cil_tree_node *next = NULL;
|
| |
+ - struct cil_tree_node *cond = NULL;
|
| |
+ int rc = SEPOL_ERR;
|
| |
+
|
| |
+ if (db == NULL || parse_current == NULL || ast_node == NULL) {
|
| |
+ @@ -2841,27 +2840,12 @@ int cil_gen_boolif(struct cil_db *db, struct cil_tree_node *parse_current, struc
|
| |
+ goto exit;
|
| |
+ }
|
| |
+
|
| |
+ - cond = parse_current->next->next;
|
| |
+ -
|
| |
+ - /* Destroying expr tree after stack is created*/
|
| |
+ - if (cond->cl_head->data != CIL_KEY_CONDTRUE &&
|
| |
+ - cond->cl_head->data != CIL_KEY_CONDFALSE) {
|
| |
+ - rc = SEPOL_ERR;
|
| |
+ - cil_log(CIL_ERR, "Conditional neither true nor false\n");
|
| |
+ + rc = cil_verify_conditional_blocks(parse_current->next->next);
|
| |
+ + if (rc != SEPOL_OK) {
|
| |
+ goto exit;
|
| |
+ }
|
| |
+
|
| |
+ - if (cond->next != NULL) {
|
| |
+ - cond = cond->next;
|
| |
+ - if (cond->cl_head->data != CIL_KEY_CONDTRUE &&
|
| |
+ - cond->cl_head->data != CIL_KEY_CONDFALSE) {
|
| |
+ - rc = SEPOL_ERR;
|
| |
+ - cil_log(CIL_ERR, "Conditional neither true nor false\n");
|
| |
+ - goto exit;
|
| |
+ - }
|
| |
+ - }
|
| |
+ -
|
| |
+ -
|
| |
+ + /* Destroying expr tree */
|
| |
+ next = parse_current->next->next;
|
| |
+ cil_tree_subtree_destroy(parse_current->next);
|
| |
+ parse_current->next = next;
|
| |
+ @@ -2905,7 +2889,6 @@ int cil_gen_tunif(struct cil_db *db, struct cil_tree_node *parse_current, struct
|
| |
+ int syntax_len = sizeof(syntax)/sizeof(*syntax);
|
| |
+ struct cil_tunableif *tif = NULL;
|
| |
+ struct cil_tree_node *next = NULL;
|
| |
+ - struct cil_tree_node *cond = NULL;
|
| |
+ int rc = SEPOL_ERR;
|
| |
+
|
| |
+ if (db == NULL || parse_current == NULL || ast_node == NULL) {
|
| |
+ @@ -2924,27 +2907,12 @@ int cil_gen_tunif(struct cil_db *db, struct cil_tree_node *parse_current, struct
|
| |
+ goto exit;
|
| |
+ }
|
| |
+
|
| |
+ - cond = parse_current->next->next;
|
| |
+ -
|
| |
+ - if (cond->cl_head->data != CIL_KEY_CONDTRUE &&
|
| |
+ - cond->cl_head->data != CIL_KEY_CONDFALSE) {
|
| |
+ - rc = SEPOL_ERR;
|
| |
+ - cil_log(CIL_ERR, "Conditional neither true nor false\n");
|
| |
+ + rc = cil_verify_conditional_blocks(parse_current->next->next);
|
| |
+ + if (rc != SEPOL_OK) {
|
| |
+ goto exit;
|
| |
+ }
|
| |
+
|
| |
+ - if (cond->next != NULL) {
|
| |
+ - cond = cond->next;
|
| |
+ -
|
| |
+ - if (cond->cl_head->data != CIL_KEY_CONDTRUE &&
|
| |
+ - cond->cl_head->data != CIL_KEY_CONDFALSE) {
|
| |
+ - rc = SEPOL_ERR;
|
| |
+ - cil_log(CIL_ERR, "Conditional neither true nor false\n");
|
| |
+ - goto exit;
|
| |
+ - }
|
| |
+ - }
|
| |
+ -
|
| |
+ - /* Destroying expr tree after stack is created*/
|
| |
+ + /* Destroying expr tree */
|
| |
+ next = parse_current->next->next;
|
| |
+ cil_tree_subtree_destroy(parse_current->next);
|
| |
+ parse_current->next = next;
|
| |
+ diff --git a/libsepol/cil/src/cil_verify.c b/libsepol/cil/src/cil_verify.c
|
| |
+ index c73bbeee371b..6706e21921fe 100644
|
| |
+ --- a/libsepol/cil/src/cil_verify.c
|
| |
+ +++ b/libsepol/cil/src/cil_verify.c
|
| |
+ @@ -324,6 +324,41 @@ exit:
|
| |
+ return SEPOL_ERR;
|
| |
+ }
|
| |
+
|
| |
+ +int cil_verify_conditional_blocks(struct cil_tree_node *current)
|
| |
+ +{
|
| |
+ + int found_true = CIL_FALSE;
|
| |
+ + int found_false = CIL_FALSE;
|
| |
+ +
|
| |
+ + if (current->cl_head->data == CIL_KEY_CONDTRUE) {
|
| |
+ + found_true = CIL_TRUE;
|
| |
+ + } else if (current->cl_head->data == CIL_KEY_CONDFALSE) {
|
| |
+ + found_false = CIL_TRUE;
|
| |
+ + } else {
|
| |
+ + cil_tree_log(current, CIL_ERR, "Expected true or false block in conditional");
|
| |
+ + return SEPOL_ERR;
|
| |
+ + }
|
| |
+ +
|
| |
+ + current = current->next;
|
| |
+ + if (current != NULL) {
|
| |
+ + if (current->cl_head->data == CIL_KEY_CONDTRUE) {
|
| |
+ + if (found_true) {
|
| |
+ + cil_tree_log(current, CIL_ERR, "More than one true block in conditional");
|
| |
+ + return SEPOL_ERR;
|
| |
+ + }
|
| |
+ + } else if (current->cl_head->data == CIL_KEY_CONDFALSE) {
|
| |
+ + if (found_false) {
|
| |
+ + cil_tree_log(current, CIL_ERR, "More than one false block in conditional");
|
| |
+ + return SEPOL_ERR;
|
| |
+ + }
|
| |
+ + } else {
|
| |
+ + cil_tree_log(current, CIL_ERR, "Expected true or false block in conditional");
|
| |
+ + 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 bda1565fced5..905761b0a19c 100644
|
| |
+ --- a/libsepol/cil/src/cil_verify.h
|
| |
+ +++ b/libsepol/cil/src/cil_verify.h
|
| |
+ @@ -61,6 +61,7 @@ int __cil_verify_syntax(struct cil_tree_node *parse_current, enum cil_syntax s[]
|
| |
+ 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);
|
| |
+ 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_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.29.2
|
| |
+
|
| |