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

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