This change will be needed to support explicly specifying the policy version in semodule (in a subsequent patch). Signed-off-by: Ondrej Mosnacek <omosnace@xxxxxxxxxx> --- libsemanage/include/semanage/handle.h | 6 +++ libsemanage/src/direct_api.c | 9 ++++- libsemanage/src/handle.c | 24 ++++++++++++ libsemanage/src/handle.h | 1 + libsemanage/src/libsemanage.map | 6 +++ libsemanage/src/semanage_store.c | 54 ++++++++++++++++----------- libsemanage/src/semanage_store.h | 6 ++- 7 files changed, 81 insertions(+), 25 deletions(-) diff --git a/libsemanage/include/semanage/handle.h b/libsemanage/include/semanage/handle.h index 946d69bc..70b37863 100644 --- a/libsemanage/include/semanage/handle.h +++ b/libsemanage/include/semanage/handle.h @@ -85,6 +85,12 @@ extern void semanage_set_disable_dontaudit(semanage_handle_t * handle, int disab /* Set whether or not to execute setfiles to check file contexts upon commit */ extern void semanage_set_check_contexts(semanage_handle_t * sh, int do_check_contexts); +/* Get the kernel policy version. */ +extern unsigned semanage_get_policyvers(semanage_handle_t *sh); + +/* Set the kernel policy version. */ +extern int semanage_set_policyvers(semanage_handle_t *sh, unsigned policyvers); + /* Get the default priority. */ extern uint16_t semanage_get_default_priority(semanage_handle_t *sh); diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c index 1088a0ac..78c40018 100644 --- a/libsemanage/src/direct_api.c +++ b/libsemanage/src/direct_api.c @@ -1204,6 +1204,7 @@ static int semanage_direct_commit(semanage_handle_t * sh) size_t fc_buffer_len = 0; const char *ofilename = NULL; const char *path; + char kernel_path[PATH_MAX]; int retval = -1, num_modinfos = 0, i; sepol_policydb_t *out = NULL; struct cil_db *cildb = NULL; @@ -1593,9 +1594,13 @@ rebuild: if (retval < 0) goto cleanup; + if (semanage_get_full_kernel_path(sh, SEMANAGE_FINAL_TMP, kernel_path)) { + ERR(sh, "Unable to build path to kernel policy."); + goto cleanup; + } + retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL), - semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_KERNEL), - sh->conf->file_mode); + kernel_path, sh->conf->file_mode); if (retval < 0) { goto cleanup; } diff --git a/libsemanage/src/handle.c b/libsemanage/src/handle.c index 5e59aef7..78818930 100644 --- a/libsemanage/src/handle.c +++ b/libsemanage/src/handle.c @@ -81,6 +81,9 @@ semanage_handle_t *semanage_handle_create(void) goto err; sepol_msg_set_callback(sh->sepolh, semanage_msg_relay_handler, sh); + /* Default policy version is taken from config */ + sh->policyvers = sh->conf->policyvers; + /* Default priority is 400 */ sh->priority = 400; @@ -246,6 +249,27 @@ void semanage_set_check_contexts(semanage_handle_t * sh, int do_check_contexts) return; } +unsigned semanage_get_policyvers(semanage_handle_t *sh) +{ + assert(sh != NULL); + return sh->policyvers; +} + +int semanage_set_policyvers(semanage_handle_t *sh, unsigned policyvers) +{ + assert(sh != NULL); + + /* Verify policy version */ + if ( policyvers < POLICYDB_VERSION_MIN + || policyvers > POLICYDB_VERSION_MAX) { + ERR(sh, "Policy version %u is invalid.", policyvers); + return -1; + } + + sh->policyvers = policyvers; + return 0; +} + uint16_t semanage_get_default_priority(semanage_handle_t *sh) { assert(sh != NULL); diff --git a/libsemanage/src/handle.h b/libsemanage/src/handle.h index a91907b0..ee389226 100644 --- a/libsemanage/src/handle.h +++ b/libsemanage/src/handle.h @@ -57,6 +57,7 @@ struct semanage_handle { semanage_conf_t *conf; + unsigned policyvers; uint16_t priority; int is_connected; int is_in_transaction; diff --git a/libsemanage/src/libsemanage.map b/libsemanage/src/libsemanage.map index 02036696..8c05b9ad 100644 --- a/libsemanage/src/libsemanage.map +++ b/libsemanage/src/libsemanage.map @@ -63,3 +63,9 @@ LIBSEMANAGE_1.1 { semanage_module_remove_key; semanage_set_store_root; } LIBSEMANAGE_1.0; + +LIBSEMANAGE_1.2 { + global: + semanage_get_policyvers; + semanage_set_policyvers; +} LIBSEMANAGE_1.1; diff --git a/libsemanage/src/semanage_store.c b/libsemanage/src/semanage_store.c index 58dded6e..52217be7 100644 --- a/libsemanage/src/semanage_store.c +++ b/libsemanage/src/semanage_store.c @@ -277,9 +277,7 @@ cleanup: static int semanage_init_final_suffix(semanage_handle_t *sh) { - int ret = 0; int status = 0; - char path[PATH_MAX]; size_t offset = strlen(selinux_policy_root()); semanage_final_suffix[SEMANAGE_FINAL_TOPLEVEL] = strdup(""); @@ -350,19 +348,9 @@ static int semanage_init_final_suffix(semanage_handle_t *sh) goto cleanup; } - ret = snprintf(path, - sizeof(path), - "%s.%d", - selinux_binary_policy_path() + offset, - sh->conf->policyvers); - if (ret < 0 || ret >= (int)sizeof(path)) { - ERR(sh, "Unable to compose policy binary path."); - status = -1; - goto cleanup; - } - - semanage_final_suffix[SEMANAGE_KERNEL] = strdup(path); - if (semanage_final_suffix[SEMANAGE_KERNEL] == NULL) { + semanage_final_suffix[SEMANAGE_KERNEL_PREFIX] = + strdup(selinux_binary_policy_path() + offset); + if (semanage_final_suffix[SEMANAGE_KERNEL_PREFIX] == NULL) { ERR(sh, "Unable to allocate space for policy binary path."); status = -1; goto cleanup; @@ -503,6 +491,20 @@ const char *semanage_final_path(enum semanage_final_defs store, return semanage_final_paths[store][path_name]; } +/* Return a fully-qualified path + filename to kernel policy for the given + * semanage store. + */ +int semanage_get_full_kernel_path(semanage_handle_t * sh, + enum semanage_final_defs root, + char out[PATH_MAX]) +{ + int ret = snprintf(out, PATH_MAX, "%s.%u", + semanage_final_path(root, SEMANAGE_KERNEL_PREFIX), + sh->policyvers); + + return ret < 0 || ret >= PATH_MAX ? -1 : 0; +} + /* Return a fully-qualified path + filename to the semanage * configuration file. If semanage.conf file in the semanage * root is cannot be read, use the default semanage.conf as a @@ -1568,12 +1570,16 @@ static int semanage_validate_and_compile_fcontexts(semanage_handle_t * sh) int status = -1; if (sh->do_check_contexts) { + char path[PATH_MAX]; int ret; + + if (semanage_get_full_kernel_path(sh, SEMANAGE_FINAL_TMP, path)) { + ERR(sh, "Unable to build path to kernel policy."); + goto cleanup; + } + ret = semanage_exec_prog( - sh, - sh->conf->setfiles, - semanage_final_path(SEMANAGE_FINAL_TMP, - SEMANAGE_KERNEL), + sh, sh->conf->setfiles, path, semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC)); if (ret != 0) { @@ -2233,15 +2239,19 @@ int semanage_verify_linked(semanage_handle_t * sh) int semanage_verify_kernel(semanage_handle_t * sh) { int retval = -1; - const char *kernel_filename = - semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_KERNEL); + char path[PATH_MAX]; semanage_conf_t *conf = sh->conf; external_prog_t *e; + if (conf->kernel_prog == NULL) { return 0; } + if (semanage_get_full_kernel_path(sh, SEMANAGE_FINAL_TMP, path)) { + ERR(sh, "Unable to build path to kernel policy."); + goto cleanup; + } for (e = conf->kernel_prog; e != NULL; e = e->next) { - if (semanage_exec_prog(sh, e, kernel_filename, "$<") != 0) { + if (semanage_exec_prog(sh, e, path, "$<") != 0) { goto cleanup; } } diff --git a/libsemanage/src/semanage_store.h b/libsemanage/src/semanage_store.h index 34bf8523..d5567782 100644 --- a/libsemanage/src/semanage_store.h +++ b/libsemanage/src/semanage_store.h @@ -81,7 +81,7 @@ enum semanage_final_path_defs { SEMANAGE_FC_HOMEDIRS_BIN, SEMANAGE_FC_LOCAL, SEMANAGE_FC_LOCAL_BIN, - SEMANAGE_KERNEL, + SEMANAGE_KERNEL_PREFIX, SEMANAGE_NC, SEMANAGE_SEUSERS, SEMANAGE_FINAL_PATH_NUM @@ -102,6 +102,10 @@ extern const char *semanage_path(enum semanage_store_defs store, extern const char *semanage_final_path(enum semanage_final_defs root, enum semanage_final_path_defs suffix); +int semanage_get_full_kernel_path(semanage_handle_t * sh, + enum semanage_final_defs root, + char out[PATH_MAX]); + int semanage_create_store(semanage_handle_t * sh, int create); int semanage_store_access_check(void); -- 2.24.1