| From fafe4c212bf6c32c3021d7b69bcc0cf219e71608 Mon Sep 17 00:00:00 2001 |
| From: Dan Cashman <dcashman@android.com> |
| Date: Tue, 29 Aug 2017 09:32:05 -0700 |
| Subject: [PATCH 03/12] libsepol: cil: Add ability to redeclare |
| types[attributes] |
| |
| Modify cil_gen_node() to check to see if the cil_db supports multiple |
| declarations, and if so, to check whether or not the |
| repeated symbol is eligible to share the existing, already-stored datum. The |
| only types considered so far are CIL_TYPE and CIL_TYPEATTRIBUTE, both of |
| which intall empty datums during AST building, so they automatically return |
| true. |
| |
| Test: Build policy with multilpe type and attribute declarations, and |
| without. Policies are binary-identical. |
| |
| Signed-off-by: Dan Cashman <dcashman@android.com> |
| Signed-off-by: James Carter <jwcart2@tycho.nsa.gov> |
| --- |
| libsepol/cil/include/cil/cil.h | 1 + |
| libsepol/cil/src/cil.c | 5 ++++ |
| libsepol/cil/src/cil_build_ast.c | 48 +++++++++++++++++++++++++++----- |
| libsepol/cil/src/cil_internal.h | 1 + |
| libsepol/src/libsepol.map.in | 1 + |
| 5 files changed, 49 insertions(+), 7 deletions(-) |
| |
| diff --git a/libsepol/cil/include/cil/cil.h b/libsepol/cil/include/cil/cil.h |
| index 86117f24..f8cfc3be 100644 |
| --- a/libsepol/cil/include/cil/cil.h |
| +++ b/libsepol/cil/include/cil/cil.h |
| @@ -50,6 +50,7 @@ extern int cil_userprefixes_to_string(cil_db_t *db, char **out, size_t *size); |
| 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_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 c02a41a5..3fe68af8 100644 |
| --- a/libsepol/cil/src/cil.c |
| +++ b/libsepol/cil/src/cil.c |
| @@ -1691,6 +1691,11 @@ void cil_set_mls(struct cil_db *db, int mls) |
| db->mls = mls; |
| } |
| |
| +void cil_set_multiple_decls(struct cil_db *db, int multiple_decls) |
| +{ |
| + db->multiple_decls = multiple_decls; |
| +} |
| + |
| 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 04492e52..9fc8ab87 100644 |
| --- a/libsepol/cil/src/cil_build_ast.c |
| +++ b/libsepol/cil/src/cil_build_ast.c |
| @@ -82,10 +82,33 @@ 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, |
| + __attribute__((unused)) struct cil_symtab_datum *old, |
| + enum cil_flavor f) |
| +{ |
| + int rc = CIL_FALSE; |
| + |
| + switch (f) { |
| + case CIL_TYPE: |
| + case CIL_TYPEATTRIBUTE: |
| + /* type and typeattribute statements insert empty datums, ret true */ |
| + rc = CIL_TRUE; |
| + break; |
| + default: |
| + break; |
| + } |
| + return rc; |
| +} |
| + |
| int cil_gen_node(__attribute__((unused)) 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); |
| if (rc != SEPOL_OK) { |
| @@ -103,15 +126,26 @@ int cil_gen_node(__attribute__((unused)) struct cil_db *db, struct cil_tree_node |
| if (symtab != NULL) { |
| rc = cil_symtab_insert(symtab, (hashtab_key_t)key, datum, ast_node); |
| if (rc == SEPOL_EEXIST) { |
| - cil_log(CIL_ERR, "Re-declaration of %s %s\n", |
| - cil_node_to_string(ast_node), key); |
| - if (cil_symtab_get_datum(symtab, key, &datum) == SEPOL_OK) { |
| - if (sflavor == CIL_SYM_BLOCKS) { |
| - struct cil_tree_node *node = datum->nodes->head->data; |
| - cil_tree_log(node, CIL_ERR, "Previous declaration"); |
| + if (!db->multiple_decls || |
| + cil_symtab_get_datum(symtab, (hashtab_key_t)key, &prev) != SEPOL_OK || |
| + !cil_is_datum_multiple_decl(datum, prev, nflavor)) { |
| + |
| + /* multiple_decls not ok, ret error */ |
| + cil_log(CIL_ERR, "Re-declaration of %s %s\n", |
| + cil_node_to_string(ast_node), key); |
| + if (cil_symtab_get_datum(symtab, key, &datum) == SEPOL_OK) { |
| + if (sflavor == CIL_SYM_BLOCKS) { |
| + struct cil_tree_node *node = datum->nodes->head->data; |
| + cil_tree_log(node, CIL_ERR, "Previous declaration"); |
| + } |
| } |
| + goto exit; |
| } |
| - 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); |
| } |
| } |
| |
| diff --git a/libsepol/cil/src/cil_internal.h b/libsepol/cil/src/cil_internal.h |
| index 6d6a7d90..136a0049 100644 |
| --- a/libsepol/cil/src/cil_internal.h |
| +++ b/libsepol/cil/src/cil_internal.h |
| @@ -316,6 +316,7 @@ struct cil_db { |
| int preserve_tunables; |
| int handle_unknown; |
| int mls; |
| + int multiple_decls; |
| int target_platform; |
| int policy_version; |
| }; |
| diff --git a/libsepol/src/libsepol.map.in b/libsepol/src/libsepol.map.in |
| index dd1fec21..2a9996f7 100644 |
| --- a/libsepol/src/libsepol.map.in |
| +++ b/libsepol/src/libsepol.map.in |
| @@ -49,6 +49,7 @@ LIBSEPOL_1.1 { |
| cil_set_mls; |
| cil_set_attrs_expand_generated; |
| cil_set_attrs_expand_size; |
| + cil_set_multiple_decls; |
| cil_write_policy_conf; |
| sepol_ppfile_to_module_package; |
| sepol_module_package_to_cil; |
| -- |
| 2.16.1.291.g4437f3f132-goog |
| |