On Tue, 2010-01-26 at 17:08 -0500, Caleb Case wrote: > Supporting both binary policy packages and source modules is difficult > and leads to problems that are unacceptable. For instance, the binary > modules would lack relevant information for recompilation such as the > interface definition (which would lead to unexpected behavior if a > source module interface changes, but those changes don't appear in the > binary modules). Consequently, we completely removed support for binary > modules, leaving only support for source modules. Also, because we are > now creating the base module automatically from the source modules, the > base module interfaces are removed as well. > > This patch deprecates the following: > > semanage_module_install > semanage_module_upgrade > semanage_module_install_base > semanage_module_intall_base_file > > and removes their direct_api implementations. > > For the sake of rendering meaningful error messages, the callbacks for > these functions have been initialized to NULL. This will result in an > error message indicating that the function is not implemented for the > given connection type. At a future time these functions would be removed > entirely. > > The file related functions are updated to expect source modules: > > semanage_module_install_file > semanage_module_upgrade_file > --- > libsemanage/include/semanage/modules.h | 14 +- > libsemanage/src/direct_api.c | 751 +++++++++++++------------------- > 2 files changed, 302 insertions(+), 463 deletions(-) > > diff --git a/libsemanage/include/semanage/modules.h b/libsemanage/include/semanage/modules.h > index e169279..8a26e6c 100644 > --- a/libsemanage/include/semanage/modules.h > +++ b/libsemanage/include/semanage/modules.h > @@ -1,7 +1,7 @@ > /* Authors: Joshua Brindle <jbrindle@xxxxxxxxxx> > * Jason Tang <jtang@xxxxxxxxxx> > * > - * Copyright (C) 2005 Tresys Technology, LLC > + * Copyright (C) 2005,2010 Tresys Technology, LLC > * > * This library is free software; you can redistribute it and/or > * modify it under the terms of the GNU Lesser General Public > @@ -29,17 +29,21 @@ > */ > > int semanage_module_install(semanage_handle_t *, > - char *module_data, size_t data_len); > + char *module_data, size_t data_len) > + __attribute__ ((deprecated)); > int semanage_module_install_file(semanage_handle_t *, > const char *module_name); > int semanage_module_upgrade(semanage_handle_t *, > - char *module_data, size_t data_len); > + char *module_data, size_t data_len) > + __attribute__ ((deprecated)); > int semanage_module_upgrade_file(semanage_handle_t *, > const char *module_name); > int semanage_module_install_base(semanage_handle_t *, > - char *module_data, size_t data_len); > + char *module_data, size_t data_len) > + __attribute__ ((deprecated)); > int semanage_module_install_base_file(semanage_handle_t *, > - const char *module_name); > + const char *module_name) > + __attribute__ ((deprecated)); swig doesn't seem to like "__attribute__ ((deprecated))". If I comment out the attribute part, it swigifies. make[1]: Entering directory `/home/jwcart2/src/tresys/selinux/libsemanage' make -C src swigify make[2]: Entering directory `/home/jwcart2/src/tresys/selinux/libsemanage/src' swig -Wall -python -o semanageswig_wrap.c -outdir ./ semanageswig_python.i ../include/semanage/modules.h:33: Error: Syntax error in input(1). make[2]: *** [swigify] Error 1 make[2]: Leaving directory `/home/jwcart2/src/tresys/selinux/libsemanage/src' make[1]: *** [swigify] Error 2 make[1]: Leaving directory `/home/jwcart2/src/tresys/selinux/libsemanage' make: *** [swigify] Error 1 > int semanage_module_remove(semanage_handle_t *, char *module_name); > > /* semanage_module_info is for getting information on installed > diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c > index 0623497..6f7cf63 100644 > --- a/libsemanage/src/direct_api.c > +++ b/libsemanage/src/direct_api.c > @@ -58,15 +58,8 @@ static void semanage_direct_destroy(semanage_handle_t * sh); > static int semanage_direct_disconnect(semanage_handle_t * sh); > static int semanage_direct_begintrans(semanage_handle_t * sh); > static int semanage_direct_commit(semanage_handle_t * sh); > -static int semanage_direct_install(semanage_handle_t * sh, char *data, > - size_t data_len); > static int semanage_direct_install_file(semanage_handle_t * sh, const char *module_name); > -static int semanage_direct_upgrade(semanage_handle_t * sh, char *data, > - size_t data_len); > static int semanage_direct_upgrade_file(semanage_handle_t * sh, const char *module_name); > -static int semanage_direct_install_base(semanage_handle_t * sh, char *base_data, > - size_t data_len); > -static int semanage_direct_install_base_file(semanage_handle_t * sh, const char *module_name); > static int semanage_direct_remove(semanage_handle_t * sh, char *module_name); > static int semanage_direct_list(semanage_handle_t * sh, > semanage_module_info_t ** modinfo, > @@ -105,12 +98,12 @@ static struct semanage_policy_table direct_funcs = { > .disconnect = semanage_direct_disconnect, > .begin_trans = semanage_direct_begintrans, > .commit = semanage_direct_commit, > - .install = semanage_direct_install, > .install_file = semanage_direct_install_file, > - .upgrade = semanage_direct_upgrade, > .upgrade_file = semanage_direct_upgrade_file, > - .install_base = semanage_direct_install_base, > - .install_base_file = semanage_direct_install_base_file, > + .install = NULL, > + .upgrade = NULL, > + .install_base = NULL, > + .install_base_file = NULL, > .remove = semanage_direct_remove, > .list = semanage_direct_list, > .get_enabled = semanage_direct_get_enabled, > @@ -373,87 +366,6 @@ static int semanage_direct_begintrans(semanage_handle_t * sh) > > /********************* utility functions *********************/ > > -/* Takes a module stored in 'module_data' and parses its headers. > - * Sets reference variables 'module_name' to module's name, and > - * 'version' to module's version. The caller is responsible for > - * free()ing 'module_name', and 'version'; they will be > - * set to NULL upon entering this function. Returns 0 on success, -1 > - * if out of memory, or -2 if data did not represent a module. > - */ > -static int parse_module_headers(semanage_handle_t * sh, char *module_data, > - size_t data_len, char **module_name, > - char **version) > -{ > - struct sepol_policy_file *pf; > - int file_type; > - *module_name = *version = NULL; > - > - if (sepol_policy_file_create(&pf)) { > - ERR(sh, "Out of memory!"); > - return -1; > - } > - sepol_policy_file_set_mem(pf, module_data, data_len); > - sepol_policy_file_set_handle(pf, sh->sepolh); > - if (module_data == NULL || > - data_len == 0 || > - sepol_module_package_info(pf, &file_type, module_name, > - version) == -1) { > - sepol_policy_file_free(pf); > - ERR(sh, "Could not parse module data."); > - return -2; > - } > - sepol_policy_file_free(pf); > - if (file_type != SEPOL_POLICY_MOD) { > - if (file_type == SEPOL_POLICY_BASE) > - ERR(sh, > - "Received a base module, expected a non-base module."); > - else > - ERR(sh, "Data did not represent a module."); > - return -2; > - } > - > - return 0; > -} > - > -/* Takes a base module stored in 'module_data' and parse its headers. > - * Returns 0 on success, -1 if out of memory, or -2 if data did not > - * represent a module. > - */ > -static int parse_base_headers(semanage_handle_t * sh, > - char *module_data, size_t data_len) > -{ > - struct sepol_policy_file *pf; > - char *module_name = NULL, *version = NULL; > - int file_type; > - > - if (sepol_policy_file_create(&pf)) { > - ERR(sh, "Out of memory!"); > - return -1; > - } > - sepol_policy_file_set_mem(pf, module_data, data_len); > - sepol_policy_file_set_handle(pf, sh->sepolh); > - if (module_data == NULL || > - data_len == 0 || > - sepol_module_package_info(pf, &file_type, > - &module_name, &version) == -1) { > - sepol_policy_file_free(pf); > - ERR(sh, "Could not parse base module data."); > - return -2; > - } > - sepol_policy_file_free(pf); > - free(module_name); > - free(version); > - if (file_type != SEPOL_POLICY_BASE) { > - if (file_type == SEPOL_POLICY_MOD) > - ERR(sh, > - "Received a non-base module, expected a base module."); > - else > - ERR(sh, "Data did not represent a module."); > - return -2; > - } > - return 0; > -} > - > #include <stdlib.h> > #include <bzlib.h> > #include <string.h> > @@ -564,41 +476,6 @@ ssize_t bunzip(semanage_handle_t *sh, FILE *f, char **data) > return total; > } > > -/* mmap() a file to '*data', > - * If the file is bzip compressed map_file will uncompress > - * the file into '*data'. > - * Returns the total number of bytes in memory . > - * Returns -1 if file could not be opened or mapped. */ > -static ssize_t map_file(semanage_handle_t *sh, int fd, char **data, > - int *compressed) > -{ > - ssize_t size = -1; > - char *uncompress; > - if ((size = bunzip(sh, fdopen(fd, "r"), &uncompress)) > 0) { > - *data = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); > - if (*data == MAP_FAILED) { > - free(uncompress); > - return -1; > - } else { > - memcpy(*data, uncompress, size); > - } > - free(uncompress); > - *compressed = 1; > - } else { > - struct stat sb; > - if (fstat(fd, &sb) == -1 || > - (*data = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) == > - MAP_FAILED) { > - size = -1; > - } else { > - size = sb.st_size; > - } > - *compressed = 0; > - } > - > - return size; > -} > - > /* Writes a block of data to a file. Returns 0 on success, -1 on > * error. */ > static int write_file(semanage_handle_t * sh, > @@ -706,6 +583,169 @@ static int semanage_direct_update_seuser(semanage_handle_t * sh, sepol_module_pa > return retval; > } > > +/* Reads the source module pointed to by @path into a memory buffer > + * @data of length @data_len. @modinfo is constructed with gleaned from > + * the module path and defaults as follows: > + * > + * priority default from handle > + * name basename(path) sans extension > + * version empty string (gets overridden by hll compiler) > + * lang_ext basename(path) sans name and '.' > + * enabled default of -1 (don't change status) > + * > + * On call @modinfo and @data will be set to NULL. @data_len will be set > + * to 0. > + * > + * Caller should destroy and free @modinfo and free @data. > + * > + * Returns: > + * > + * 0 success > + * -1 failure, out of memory > + * -2 failure, invalid @path > + */ > +static int semanage_path_to_info(semanage_handle_t *sh, > + const char *path, > + semanage_module_info_t **modinfo, > + char **data, > + size_t *data_len) > +{ > + assert(sh); > + assert(path); > + assert(modinfo); > + assert(data); > + assert(data_len); > + > + int status = 0; > + int ret = 0; > + > + int fd = -1; > + char *path_tmp = NULL; > + char *name = NULL; > + int i; > + char *ext = NULL; > + > + *modinfo = NULL; > + > + /* Open the module. */ > + fd = open(path, O_RDONLY); > + if (fd < 0) { > + ERR(sh, "Failed to open file %s.", path); > + status = -2; > + goto cleanup; > + } > + > + /* Convert to buffer. */ > + ret = semanage_fd_to_data(sh, fd, data, data_len); > + if (ret != 0) { > + status = ret; > + goto cleanup; > + } > + > + /* Get the name and ext from the path. > + * name will be the first part of the string. > + * ext will be the last part. > + * Note that neither should be free'd. > + * strduping here since basename can modify. > + */ > + path_tmp = strdup(path); > + if (path_tmp == NULL) { > + status = -1; > + goto cleanup; > + } > + > + name = basename(path_tmp); > + for (i = strlen(name) - 1; i >= 1; i--) { > + if (name[i] == '.') { > + name[i] = '\0'; > + ext = &name[i] + 1; > + break; > + } > + } > + > + /* Failed to find an ext or name begins with '.'. */ > + if (i == 0) { > + status = -2; > + goto cleanup; > + } > + > + /* Create and initialize a modinfo. */ > + ret = semanage_module_info_create(sh, modinfo); > + if (ret != 0) { > + status = -1; > + goto cleanup; > + } > + > + ret = semanage_module_info_set_priority( > + sh, > + *modinfo, > + sh->priority); > + if (ret != 0) { > + status = -1; > + goto cleanup; > + } > + > + ret = semanage_module_info_set_name( > + sh, > + *modinfo, > + name); > + if (ret != 0) { > + status = -1; > + goto cleanup; > + } > + > + /* Initialize version to 0. > + * The module version will changed later by the hll compiler. > + */ > + ret = semanage_module_info_set_version( > + sh, > + *modinfo, > + "0"); > + if (ret != 0) { > + status = -1; > + goto cleanup; > + } > + > + ret = semanage_module_info_set_lang_ext( > + sh, > + *modinfo, > + ext); > + if (ret != 0) { > + status = -1; > + goto cleanup; > + } > + > + /* Set enabled to the default -1 value. This means that > + * installing the module will not modify the enabled/disabled > + * status. > + */ > + ret = semanage_module_info_set_enabled( > + sh, > + *modinfo, > + -1); > + if (ret != 0) { > + status = -1; > + goto cleanup; > + } > + > +cleanup: > + if (status != 0) { > + semanage_module_info_destroy(sh, *modinfo); > + free(*modinfo); > + *modinfo = NULL; > + > + free(*data); > + *data = NULL; > + *data_len = 0; > + } > + > + free(path_tmp); > + > + close(fd); > + > + return status; > +} > + > /********************* direct API functions ********************/ > > /* Commits all changes in sandbox to the actual kernel policy. > @@ -1055,72 +1095,6 @@ static int semanage_direct_commit(semanage_handle_t * sh) > return retval; > } > > -/* Writes a module to the sandbox's module directory, overwriting any > - * previous module stored within. Note that module data are not > - * free()d by this function; caller is responsible for deallocating it > - * if necessary. Returns 0 on success, -1 if out of memory, -2 if the > - * data does not represent a valid module file, -3 if error while > - * writing file. */ > -static int semanage_direct_install(semanage_handle_t * sh, > - char *data, size_t data_len) > -{ > - int status = 0; > - int ret = 0; > - > - char *module_name = NULL, *version = NULL; > - if ((status = parse_module_headers(sh, data, data_len, > - &module_name, &version)) != 0) { > - goto cleanup; > - } > - > - semanage_module_info_t modinfo; > - ret = semanage_module_info_init(sh, &modinfo); > - if (ret != 0) { > - status = -1; > - goto cleanup; > - } > - > - ret = semanage_module_info_set_priority(sh, &modinfo, sh->priority); > - if (ret != 0) { > - status = -1; > - goto cleanup; > - } > - > - ret = semanage_module_info_set_name(sh, &modinfo, module_name); > - if (ret != 0) { > - status = -1; > - goto cleanup; > - } > - > - ret = semanage_module_info_set_version(sh, &modinfo, version); > - if (ret != 0) { > - status = -1; > - goto cleanup; > - } > - > - ret = semanage_module_info_set_lang_ext(sh, &modinfo, "pp"); > - if (ret != 0) { > - status = -1; > - goto cleanup; > - } > - > - ret = semanage_module_info_set_enabled(sh, &modinfo, -1); > - if (ret != 0) { > - status = -1; > - goto cleanup; > - } > - > - status = semanage_direct_install_info(sh, &modinfo, data, data_len); > - > -cleanup: > - free(version); > - free(module_name); > - > - semanage_module_info_destroy(sh, &modinfo); > - > - return status; > -} > - > /* Attempts to link a module to the sandbox's module directory, unlinking any > * previous module stored within. Returns 0 on success, -1 if out of memory, -2 if the > * data does not represent a valid module file, -3 if error while > @@ -1129,97 +1103,31 @@ cleanup: > static int semanage_direct_install_file(semanage_handle_t * sh, > const char *install_filename) > { > + int status = 0; > > - int retval = -1; > + semanage_module_info_t *modinfo = NULL; > char *data = NULL; > - ssize_t data_len = 0; > - int compressed = 0; > - int in_fd = -1; > - > - if ((in_fd = open(install_filename, O_RDONLY)) == -1) { > - return -1; > - } > - > - if ((data_len = map_file(sh, in_fd, &data, &compressed)) <= 0) { > - goto cleanup; > - } > - > - retval = semanage_direct_install(sh, data, data_len); > - > - cleanup: > - close(in_fd); > - if (data_len > 0) munmap(data, data_len); > - > - return retval; > -} > + size_t data_len = 0; > > -/* Similar to semanage_direct_install(), except that it checks that > - * there already exists a module with the same name and that the > - * module is an older version then the one in 'data'. Returns 0 on > - * success, -1 if out of memory, -2 if the data does not represent a > - * valid module file, -3 if error while writing file or reading > - * modules directory, -4 if the previous module is same or newer than 'data', > - * -5 if there does not exist an older module. > - */ > -static int semanage_direct_upgrade(semanage_handle_t * sh, > - char *data, size_t data_len) > -{ > - int status = 0; > - int ret = 0; > + status = semanage_path_to_info( > + sh, > + install_filename, > + &modinfo, > + &data, > + &data_len); > + if (status != 0) goto cleanup; > > - char *module_name = NULL, *version = NULL; > - status = parse_module_headers( > + status = semanage_module_install_info( > sh, > + modinfo, > data, > - data_len, > - &module_name, > - &version); > - if (status != 0) { > - goto cleanup; > - } > - > - semanage_module_info_t modinfo; > - ret = semanage_module_info_init(sh, &modinfo); > - if (ret != 0) { > - status = -1; > - goto cleanup; > - } > - > - ret = semanage_module_info_set_priority(sh, &modinfo, sh->priority); > - if (ret != 0) { > - status = -1; > - goto cleanup; > - } > - > - ret = semanage_module_info_set_name(sh, &modinfo, module_name); > - if (ret != 0) { > - status = -1; > - goto cleanup; > - } > - > - ret = semanage_module_info_set_version(sh, &modinfo, version); > - if (ret != 0) { > - status = -1; > - goto cleanup; > - } > - > - ret = semanage_module_info_set_lang_ext(sh, &modinfo, "pp"); > - if (ret != 0) { > - status = -1; > - goto cleanup; > - } > - > - ret = semanage_module_info_set_enabled(sh, &modinfo, -1); > - if (ret != 0) { > - status = -1; > - goto cleanup; > - } > - > - status = semanage_direct_upgrade_info(sh, &modinfo, data, data_len); > + data_len); > > cleanup: > - free(module_name); > - free(version); > + semanage_module_info_destroy(sh, modinfo); > + free(modinfo); > + > + free(data); > > return status; > } > @@ -1233,125 +1141,33 @@ cleanup: > static int semanage_direct_upgrade_file(semanage_handle_t * sh, > const char *module_filename) > { > - int retval = -1; > - char *data = NULL; > - ssize_t data_len = 0; > - int compressed = 0; > - int in_fd = -1; > - > - if ((in_fd = open(module_filename, O_RDONLY)) == -1) { > - return -1; > - } > - > - if ((data_len = map_file(sh, in_fd, &data, &compressed)) <= 0) { > - goto cleanup; > - } > - > - retval = semanage_direct_upgrade(sh, data, data_len); > - > - cleanup: > - close(in_fd); > - if (data_len > 0) munmap(data, data_len); > - > - return retval; > -} > - > -/* Writes a base module into a sandbox, overwriting any previous base > - * module. Note that 'module_data' is not free()d by this function; > - * caller is responsible for deallocating it if necessary. Returns 0 > - * on success, -1 if out of memory, -2 if the data does not represent > - * a valid base module file, -3 if error while writing file. > - */ > -static int semanage_direct_install_base(semanage_handle_t * sh, > - char *base_data, size_t data_len) > -{ > int status = 0; > - int ret = 0; > - > - ret = parse_base_headers(sh, base_data, data_len); > - if (ret != 0) { > - status = -1; > - goto cleanup; > - } > - > - semanage_module_info_t modinfo; > - ret = semanage_module_info_init(sh, &modinfo); > - if (ret != 0) { > - status = -1; > - goto cleanup; > - } > - > - ret = semanage_module_info_set_priority(sh, &modinfo, sh->priority); > - if (ret != 0) { > - status = -1; > - goto cleanup; > - } > - > - ret = semanage_module_info_set_name(sh, &modinfo, "_base"); > - if (ret != 0) { > - status = -1; > - goto cleanup; > - } > - > - ret = semanage_module_info_set_version(sh, &modinfo, "1.0.0"); > - if (ret != 0) { > - status = -1; > - goto cleanup; > - } > - > - ret = semanage_module_info_set_lang_ext(sh, &modinfo, "pp"); > - if (ret != 0) { > - status = -1; > - goto cleanup; > - } > > - ret = semanage_module_info_set_enabled(sh, &modinfo, 1); > - if (ret != 0) { > - status = -1; > - goto cleanup; > - } > + semanage_module_info_t *modinfo = NULL; > + char *data = NULL; > + size_t data_len = 0; > > - status = semanage_direct_install_info( > + status = semanage_path_to_info( > sh, > + module_filename, > &modinfo, > - base_data, > + &data, > + &data_len); > + if (status != 0) goto cleanup; > + > + status = semanage_module_upgrade_info( > + sh, > + modinfo, > + data, > data_len); > > cleanup: > - semanage_module_info_destroy(sh, &modinfo); > - > - return status; > -} > - > -/* Writes a base module into a sandbox, overwriting any previous base > - * module. > - * Returns 0 on success, -1 if out of memory, -2 if the data does not represent > - * a valid base module file, -3 if error while writing file. > - */ > -static int semanage_direct_install_base_file(semanage_handle_t * sh, > - const char *install_filename) > -{ > - int retval = -1; > - char *data = NULL; > - ssize_t data_len = 0; > - int compressed = 0; > - int in_fd; > - > - if ((in_fd = open(install_filename, O_RDONLY)) == -1) { > - return -1; > - } > - > - if ((data_len = map_file(sh, in_fd, &data, &compressed)) <= 0) { > - goto cleanup; > - } > - > - retval = semanage_direct_install_base(sh, data, data_len); > + semanage_module_info_destroy(sh, modinfo); > + free(modinfo); > > - cleanup: > - close(in_fd); > - if (data_len > 0) munmap(data, data_len); > + free(data); > > - return retval; > + return status; > } > > /* Removes a module from the sandbox. Returns 0 on success, -1 if out > @@ -1386,6 +1202,14 @@ cleanup: > return status; > } > > +/* qsort comparison function for semanage_direct_list. */ > +static int semanage_direct_list_cmp(const void *a, const void *b) > +{ > + semanage_module_info_t *ma = (semanage_module_info_t *)a; > + semanage_module_info_t *mb = (semanage_module_info_t *)b; > + return strverscmp(ma->name, mb->name); > +} > + > /* Allocate an array of module_info structures for each readable > * module within the store. Note that if the calling program has > * already begun a transaction then this function will get a list of > @@ -1393,97 +1217,108 @@ cleanup: > * semanage_module_info_datum_destroy() on each element of the array > * as well as free()ing the entire list. > */ > -static int semanage_direct_list(semanage_handle_t * sh, > - semanage_module_info_t ** modinfo, > - int *num_modules) > +static int semanage_direct_list(semanage_handle_t *sh, > + semanage_module_info_t **modinfos, > + int *modinfos_len) > { > - struct sepol_policy_file *pf = NULL; > - int i, retval = -1; > - char **module_filenames = NULL; > - int num_mod_files; > - *modinfo = NULL; > - *num_modules = 0; > + assert(sh); > + assert(modinfos); > + assert(modinfos_len); > > - /* get the read lock when reading from the active > - (non-transaction) directory */ > - if (!sh->is_in_transaction) > - if (semanage_get_active_lock(sh) < 0) > - return -1; > + int status = 0; > + int ret = 0; > > - if (semanage_get_modules_names(sh, &module_filenames, &num_mod_files) == > - -1) { > - goto cleanup; > - } > - if (num_mod_files == 0) { > - retval = semanage_direct_get_serial(sh); > - goto cleanup; > - } > + int i = 0; > + int j = 0; > > - if (sepol_policy_file_create(&pf)) { > - ERR(sh, "Out of memory!"); > + semanage_list_t *list = NULL; > + semanage_list_t *found = NULL; > + > + semanage_module_info_t *all_modinfos = NULL; > + int all_modinfos_len = 0; > + > + void *tmp = NULL; > + > + /* get all modules */ > + ret = semanage_module_list_all(sh, &all_modinfos, &all_modinfos_len); > + if (ret != 0) { > + status = -1; > goto cleanup; > } > - sepol_policy_file_set_handle(pf, sh->sepolh); > > - if ((*modinfo = calloc(num_mod_files, sizeof(**modinfo))) == NULL) { > - ERR(sh, "Out of memory!"); > + /* allocate enough for worst case */ > + (*modinfos) = calloc(all_modinfos_len, sizeof(semanage_module_info_t)); > + if ((*modinfos) == NULL) { > + ERR(sh, "Error allocating space for module info array."); > + status = -1; > goto cleanup; > } > > - for (i = 0; i < num_mod_files; i++) { > - FILE *fp; > - char *name = NULL, *version = NULL; > - int type; > - if ((fp = fopen(module_filenames[i], "rb")) == NULL) { > - /* could not open this module file, so don't > - * report it */ > - continue; > - } > - ssize_t size; > - char *data = NULL; > - > - if ((size = bunzip(sh, fp, &data)) > 0) { > - fclose(fp); > - fp = fmemopen(data, size, "rb"); > - if (!fp) { > - ERR(sh, "Out of memory!"); > + *modinfos_len = all_modinfos_len; > + > + /* for each highest priority, enabled module clone */ > + semanage_list_destroy(&list); > + for (i = 0, j = 0; i < all_modinfos_len; i++) { > + /* check if enabled */ > + if (all_modinfos[i].enabled != 1) continue; > + > + /* check if we've seen this before (i.e. highest priority) */ > + found = semanage_list_find(list, all_modinfos[i].name); > + if (found == NULL) { > + ret = semanage_list_push(&list, all_modinfos[i].name); > + if (ret != 0) { > + ERR(sh, "Failed to add module name to list of known names."); > + status = -1; > goto cleanup; > } > } > - rewind(fp); > - __fsetlocking(fp, FSETLOCKING_BYCALLER); > - sepol_policy_file_set_fp(pf, fp); > - if (sepol_module_package_info(pf, &type, &name, &version)) { > - fclose(fp); > - free(data); > - free(name); > - free(version); > - continue; > - } > - fclose(fp); > - free(data); > - if (type == SEPOL_POLICY_MOD) { > - (*modinfo)[*num_modules].name = name; > - (*modinfo)[*num_modules].version = version; > - (*num_modules)++; > - } else { > - /* file was not a module, so don't report it */ > - free(name); > - free(version); > + else continue; > + > + ret = semanage_module_info_clone( > + sh, > + &all_modinfos[i], > + &(*modinfos)[j]); > + if (ret != 0) { > + ERR(sh, "Failed to clone module into array."); > + status = -1; > + goto cleanup; > } > + > + j += 1; > } > - retval = semanage_direct_get_serial(sh); > > - cleanup: > - sepol_policy_file_free(pf); > - for (i = 0; module_filenames != NULL && i < num_mod_files; i++) { > - free(module_filenames[i]); > + /* realloc the array to its min size */ > + tmp = realloc(*modinfos, j * sizeof(semanage_module_info_t)); > + if (tmp == NULL) { > + ERR(sh, "Error allocating space for module info array."); > + status = -1; > + goto cleanup; > } > - free(module_filenames); > - if (!sh->is_in_transaction) { > - semanage_release_active_lock(sh); > + *modinfos = tmp; > + *modinfos_len = j; > + > + /* sort array on module name */ > + qsort(*modinfos, > + *modinfos_len, > + sizeof(semanage_module_info_t), > + semanage_direct_list_cmp); > + > +cleanup: > + semanage_list_destroy(&list); > + > + for (i = 0; i < all_modinfos_len; i++) { > + semanage_module_info_destroy(sh, &all_modinfos[i]); > } > - return retval; > + free(all_modinfos); > + > + if (status != 0) { > + for (i = 0; i < *modinfos_len; i++) { > + semanage_module_info_destroy(sh, &(*modinfos)[i]); > + } > + free(*modinfos); > + } > + > + return status; > } > > static int semanage_direct_get_enabled(semanage_handle_t *sh, -- James Carter <jwcart2@xxxxxxxxxxxxx> National Security Agency -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to majordomo@xxxxxxxxxxxxx with the words "unsubscribe selinux" without quotes as the message.