selinux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH 1/4] semodule_expand: update
@ 2023-05-12 11:07 Christian Göttsche
  2023-05-12 11:07 ` [RFC PATCH 2/4] semodule_link: update Christian Göttsche
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Christian Göttsche @ 2023-05-12 11:07 UTC (permalink / raw)
  To: selinux

Drop unnecessary declarations.
Reduce scope of file global variable.
Mention -v argument in help usage message.
More strict integer conversion.
More strict argument count checking.
Check closing file for incomplete write.
Rework resource cleanup, so that all files and allocated memory are
released in all branches, useful to minimize reports while debugging
libsepol under valgrind(8) or sanitizers.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 .../semodule_expand/semodule_expand.c         | 91 +++++++++++--------
 1 file changed, 55 insertions(+), 36 deletions(-)

diff --git a/semodule-utils/semodule_expand/semodule_expand.c b/semodule-utils/semodule_expand/semodule_expand.c
index 895cdd78..8d9feb05 100644
--- a/semodule-utils/semodule_expand/semodule_expand.c
+++ b/semodule-utils/semodule_expand/semodule_expand.c
@@ -21,30 +21,24 @@
 #include <unistd.h>
 #include <string.h>
 
-extern char *optarg;
-extern int optind;
-
-int policyvers = 0;
-
 #define EXPANDPOLICY_VERSION "1.0"
 
 static __attribute__((__noreturn__)) void usage(const char *program_name)
 {
-	printf("usage: %s [-V -a -c [version]] basemodpkg outputfile\n",
+	printf("usage: %s [-V -a -c [version] -v] basemodpkg outputfile\n",
 	       program_name);
 	exit(1);
 }
 
 int main(int argc, char **argv)
 {
-	char *basename, *outname;
-	int ch, ret, show_version = 0, verbose = 0;
-	struct sepol_policy_file *pf;
-	sepol_module_package_t *base;
-	sepol_policydb_t *out, *p;
-	FILE *fp, *outfile;
-	int check_assertions = 1;
-	sepol_handle_t *handle;
+	const char *basename, *outname;
+	int ch, ret, show_version = 0, verbose = 0, policyvers = 0, check_assertions = 1;
+	struct sepol_policy_file *pf = NULL;
+	sepol_module_package_t *base = NULL;
+	sepol_policydb_t *out = NULL, *p;
+	FILE *fp = NULL, *outfile = NULL;
+	sepol_handle_t *handle = NULL;
 
 	while ((ch = getopt(argc, argv, "c:Vva")) != EOF) {
 		switch (ch) {
@@ -55,13 +49,15 @@ int main(int argc, char **argv)
 			verbose = 1;
 			break;
 		case 'c':{
-				long int n = strtol(optarg, NULL, 10);
+				long int n;
+
+				errno = 0;
+				n = strtol(optarg, NULL, 10);
 				if (errno) {
 					fprintf(stderr,
 						"%s:  Invalid policyvers specified: %s\n",
 						argv[0], optarg);
 					usage(argv[0]);
-					exit(1);
 				}
 				if (n < sepol_policy_kern_vers_min()
 				    || n > sepol_policy_kern_vers_max()) {
@@ -71,7 +67,6 @@ int main(int argc, char **argv)
 						sepol_policy_kern_vers_min(),
 						sepol_policy_kern_vers_max());
 					usage(argv[0]);
-					exit(1);
 				}
 				policyvers = n;
 				break;
@@ -96,7 +91,7 @@ int main(int argc, char **argv)
 	}
 
 	/* check args */
-	if (argc < 3 || !(optind != (argc - 1))) {
+	if (argc < 3 || argc - optind != 2) {
 		fprintf(stderr,
 			"%s:  You must provide the base module package and output filename\n",
 			argv[0]);
@@ -107,69 +102,74 @@ int main(int argc, char **argv)
 	outname = argv[optind];
 
 	handle = sepol_handle_create();
-	if (!handle)
-		exit(1);
+	if (!handle) {
+		fprintf(stderr, "%s:  Out of memory\n", argv[0]);
+		goto failure;
+	}
 
 	if (sepol_policy_file_create(&pf)) {
 		fprintf(stderr, "%s:  Out of memory\n", argv[0]);
-		exit(1);
+		goto failure;
 	}
 
 	/* read the base module */
 	if (sepol_module_package_create(&base)) {
 		fprintf(stderr, "%s:  Out of memory\n", argv[0]);
-		exit(1);
+		goto failure;
 	}
+
 	fp = fopen(basename, "r");
 	if (!fp) {
 		fprintf(stderr, "%s:  Can't open '%s':  %s\n",
 			argv[0], basename, strerror(errno));
-		exit(1);
+		goto failure;
 	}
+
 	sepol_policy_file_set_fp(pf, fp);
 	ret = sepol_module_package_read(base, pf, 0);
 	if (ret) {
 		fprintf(stderr, "%s:  Error in reading package from %s\n",
 			argv[0], basename);
-		exit(1);
+		goto failure;
 	}
+
 	fclose(fp);
+	fp = NULL;
 
 	/* linking the base takes care of enabling optional avrules */
 	p = sepol_module_package_get_policy(base);
 	if (sepol_link_modules(handle, p, NULL, 0, 0)) {
 		fprintf(stderr, "%s:  Error while enabling avrules\n", argv[0]);
-		exit(1);
+		goto failure;
 	}
 
 	/* create the output policy */
 
 	if (sepol_policydb_create(&out)) {
 		fprintf(stderr, "%s:  Out of memory\n", argv[0]);
-		exit(1);
+		goto failure;
 	}
 
 	sepol_set_expand_consume_base(handle, 1);
 
 	if (sepol_expand_module(handle, p, out, verbose, check_assertions)) {
 		fprintf(stderr, "%s:  Error while expanding policy\n", argv[0]);
-		exit(1);
+		goto failure;
 	}
 
 	if (policyvers) {
 		if (sepol_policydb_set_vers(out, policyvers)) {
 			fprintf(stderr, "%s:  Invalid version %d\n", argv[0],
 				policyvers);
-			exit(1);
+			goto failure;
 		}
 	}
 
-	sepol_module_package_free(base);
-
 	outfile = fopen(outname, "w");
 	if (!outfile) {
-		perror(outname);
-		exit(1);
+		fprintf(stderr, "%s:  Can't open '%s':  %s\n",
+			argv[0], outname, strerror(errno));
+		goto failure;
 	}
 
 	sepol_policy_file_set_fp(pf, outfile);
@@ -178,12 +178,31 @@ int main(int argc, char **argv)
 		fprintf(stderr,
 			"%s:  Error while writing expanded policy to %s\n",
 			argv[0], outname);
-		exit(1);
+		goto failure;
 	}
-	fclose(outfile);
-	sepol_handle_destroy(handle);
+
+	ret = fclose(outfile);
+	outfile = NULL;
+	if (ret) {
+		fprintf(stderr, "%s:  Error closing policy file %s:  %s\n",
+			argv[0], outname, strerror(errno));
+		goto failure;
+	}
+
+	ret = EXIT_SUCCESS;
+cleanup:
+	if (outfile)
+		fclose(outfile);
 	sepol_policydb_free(out);
+	if (fp)
+		fclose(fp);
+	sepol_module_package_free(base);
 	sepol_policy_file_free(pf);
+	sepol_handle_destroy(handle);
+
+	return ret;
 
-	return 0;
+failure:
+	ret = EXIT_FAILURE;
+	goto cleanup;
 }
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [RFC PATCH 2/4] semodule_link: update
  2023-05-12 11:07 [RFC PATCH 1/4] semodule_expand: update Christian Göttsche
@ 2023-05-12 11:07 ` Christian Göttsche
  2023-06-09 19:27   ` James Carter
  2023-05-12 11:07 ` [RFC PATCH 3/4] semodule_package: update Christian Göttsche
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: Christian Göttsche @ 2023-05-12 11:07 UTC (permalink / raw)
  To: selinux

Drop unnecessary declarations.
More verbose error messages and add missing trailing newline.
More strict argument count checking.
Check closing file for incomplete write.
Rework resource cleanup, so that all files and allocated memory are
released in all branches, useful to minimize reports while debugging
libsepol under valgrind(8) or sanitizers.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 semodule-utils/semodule_link/semodule_link.c | 65 ++++++++++++--------
 1 file changed, 38 insertions(+), 27 deletions(-)

diff --git a/semodule-utils/semodule_link/semodule_link.c b/semodule-utils/semodule_link/semodule_link.c
index 38a6843c..58a82cb0 100644
--- a/semodule-utils/semodule_link/semodule_link.c
+++ b/semodule-utils/semodule_link/semodule_link.c
@@ -21,9 +21,7 @@
 
 #define LINKPOLICY_VERSION "1.0"
 
-char *progname;
-extern char *optarg;
-extern int optind;
+static const char *progname;
 
 static __attribute__((__noreturn__)) void usage(const char *program_name)
 {
@@ -32,7 +30,7 @@ static __attribute__((__noreturn__)) void usage(const char *program_name)
 	exit(1);
 }
 
