Blame SOURCES/0046-semodule-add-command-line-option-to-detect-module-ch.patch

61b209
From e3fc737e43561ecadcb977ce4c9a1db44be636ae Mon Sep 17 00:00:00 2001
61b209
From: Ondrej Mosnacek <omosnace@redhat.com>
61b209
Date: Thu, 3 Feb 2022 17:53:27 +0100
61b209
Subject: [PATCH] semodule: add command-line option to detect module changes
61b209
61b209
Add a new command-line option "--rebuild-if-modules-changed" to control
61b209
the newly introduced check_ext_changes libsemanage flag.
61b209
61b209
For example, running `semodule --rebuild-if-modules-changed` will ensure
61b209
that any externally added/removed modules (e.g. by an RPM transaction)
61b209
are reflected in the compiled policy, while skipping the most expensive
61b209
part of the rebuild if no module change was deteceted since the last
61b209
libsemanage transaction.
61b209
61b209
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
61b209
---
61b209
 policycoreutils/semodule/semodule.8 |  7 +++++++
61b209
 policycoreutils/semodule/semodule.c | 32 ++++++++++++++++++++++-------
61b209
 2 files changed, 32 insertions(+), 7 deletions(-)
61b209
61b209
diff --git a/policycoreutils/semodule/semodule.8 b/policycoreutils/semodule/semodule.8
61b209
index 3a2fb21c..d1735d21 100644
61b209
--- a/policycoreutils/semodule/semodule.8
61b209
+++ b/policycoreutils/semodule/semodule.8
61b209
@@ -23,6 +23,13 @@ force a reload of policy
61b209
 .B \-B, \-\-build
61b209
 force a rebuild of policy (also reloads unless \-n is used)
61b209
 .TP
61b209
+.B \-\-rebuild-if-modules-changed
61b209
+Force a rebuild of the policy if any changes to module content are detected
61b209
+(by comparing with checksum from the last transaction).  One can use this
61b209
+instead of \-B to ensure that any changes to the module store done by an
61b209
+external tool (e.g. a package manager) are applied, while automatically
61b209
+skipping the rebuild if there are no new changes.
61b209
+.TP
61b209
 .B \-D, \-\-disable_dontaudit
61b209
 Temporarily remove dontaudits from policy.  Reverts whenever policy is rebuilt
61b209
 .TP
61b209
diff --git a/policycoreutils/semodule/semodule.c b/policycoreutils/semodule/semodule.c
61b209
index 243b1add..22a42a75 100644
61b209
--- a/policycoreutils/semodule/semodule.c
61b209
+++ b/policycoreutils/semodule/semodule.c
61b209
@@ -46,6 +46,7 @@ static int verbose;
61b209
 static int reload;
61b209
 static int no_reload;
61b209
 static int build;
61b209
+static int check_ext_changes;
61b209
 static int disable_dontaudit;
61b209
 static int preserve_tunables;
61b209
 static int ignore_module_cache;
61b209
@@ -148,6 +149,9 @@ static void usage(char *progname)
61b209
 	printf("  -c, --cil extract module as cil. This only affects module extraction.\n");
61b209
 	printf("  -H, --hll extract module as hll. This only affects module extraction.\n");
61b209
 	printf("  -m, --checksum   print module checksum (SHA256).\n");
61b209
+	printf("      --rebuild-if-modules-changed\n"
61b209
+	       "                   force policy rebuild if module content changed since\n"
61b209
+	       "                   last rebuild (based on checksum)\n");
61b209
 }
61b209
 
61b209
 /* Sets the global mode variable to new_mode, but only if no other
61b209
@@ -179,6 +183,7 @@ static void set_mode(enum client_modes new_mode, char *arg)
61b209
 static void parse_command_line(int argc, char **argv)
61b209
 {
61b209
 	static struct option opts[] = {
61b209
+		{"rebuild-if-modules-changed", 0, NULL, '\0'},
61b209
 		{"store", required_argument, NULL, 's'},
61b209
 		{"base", required_argument, NULL, 'b'},
61b209
 		{"help", 0, NULL, 'h'},
61b209
@@ -206,15 +211,26 @@ static void parse_command_line(int argc, char **argv)
61b209
 	};
61b209
 	int extract_selected = 0;
61b209
 	int cil_hll_set = 0;
61b209
-	int i;
61b209
+	int i, longind;
61b209
 	verbose = 0;
61b209
 	reload = 0;
61b209
 	no_reload = 0;
61b209
+	check_ext_changes = 0;
61b209
 	priority = 400;
61b209
 	while ((i =
61b209
-		getopt_long(argc, argv, "s:b:hi:l::vr:u:RnNBDCPX:e:d:p:S:E:cHm", opts,
61b209
-			    NULL)) != -1) {
61b209
+		getopt_long(argc, argv, "s:b:hi:l::vr:u:RnNBDCPX:e:d:p:S:E:cHm",
61b209
+			    opts, &longind)) != -1) {
61b209
 		switch (i) {
61b209
+		case '\0':
61b209
+			switch(longind) {
61b209
+			case 0: /* --rebuild-if-modules-changed */
61b209
+				check_ext_changes = 1;
61b209
+				break;
61b209
+			default:
61b209
+				usage(argv[0]);
61b209
+				exit(1);
61b209
+			}
61b209
+			break;
61b209
 		case 'b':
61b209
 			fprintf(stderr, "The --base option is deprecated. Use --install instead.\n");
61b209
 			set_mode(INSTALL_M, optarg);
61b209
@@ -299,13 +315,13 @@ static void parse_command_line(int argc, char **argv)
61b209
 			}
61b209
 		}
61b209
 	}
61b209
-	if ((build || reload) && num_commands) {
61b209
+	if ((build || reload || check_ext_changes) && num_commands) {
61b209
 		fprintf(stderr,
61b209
 			"build or reload should not be used with other commands\n");
61b209
 		usage(argv[0]);
61b209
 		exit(1);
61b209
 	}
61b209
-	if (num_commands == 0 && reload == 0 && build == 0) {
61b209
+	if (num_commands == 0 && reload == 0 && build == 0 && check_ext_changes == 0) {
61b209
 		fprintf(stderr, "At least one mode must be specified.\n");
61b209
 		usage(argv[0]);
61b209
 		exit(1);
61b209
@@ -392,7 +408,7 @@ int main(int argc, char *argv[])
61b209
 	}
61b209
 	parse_command_line(argc, argv);
61b209
 
61b209
-	if (build)
61b209
+	if (build || check_ext_changes)
61b209
 		commit = 1;
61b209
 
61b209
 	sh = semanage_handle_create();
61b209
@@ -431,7 +447,7 @@ int main(int argc, char *argv[])
61b209
 		}
61b209
 	}
61b209
 
61b209
-	if (build) {
61b209
+	if (build || check_ext_changes) {
61b209
 		if ((result = semanage_begin_transaction(sh)) < 0) {
61b209
 			fprintf(stderr, "%s:  Could not begin transaction:  %s\n",
61b209
 				argv[0], errno ? strerror(errno) : "");
61b209
@@ -805,6 +821,8 @@ cleanup_disable:
61b209
 			semanage_set_reload(sh, 0);
61b209
 		if (build)
61b209
 			semanage_set_rebuild(sh, 1);
61b209
+		if (check_ext_changes)
61b209
+			semanage_set_check_ext_changes(sh, 1);
61b209
 		if (disable_dontaudit)
61b209
 			semanage_set_disable_dontaudit(sh, 1);
61b209
 		else if (build)
61b209
-- 
61b209
2.30.2
61b209