From f0b6adc46cebd71119cb6c776d4770e48d3ac494 Mon Sep 17 00:00:00 2001 From: Dan Walsh Date: Wed, 21 Nov 2012 14:30:13 -0500 Subject: [PATCH] Fix handling of missing semanage permissive -d foo, not failing correctly - Previous to this fix the first module beginning with foo would get deleted. --- libsemanage-rhat.patch | 228 ++++++++++++++++++++++++++++++++++++++++- libsemanage.spec | 6 +- 2 files changed, 232 insertions(+), 2 deletions(-) diff --git a/libsemanage-rhat.patch b/libsemanage-rhat.patch index efe7fa9..b5454cf 100644 --- a/libsemanage-rhat.patch +++ b/libsemanage-rhat.patch @@ -67,6 +67,223 @@ index 7ef4154..41ba044 100644 "[verify module]" return VERIFY_MOD_START; "[verify linked]" return VERIFY_LINKED_START; "[verify kernel]" return VERIFY_KERNEL_START; +diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c +index 4f919a6..64dc7d9 100644 +--- a/libsemanage/src/direct_api.c ++++ b/libsemanage/src/direct_api.c +@@ -1306,80 +1306,67 @@ static int semanage_direct_install_base_file(semanage_handle_t * sh, + return retval; + } + +-/* Enables a module from the sandbox. Returns 0 on success, -1 if out +- * of memory, -2 if module not found or could not be enabled. */ +-static int semanage_direct_enable(semanage_handle_t * sh, char *module_name) +-{ +- int i, retval = -1; +- char **module_filenames = NULL; +- int num_mod_files; +- size_t name_len = strlen(module_name); +- if (semanage_get_modules_names(sh, &module_filenames, &num_mod_files) == +- -1) { +- return -1; ++static int get_module_name(semanage_handle_t * sh, char *modulefile, char **module_name) { ++ FILE *fp = NULL; ++ int retval = -1; ++ char *data = NULL; ++ char *version = NULL; ++ ssize_t size; ++ int type; ++ struct sepol_policy_file *pf = NULL; ++ ++ if (sepol_policy_file_create(&pf)) { ++ ERR(sh, "Out of memory!"); ++ goto cleanup; + } +- for (i = 0; i < num_mod_files; i++) { +- char *base = strrchr(module_filenames[i], '/'); +- if (base == NULL) { +- ERR(sh, "Could not read module names."); +- retval = -2; +- goto cleanup; +- } +- base++; +- if (memcmp(module_name, base, name_len) == 0) { ++ sepol_policy_file_set_handle(pf, sh->sepolh); + +- if (semanage_enable_module(module_filenames[i]) < 0) { +- ERR(sh, "Could not enable module %s.", module_name); +- retval = -2; +- goto cleanup; +- } +- retval = 0; +- goto cleanup; +- } ++ if ((fp = fopen(modulefile, "rb")) == NULL) { ++ goto cleanup; + } +- ERR(sh, "Module %s was not found.", module_name); +- retval = -2; /* module not found */ +- cleanup: +- for (i = 0; module_filenames != NULL && i < num_mod_files; i++) { +- free(module_filenames[i]); ++ if ((size = bunzip(sh, fp, &data)) > 0) { ++ sepol_policy_file_set_mem(pf, data, size); ++ } else { ++ rewind(fp); ++ __fsetlocking(fp, FSETLOCKING_BYCALLER); ++ sepol_policy_file_set_fp(pf, fp); + } +- free(module_filenames); ++ retval = sepol_module_package_info(pf, &type, module_name, &version); ++ ++cleanup: ++ sepol_policy_file_free(pf); ++ if (fp) ++ fclose(fp); ++ free(data); ++ free(version); + return retval; + } + +-/* Disables a module from the sandbox. Returns 0 on success, -1 if out +- * of memory, -2 if module not found or could not be enabled. */ +-static int semanage_direct_disable(semanage_handle_t * sh, char *module_name) +-{ ++static int get_module_file_by_name(semanage_handle_t * sh, const char *module_name, char **module_file) { + int i, retval = -1; + char **module_filenames = NULL; ++ char *name = NULL; + int num_mod_files; +- size_t name_len = strlen(module_name); + if (semanage_get_modules_names(sh, &module_filenames, &num_mod_files) == + -1) { + return -1; + } + for (i = 0; i < num_mod_files; i++) { +- char *base = strrchr(module_filenames[i], '/'); +- if (base == NULL) { +- ERR(sh, "Could not read module names."); +- retval = -2; +- goto cleanup; +- } +- base++; +- if ((memcmp(module_name, base, name_len) == 0) && +- (strcmp(base + name_len, ".pp") == 0)) { +- if (semanage_disable_module(module_filenames[i]) < 0) { +- retval = -2; +- goto cleanup; +- } +- retval=0; ++ int rc = get_module_name(sh, module_filenames[i], &name); ++ if (rc < 0) ++ continue; ++ if (strcmp(module_name, name) == 0) { ++ *module_file = strdup(module_filenames[i]); ++ if (*module_file) ++ retval = 0; + goto cleanup; + } ++ free(name); name = NULL; + } + ERR(sh, "Module %s was not found.", module_name); + retval = -2; /* module not found */ + cleanup: ++ free(name); + for (i = 0; module_filenames != NULL && i < num_mod_files; i++) { + free(module_filenames[i]); + } +@@ -1387,44 +1374,57 @@ static int semanage_direct_disable(semanage_handle_t * sh, char *module_name) + return retval; + } + ++/* Enables a module from the sandbox. Returns 0 on success, -1 if out ++ * of memory, -2 if module not found or could not be enabled. */ ++static int semanage_direct_enable(semanage_handle_t * sh, char *module_name) ++{ ++ char *module_filename = NULL; ++ int retval = get_module_file_by_name(sh, module_name, &module_filename); ++ if (retval < 0) ++ return -1; /* module not found */ ++ retval = semanage_enable_module(module_filename); ++ if (retval < 0) { ++ ERR(sh, "Could not enable module file %s.", ++ module_filename); ++ retval = -2; ++ } ++ free(module_filename); ++ return retval; ++} ++ ++/* Disables a module from the sandbox. Returns 0 on success, -1 if out ++ * of memory, -2 if module not found or could not be enabled. */ ++static int semanage_direct_disable(semanage_handle_t * sh, char *module_name) ++{ ++ char *module_filename = NULL; ++ int retval = get_module_file_by_name(sh, module_name, &module_filename); if (retval < 0) ++ return -1; /* module not found */ ++ retval = semanage_disable_module(module_filename); ++ if (retval < 0) { ++ ERR(sh, "Could not disable module file %s.", ++ module_filename); ++ retval = -2; ++ } ++ free(module_filename); ++ return retval; ++} ++ + /* Removes a module from the sandbox. Returns 0 on success, -1 if out + * of memory, -2 if module not found or could not be removed. */ + static int semanage_direct_remove(semanage_handle_t * sh, char *module_name) + { +- int i, retval = -1; +- char **module_filenames = NULL; +- int num_mod_files; +- size_t name_len = strlen(module_name); +- if (semanage_get_modules_names(sh, &module_filenames, &num_mod_files) == +- -1) { +- return -1; +- } +- for (i = 0; i < num_mod_files; i++) { +- char *base = strrchr(module_filenames[i], '/'); +- if (base == NULL) { +- ERR(sh, "Could not read module names."); +- retval = -2; +- goto cleanup; +- } +- base++; +- if (memcmp(module_name, base, name_len) == 0) { +- semanage_enable_module(module_filenames[i]); +- if (unlink(module_filenames[i]) == -1) { +- ERR(sh, "Could not remove module file %s.", +- module_filenames[i]); +- retval = -2; +- } +- retval = 0; +- goto cleanup; +- } +- } +- ERR(sh, "Module %s was not found.", module_name); +- retval = -2; /* module not found */ +- cleanup: +- for (i = 0; module_filenames != NULL && i < num_mod_files; i++) { +- free(module_filenames[i]); +- } +- free(module_filenames); ++ char *module_filename = NULL; ++ int retval = get_module_file_by_name(sh, module_name, &module_filename); ++ if (retval < 0) ++ return -1; /* module not found */ ++ (void) semanage_enable_module(module_filename); /* Don't care if this fails */ ++ retval = unlink(module_filename); ++ if (retval < 0) { ++ ERR(sh, "Could not remove module file %s.", ++ module_filename); ++ retval = -2; ++ } ++ free(module_filename); + return retval; + } + diff --git a/libsemanage/src/handle.c b/libsemanage/src/handle.c index 7fcd2b4..6aa9057 100644 --- a/libsemanage/src/handle.c @@ -139,9 +356,18 @@ index 95f8ec3..9b7852c 100644 } semanage_conf_t; diff --git a/libsemanage/src/semanage_store.c b/libsemanage/src/semanage_store.c -index cd7ce68..2fab63e 100644 +index cd7ce68..13c25e3 100644 --- a/libsemanage/src/semanage_store.c +++ b/libsemanage/src/semanage_store.c +@@ -448,7 +448,7 @@ int semanage_enable_module(const char *file) { + char path[PATH_MAX]; + int n = snprintf(path, PATH_MAX, "%s.%s", file, DISABLESTR); + if (n < 0 || n >= PATH_MAX) +- return 1; ++ return -1; + + if ((unlink(path) < 0) && (errno != ENOENT)) + return -1; @@ -1100,6 +1100,17 @@ int semanage_split_fc(semanage_handle_t * sh) } diff --git a/libsemanage.spec b/libsemanage.spec index ca558c8..a502508 100644 --- a/libsemanage.spec +++ b/libsemanage.spec @@ -10,7 +10,7 @@ Summary: SELinux binary policy manipulation library Name: libsemanage Version: 2.1.9 -Release: 1%{?dist} +Release: 2%{?dist} License: LGPLv2+ Group: System Environment/Libraries Source: libsemanage-%{version}.tgz @@ -180,6 +180,10 @@ rm -rf ${RPM_BUILD_ROOT} %endif # if with_python3 %changelog +* Wed Nov 21 2012 Dan Walsh - 2.1.9-2 +- Fix handling of missing semanage permissive -d foo, not failing correctly +- Previous to this fix the first module beginning with foo would get deleted. + * Thu Sep 13 2012 Dan Walsh - 2.1.9-1 - Update to upstream * libsemanage: do not set soname needlessly