-static sepol_module_package_t *load_module(char *filename)
+static sepol_module_package_t *load_module(const char *filename)
 {
 	int ret;
 	FILE *fp = NULL;
@@ -49,7 +47,7 @@ static sepol_module_package_t *load_module(char *filename)
 	}
 	fp = fopen(filename, "r");
 	if (!fp) {
-		fprintf(stderr, "%s:  Could not open package %s:  %s", progname,
+		fprintf(stderr, "%s:  Could not open package %s:  %s\n", progname,
 			filename, strerror(errno));
 		goto bad;
 	}
@@ -76,11 +74,10 @@ static sepol_module_package_t *load_module(char *filename)
 
 int main(int argc, char **argv)
 {
-	int ch, i, show_version = 0, verbose = 0, num_mods;
-	char *basename, *outname = NULL;
-	sepol_module_package_t *base, **mods;
-	FILE *outfile;
-	struct sepol_policy_file *pf;
+	int ch, i, ret, show_version = 0, verbose = 0, num_mods = 0;
+	const char *basename, *outname = NULL;
+	sepol_module_package_t *base = NULL, **mods = NULL;
+	struct sepol_policy_file *pf = NULL;
 
 	progname = argv[0];
 
@@ -106,7 +103,7 @@ int main(int argc, char **argv)
 	}
 
 	/* check args */
-	if (argc < 3 || !(optind != (argc - 1))) {
+	if (argc < 3 || optind + 2 > argc) {
 		fprintf(stderr,
 			"%s:  You must provide the base module package and at least one other module package\n",
 			argv[0]);
@@ -119,18 +116,15 @@ int main(int argc, char **argv)
 		fprintf(stderr,
 			"%s:  Could not load base module from file %s\n",
 			argv[0], basename);
-		exit(1);
+		goto failure;
 	}
 
 	num_mods = argc - optind;
-	mods =
-	    (sepol_module_package_t **) malloc(sizeof(sepol_module_package_t *)
-					       * num_mods);
+	mods = calloc(num_mods, sizeof(sepol_module_package_t *));
 	if (!mods) {
 		fprintf(stderr, "%s:  Out of memory\n", argv[0]);
-		exit(1);
+		goto failure;
 	}
-	memset(mods, 0, sizeof(sepol_module_package_t *) * num_mods);
 
 	for (i = 0; optind < argc; optind++, i++) {
 		mods[i] = load_module(argv[optind]);
@@ -138,39 +132,56 @@ int main(int argc, char **argv)
 			fprintf(stderr,
 				"%s:  Could not load module from file %s\n",
 				argv[0], argv[optind]);
-			exit(1);
+			goto failure;
 		}
 	}
 
 	if (sepol_link_packages(NULL, base, mods, num_mods, verbose)) {
 		fprintf(stderr, "%s:  Error while linking packages\n", argv[0]);
-		exit(1);
+		goto failure;
 	}
 
 	if (outname) {
-		outfile = fopen(outname, "w");
+		FILE *outfile = fopen(outname, "w");
 		if (!outfile) {
-			perror(outname);
-			exit(1);
+			fprintf(stderr, "%s:  Could not open output file %s:  %s\n",
+				progname, outname, strerror(errno));
+			goto failure;
 		}
 
 		if (sepol_policy_file_create(&pf)) {
 			fprintf(stderr, "%s:  Out of memory\n", argv[0]);
-			exit(1);
+			fclose(outfile);
+			goto failure;
 		}
 		sepol_policy_file_set_fp(pf, outfile);
 		if (sepol_module_package_write(base, pf)) {
 			fprintf(stderr, "%s:  Error writing linked package.\n",
 				argv[0]);
-			exit(1);
+			sepol_policy_file_free(pf);
+			fclose(outfile);
+			goto failure;
 		}
 		sepol_policy_file_free(pf);
-		fclose(outfile);
+
+		if (fclose(outfile)) {
+			fprintf(stderr, "%s:  Error closing linked package:  %s\n",
+				argv[0], strerror(errno));
+			goto failure;
+		}
 	}
 
-	sepol_module_package_free(base);
+	ret = EXIT_SUCCESS;
+
+cleanup:
 	for (i = 0; i < num_mods; i++)
 		sepol_module_package_free(mods[i]);
 	free(mods);
-	exit(0);
+	sepol_module_package_free(base);
+
+	return ret;
+
+failure:
+	ret = EXIT_FAILURE;
+	goto cleanup;
 }
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [RFC PATCH 3/4] semodule_package: update
  2023-05-12 11:07 [RFC PATCH 1/4] semodule_expand: update Christian Göttsche
  2023-05-12 11:07 ` [RFC PATCH 2/4] semodule_link: update Christian Göttsche
@ 2023-05-12 11:07 ` Christian Göttsche
  2023-06-09 19:32   ` James Carter
  2023-05-12 11:07 ` [RFC PATCH 4/4] semodule_unpackage: update Christian Göttsche
  2023-06-09 19:25 ` [RFC PATCH 1/4] semodule_expand: update James Carter
  3 siblings, 1 reply; 9+ messages in thread
From: Christian Göttsche @ 2023-05-12 11:07 UTC (permalink / raw)
  To: selinux

Drop unnecessary declarations.
Add missing error messages.
More strict command line argument parsing.
Check closing file for incomplete write.
Rework resource cleanup, so that all files and allocated memory are
released in all branches, useful to minimize reports while debugging
libsepol under valgrind(8) or sanitizers.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 .../semodule_package/semodule_package.c       | 203 +++++++++++-------
 1 file changed, 125 insertions(+), 78 deletions(-)

diff --git a/semodule-utils/semodule_package/semodule_package.c b/semodule-utils/semodule_package/semodule_package.c
index bc8584b5..7485e254 100644
--- a/semodule-utils/semodule_package/semodule_package.c
+++ b/semodule-utils/semodule_package/semodule_package.c
@@ -19,8 +19,7 @@
 #include <fcntl.h>
 #include <errno.h>
 
-char *progname = NULL;
-extern char *optarg;
+static const char *progname = NULL;
 
 static __attribute__((__noreturn__)) void usage(const char *prog)
 {
@@ -37,26 +36,6 @@ static __attribute__((__noreturn__)) void usage(const char *prog)
 	exit(1);
 }
 
-static int file_to_policy_file(const char *filename, struct sepol_policy_file **pf,
-			       const char *mode)
-{
-	FILE *f;
-
-	if (sepol_policy_file_create(pf)) {
-		fprintf(stderr, "%s:  Out of memory\n", progname);
-		return -1;
-	}
-
-	f = fopen(filename, mode);
-	if (!f) {
-		fprintf(stderr, "%s:  Could not open file %s:  %s\n", progname,
-			strerror(errno), filename);
-		return -1;
-	}
-	sepol_policy_file_set_fp(*pf, f);
-	return 0;
-}
-
 static int file_to_data(const char *path, char **data, size_t * len)
 {
 	int fd;
@@ -94,17 +73,18 @@ static int file_to_data(const char *path, char **data, size_t * len)
 
 int main(int argc, char **argv)
 {
-	struct sepol_module_package *pkg;
-	struct sepol_policy_file *mod, *out;
+	struct sepol_module_package *pkg = NULL;
+	struct sepol_policy_file *mod = NULL, *out = NULL;
+	FILE *fp = NULL;
 	char *module = NULL, *file_contexts = NULL, *seusers =
 	    NULL, *user_extra = NULL;
 	char *fcdata = NULL, *outfile = NULL, *seusersdata =
 	    NULL, *user_extradata = NULL;
 	char *netfilter_contexts = NULL, *ncdata = NULL;
 	size_t fclen = 0, seuserslen = 0, user_extralen = 0, nclen = 0;
-	int i;
+	int i, ret;
 
-	static struct option opts[] = {
+	const struct option opts[] = {
 		{"module", required_argument, NULL, 'm'},
 		{"fc", required_argument, NULL, 'f'},
 		{"seuser", required_argument, NULL, 's'},
@@ -115,11 +95,12 @@ int main(int argc, char **argv)
 		{NULL, 0, NULL, 0}
 	};
 
+	progname = argv[0];
+
 	while ((i = getopt_long(argc, argv, "m:f:s:u:o:n:h", opts, NULL)) != -1) {
 		switch (i) {
 		case 'h':
-			usage(argv[0]);
-			exit(0);
+			usage(progname);
 		case 'm':
 			if (module) {
 				fprintf(stderr,
@@ -127,8 +108,10 @@ int main(int argc, char **argv)
 				exit(1);
 			}
 			module = strdup(optarg);
-			if (!module)
+			if (!module) {
+				fprintf(stderr, "%s:  Out of memory\n", progname);
 				exit(1);
+			}
 			break;
 		case 'f':
 			if (file_contexts) {
@@ -137,8 +120,10 @@ int main(int argc, char **argv)
 				exit(1);
 			}
 			file_contexts = strdup(optarg);
-			if (!file_contexts)
+			if (!file_contexts) {
+				fprintf(stderr, "%s:  Out of memory\n", progname);
 				exit(1);
+			}
 			break;
 		case 'o':
 			if (outfile) {
@@ -147,8 +132,10 @@ int main(int argc, char **argv)
 				exit(1);
 			}
 			outfile = strdup(optarg);
-			if (!outfile)
+			if (!outfile) {
+				fprintf(stderr, "%s:  Out of memory\n", progname);
 				exit(1);
+			}
 			break;
 		case 's':
 			if (seusers) {
@@ -157,8 +144,10 @@ int main(int argc, char **argv)
 				exit(1);
 			}
 			seusers = strdup(optarg);
-			if (!seusers)
+			if (!seusers) {
+				fprintf(stderr, "%s:  Out of memory\n", progname);
 				exit(1);
+			}
 			break;
 		case 'u':
 			if (user_extra) {
@@ -167,8 +156,10 @@ int main(int argc, char **argv)
 				exit(1);
 			}
 			user_extra = strdup(optarg);
-			if (!user_extra)
+			if (!user_extra) {
+				fprintf(stderr, "%s:  Out of memory\n", progname);
 				exit(1);
+			}
 			break;
 		case 'n':
 			if (netfilter_contexts) {
@@ -177,88 +168,144 @@ int main(int argc, char **argv)
 				exit(1);
 			}
 			netfilter_contexts = strdup(optarg);
-			if (!netfilter_contexts)
+			if (!netfilter_contexts) {
+				fprintf(stderr, "%s:  Out of memory\n", progname);
 				exit(1);
+			}
 			break;
+		case '?':
+			usage(progname);
+		default:
+			fprintf(stderr, "%s:  Unsupported getopt return code: %d\n", progname, i);
+			usage(progname);
 		}
 	}
 
-	progname = argv[0];
-
-	if (!module || !outfile) {
-		usage(argv[0]);
-		exit(0);
+	if (optind < argc) {
+		fprintf(stderr, "%s:  Superfluous command line arguments: ", progname);
+		 while (optind < argc)
+			 fprintf(stderr, "%s ", argv[optind++]);
+		fprintf(stderr, "\n");
+		usage(progname);
 	}
 
-	if (file_contexts) {
-		if (file_to_data(file_contexts, &fcdata, &fclen))
-			exit(1);
-	}
+	if (!module || !outfile)
+		usage(progname);
 
-	if (seusers) {
-		if (file_to_data(seusers, &seusersdata, &seuserslen))
-			exit(1);
-	}
+	if (file_contexts && file_to_data(file_contexts, &fcdata, &fclen))
+		goto failure;
 
-	if (user_extra) {
-		if (file_to_data(user_extra, &user_extradata, &user_extralen))
-			exit(1);
-	}
+	if (seusers && file_to_data(seusers, &seusersdata, &seuserslen))
+		goto failure;
+
+	if (user_extra && file_to_data(user_extra, &user_extradata, &user_extralen))
+		goto failure;
 
-	if (netfilter_contexts) {
-		if (file_to_data(netfilter_contexts, &ncdata, &nclen))
-			exit(1);
+	if (netfilter_contexts && file_to_data(netfilter_contexts, &ncdata, &nclen))
+		goto failure;
+
+	if (sepol_policy_file_create(&mod)) {
+		fprintf(stderr, "%s:  Out of memory\n", progname);
+		goto failure;
 	}
 
-	if (file_to_policy_file(module, &mod, "r"))
-		exit(1);
+	fp = fopen(module, "r");
+	if (!fp) {
+		fprintf(stderr, "%s:  Could not open file %s:  %s\n", progname,
+			module, strerror(errno));
+		goto failure;
+	}
+	sepol_policy_file_set_fp(mod, fp);
 
 	if (sepol_module_package_create(&pkg)) {
 		fprintf(stderr, "%s:  Out of memory\n", argv[0]);
-		exit(1);
+		goto failure;
 	}
 
 	if (sepol_policydb_read(sepol_module_package_get_policy(pkg), mod)) {
 		fprintf(stderr,
 			"%s:  Error while reading policy module from %s\n",
 			argv[0], module);
-		exit(1);
+		goto failure;
 	}
 
-	if (fclen)
-		sepol_module_package_set_file_contexts(pkg, fcdata, fclen);
+	fclose(fp);
+	fp = NULL;
 
-	if (seuserslen)
-		sepol_module_package_set_seusers(pkg, seusersdata, seuserslen);
+	if (fclen && sepol_module_package_set_file_contexts(pkg, fcdata, fclen)) {
+		fprintf(stderr, "%s:  Error while setting file contexts\n", progname);
+		goto failure;
+	}
 
-	if (user_extra)
-		sepol_module_package_set_user_extra(pkg, user_extradata,
-						    user_extralen);
+	if (seuserslen && sepol_module_package_set_seusers(pkg, seusersdata, seuserslen)) {
+		fprintf(stderr, "%s:  Error while setting seusers\n", progname);
+		goto failure;
+	}
 
-	if (nclen)
-		sepol_module_package_set_netfilter_contexts(pkg, ncdata, nclen);
+	if (user_extra && sepol_module_package_set_user_extra(pkg, user_extradata, user_extralen)) {
+		fprintf(stderr, "%s:  Error while setting extra users\n", progname);
+		goto failure;
+	}
+
+	if (nclen && sepol_module_package_set_netfilter_contexts(pkg, ncdata, nclen)) {
+		fprintf(stderr, "%s:  Error while setting netfilter contexts\n", progname);
+		goto failure;
+	}
+
+	if (sepol_policy_file_create(&out)) {
+		fprintf(stderr, "%s:  Out of memory\n", progname);
+		goto failure;
+	}
 
-	if (file_to_policy_file(outfile, &out, "w"))
-		exit(1);
+	fp = fopen(outfile, "w");
+	if (!fp) {
+		fprintf(stderr, "%s:  Could not open file %s:  %s\n", progname,
+			outfile, strerror(errno));
+		goto failure;
+	}
+	sepol_policy_file_set_fp(out, fp);
 
 	if (sepol_module_package_write(pkg, out)) {
 		fprintf(stderr,
 			"%s:  Error while writing module package to %s\n",
 			argv[0], argv[1]);
-		exit(1);
+		goto failure;
 	}
 
-	if (fclen)
-		munmap(fcdata, fclen);
+	ret = fclose(fp);
+	fp = NULL;
+	if (ret) {
+		fprintf(stderr, "%s:  Could not close file %s:  %s\n", progname,
+			outfile, strerror(errno));
+		goto failure;
+	}
+
+	ret = EXIT_SUCCESS;
+
+cleanup:
+	if (fp)
+		fclose(fp);
+	sepol_policy_file_free(out);
 	if (nclen)
 		munmap(ncdata, nclen);
-	sepol_policy_file_free(mod);
-	sepol_policy_file_free(out);
+	if (user_extradata)
+		munmap(user_extradata, user_extralen);
+	if (seuserslen)
+		munmap(seusersdata, seuserslen);
+	if (fclen)
+		munmap(fcdata, fclen);
 	sepol_module_package_free(pkg);
-	free(file_contexts);
+	sepol_policy_file_free(mod);
+	free(netfilter_contexts);
+	free(user_extra);
+	free(seusers);
 	free(outfile);
+	free(file_contexts);
 	free(module);
-	free(seusers);
-	free(user_extra);
-	exit(0);
+
+	return ret;
+
+failure:
+	ret = EXIT_FAILURE;
+	goto cleanup;
 }
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [RFC PATCH 4/4] semodule_unpackage: update
  2023-05-12 11:07 [RFC PATCH 1/4] semodule_expand: update Christian Göttsche
  2023-05-12 11:07 ` [RFC PATCH 2/4] semodule_link: update Christian Göttsche
  2023-05-12 11:07 ` [RFC PATCH 3/4] semodule_package: update Christian Göttsche
@ 2023-05-12 11:07 ` Christian Göttsche
  2023-06-09 19:36   ` James Carter
  2023-06-09 19:25 ` [RFC PATCH 1/4] semodule_expand: update James Carter
  3 siblings, 1 reply; 9+ messages in thread
