Re: [PATCH 08/15] [src-policy] libsemanage: remove binary interfaces

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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.

[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux