checkmodule: add support for specifying module policy version
Currently checkpolicy can produce binary policies for earlier policy versions
to provide support for building policies on one machine and loading/analyzing
them on another machine with an earlier version of the kernel or libsepol,
respectively. However, checkmodule was lacking this capability.
This commit adds an identical `-c` flag that can be passed to checkmodule that
will build a modular policy file of the specified version.
Signed-off-by: Gary Tierney <[email protected]>
diff --git a/checkpolicy/checkmodule.8 b/checkpolicy/checkmodule.8
index cf76591..e55582f 100644
--- a/checkpolicy/checkmodule.8
+++ b/checkpolicy/checkmodule.8
@@ -38,7 +38,7 @@
Enable the MLS/MCS support when checking and compiling the policy module.
.TP
.B \-V,\-\-version
- Show policy versions created by this program. Note that you cannot currently build older versions.
+Show policy versions created by this program.
.TP
.B \-o,\-\-output filename
Write a binary policy module file to the specified filename.
@@ -47,6 +47,9 @@
.TP
.B \-U,\-\-handle-unknown <action>
Specify how the kernel should handle unknown classes or permissions (deny, allow or reject).
+.TP
+.B \-c policyvers
+Specify the policy version, defaults to the latest.
.SH EXAMPLE
.nf
diff --git a/checkpolicy/checkmodule.c b/checkpolicy/checkmodule.c
index 8edc1f8..c9efaf8 100644
--- a/checkpolicy/checkmodule.c
+++ b/checkpolicy/checkmodule.c
@@ -142,6 +142,8 @@
printf(" -m build a policy module instead of a base module\n");
printf(" -M enable MLS policy\n");
printf(" -o FILE write module to FILE (else just check syntax)\n");
+ printf(" -c VERSION build a policy module targeting a modular policy version (%d-%d)\n",
+ MOD_POLICYDB_VERSION_MIN, MOD_POLICYDB_VERSION_MAX);
exit(1);
}
@@ -163,7 +165,7 @@
{NULL, 0, NULL, 0}
};
- while ((ch = getopt_long(argc, argv, "ho:bVU:mMC", long_options, NULL)) != -1) {
+ while ((ch = getopt_long(argc, argv, "ho:bVU:mMCc:", long_options, NULL)) != -1) {
switch (ch) {
case 'h':
usage(argv[0]);
@@ -194,7 +196,6 @@
usage(argv[0]);
case 'm':
policy_type = POLICY_MOD;
- policyvers = MOD_POLICYDB_VERSION_MAX;
break;
case 'M':
mlspol = 1;
@@ -202,6 +203,29 @@
case 'C':
cil = 1;
break;
+ case 'c': {
+ long int n;
+ errno = 0;
+ n = strtol(optarg, NULL, 10);
+ if (errno) {
+ fprintf(stderr,
+ "Invalid policyvers specified: %s\n",
+ optarg);
+ usage(argv[0]);
+ }
+
+ if (n < MOD_POLICYDB_VERSION_MIN
+ || n > MOD_POLICYDB_VERSION_MAX) {
+ fprintf(stderr,
+ "policyvers value %ld not in range %d-%d\n",
+ n, MOD_POLICYDB_VERSION_MIN,
+ MOD_POLICYDB_VERSION_MAX);
+ usage(argv[0]);
+ }
+
+ policyvers = n;
+ break;
+ }
default:
usage(argv[0]);
}