From: Christian Göttsche @ 2023-05-12 11:07 UTC (permalink / raw)
  To: selinux

Drop unnecessary declarations.
Check closing file for incomplete write.
Rework resource cleanup, so that all files and allocated memory are
released in all branches, useful to minimize reports while debugging
libsepol under valgrind(8) or sanitizers.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 .../semodule_package/semodule_unpackage.c     | 122 +++++++++++-------
 1 file changed, 75 insertions(+), 47 deletions(-)

diff --git a/semodule-utils/semodule_package/semodule_unpackage.c b/semodule-utils/semodule_package/semodule_unpackage.c
index b8c4fbce..21c97953 100644
--- a/semodule-utils/semodule_package/semodule_unpackage.c
+++ b/semodule-utils/semodule_package/semodule_unpackage.c
@@ -11,8 +11,7 @@
 #include <fcntl.h>
 #include <errno.h>
 
-char *progname = NULL;
-extern char *optarg;
+static const char *progname = NULL;
 
 static __attribute__((__noreturn__)) void usage(void)
 {
@@ -20,84 +19,113 @@ static __attribute__((__noreturn__)) void usage(void)
 	exit(1);
 }
 
-static int file_to_policy_file(const char *filename, struct sepol_policy_file **pf, const char *mode)
-{
-	FILE *f;
-
-	if (sepol_policy_file_create(pf)) {
-		fprintf(stderr, "%s:  Out of memory\n", progname);
-		return -1;
-	}
-
-	f = fopen(filename, mode);
-	if (!f) {
-		fprintf(stderr, "%s:  Could not open file %s:  %s\n", progname, strerror(errno), filename);
-		return -1;
-	}
-	sepol_policy_file_set_fp(*pf, f);
-	return 0;
-}
-
 int main(int argc, char **argv)
 {
-	struct sepol_module_package *pkg;
-	struct sepol_policy_file *in, *out;
-	FILE *fp;
+	struct sepol_module_package *pkg = NULL;
+	struct sepol_policy_file *in = NULL, *out = NULL;
+	FILE *fp = NULL;
 	size_t len;
-	char *ppfile, *modfile, *fcfile = NULL, *fcdata;
+	const char *ppfile, *modfile, *fcfile = NULL, *fcdata;
+	int ret;
 
 	progname = argv[0];
 
-	if (argc < 3) {
+	if (argc < 3)
 		usage();
-		exit(1);
-	}
 
 	ppfile = argv[1];
 	modfile = argv[2];
 	if (argc >= 4)
 		fcfile = argv[3];
 
-	if (file_to_policy_file(ppfile, &in, "r"))
-		exit(1);
-
 	if (sepol_module_package_create(&pkg)) {
-                fprintf(stderr, "%s:  Out of memory\n", progname);
-                exit(1);
+		fprintf(stderr, "%s:  Out of memory\n", progname);
+		goto failure;
+	}
+
+	if (sepol_policy_file_create(&in)) {
+		fprintf(stderr, "%s:  Out of memory\n", progname);
+		goto failure;
 	}
 
+	fp = fopen(ppfile, "r");
+	if (!fp) {
+		fprintf(stderr, "%s:  Could not open file %s:  %s\n", progname, ppfile, strerror(errno));
+		goto failure;
+	}
+	sepol_policy_file_set_fp(in, fp);
+
 	if (sepol_module_package_read(pkg, in, 0) == -1) {
-                fprintf(stderr, "%s:  Error while reading policy module from %s\n",
+		fprintf(stderr, "%s:  Error while reading policy module from %s\n",
 			progname, ppfile);
-                exit(1);
+		goto failure;
 	}
 
-	if (file_to_policy_file(modfile, &out, "w"))
-		exit(1);
+	sepol_policy_file_free(in);
+	in = NULL;
+	fclose(fp);
+	fp = NULL;
 
-        if (sepol_policydb_write(sepol_module_package_get_policy(pkg), out)) {
-                fprintf(stderr, "%s:  Error while writing module to %s\n", progname, modfile);
-                exit(1);
-        }
+	if (sepol_policy_file_create(&out)) {
+		fprintf(stderr, "%s:  Out of memory\n", progname);
+		goto failure;
+	}
+
+	fp = fopen(modfile, "w");
+	if (!fp) {
+		fprintf(stderr, "%s:  Could not open file %s:  %s\n", progname, modfile, strerror(errno));
+		goto failure;
+	}
+	sepol_policy_file_set_fp(out, fp);
+
+	if (sepol_policydb_write(sepol_module_package_get_policy(pkg), out)) {
+		fprintf(stderr, "%s:  Error while writing module to %s\n", progname, modfile);
+		goto failure;
+	}
+
+	ret = fclose(fp);
+	fp = NULL;
+	if (ret) {
+		fprintf(stderr, "%s:  Error while closing file %s:  %s\n", progname, modfile, strerror(errno));
+		goto failure;
+	}
 
-	sepol_policy_file_free(in);
 	sepol_policy_file_free(out);
+	out = NULL;
 
 	len = sepol_module_package_get_file_contexts_len(pkg);
 	if (fcfile && len) {
 		fp = fopen(fcfile, "w");
 		if (!fp) {
-			fprintf(stderr, "%s:  Could not open file %s:  %s\n", progname, strerror(errno), fcfile);
-			exit(1);
+			fprintf(stderr, "%s:  Could not open file %s:  %s\n", progname, fcfile, strerror(errno));
+			goto failure;
 		}
 		fcdata = sepol_module_package_get_file_contexts(pkg);
 		if (fwrite(fcdata, 1, len, fp) != len) {
-			fprintf(stderr, "%s:  Could not write file %s:  %s\n", progname, strerror(errno), fcfile);
-			exit(1);
+			fprintf(stderr, "%s:  Could not write file %s:  %s\n", progname, fcfile, strerror(errno));
+			goto failure;
+		}
+
+		ret = fclose(fp);
+		fp = NULL;
+		if (ret) {
+			fprintf(stderr, "%s:  Could not close file %s:  %s\n", progname, fcfile, strerror(errno));
+			goto failure;
 		}
-		fclose(fp);
 	}
 
+	ret = EXIT_SUCCESS;
+
+cleanup:
+	if (fp)
+		fclose(fp);
+	sepol_policy_file_free(out);
 	sepol_module_package_free(pkg);
-	exit(0);
+	sepol_policy_file_free(in);
+
+	return ret;
+
+failure:
+	ret = EXIT_FAILURE;
+	goto cleanup;
 }
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [RFC PATCH 1/4] semodule_expand: update
  2023-05-12 11:07 [RFC PATCH 1/4] semodule_expand: update Christian Göttsche
                   ` (2 preceding siblings ...)
  2023-05-12 11:07 ` [RFC PATCH 4/4] semodule_unpackage: update Christian Göttsche
@ 2023-06-09 19:25 ` James Carter
  3 siblings, 0 replies; 9+ messages in thread
From: James Carter @ 2023-06-09 19:25 UTC (permalink / raw)
  To: Christian Göttsche; +Cc: selinux

On Fri, May 12, 2023 at 7:28 AM Christian Göttsche
<cgzones@googlemail.com> wrote:
>
> Drop unnecessary declarations.
> Reduce scope of file global variable.
> Mention -v argument in help usage message.
> More strict integer conversion.
> More strict argument count checking.
> Check closing file for incomplete write.
> Rework resource cleanup, so that all files and allocated memory are
> released in all branches, useful to minimize reports while debugging
> libsepol under valgrind(8) or sanitizers.
>
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
> ---
>  .../semodule_expand/semodule_expand.c         | 91 +++++++++++--------
>  1 file changed, 55 insertions(+), 36 deletions(-)
>
> diff --git a/semodule-utils/semodule_expand/semodule_expand.c b/semodule-utils/semodule_expand/semodule_expand.c
> index 895cdd78..8d9feb05 100644
> --- a/semodule-utils/semodule_expand/semodule_expand.c
> +++ b/semodule-utils/semodule_expand/semodule_expand.c
> @@ -21,30 +21,24 @@
>  #include <unistd.h>
>  #include <string.h>
>
> -extern char *optarg;
> -extern int optind;
> -
> -int policyvers = 0;
> -
>  #define EXPANDPOLICY_VERSION "1.0"
>
>  static __attribute__((__noreturn__)) void usage(const char *program_name)
>  {
> -       printf("usage: %s [-V -a -c [version]] basemodpkg outputfile\n",
> +       printf("usage: %s [-V -a -c [version] -v] basemodpkg outputfile\n",
>                program_name);
>         exit(1);

If you are going to use EXIT_FAILURE, then all the uses of "exit(1)"
should be removed.

>  }
>
>  int main(int argc, char **argv)
>  {
> -       char *basename, *outname;
> -       int ch, ret, show_version = 0, verbose = 0;
> -       struct sepol_policy_file *pf;
> -       sepol_module_package_t *base;
> -       sepol_policydb_t *out, *p;
> -       FILE *fp, *outfile;
> -       int check_assertions = 1;
> -       sepol_handle_t *handle;
> +       const char *basename, *outname;
> +       int ch, ret, show_version = 0, verbose = 0, policyvers = 0, check_assertions = 1;
> +       struct sepol_policy_file *pf = NULL;
> +       sepol_module_package_t *base = NULL;
> +       sepol_policydb_t *out = NULL, *p;
> +       FILE *fp = NULL, *outfile = NULL;
> +       sepol_handle_t *handle = NULL;
>
>         while ((ch = getopt(argc, argv, "c:Vva")) != EOF) {
>                 switch (ch) {
> @@ -55,13 +49,15 @@ int main(int argc, char **argv)
>                         verbose = 1;
>                         break;
>                 case 'c':{
> -                               long int n = strtol(optarg, NULL, 10);
> +                               long int n;
> +
> +                               errno = 0;
> +                               n = strtol(optarg, NULL, 10);
>                                 if (errno) {
>                                         fprintf(stderr,
>                                                 "%s:  Invalid policyvers specified: %s\n",
>                                                 argv[0], optarg);
>                                         usage(argv[0]);
> -                                       exit(1);
>                                 }
>                                 if (n < sepol_policy_kern_vers_min()
>                                     || n > sepol_policy_kern_vers_max()) {
> @@ -71,7 +67,6 @@ int main(int argc, char **argv)
>                                                 sepol_policy_kern_vers_min(),
>                                                 sepol_policy_kern_vers_max());
>                                         usage(argv[0]);
> -                                       exit(1);
>                                 }
>                                 policyvers = n;
>                                 break;
> @@ -96,7 +91,7 @@ int main(int argc, char **argv)
>         }
>
>         /* check args */
> -       if (argc < 3 || !(optind != (argc - 1))) {
> +       if (argc < 3 || argc - optind != 2) {
>                 fprintf(stderr,
>                         "%s:  You must provide the base module package and output filename\n",
>                         argv[0]);
> @@ -107,69 +102,74 @@ int main(int argc, char **argv)
>         outname = argv[optind];
>
>         handle = sepol_handle_create();
> -       if (!handle)
> -               exit(1);
> +       if (!handle) {
> +               fprintf(stderr, "%s:  Out of memory\n", argv[0]);
> +               goto failure;
> +       }
>
>         if (sepol_policy_file_create(&pf)) {
>                 fprintf(stderr, "%s:  Out of memory\n", argv[0]);
> -               exit(1);
> +               goto failure;
>         }
>
>         /* read the base module */
>         if (sepol_module_package_create(&base)) {
>                 fprintf(stderr, "%s:  Out of memory\n", argv[0]);
> -               exit(1);
> +               goto failure;
>         }
> +
>         fp = fopen(basename, "r");
>         if (!fp) {
>                 fprintf(stderr, "%s:  Can't open '%s':  %s\n",
>                         argv[0], basename, strerror(errno));
> -               exit(1);
> +               goto failure;
>         }
> +
>         sepol_policy_file_set_fp(pf, fp);
>         ret = sepol_module_package_read(base, pf, 0);
>         if (ret) {
>                 fprintf(stderr, "%s:  Error in reading package from %s\n",
>                         argv[0], basename);
> -               exit(1);
> +               goto failure;
>         }
> +
>         fclose(fp);
> +       fp = NULL;
>
>         /* linking the base takes care of enabling optional avrules */
>         p = sepol_module_package_get_policy(base);
>         if (sepol_link_modules(handle, p, NULL, 0, 0)) {
>                 fprintf(stderr, "%s:  Error while enabling avrules\n", argv[0]);
> -               exit(1);
> +               goto failure;
>         }
>
>         /* create the output policy */
>
>         if (sepol_policydb_create(&out)) {
>                 fprintf(stderr, "%s:  Out of memory\n", argv[0]);
> -               exit(1);
> +               goto failure;
>         }
>
>         sepol_set_expand_consume_base(handle, 1);
>
>         if (sepol_expand_module(handle, p, out, verbose, check_assertions)) {
>                 fprintf(stderr, "%s:  Error while expanding policy\n", argv[0]);
> -               exit(1);
> +               goto failure;
>         }
>
>         if (policyvers) {
>                 if (sepol_policydb_set_vers(out, policyvers)) {
>                         fprintf(stderr, "%s:  Invalid version %d\n", argv[0],
>                                 policyvers);
> -                       exit(1);
> +                       goto failure;
>                 }
>         }
>
> -       sepol_module_package_free(base);
> -
>         outfile = fopen(outname, "w");
>         if (!outfile) {
> -               perror(outname);
> -               exit(1);
> +               fprintf(stderr, "%s:  Can't open '%s':  %s\n",
> +                       argv[0], outname, strerror(errno));
> +               goto failure;
>         }
>
>         sepol_policy_file_set_fp(pf, outfile);
> @@ -178,12 +178,31 @@ int main(int argc, char **argv)
>                 fprintf(stderr,
>                         "%s:  Error while writing expanded policy to %s\n",
>                         argv[0], outname);
> -               exit(1);
> +               goto failure;
>         }
> -       fclose(outfile);
> -       sepol_handle_destroy(handle);
> +
> +       ret = fclose(outfile);
> +       outfile = NULL;
> +       if (ret) {
> +               fprintf(stderr, "%s:  Error closing policy file %s:  %s\n",
> +                       argv[0], outname, strerror(errno));
> +               goto failure;
> +       }
> +
> +       ret = EXIT_SUCCESS;
> +cleanup:
> +       if (outfile)
> +               fclose(outfile);
>         sepol_policydb_free(out);
> +       if (fp)
> +               fclose(fp);
> +       sepol_module_package_free(base);
>         sepol_policy_file_free(pf);
> +       sepol_handle_destroy(handle);
> +
> +       return ret;
>
> -       return 0;
> +failure:
> +       ret = EXIT_FAILURE;
> +       goto cleanup;
>  }

I would prefer to have the return at the end.
Something like this:

  ret = EXIT_SUCCESS;
  goto cleanup;
failure:
  ret = EXIT_FAILURE;
cleanup:
...
  return ret;
}

Thanks,
Jim

> --
> 2.40.1
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC PATCH 2/4] semodule_link: update
  2023-05-12 11:07 ` [RFC PATCH 2/4] semodule_link: update Christian Göttsche
@ 2023-06-09 19:27   ` James Carter
  0 siblings, 0 replies; 9+ messages in thread
From: James Carter @ 2023-06-09 19:27 UTC (permalink / raw)
  To: Christian Göttsche; +Cc: selinux

On Fri, May 12, 2023 at 7:22 AM Christian Göttsche
<cgzones@googlemail.com> wrote:
>
> Drop unnecessary declarations.
> More verbose error messages and add missing trailing newline.
> More strict argument count checking.
> Check closing file for incomplete write.
> Rework resource cleanup, so that all files and allocated memory are
> released in all branches, useful to minimize reports while debugging
> libsepol under valgrind(8) or sanitizers.
>
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
> ---
>  semodule-utils/semodule_link/semodule_link.c | 65 ++++++++++++--------
>  1 file changed, 38 insertions(+), 27 deletions(-)
>
> diff --git a/semodule-utils/semodule_link/semodule_link.c b/semodule-utils/semodule_link/semodule_link.c
> index 38a6843c..58a82cb0 100644
> --- a/semodule-utils/semodule_link/semodule_link.c
> +++ b/semodule-utils/semodule_link/semodule_link.c
> @@ -21,9 +21,7 @@
>
>  #define LINKPOLICY_VERSION "1.0"
>
> -char *progname;
> -extern char *optarg;
> -extern int optind;
> +static const char *progname;
>

Is there a reason that we can't eliminate this global and just pass in
the program name?

>  static __attribute__((__noreturn__)) void usage(const char *program_name)
>  {
> @@ -32,7 +30,7 @@ static __attribute__((__noreturn__)) void usage(const char *program_name)
>         exit(1);

Same comment as for patch 1 about "exit(1)"

>  }
>
> -static sepol_module_package_t *load_module(char *filename)
> +static sepol_module_package_t *load_module(const char *filename)
>  {
>         int ret;
>         FILE *fp = NULL;
> @@ -49,7 +47,7 @@ static sepol_module_package_t *load_module(char *filename)
>         }
>         fp = fopen(filename, "r");
>         if (!fp) {
> -               fprintf(stderr, "%s:  Could not open package %s:  %s", progname,
> +               fprintf(stderr, "%s:  Could not open package %s:  %s\n", progname,
>                         filename, strerror(errno));
>                 goto bad;
>         }
> @@ -76,11 +74,10 @@ static sepol_module_package_t *load_module(char *filename)
>
>  int main(int argc, char **argv)
>  {
> -       int ch, i, show_version = 0, verbose = 0, num_mods;
> -       char *basename, *outname = NULL;
> -       sepol_module_package_t *base, **mods;
> -       FILE *outfile;
> -       struct sepol_policy_file *pf;
> +       int ch, i, ret, show_version = 0, verbose = 0, num_mods = 0;
> +       const char *basename, *outname = NULL;
> +       sepol_module_package_t *base = NULL, **mods = NULL;
> +       struct sepol_policy_file *pf = NULL;
>
>         progname = argv[0];
>
> @@ -106,7 +103,7 @@ int main(int argc, char **argv)
>         }
>
>         /* check args */
> -       if (argc < 3 || !(optind != (argc - 1))) {
> +       if (argc < 3 || optind + 2 > argc) {
>                 fprintf(stderr,
>                         "%s:  You must provide the base module package and at least one other module package\n",
>                         argv[0]);
> @@ -119,18 +116,15 @@ int main(int argc, char **argv)
>                 fprintf(stderr,
>                         "%s:  Could not load base module from file %s\n",
>                         argv[0], basename);
> -               exit(1);
> +               goto failure;
>         }
>
>         num_mods = argc - optind;
> -       mods =
> -           (sepol_module_package_t **) malloc(sizeof(sepol_module_package_t *)
> -                                              * num_mods);
> +       mods = calloc(num_mods, sizeof(sepol_module_package_t *));
>         if (!mods) {
>                 fprintf(stderr, "%s:  Out of memory\n", argv[0]);
> -               exit(1);
> +               goto failure;
>         }
> -       memset(mods, 0, sizeof(sepol_module_package_t *) * num_mods);
>
>         for (i = 0; optind < argc; optind++, i++) {
>                 mods[i] = load_module(argv[optind]);
> @@ -138,39 +132,56 @@ int main(int argc, char **argv)
>                         fprintf(stderr,
>                                 "%s:  Could not load module from file %s\n",
>                                 argv[0], argv[optind]);
> -                       exit(1);
> +                       goto failure;
>                 }
>         }
>
>         if (sepol_link_packages(NULL, base, mods, num_mods, verbose)) {
>                 fprintf(stderr, "%s:  Error while linking packages\n", argv[0]);
> -               exit(1);
> +               goto failure;
>         }
>
>         if (outname) {
> -               outfile = fopen(outname, "w");
> +               FILE *outfile = fopen(outname, "w");
>                 if (!outfile) {
> -                       perror(outname);
> -                       exit(1);
> +                       fprintf(stderr, "%s:  Could not open output file %s:  %s\n",
> +                               progname, outname, strerror(errno));
> +                       goto failure;
>                 }
>
>                 if (sepol_policy_file_create(&pf)) {
>                         fprintf(stderr, "%s:  Out of memory\n", argv[0]);
> -                       exit(1);
> +                       fclose(outfile);
> +                       goto failure;
>                 }
>                 sepol_policy_file_set_fp(pf, outfile);
>                 if (sepol_module_package_write(base, pf)) {
>                         fprintf(stderr, "%s:  Error writing linked package.\n",
>                                 argv[0]);
> -                       exit(1);
> +                       sepol_policy_file_free(pf);
> +                       fclose(outfile);
> +                       goto failure;
>                 }
>                 sepol_policy_file_free(pf);
> -               fclose(outfile);
> +
> +               if (fclose(outfile)) {
> +                       fprintf(stderr, "%s:  Error closing linked package:  %s\n",
> +                               argv[0], strerror(errno));
> +                       goto failure;
> +               }
>         }
>
> -       sepol_module_package_free(base);
> +       ret = EXIT_SUCCESS;
> +
> +cleanup:
>         for (i = 0; i < num_mods; i++)
>                 sepol_module_package_free(mods[i]);
>         free(mods);
> -       exit(0);
> +       sepol_module_package_free(base);
> +
> +       return ret;
> +
> +failure:
> +       ret = EXIT_FAILURE;
> +       goto cleanup;

Same comment as for patch 1 here as well.

Thanks,
Jim

>  }
> --
> 2.40.1
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC PATCH 3/4] semodule_package: update
  2023-05-12 11:07 ` [RFC PATCH 3/4] semodule_package: update Christian Göttsche
@ 2023-06-09 19:32   ` James Carter
  2023-06-09 19:37     ` James Carter
  0 siblings, 1 reply; 9+ messages in thread
From: James Carter @ 2023-06-09 19:32 UTC (permalink / raw)
  To: Christian Göttsche; +Cc: selinux

On Fri, May 12, 2023 at 7:25 AM Christian Göttsche
<cgzones@googlemail.com> wrote:
>
> Drop unnecessary declarations.
> Add missing error messages.
> More strict command line argument parsing.
> Check closing file for incomplete write.
> Rework resource cleanup, so that all files and allocated memory are
> released in all branches, useful to minimize reports while debugging
> libsepol under valgrind(8) or sanitizers.
>
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
> ---
>  .../semodule_package/semodule_package.c       | 203 +++++++++++-------
>  1 file changed, 125 insertions(+), 78 deletions(-)
>
> diff --git a/semodule-utils/semodule_package/semodule_package.c b/semodule-utils/semodule_package/semodule_package.c
> index bc8584b5..7485e254 100644
> --- a/semodule-utils/semodule_package/semodule_package.c
> +++ b/semodule-utils/semodule_package/semodule_package.c
> @@ -19,8 +19,7 @@
>  #include <fcntl.h>
>  #include <errno.h>
>
> -char *progname = NULL;
> -extern char *optarg;
> +static const char *progname = NULL;
>
>  static __attribute__((__noreturn__)) void usage(const char *prog)
>  {
> @@ -37,26 +36,6 @@ static __attribute__((__noreturn__)) void usage(const char *prog)
>         exit(1);

Same comment as patch 1 about "exit(1)".

>  }
>
> -static int file_to_policy_file(const char *filename, struct sepol_policy_file **pf,
> -                              const char *mode)
> -{
> -       FILE *f;
> -
> -       if (sepol_policy_file_create(pf)) {
> -               fprintf(stderr, "%s:  Out of memory\n", progname);
> -               return -1;
> -       }
> -
> -       f = fopen(filename, mode);
> -       if (!f) {
> -               fprintf(stderr, "%s:  Could not open file %s:  %s\n", progname,
> -                       strerror(errno), filename);
> -               return -1;
> -       }
> -       sepol_policy_file_set_fp(*pf, f);
> -       return 0;
> -}
> -
>  static int file_to_data(const char *path, char **data, size_t * len)
>  {
>         int fd;
> @@ -94,17 +73,18 @@ static int file_to_data(const char *path, char **data, size_t * len)
>
>  int main(int argc, char **argv)
>  {
> -       struct sepol_module_package *pkg;
> -       struct sepol_policy_file *mod, *out;
> +       struct sepol_module_package *pkg = NULL;
> +       struct sepol_policy_file *mod = NULL, *out = NULL;
> +       FILE *fp = NULL;
>         char *module = NULL, *file_contexts = NULL, *seusers =
>             NULL, *user_extra = NULL;
>         char *fcdata = NULL, *outfile = NULL, *seusersdata =
>             NULL, *user_extradata = NULL;
>         char *netfilter_contexts = NULL, *ncdata = NULL;
>         size_t fclen = 0, seuserslen = 0, user_extralen = 0, nclen = 0;
> -       int i;
> +       int i, ret;
>
> -       static struct option opts[] = {
> +       const struct option opts[] = {
>                 {"module", required_argument, NULL, 'm'},
>                 {"fc", required_argument, NULL, 'f'},
>                 {"seuser", required_argument, NULL, 's'},
> @@ -115,11 +95,12 @@ int main(int argc, char **argv)
>                 {NULL, 0, NULL, 0}
>         };
>
> +       progname = argv[0];
> +
>         while ((i = getopt_long(argc, argv, "m:f:s:u:o:n:h", opts, NULL)) != -1) {
>                 switch (i) {
>                 case 'h':
> -                       usage(argv[0]);
> -                       exit(0);
> +                       usage(progname);
>                 case 'm':
>                         if (module) {
>                                 fprintf(stderr,
> @@ -127,8 +108,10 @@ int main(int argc, char **argv)
>                                 exit(1);
>                         }
>                         module = strdup(optarg);
> -                       if (!module)
> +                       if (!module) {
> +                               fprintf(stderr, "%s:  Out of memory\n", progname);
>                                 exit(1);
> +                       }
>                         break;
>                 case 'f':
>                         if (file_contexts) {
> @@ -137,8 +120,10 @@ int main(int argc, char **argv)
>                                 exit(1);
>                         }
>                         file_contexts = strdup(optarg);
> -                       if (!file_contexts)
> +                       if (!file_contexts) {
> +                               fprintf(stderr, "%s:  Out of memory\n", progname);
>                                 exit(1);
> +                       }
>                         break;
>                 case 'o':
>                         if (outfile) {
> @@ -147,8 +132,10 @@ int main(int argc, char **argv)
>                                 exit(1);
>                         }
>                         outfile = strdup(optarg);
> -                       if (!outfile)
> +                       if (!outfile) {
> +                               fprintf(stderr, "%s:  Out of memory\n", progname);
>                                 exit(1);
> +                       }
>                         break;
>                 case 's':
>                         if (seusers) {
> @@ -157,8 +144,10 @@ int main(int argc, char **argv)
>                                 exit(1);
>                         }
>                         seusers = strdup(optarg);
> -                       if (!seusers)
> +                       if (!seusers) {
> +                               fprintf(stderr, "%s:  Out of memory\n", progname);
>                                 exit(1);
> +                       }
>                         break;
>                 case 'u':
>                         if (user_extra) {
> @@ -167,8 +156,10 @@ int main(int argc, char **argv)
>                                 exit(1);
>                         }
>                         user_extra = strdup(optarg);
> -                       if (!user_extra)
> +                       if (!user_extra) {
> +                               fprintf(stderr, "%s:  Out of memory\n", progname);
>                                 exit(1);
> +                       }
>                         break;
>                 case 'n':
>                         if (netfilter_contexts) {
> @@ -177,88 +168,144 @@ int main(int argc, char **argv)
>                                 exit(1);
>                         }
>                         netfilter_contexts = strdup(optarg);
> -                       if (!netfilter_contexts)
> +                       if (!netfilter_contexts) {
> +                               fprintf(stderr, "%s:  Out of memory\n", progname);
>                                 exit(1);
> +                       }
>                         break;
> +               case '?':
> +                       usage(progname);

What is this option "?" for?

> +               default:
> +                       fprintf(stderr, "%s:  Unsupported getopt return code: %d\n", progname, i);
> +                       usage(progname);

Why not just default to calling usage() without the error message?

>                 }
>         }
>
> -       progname = argv[0];
> -
> -       if (!module || !outfile) {
> -               usage(argv[0]);
> -               exit(0);
> +       if (optind < argc) {
> +               fprintf(stderr, "%s:  Superfluous command line arguments: ", progname);
> +                while (optind < argc)
> +                        fprintf(stderr, "%s ", argv[optind++]);
> +               fprintf(stderr, "\n");
> +               usage(progname);
>         }
>
> -       if (file_contexts) {
> -               if (file_to_data(file_contexts, &fcdata, &fclen))
> -                       exit(1);
> -       }
> +       if (!module || !outfile)
> +               usage(progname);
>
> -       if (seusers) {
> -               if (file_to_data(seusers, &seusersdata, &seuserslen))
> -                       exit(1);
> -       }
> +       if (file_contexts && file_to_data(file_contexts, &fcdata, &fclen))
> +               goto failure;
>
> -       if (user_extra) {
> -               if (file_to_data(user_extra, &user_extradata, &user_extralen))
> -                       exit(1);
> -       }
> +       if (seusers && file_to_data(seusers, &seusersdata, &seuserslen))
> +               goto failure;
> +
> +       if (user_extra && file_to_data(user_extra, &user_extradata, &user_extralen))
> +               goto failure;
>
> -       if (netfilter_contexts) {
> -               if (file_to_data(netfilter_contexts, &ncdata, &nclen))
> -                       exit(1);
> +       if (netfilter_contexts && file_to_data(netfilter_contexts, &ncdata, &nclen))
> +               goto failure;
> +
> +       if (sepol_policy_file_create(&mod)) {
> +               fprintf(stderr, "%s:  Out of memory\n", progname);
> +               goto failure;
>         }
>
> -       if (file_to_policy_file(module, &mod, "r"))
> -               exit(1);
> +       fp = fopen(module, "r");
> +       if (!fp) {
> +               fprintf(stderr, "%s:  Could not open file %s:  %s\n", progname,
> +                       module, strerror(errno));
> +               goto failure;
> +       }
> +       sepol_policy_file_set_fp(mod, fp);
>
>         if (sepol_module_package_create(&pkg)) {
>                 fprintf(stderr, "%s:  Out of memory\n", argv[0]);
> -               exit(1);
> +               goto failure;
>         }
>
>         if (sepol_policydb_read(sepol_module_package_get_policy(pkg), mod)) {
>                 fprintf(stderr,
>                         "%s:  Error while reading policy module from %s\n",
>                         argv[0], module);
> -               exit(1);
> +               goto failure;
>         }
>
> -       if (fclen)
> -               sepol_module_package_set_file_contexts(pkg, fcdata, fclen);
> +       fclose(fp);
> +       fp = NULL;
>
> -       if (seuserslen)
> -               sepol_module_package_set_seusers(pkg, seusersdata, seuserslen);
> +       if (fclen && sepol_module_package_set_file_contexts(pkg, fcdata, fclen)) {
> +               fprintf(stderr, "%s:  Error while setting file contexts\n", progname);
> +               goto failure;
> +       }
>
> -       if (user_extra)
> -               sepol_module_package_set_user_extra(pkg, user_extradata,
> -                                                   user_extralen);
> +       if (seuserslen && sepol_module_package_set_seusers(pkg, seusersdata, seuserslen)) {
> +               fprintf(stderr, "%s:  Error while setting seusers\n", progname);
> +               goto failure;
> +       }
>
> -       if (nclen)
> -               sepol_module_package_set_netfilter_contexts(pkg, ncdata, nclen);
> +       if (user_extra && sepol_module_package_set_user_extra(pkg, user_extradata, user_extralen)) {
> +               fprintf(stderr, "%s:  Error while setting extra users\n", progname);
> +               goto failure;
> +       }
> +
> +       if (nclen && sepol_module_package_set_netfilter_contexts(pkg, ncdata, nclen)) {
> +               fprintf(stderr, "%s:  Error while setting netfilter contexts\n", progname);
> +               goto failure;
> +       }
> +
> +       if (sepol_policy_file_create(&out)) {
> +               fprintf(stderr, "%s:  Out of memory\n", progname);
> +               goto failure;
> +       }
>
> -       if (file_to_policy_file(outfile, &out, "w"))
> -               exit(1);
> +       fp = fopen(outfile, "w");
> +       if (!fp) {
> +               fprintf(stderr, "%s:  Could not open file %s:  %s\n", progname,
> +                       outfile, strerror(errno));
> +               goto failure;
> +       }
> +       sepol_policy_file_set_fp(out, fp);
>
>         if (sepol_module_package_write(pkg, out)) {
>                 fprintf(stderr,
>                         "%s:  Error while writing module package to %s\n",
>                         argv[0], argv[1]);
> -               exit(1);
> +               goto failure;
>         }
>
> -       if (fclen)
> -               munmap(fcdata, fclen);
> +       ret = fclose(fp);
> +       fp = NULL;
> +       if (ret) {
> +               fprintf(stderr, "%s:  Could not close file %s:  %s\n", progname,
> +                       outfile, strerror(errno));
> +               goto failure;
> +       }
> +
> +       ret = EXIT_SUCCESS;
> +
> +cleanup:
> +       if (fp)
> +               fclose(fp);
> +       sepol_policy_file_free(out);
>         if (nclen)
>                 munmap(ncdata, nclen);
> -       sepol_policy_file_free(mod);
> -       sepol_policy_file_free(out);
> +       if (user_extradata)
> +               munmap(user_extradata, user_extralen);
> +       if (seuserslen)
> +               munmap(seusersdata, seuserslen);
> +       if (fclen)
> +               munmap(fcdata, fclen);
>         sepol_module_package_free(pkg);
> -       free(file_contexts);
> +       sepol_policy_file_free(mod);
> +       free(netfilter_contexts);
> +       free(user_extra);
> +       free(seusers);
>         free(outfile);
> +       free(file_contexts);
>         free(module);
> -       free(seusers);
> -       free(user_extra);
> -       exit(0);
> +
> +       return ret;
> +
> +failure:
> +       ret = EXIT_FAILURE;
> +       goto cleanup;

Same as the comment for patch 1 about preferring "return ret" to be at the end.

Thanks,
Jim

>  }
> --
> 2.40.1
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC PATCH 4/4] semodule_unpackage: update
  2023-05-12 11:07 ` [RFC PATCH 4/4] semodule_unpackage: update Christian Göttsche
@ 2023-06-09 19:36   ` James Carter
  0 siblings, 0 replies; 9+ messages in thread
From: James Carter @ 2023-06-09 19:36 UTC (permalink / raw)
  To: Christian Göttsche; +Cc: selinux

On Fri, May 12, 2023 at 7:22 AM Christian Göttsche
<cgzones@googlemail.com> wrote:
>
> Drop unnecessary declarations.
> Check closing file for incomplete write.
> Rework resource cleanup, so that all files and allocated memory are
> released in all branches, useful to minimize reports while debugging
> libsepol under valgrind(8) or sanitizers.
>
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
> ---
>  .../semodule_package/semodule_unpackage.c     | 122 +++++++++++-------
>  1 file changed, 75 insertions(+), 47 deletions(-)
>
> diff --git a/semodule-utils/semodule_package/semodule_unpackage.c b/semodule-utils/semodule_package/semodule_unpackage.c
> index b8c4fbce..21c97953 100644
> --- a/semodule-utils/semodule_package/semodule_unpackage.c
> +++ b/semodule-utils/semodule_package/semodule_unpackage.c
> @@ -11,8 +11,7 @@
>  #include <fcntl.h>
>  #include <errno.h>
>
> -char *progname = NULL;
> -extern char *optarg;
> +static const char *progname = NULL;

Can we get rid of the global here and just pass in the program name?

>
>  static __attribute__((__noreturn__)) void usage(void)
>  {
> @@ -20,84 +19,113 @@ static __attribute__((__noreturn__)) void usage(void)
>         exit(1);

Same comment as patch 1 about removing "exit(1)"

>  }
>
> -static int file_to_policy_file(const char *filename, struct sepol_policy_file **pf, const char *mode)
> -{
> -       FILE *f;
> -
> -       if (sepol_policy_file_create(pf)) {
> -               fprintf(stderr, "%s:  Out of memory\n", progname);
> -               return -1;
> -       }
> -
> -       f = fopen(filename, mode);
> -       if (!f) {
> -               fprintf(stderr, "%s:  Could not open file %s:  %s\n", progname, strerror(errno), filename);
> -               return -1;
> -       }
> -       sepol_policy_file_set_fp(*pf, f);
> -       return 0;
> -}
> -
>  int main(int argc, char **argv)
>  {
> -       struct sepol_module_package *pkg;
> -       struct sepol_policy_file *in, *out;
> -       FILE *fp;
> +       struct sepol_module_package *pkg = NULL;
> +       struct sepol_policy_file *in = NULL, *out = NULL;
> +       FILE *fp = NULL;
>         size_t len;
> -       char *ppfile, *modfile, *fcfile = NULL, *fcdata;
> +       const char *ppfile, *modfile, *fcfile = NULL, *fcdata;
> +       int ret;
>
>         progname = argv[0];
>
> -       if (argc < 3) {
> +       if (argc < 3)
>                 usage();
> -               exit(1);
> -       }
>
>         ppfile = argv[1];
>         modfile = argv[2];
>         if (argc >= 4)
>                 fcfile = argv[3];
>
> -       if (file_to_policy_file(ppfile, &in, "r"))
> -               exit(1);
> -
>         if (sepol_module_package_create(&pkg)) {
> -                fprintf(stderr, "%s:  Out of memory\n", progname);
> -                exit(1);
> +               fprintf(stderr, "%s:  Out of memory\n", progname);
> +               goto failure;
> +       }
> +
> +       if (sepol_policy_file_create(&in)) {
> +               fprintf(stderr, "%s:  Out of memory\n", progname);
> +               goto failure;
>         }
>
> +       fp = fopen(ppfile, "r");
> +       if (!fp) {
> +               fprintf(stderr, "%s:  Could not open file %s:  %s\n", progname, ppfile, strerror(errno));
> +               goto failure;
> +       }
> +       sepol_policy_file_set_fp(in, fp);
> +
>         if (sepol_module_package_read(pkg, in, 0) == -1) {
> -                fprintf(stderr, "%s:  Error while reading policy module from %s\n",
> +               fprintf(stderr, "%s:  Error while reading policy module from %s\n",
>                         progname, ppfile);
> -                exit(1);
> +               goto failure;
>         }
>
> -       if (file_to_policy_file(modfile, &out, "w"))
> -               exit(1);
> +       sepol_policy_file_free(in);
> +       in = NULL;
> +       fclose(fp);
> +       fp = NULL;
>
> -        if (sepol_policydb_write(sepol_module_package_get_policy(pkg), out)) {
> -                fprintf(stderr, "%s:  Error while writing module to %s\n", progname, modfile);
> -                exit(1);
> -        }
> +       if (sepol_policy_file_create(&out)) {
> +               fprintf(stderr, "%s:  Out of memory\n", progname);
> +               goto failure;
> +       }
> +
> +       fp = fopen(modfile, "w");
> +       if (!fp) {
> +               fprintf(stderr, "%s:  Could not open file %s:  %s\n", progname, modfile, strerror(errno));
> +               goto failure;
> +       }
> +       sepol_policy_file_set_fp(out, fp);
> +
> +       if (sepol_policydb_write(sepol_module_package_get_policy(pkg), out)) {
> +               fprintf(stderr, "%s:  Error while writing module to %s\n", progname, modfile);
> +               goto failure;
> +       }
> +
> +       ret = fclose(fp);
> +       fp = NULL;
> +       if (ret) {
> +               fprintf(stderr, "%s:  Error while closing file %s:  %s\n", progname, modfile, strerror(errno));
> +               goto failure;
> +       }
>
> -       sepol_policy_file_free(in);
>         sepol_policy_file_free(out);
> +       out = NULL;
>
>         len = sepol_module_package_get_file_contexts_len(pkg);
>         if (fcfile && len) {
>                 fp = fopen(fcfile, "w");
>                 if (!fp) {
> -                       fprintf(stderr, "%s:  Could not open file %s:  %s\n", progname, strerror(errno), fcfile);
> -                       exit(1);
> +                       fprintf(stderr, "%s:  Could not open file %s:  %s\n", progname, fcfile, strerror(errno));
> +                       goto failure;
>                 }
>                 fcdata = sepol_module_package_get_file_contexts(pkg);
>                 if (fwrite(fcdata, 1, len, fp) != len) {
> -                       fprintf(stderr, "%s:  Could not write file %s:  %s\n", progname, strerror(errno), fcfile);
> -                       exit(1);
> +                       fprintf(stderr, "%s:  Could not write file %s:  %s\n", progname, fcfile, strerror(errno));
> +                       goto failure;
> +               }
> +
> +               ret = fclose(fp);
> +               fp = NULL;
> +               if (ret) {
> +                       fprintf(stderr, "%s:  Could not close file %s:  %s\n", progname, fcfile, strerror(errno));
> +                       goto failure;
>                 }
> -               fclose(fp);
>         }
>
> +       ret = EXIT_SUCCESS;
> +
> +cleanup:
> +       if (fp)
> +               fclose(fp);
> +       sepol_policy_file_free(out);
>         sepol_module_package_free(pkg);
> -       exit(0);
> +       sepol_policy_file_free(in);
> +
> +       return ret;
> +
> +failure:
> +       ret = EXIT_FAILURE;
> +       goto cleanup;

Same comment as patch 1 about ending with "return ret".

Thanks,
Jim

>  }
> --
> 2.40.1
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC PATCH 3/4] semodule_package: update
  2023-06-09 19:32   ` James Carter
@ 2023-06-09 19:37     ` James Carter
  0 siblings, 0 replies; 9+ messages in thread
From: James Carter @ 2023-06-09 19:37 UTC (permalink / raw)
  To: Christian Göttsche; +Cc: selinux

On Fri, Jun 9, 2023 at 3:32 PM James Carter <jwcart2@gmail.com> wrote:
>
> On Fri, May 12, 2023 at 7:25 AM Christian Göttsche
> <cgzones@googlemail.com> wrote:
> >
> > Drop unnecessary declarations.
> > Add missing error messages.
> > More strict command line argument parsing.
> > Check closing file for incomplete write.
> > Rework resource cleanup, so that all files and allocated memory are
> > released in all branches, useful to minimize reports while debugging
> > libsepol under valgrind(8) or sanitizers.
> >
> > Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
> > ---
> >  .../semodule_package/semodule_package.c       | 203 +++++++++++-------
> >  1 file changed, 125 insertions(+), 78 deletions(-)
> >
> > diff --git a/semodule-utils/semodule_package/semodule_package.c b/semodule-utils/semodule_package/semodule_package.c
> > index bc8584b5..7485e254 100644
> > --- a/semodule-utils/semodule_package/semodule_package.c
> > +++ b/semodule-utils/semodule_package/semodule_package.c
> > @@ -19,8 +19,7 @@
> >  #include <fcntl.h>
> >  #include <errno.h>
> >
> > -char *progname = NULL;
> > -extern char *optarg;
> > +static const char *progname = NULL;

I forgot to ask if this global can be removed as well.

Thanks,
Jim

> >
> >  static __attribute__((__noreturn__)) void usage(const char *prog)
> >  {
> > @@ -37,26 +36,6 @@ static __attribute__((__noreturn__)) void usage(const char *prog)
> >         exit(1);
>
> Same comment as patch 1 about "exit(1)".
>
> >  }
> >
> > -static int file_to_policy_file(const char *filename, struct sepol_policy_file **pf,
> > -                              const char *mode)
> > -{
> > -       FILE *f;
> > -
> > -       if (sepol_policy_file_create(pf)) {
> > -               fprintf(stderr, "%s:  Out of memory\n", progname);
> > -               return -1;
> > -       }
> > -
> > -       f = fopen(filename, mode);
> > -       if (!f) {
> > -               fprintf(stderr, "%s:  Could not open file %s:  %s\n", progname,
> > -                       strerror(errno), filename);
> > -               return -1;
> > -       }
> > -       sepol_policy_file_set_fp(*pf, f);
> > -       return 0;
> > -}
> > -
> >  static int file_to_data(const char *path, char **data, size_t * len)
> >  {
> >         int fd;
> > @@ -94,17 +73,18 @@ static int file_to_data(const char *path, char **data, size_t * len)
> >
> >  int main(int argc, char **argv)
> >  {
> > -       struct sepol_module_package *pkg;
> > -       struct sepol_policy_file *mod, *out;
> > +       struct sepol_module_package *pkg = NULL;
> > +       struct sepol_policy_file *mod = NULL, *out = NULL;
> > +       FILE *fp = NULL;
> >         char *module = NULL, *file_contexts = NULL, *seusers =
> >             NULL, *user_extra = NULL;
> >         char *fcdata = NULL, *outfile = NULL, *seusersdata =
> >             NULL, *user_extradata = NULL;
> >         char *netfilter_contexts = NULL, *ncdata = NULL;
> >         size_t fclen = 0, seuserslen = 0, user_extralen = 0, nclen = 0;
> > -       int i;
> > +       int i, ret;
> >
> > -       static struct option opts[] = {
> > +       const struct option opts[] = {
> >                 {"module", required_argument, NULL, 'm'},
> >                 {"fc", required_argument, NULL, 'f'},
> >                 {"seuser", required_argument, NULL, 's'},
> > @@ -115,11 +95,12 @@ int main(int argc, char **argv)
> >                 {NULL, 0, NULL, 0}
> >         };
> >
> > +       progname = argv[0];
> > +
> >         while ((i = getopt_long(argc, argv, "m:f:s:u:o:n:h", opts, NULL)) != -1) {
> >                 switch (i) {
> >                 case 'h':
> > -                       usage(argv[0]);
> > -                       exit(0);
> > +                       usage(progname);
> >                 case 'm':
> >                         if (module) {
> >                                 fprintf(stderr,
> > @@ -127,8 +108,10 @@ int main(int argc, char **argv)
> >                                 exit(1);
> >                         }
> >                         module = strdup(optarg);
> > -                       if (!module)
> > +                       if (!module) {
> > +                               fprintf(stderr, "%s:  Out of memory\n", progname);
> >                                 exit(1);
> > +                       }
> >                         break;
> >                 case 'f':
> >                         if (file_contexts) {
> > @@ -137,8 +120,10 @@ int main(int argc, char **argv)
> >                                 exit(1);
> >                         }
> >                         file_contexts = strdup(optarg);
> > -                       if (!file_contexts)
> > +                       if (!file_contexts) {
> > +                               fprintf(stderr, "%s:  Out of memory\n", progname);
> >                                 exit(1);
> > +                       }
> >                         break;
> >                 case 'o':
> >                         if (outfile) {
> > @@ -147,8 +132,10 @@ int main(int argc, char **argv)
> >                                 exit(1);
> >                         }
> >                         outfile = strdup(optarg);
> > -                       if (!outfile)
> > +                       if (!outfile) {
> > +                               fprintf(stderr, "%s:  Out of memory\n", progname);
> >                                 exit(1);
> > +                       }
> >                         break;
> >                 case 's':
> >                         if (seusers) {
> > @@ -157,8 +144,10 @@ int main(int argc, char **argv)
> >                                 exit(1);
> >                         }
> >                         seusers = strdup(optarg);
> > -                       if (!seusers)
> > +                       if (!seusers) {
> > +                               fprintf(stderr, "%s:  Out of memory\n", progname);
> >                                 exit(1);
> > +                       }
> >                         break;
> >                 case 'u':
> >                         if (user_extra) {
> > @@ -167,8 +156,10 @@ int main(int argc, char **argv)
> >                                 exit(1);
> >                         }
> >                         user_extra = strdup(optarg);
> > -                       if (!user_extra)
> > +                       if (!user_extra) {
> > +                               fprintf(stderr, "%s:  Out of memory\n", progname);
> >                                 exit(1);
> > +                       }
> >                         break;
> >                 case 'n':
> >                         if (netfilter_contexts) {
> > @@ -177,88 +168,144 @@ int main(int argc, char **argv)
> >                                 exit(1);
> >                         }
> >                         netfilter_contexts = strdup(optarg);
> > -                       if (!netfilter_contexts)
> > +                       if (!netfilter_contexts) {
> > +                               fprintf(stderr, "%s:  Out of memory\n", progname);
> >                                 exit(1);
> > +                       }
> >                         break;
> > +               case '?':
> > +                       usage(progname);
>
> What is this option "?" for?
>
> > +               default:
> > +                       fprintf(stderr, "%s:  Unsupported getopt return code: %d\n", progname, i);
> > +                       usage(progname);
>
> Why not just default to calling usage() without the error message?
>
> >                 }
> >         }
> >
> > -       progname = argv[0];
> > -
> > -       if (!module || !outfile) {
> > -               usage(argv[0]);
> > -               exit(0);
> > +       if (optind < argc) {
> > +               fprintf(stderr, "%s:  Superfluous command line arguments: ", progname);
> > +                while (optind < argc)
> > +                        fprintf(stderr, "%s ", argv[optind++]);
> > +               fprintf(stderr, "\n");
> > +               usage(progname);
> >         }
> >
> > -       if (file_contexts) {
> > -               if (file_to_data(file_contexts, &fcdata, &fclen))
> > -                       exit(1);
> > -       }
> > +       if (!module || !outfile)
> > +               usage(progname);
> >
> > -       if (seusers) {
> > -               if (file_to_data(seusers, &seusersdata, &seuserslen))
> > -                       exit(1);
> > -       }
> > +       if (file_contexts && file_to_data(file_contexts, &fcdata, &fclen))
> > +               goto failure;
> >
> > -       if (user_extra) {
> > -               if (file_to_data(user_extra, &user_extradata, &user_extralen))
> > -                       exit(1);
> > -       }
> > +       if (seusers && file_to_data(seusers, &seusersdata, &seuserslen))
> > +               goto failure;
> > +
> > +       if (user_extra && file_to_data(user_extra, &user_extradata, &user_extralen))
> > +               goto failure;
> >
> > -       if (netfilter_contexts) {
> > -               if (file_to_data(netfilter_contexts, &ncdata, &nclen))
> > -                       exit(1);
> > +       if (netfilter_contexts && file_to_data(netfilter_contexts, &ncdata, &nclen))
> > +               goto failure;
> > +
> > +       if (sepol_policy_file_create(&mod)) {
> > +               fprintf(stderr, "%s:  Out of memory\n", progname);
> > +               goto failure;
> >         }
> >
> > -       if (file_to_policy_file(module, &mod, "r"))
> > -               exit(1);
> > +       fp = fopen(module, "r");
> > +       if (!fp) {
> > +               fprintf(stderr, "%s:  Could not open file %s:  %s\n", progname,
> > +                       module, strerror(errno));
> > +               goto failure;
> > +       }
> > +       sepol_policy_file_set_fp(mod, fp);
> >
> >         if (sepol_module_package_create(&pkg)) {
> >                 fprintf(stderr, "%s:  Out of memory\n", argv[0]);
> > -               exit(1);
> > +               goto failure;
> >         }
> >
> >         if (sepol_policydb_read(sepol_module_package_get_policy(pkg), mod)) {
> >                 fprintf(stderr,
> >                         "%s:  Error while reading policy module from %s\n",
> >                         argv[0], module);
> > -               exit(1);
> > +               goto failure;
> >         }
> >
> > -       if (fclen)
> > -               sepol_module_package_set_file_contexts(pkg, fcdata, fclen);
> > +       fclose(fp);
> > +       fp = NULL;
> >
> > -       if (seuserslen)
> > -               sepol_module_package_set_seusers(pkg, seusersdata, seuserslen);
> > +       if (fclen && sepol_module_package_set_file_contexts(pkg, fcdata, fclen)) {
> > +               fprintf(stderr, "%s:  Error while setting file contexts\n", progname);
> > +               goto failure;
> > +       }
> >
> > -       if (user_extra)
> > -               sepol_module_package_set_user_extra(pkg, user_extradata,
> > -                                                   user_extralen);
> > +       if (seuserslen && sepol_module_package_set_seusers(pkg, seusersdata, seuserslen)) {
> > +               fprintf(stderr, "%s:  Error while setting seusers\n", progname);
> > +               goto failure;
> > +       }
> >
> > -       if (nclen)
> > -               sepol_module_package_set_netfilter_contexts(pkg, ncdata, nclen);
> > +       if (user_extra && sepol_module_package_set_user_extra(pkg, user_extradata, user_extralen)) {
> > +               fprintf(stderr, "%s:  Error while setting extra users\n", progname);
> > +               goto failure;
> > +       }
> > +
> > +       if (nclen && sepol_module_package_set_netfilter_contexts(pkg, ncdata, nclen)) {
> > +               fprintf(stderr, "%s:  Error while setting netfilter contexts\n", progname);
> > +               goto failure;
> > +       }
> > +
> > +       if (sepol_policy_file_create(&out)) {
> > +               fprintf(stderr, "%s:  Out of memory\n", progname);
> > +               goto failure;
> > +       }
> >
> > -       if (file_to_policy_file(outfile, &out, "w"))
> > -               exit(1);
> > +       fp = fopen(outfile, "w");
> > +       if (!fp) {
> > +               fprintf(stderr, "%s:  Could not open file %s:  %s\n", progname,
> > +                       outfile, strerror(errno));
> > +               goto failure;
> > +       }
> > +       sepol_policy_file_set_fp(out, fp);
> >
> >         if (sepol_module_package_write(pkg, out)) {
> >                 fprintf(stderr,
> >                         "%s:  Error while writing module package to %s\n",
> >                         argv[0], argv[1]);
> > -               exit(1);
> > +               goto failure;
> >         }
> >
> > -       if (fclen)
> > -               munmap(fcdata, fclen);
> > +       ret = fclose(fp);
> > +       fp = NULL;
> > +       if (ret) {
> > +               fprintf(stderr, "%s:  Could not close file %s:  %s\n", progname,
> > +                       outfile, strerror(errno));
> > +               goto failure;
> > +       }
> > +
> > +       ret = EXIT_SUCCESS;
> > +
> > +cleanup:
> > +       if (fp)
> > +               fclose(fp);
> > +       sepol_policy_file_free(out);
> >         if (nclen)
> >                 munmap(ncdata, nclen);
> > -       sepol_policy_file_free(mod);
> > -       sepol_policy_file_free(out);
> > +       if (user_extradata)
> > +               munmap(user_extradata, user_extralen);
> > +       if (seuserslen)
> > +               munmap(seusersdata, seuserslen);
> > +       if (fclen)
> > +               munmap(fcdata, fclen);
> >         sepol_module_package_free(pkg);
> > -       free(file_contexts);
> > +       sepol_policy_file_free(mod);
> > +       free(netfilter_contexts);
> > +       free(user_extra);
> > +       free(seusers);
> >         free(outfile);
> > +       free(file_contexts);
> >         free(module);
> > -       free(seusers);
> > -       free(user_extra);
> > -       exit(0);
> > +
> > +       return ret;
> > +
> > +failure:
> > +       ret = EXIT_FAILURE;
> > +       goto cleanup;
>
> Same as the comment for patch 1 about preferring "return ret" to be at the end.
>
> Thanks,
> Jim
>
> >  }
> > --
> > 2.40.1
> >

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2023-06-09 19:37 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-12 11:07 [RFC PATCH 1/4] semodule_expand: update Christian Göttsche
2023-05-12 11:07 ` [RFC PATCH 2/4] semodule_link: update Christian Göttsche
2023-06-09 19:27   ` James Carter
2023-05-12 11:07 ` [RFC PATCH 3/4] semodule_package: update Christian Göttsche
2023-06-09 19:32   ` James Carter
2023-06-09 19:37     ` James Carter
2023-05-12 11:07 ` [RFC PATCH 4/4] semodule_unpackage: update Christian Göttsche
2023-06-09 19:36   ` James Carter
2023-06-09 19:25 ` [RFC PATCH 1/4] semodule_expand: update James Carter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).