Fix handling of missing semanage permissive -d foo, not failing correctly

- Previous to this fix the first module beginning with foo would get deleted.
This commit is contained in:
Dan Walsh 2012-11-21 14:30:13 -05:00
parent 1264a1fe67
commit f0b6adc46c
2 changed files with 232 additions and 2 deletions

View File

@ -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)
}

View File

@ -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 <dwalsh@redhat.com> - 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 <dwalsh@redhat.com> - 2.1.9-1
- Update to upstream
* libsemanage: do not set soname needlessly