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

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