Re: [PATCH 3/3] policycoreutils/semodule: update semodule to allow extracting modules

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

 



On 07/28/2015 12:38 PM, Yuli Khodorkovskiy wrote:
> Add --extract/-E, --cil/-c, and --hll/-H to extract modules. If -c/-H
> are not provided, the module will be output as HLL by default. Only
> --cil or --hll (which will use the lang_ext in the semodule store) are valid
> options to use with -E. The module is written to the current working directory
> as <module_name>.<lang_ext>.
> 
> If a module exists as HLL and is exported as CIL, it will first compile into
> CIL and cache to the module store. Once compiled, exporting will
> continue.

So, is it expected/desirable that this would fail on any
non-user-installed module unless the user specifies the particular
priority (e.g. -E apache -X 100)?  Or should it automatically try to
fallback in some way?

> 
> Examples:
> 
> Extract the wireshark module in a .cil format. If the module only exists
> as HLL on the system, the module will be compiled into CIL and placed
> into the module store. This command will then write wireshark.cil to the CWD.
> 
>     semodule --cil --extract wireshark
> 
> Extract the wireshark module in HLL format. Since the original HLL file
> was a policy package, a wireshark.pp will be written to the CWD.
> 
>     semodule -E wireshark
> 
> Extract the wireshark module as CIL and HLL and extract the puppet
> module as CIL at priority 400.
> 
>     semodule --hll -E wireshark --cil -E wireshark -X 400 --cil -E puppet
> 
> Signed-off-by: Yuli Khodorkovskiy <ykhodorkovskiy@xxxxxxxxxx>
> ---
>  policycoreutils/semodule/semodule.8 |  14 ++++
>  policycoreutils/semodule/semodule.c | 131 ++++++++++++++++++++++++++++++++++--
>  2 files changed, 141 insertions(+), 4 deletions(-)
> 
> diff --git a/policycoreutils/semodule/semodule.8 b/policycoreutils/semodule/semodule.8
> index dde0efb..9cd04e7 100644
> --- a/policycoreutils/semodule/semodule.8
> +++ b/policycoreutils/semodule/semodule.8
> @@ -41,6 +41,11 @@ remove existing module
>  .B  \-l,\-\-list-modules=[KIND]
>  display list of installed modules (other than base)
>  .TP
> +.B  \-E,\-\-extract=MODULE_PKG
> +Extract a module from the store as an HLL or CIL file to the current directory.
> +A module is extracted as HLL by default. The name of the module written is
> +<module-name>.<lang_ext>
> +.TP
>  .B  KIND:
>  .TP
>  standard
> @@ -81,6 +86,12 @@ Use an alternate path for the policy store root
>  .TP
>  .B  \-v,\-\-verbose     
>  be verbose
> +.TP
> +.B  \-c,\-\-cil
> +Extract module as a CIL file. This only affects the \-\-extract option.
> +.TP
> +.B  \-H,\-\-hll
> +Extract module as an HLL file. This only affects the \-\-extract option.
>  
>  .SH EXAMPLE
>  .nf
> @@ -108,6 +119,9 @@ $ semodule \-l full
>  $ semodule \-B \-p "/tmp"
>  # Set an alternate path for the policy store root
>  $ semodule \-B \-S "/tmp/var/lib/selinux"
> +# Write the HLL version of puppet and the CIL version of wireshark
> +# modules at priority 400 to the current working directory
> +$ semodule \-X 400 \-g wireshark \-\-cil \-g puppet \-\-hll
>  .fi
>  
>  .SH SEE ALSO
> diff --git a/policycoreutils/semodule/semodule.c b/policycoreutils/semodule/semodule.c
> index baff057..f4b2749 100644
> --- a/policycoreutils/semodule/semodule.c
> +++ b/policycoreutils/semodule/semodule.c
> @@ -20,16 +20,17 @@
>  #include <sys/stat.h>
>  #include <sys/types.h>
>  #include <libgen.h>
> +#include <limits.h>
>  
>  #include <semanage/modules.h>
>  
>  enum client_modes {
> -	NO_MODE, INSTALL_M, REMOVE_M,
> +	NO_MODE, INSTALL_M, REMOVE_M, EXTRACT_M, CIL_M, HLL_M,
>  	LIST_M, RELOAD, PRIORITY_M, ENABLE_M, DISABLE_M
>  };
>  /* list of modes in which one ought to commit afterwards */
>  static const int do_commit[] = {
> -	0, 1, 1,
> +	0, 1, 1, 0, 0, 0,
>  	0, 0, 0, 1, 1,
>  };
>  
> @@ -53,6 +54,7 @@ static uint16_t priority;
>  static semanage_handle_t *sh = NULL;
>  static char *store;
>  static char *store_root;
> +int extract_cil = 0;
>  
>  extern char *optarg;
>  extern int optind;
> @@ -130,6 +132,7 @@ static void usage(char *progname)
>  	printf("  -X,--priority=PRIORITY    set priority for following operations (1-999)\n");
>  	printf("  -e,--enable=MODULE_NAME   enable module\n");
>  	printf("  -d,--disable=MODULE_NAME  disable module\n");
> +	printf("  -E,--extract=MODULE_NAME  extract module\n");
>  	printf("Other options:\n");
>  	printf("  -s,--store	   name of the store to operate on\n");
>  	printf("  -N,-n,--noreload do not reload policy after commit\n");
> @@ -140,6 +143,8 @@ static void usage(char *progname)
>  	printf("  -C,--ignore-module-cache	Rebuild CIL modules compiled from HLL files\n");
>  	printf("  -p,--path        use an alternate path for the policy root\n");
>  	printf("  -S,--store-path  use an alternate path for the policy store root\n");
> +	printf("  -c, --cil extract module as cil. This only affects module extraction.\n");
> +	printf("  -H, --hll extract module as hll. This only affects module extraction.\n");
>  }
>  
>  /* Sets the global mode variable to new_mode, but only if no other
> @@ -175,6 +180,9 @@ static void parse_command_line(int argc, char **argv)
>  		{"base", required_argument, NULL, 'b'},
>  		{"help", 0, NULL, 'h'},
>  		{"install", required_argument, NULL, 'i'},
> +		{"extract", required_argument, NULL, 'E'},
> +		{"cil", 0, NULL, 'c'},
> +		{"hll", 0, NULL, 'H'},
>  		{"list-modules", optional_argument, NULL, 'l'},
>  		{"verbose", 0, NULL, 'v'},
>  		{"remove", required_argument, NULL, 'r'},
> @@ -192,13 +200,15 @@ static void parse_command_line(int argc, char **argv)
>  		{"store-path", required_argument, NULL, 'S'},
>  		{NULL, 0, NULL, 0}
>  	};
> +	int extract_selected = 0;
> +	int cil_hll_set = 0;
>  	int i;
>  	verbose = 0;
>  	reload = 0;
>  	no_reload = 0;
>  	priority = 400;
>  	while ((i =
> -		getopt_long(argc, argv, "s:b:hi:l::vqr:u:RnNBDCPX:e:d:p:S:", opts,
> +		getopt_long(argc, argv, "s:b:hi:l::vqr:u:RnNBDCPX:e:d:p:S:E:cH", opts,
>  			    NULL)) != -1) {
>  		switch (i) {
>  		case 'b':
> @@ -211,6 +221,18 @@ static void parse_command_line(int argc, char **argv)
>  		case 'i':
>  			set_mode(INSTALL_M, optarg);
>  			break;
> +		case 'E':
> +			set_mode(EXTRACT_M, optarg);
> +			extract_selected = 1;
> +			break;
> +		case 'c':
> +			set_mode(CIL_M, NULL);
> +			cil_hll_set = 1;
> +			break;
> +		case 'H':
> +			set_mode(HLL_M, NULL);
> +			cil_hll_set = 1;
> +			break;
>  		case 'l':
>  			set_mode(LIST_M, optarg);
>  			break;
> @@ -281,10 +303,15 @@ static void parse_command_line(int argc, char **argv)
>  		usage(argv[0]);
>  		exit(1);
>  	}
> +	if (extract_selected == 0 && cil_hll_set == 1) {
> +		fprintf(stderr, "--cil and --hll require a module to export with the --extract option.\n");
> +		usage(argv[0]);
> +		exit(1);
> +	}
>  
>  	if (optind < argc) {
>  		int mode;
> -		/* if -i/u/r was the last command treat any remaining
> +		/* if -i/u/r/E was the last command treat any remaining
>  		 * arguments as args. Will allow 'semodule -i *.pp' to
>  		 * work as expected.
>  		 */
> @@ -293,6 +320,8 @@ static void parse_command_line(int argc, char **argv)
>  			mode = INSTALL_M;
>  		} else if (commands && commands[num_commands - 1].mode == REMOVE_M) {
>  			mode = REMOVE_M;
> +		} else if (commands && commands[num_commands - 1].mode == EXTRACT_M) {
> +			mode = EXTRACT_M;
>  		} else {
>  			fprintf(stderr, "unknown additional arguments:\n");
>  			while (optind < argc)
> @@ -389,6 +418,100 @@ int main(int argc, char *argv[])
>  				    semanage_module_install_file(sh, mode_arg);
>  				break;
>  			}
> +		case EXTRACT_M:{
> +				semanage_module_info_t *extract_info = NULL;
> +				semanage_module_key_t *modkey = NULL;
> +				void *data = NULL;
> +				size_t data_len = 0;
> +				char output_path[PATH_MAX];
> +				const char *output_name = NULL;
> +				const char *lang_ext = NULL;
> +				int rlen;
> +				FILE *output_fd = NULL;
> +
> +				result = semanage_module_key_create(sh, &modkey);
> +				if (result != 0) {
> +					goto cleanup_extract;
> +				}
> +
> +				result = semanage_module_key_set_name(sh, modkey, mode_arg);
> +				if (result != 0) {
> +					goto cleanup_extract;
> +				}
> +
> +				result  = semanage_module_key_set_priority(sh, modkey, priority);
> +				if (result != 0) {
> +					goto cleanup_extract;
> +				}
> +
> +				if (verbose) {
> +					printf
> +						("Attempting to extract module '%s':\n",
> +							mode_arg);
> +				}
> +				result = semanage_module_extract(sh, modkey, extract_cil, &data, &data_len, &extract_info);
> +				if (result != 0) {
> +					goto cleanup_extract;
> +				}
> +
> +				if (extract_cil) {
> +					lang_ext = "cil";
> +				} else {
> +					result = semanage_module_info_get_lang_ext(sh, extract_info, &lang_ext);
> +					if (result != 0) {
> +						goto cleanup_extract;
> +					}
> +				}
> +
> +				result = semanage_module_info_get_name(sh, extract_info, &output_name);
> +				if (result != 0) {
> +					goto cleanup_extract;
> +				}
> +
> +				rlen = snprintf(output_path, PATH_MAX, "%s.%s", output_name, lang_ext);
> +				if (rlen < 0 || rlen >= PATH_MAX) {
> +					fprintf(stderr, "%s: Failed to generate output path.\n", argv[0]);
> +					result = -1;
> +					goto cleanup_extract;
> +				}
> +
> +				if (access(output_path, F_OK) == 0) {
> +					fprintf(stderr, "%s: %s is already extracted with extension %s.\n", argv[0], mode_arg, lang_ext);
> +					result = -1;
> +					goto cleanup_extract;
> +				}
> +
> +				output_fd = fopen(output_path, "w");
> +				if (output_fd == NULL) {
> +					fprintf(stderr, "%s: Unable to open %s\n", argv[0], output_path);
> +					result = -1;
> +					goto cleanup_extract;
> +				}
> +
> +				if (fwrite(data, 1, data_len, output_fd) < data_len) {
> +					fprintf(stderr, "%s: Unable to write to %s\n", argv[0], output_path);
> +					result = -1;
> +					goto cleanup_extract;
> +				}
> +cleanup_extract:
> +				if (output_fd != NULL) {
> +					fclose(output_fd);
> +				}
> +				if (data_len > 0) {
> +					munmap(data, data_len);
> +				}
> +				semanage_module_info_destroy(sh, extract_info);
> +				free(extract_info);
> +				semanage_module_key_destroy(sh, modkey);
> +				free(modkey);
> +				break;
> +			}
> +		case CIL_M:
> +				extract_cil = 1;
> +				break;
> +		case HLL_M:
> +				extract_cil = 0;
> +				break;
>  		case REMOVE_M:{
>  				if (verbose) {
>  					printf
> 

_______________________________________________
Selinux mailing list
Selinux@xxxxxxxxxxxxx
To unsubscribe, send email to Selinux-leave@xxxxxxxxxxxxx.
To get help, send an email containing "help" to Selinux-request@xxxxxxxxxxxxx.



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

  Powered by Linux