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

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