selinux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/3] checkpolicy: add option to skip checking neverallow rules
@ 2023-03-31 17:34 Christian Göttsche
  2023-03-31 17:34 ` [PATCH 2/3] checkpolicy/dispol: add output functions Christian Göttsche
                   ` (4 more replies)
  0 siblings, 5 replies; 15+ messages in thread
From: Christian Göttsche @ 2023-03-31 17:34 UTC (permalink / raw)
  To: selinux

Add the command line argument `-N/--disable-neverallow`, similar to
secilc(8), to checkpolicy(8) and checkmodule(8) to skip the check of
neverallow rule violations.

This is mainly useful in development, e.g. to quickly add rules to a
policy without fulfilling all neverallow rules or build policies with
known violations.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 checkpolicy/checkmodule.8 |  5 ++++-
 checkpolicy/checkmodule.c | 13 +++++++++----
 checkpolicy/checkpolicy.8 |  5 ++++-
 checkpolicy/checkpolicy.c | 12 ++++++++----
 4 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/checkpolicy/checkmodule.8 b/checkpolicy/checkmodule.8
index 1061a6f2..ed9efd4c 100644
--- a/checkpolicy/checkmodule.8
+++ b/checkpolicy/checkmodule.8
@@ -3,7 +3,7 @@
 checkmodule \- SELinux policy module compiler
 .SH SYNOPSIS
 .B checkmodule
-.I "[\-h] [\-b] [\-c policy_version] [\-C] [\-E] [\-m] [\-M] [\-U handle_unknown] [\-V] [\-o output_file] [input_file]"
+.I "[\-h] [\-b] [\-c policy_version] [\-C] [\-E] [\-m] [\-M] [\-N] [\-U handle_unknown] [\-V] [\-o output_file] [input_file]"
 .SH "DESCRIPTION"
 This manual page describes the
 .BR checkmodule
@@ -43,6 +43,9 @@ Generate a non-base policy module.
 .B \-M,\-\-mls
 Enable the MLS/MCS support when checking and compiling the policy module.
 .TP
+.B \-N,\-\-disable-neverallow
+Do not check neverallow rules.
+.TP
 .B \-V,\-\-version
 Show policy versions created by this program.
 .TP
diff --git a/checkpolicy/checkmodule.c b/checkpolicy/checkmodule.c
index 3432608b..4f0d7bbe 100644
--- a/checkpolicy/checkmodule.c
+++ b/checkpolicy/checkmodule.c
@@ -123,7 +123,7 @@ static int write_binary_policy(policydb_t * p, FILE *outfp)
 
 static __attribute__((__noreturn__)) void usage(const char *progname)
 {
-	printf("usage:  %s [-h] [-V] [-b] [-C] [-E] [-U handle_unknown] [-m] [-M] [-o FILE] [-c VERSION] [INPUT]\n", progname);
+	printf("usage:  %s [-h] [-V] [-b] [-C] [-E] [-U handle_unknown] [-m] [-M] [-N] [-o FILE] [-c VERSION] [INPUT]\n", progname);
 	printf("Build base and policy modules.\n");
 	printf("Options:\n");
 	printf("  INPUT      build module from INPUT (else read from \"%s\")\n",
@@ -139,6 +139,7 @@ static __attribute__((__noreturn__)) void usage(const char *progname)
 	printf("               allow: Allow unknown kernel checks\n");
 	printf("  -m         build a policy module instead of a base module\n");
 	printf("  -M         enable MLS policy\n");
+	printf("  -N         do not check neverallow rules\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);
@@ -148,7 +149,7 @@ static __attribute__((__noreturn__)) void usage(const char *progname)
 int main(int argc, char **argv)
 {
 	const char *file = txtfile, *outfile = NULL;
-	unsigned int binary = 0, cil = 0;
+	unsigned int binary = 0, cil = 0, check_neverallow = 1;
 	int ch;
 	int show_version = 0;
 	policydb_t modpolicydb;
@@ -159,12 +160,13 @@ int main(int argc, char **argv)
 		{"version", no_argument, NULL, 'V'},
 		{"handle-unknown", required_argument, NULL, 'U'},
 		{"mls", no_argument, NULL, 'M'},
+		{"disable-neverallow", no_argument, NULL, 'N'},
 		{"cil", no_argument, NULL, 'C'},
 		{"werror", no_argument, NULL, 'E'},
 		{NULL, 0, NULL, 0}
 	};
 
-	while ((ch = getopt_long(argc, argv, "ho:bVEU:mMCc:", long_options, NULL)) != -1) {
+	while ((ch = getopt_long(argc, argv, "ho:bVEU:mMNCc:", long_options, NULL)) != -1) {
 		switch (ch) {
 		case 'h':
 			usage(argv[0]);
@@ -202,6 +204,9 @@ int main(int argc, char **argv)
 		case 'M':
 			mlspol = 1;
 			break;
+		case 'N':
+			check_neverallow = 0;
+			break;
 		case 'C':
 			cil = 1;
 			break;
@@ -317,7 +322,7 @@ int main(int argc, char **argv)
 			fprintf(stderr, "%s:  link modules failed\n", argv[0]);
 			exit(1);
 		}
-		if (expand_module(NULL, &modpolicydb, &kernpolicydb, 0, 1)) {
+		if (expand_module(NULL, &modpolicydb, &kernpolicydb, /*verbose=*/0, check_neverallow)) {
 			fprintf(stderr, "%s:  expand module failed\n", argv[0]);
 			exit(1);
 		}
diff --git a/checkpolicy/checkpolicy.8 b/checkpolicy/checkpolicy.8
index 2984c238..c66e084b 100644
--- a/checkpolicy/checkpolicy.8
+++ b/checkpolicy/checkpolicy.8
@@ -3,7 +3,7 @@
 checkpolicy \- SELinux policy compiler
 .SH SYNOPSIS
 .B checkpolicy
-.I "[\-b[F]] [\-C] [\-d] [\-U handle_unknown (allow,deny,reject)] [\-M] [\-c policyvers] [\-o output_file|\-] [\-S] [\-t target_platform (selinux,xen)] [\-O] [\-E] [\-V] [input_file]"
+.I "[\-b[F]] [\-C] [\-d] [\-U handle_unknown (allow,deny,reject)] [\-M] [\-N] [\-c policyvers] [\-o output_file|\-] [\-S] [\-t target_platform (selinux,xen)] [\-O] [\-E] [\-V] [input_file]"
 .br
 .SH "DESCRIPTION"
 This manual page describes the
@@ -38,6 +38,9 @@ Specify how the kernel should handle unknown classes or permissions (deny, allow
 .B \-M,\-\-mls
 Enable the MLS policy when checking and compiling the policy.
 .TP
+.B \-N,\-\-disable-neverallow
+Do not check neverallow rules.
+.TP
 .B \-c policyvers
 Specify the policy version, defaults to the latest.
 .TP
diff --git a/checkpolicy/checkpolicy.c b/checkpolicy/checkpolicy.c
index 48c31261..209f36d8 100644
--- a/checkpolicy/checkpolicy.c
+++ b/checkpolicy/checkpolicy.c
@@ -109,7 +109,7 @@ static __attribute__((__noreturn__)) void usage(const char *progname)
 {
 	printf
 	    ("usage:  %s [-b[F]] [-C] [-d] [-U handle_unknown (allow,deny,reject)] [-M] "
-	     "[-c policyvers (%d-%d)] [-o output_file|-] [-S] [-O] "
+	     "[-N] [-c policyvers (%d-%d)] [-o output_file|-] [-S] [-O] "
 	     "[-t target_platform (selinux,xen)] [-E] [-V] [input_file]\n",
 	     progname, POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX);
 	exit(1);
@@ -393,7 +393,7 @@ int main(int argc, char **argv)
 	size_t scontext_len, pathlen;
 	unsigned int i;
 	unsigned int protocol, port;
-	unsigned int binary = 0, debug = 0, sort = 0, cil = 0, conf = 0, optimize = 0;
+	unsigned int binary = 0, debug = 0, sort = 0, cil = 0, conf = 0, optimize = 0, check_neverallow = 1;
 	struct val_to_name v;
 	int ret, ch, fd, target = SEPOL_TARGET_SELINUX;
 	unsigned int nel, uret;
@@ -415,6 +415,7 @@ int main(int argc, char **argv)
 		{"version", no_argument, NULL, 'V'},
 		{"handle-unknown", required_argument, NULL, 'U'},
 		{"mls", no_argument, NULL, 'M'},
+		{"disable-neverallow", no_argument, NULL, 'N'},
 		{"cil", no_argument, NULL, 'C'},
 		{"conf",no_argument, NULL, 'F'},
 		{"sort", no_argument, NULL, 'S'},
@@ -424,7 +425,7 @@ int main(int argc, char **argv)
 		{NULL, 0, NULL, 0}
 	};
 
-	while ((ch = getopt_long(argc, argv, "o:t:dbU:MCFSVc:OEh", long_options, NULL)) != -1) {
+	while ((ch = getopt_long(argc, argv, "o:t:dbU:MNCFSVc:OEh", long_options, NULL)) != -1) {
 		switch (ch) {
 		case 'o':
 			outfile = optarg;
@@ -473,6 +474,9 @@ int main(int argc, char **argv)
 		case 'M':
 			mlspol = 1;
 			break;
+		case 'N':
+			check_neverallow = 0;
+			break;
 		case 'C':
 			cil = 1;
 			break;
@@ -630,7 +634,7 @@ int main(int argc, char **argv)
 				fprintf(stderr, "%s:  policydb_init failed\n", argv[0]);
 				exit(1);
 			}
-			if (expand_module(NULL, policydbp, &policydb, 0, 1)) {
+			if (expand_module(NULL, policydbp, &policydb, /*verbose=*/0, check_neverallow)) {
 				fprintf(stderr, "Error while expanding policy\n");
 				exit(1);
 			}
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 2/3] checkpolicy/dispol: add output functions
  2023-03-31 17:34 [PATCH 1/3] checkpolicy: add option to skip checking neverallow rules Christian Göttsche
@ 2023-03-31 17:34 ` Christian Göttsche
  2023-04-24 19:07   ` James Carter
  2023-03-31 17:34 ` [PATCH 3/3] checkpolicy/dismod: misc improvements Christian Göttsche
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 15+ messages in thread
From: Christian Göttsche @ 2023-03-31 17:34 UTC (permalink / raw)
  To: selinux

Add the ability to show booleans, classes, roles, types and type
attributes of policies.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
Almost all of the time seinfo(8) is a superior tool and several policy
details are still not supported, e.g. genfscon, ocontexts and class
constraints.
dispol was however useful in the past to analyze some OSS-Fuzz generated
policies, since seinfo trips over non-ascii identifier names.
---
 checkpolicy/test/dispol.c | 94 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 94 insertions(+)

diff --git a/checkpolicy/test/dispol.c b/checkpolicy/test/dispol.c
index 36a3362c..adac2370 100644
--- a/checkpolicy/test/dispol.c
+++ b/checkpolicy/test/dispol.c
@@ -274,6 +274,18 @@ static int change_bool(char *name, int state, policydb_t * p, FILE * fp)
 	return 0;
 }
 
+static int display_booleans(policydb_t * p, FILE *fp)
+{
+	uint32_t i;
+
+	fprintf(fp, "booleans:\n");
+	for (i = 0; i < p->p_bools.nprim; i++) {
+		fprintf(fp, "\t%s : %d\n", p->p_bool_val_to_name[i],
+			p->bool_val_to_struct[i]->state);
+	}
+	return 0;
+}
+
 static void display_policycaps(policydb_t * p, FILE * fp)
 {
 	ebitmap_node_t *node;
@@ -292,6 +304,20 @@ static void display_policycaps(policydb_t * p, FILE * fp)
 	}
 }
 
+static int display_classes(policydb_t * p, FILE *fp)
+{
+	uint32_t i;
+
+	fprintf(fp, "classes:\n");
+	for (i = 0; i < p->p_classes.nprim; i++) {
+		if (!p->p_class_val_to_name[i])
+			continue;
+
+		fprintf(fp, "\t%s\n", p->p_class_val_to_name[i]);
+	}
+	return 0;
+}
+
 static void display_id(policydb_t *p, FILE *fp, uint32_t symbol_type,
 		       uint32_t symbol_value, const char *prefix)
 {
@@ -312,6 +338,54 @@ static void display_permissive(policydb_t *p, FILE *fp)
 	}
 }
 
+static int display_roles(policydb_t * p, FILE *fp)
+{
+	uint32_t i;
+
+	fprintf(fp, "roles:\n");
+	for (i = 0; i < p->p_roles.nprim; i++) {
+		if (!p->p_role_val_to_name[i])
+			continue;
+
+		fprintf(fp, "\t%s\n", p->p_role_val_to_name[i]);
+	}
+	return 0;
+}
+
+static int display_types(policydb_t * p, FILE *fp)
+{
+	uint32_t i;
+
+	fprintf(fp, "types:\n");
+	for (i = 0; i < p->p_types.nprim; i++) {
+		if (!p->p_type_val_to_name[i])
+			continue;
+
+		if (p->type_val_to_struct[i]->flavor == TYPE_ATTRIB)
+			continue;
+
+		fprintf(fp, "\t%s\n", p->p_type_val_to_name[i]);
+	}
+	return 0;
+}
+
+static int display_attributes(policydb_t * p, FILE *fp)
+{
+	uint32_t i;
+
+	fprintf(fp, "attributes:\n");
+	for (i = 0; i < p->p_types.nprim; i++) {
+		if (!p->p_type_val_to_name[i])
+			continue;
+
+		if (p->type_val_to_struct[i]->flavor != TYPE_ATTRIB)
+			continue;
+
+		fprintf(fp, "\t%s\n", p->p_type_val_to_name[i]);
+	}
+	return 0;
+}
+
 static void display_role_trans(policydb_t *p, FILE *fp)
 {
 	role_trans_t *rt;
@@ -381,6 +455,11 @@ static int menu(void)
 	printf("8)  display role transitions\n");
 	printf("\n");
 	printf("c)  display policy capabilities\n");
+	printf("b)  display booleans\n");
+	printf("C)  display classes\n");
+	printf("r)  display roles\n");
+	printf("t)  display types\n");
+	printf("a)  display type attributes\n");
 	printf("p)  display the list of permissive types\n");
 	printf("u)  display unknown handling setting\n");
 	printf("F)  display filename_trans rules\n");
@@ -511,12 +590,27 @@ int main(int argc, char **argv)
 		case '8':
 			display_role_trans(&policydb, out_fp);
 			break;
+		case 'a':
+			display_attributes(&policydb, out_fp);
+			break;
+		case 'b':
+			display_booleans(&policydb, out_fp);
+			break;
 		case 'c':
 			display_policycaps(&policydb, out_fp);
 			break;
+		case 'C':
+			display_classes(&policydb, out_fp);
+			break;
 		case 'p':
 			display_permissive(&policydb, out_fp);
 			break;
+		case 'r':
+			display_roles(&policydb, out_fp);
+			break;
+		case 't':
+			display_types(&policydb, out_fp);
+			break;
 		case 'u':
 		case 'U':
 			display_handle_unknown(&policydb, out_fp);
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 3/3] checkpolicy/dismod: misc improvements
  2023-03-31 17:34 [PATCH 1/3] checkpolicy: add option to skip checking neverallow rules Christian Göttsche
  2023-03-31 17:34 ` [PATCH 2/3] checkpolicy/dispol: add output functions Christian Göttsche
@ 2023-03-31 17:34 ` Christian Göttsche
  2023-04-24 19:12   ` James Carter
  2023-05-12 10:08   ` [PATCH v2] " Christian Göttsche
  2023-03-31 17:58 ` [PATCH 1/3] checkpolicy: add option to skip checking neverallow rules Daniel Burgener
                   ` (2 subsequent siblings)
  4 siblings, 2 replies; 15+ messages in thread
From: Christian Göttsche @ 2023-03-31 17:34 UTC (permalink / raw)
  To: selinux

* fix minus self formatting in neverallow rules, avoiding `~ - self`

* show neverallow and neverallowxperm rules

* whitespace improvements in output
  - avoid duplicate whitespaces before permission list, since
    sepol_av_to_string() already adds a trailing one
  - avoid duplicate whitespace after wildcard type
  - unify indentation for xperm rules

* drop unused global variables

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 checkpolicy/test/dismod.c | 33 ++++++++++++++++++---------------
 1 file changed, 18 insertions(+), 15 deletions(-)

diff --git a/checkpolicy/test/dismod.c b/checkpolicy/test/dismod.c
index a2d74d42..ebc1eec3 100644
--- a/checkpolicy/test/dismod.c
+++ b/checkpolicy/test/dismod.c
@@ -54,11 +54,8 @@
 #define DISPLAY_AVBLOCK_FILENAME_TRANS	7
 
 static policydb_t policydb;
-extern unsigned int ss_initialized;
 
-int policyvers = MOD_POLICYDB_VERSION_BASE;
-
-static const char *symbol_labels[9] = {
+static const char *const symbol_labels[9] = {
 	"commons",
 	"classes", "roles  ", "types  ", "users  ", "bools  ",
 	"levels ", "cats   ", "attribs"
@@ -86,12 +83,12 @@ static void render_access_bitmap(ebitmap_t * map, uint32_t class,
 {
 	unsigned int i;
 	char *perm;
-	fprintf(fp, "{");
+	fprintf(fp, " {");
 	for (i = ebitmap_startbit(map); i < ebitmap_length(map); i++) {
 		if (ebitmap_get_bit(map, i)) {
 			perm = sepol_av_to_string(p, class, UINT32_C(1) << i);
 			if (perm)
-				fprintf(fp, " %s", perm);
+				fprintf(fp, "%s", perm);
 		}
 	}
 	fprintf(fp, " }");
@@ -117,7 +114,7 @@ static int display_type_set(type_set_t * set, uint32_t flags, policydb_t * polic
 	unsigned int i, num_types;
 
 	if (set->flags & TYPE_STAR) {
-		fprintf(fp, " * ");
+		fprintf(fp, " *");
 		return 0;
 	} else if (set->flags & TYPE_COMP) {
 		fprintf(fp, " ~");
@@ -149,7 +146,7 @@ static int display_type_set(type_set_t * set, uint32_t flags, policydb_t * polic
 	}
 
 	if (num_types > 1)
-		fprintf(fp, "{");
+		fprintf(fp, " {");
 
 	for (i = ebitmap_startbit(&set->types); i < ebitmap_length(&set->types);
 	     i++) {
@@ -170,7 +167,10 @@ static int display_type_set(type_set_t * set, uint32_t flags, policydb_t * polic
 	}
 
 	if (flags & RULE_NOTSELF) {
-		fprintf(fp, " -self");
+		if (set->flags & TYPE_COMP)
+			fprintf(fp, " self");
+		else
+			fprintf(fp, " -self");
 	}
 
 	if (num_types > 1)
@@ -234,6 +234,9 @@ static int display_avrule(avrule_t * avrule, policydb_t * policy,
 		if (avrule->specified & AVRULE_DONTAUDIT) {
 			fprintf(fp, "  dontaudit");
 		}
+		if (avrule->specified & AVRULE_NEVERALLOW) {
+			fprintf(fp, "  neverallow");
+		}
 	} else if (avrule->specified & AVRULE_TYPE) {
 		if (avrule->specified & AVRULE_TRANSITION) {
 			fprintf(fp, "  type_transition");
@@ -244,15 +247,15 @@ static int display_avrule(avrule_t * avrule, policydb_t * policy,
 		if (avrule->specified & AVRULE_CHANGE) {
 			fprintf(fp, "  type_change");
 		}
-	} else if (avrule->specified & AVRULE_NEVERALLOW) {
-		fprintf(fp, "  neverallow");
 	} else if (avrule->specified & AVRULE_XPERMS) {
 		if (avrule->specified & AVRULE_XPERMS_ALLOWED)
-			fprintf(fp, "allowxperm ");
+			fprintf(fp, "  allowxperm");
 		else if (avrule->specified & AVRULE_XPERMS_AUDITALLOW)
-			fprintf(fp, "auditallowxperm ");
+			fprintf(fp, "  auditallowxperm");
 		else if (avrule->specified & AVRULE_XPERMS_DONTAUDIT)
-			fprintf(fp, "dontauditxperm ");
+			fprintf(fp, "  dontauditxperm");
+		else if (avrule->specified & AVRULE_XPERMS_NEVERALLOW)
+			fprintf(fp, "  neverallowxperm");
 	} else {
 		fprintf(fp, "     ERROR: no valid rule type specified\n");
 		return -1;
@@ -560,7 +563,7 @@ static int display_scope_index(scope_index_t * indices, policydb_t * p,
 								     p, out_fp);
 					} else {
 						fprintf(out_fp,
-							"<no perms known>");
+							" <no perms known>");
 					}
 				}
 			}
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH 1/3] checkpolicy: add option to skip checking neverallow rules
  2023-03-31 17:34 [PATCH 1/3] checkpolicy: add option to skip checking neverallow rules Christian Göttsche
  2023-03-31 17:34 ` [PATCH 2/3] checkpolicy/dispol: add output functions Christian Göttsche
  2023-03-31 17:34 ` [PATCH 3/3] checkpolicy/dismod: misc improvements Christian Göttsche
@ 2023-03-31 17:58 ` Daniel Burgener
  2023-04-24 19:02   ` James Carter
  2023-04-24 19:06 ` James Carter
  2023-05-12  9:57 ` [PATCH v2] " Christian Göttsche
  4 siblings, 1 reply; 15+ messages in thread
From: Daniel Burgener @ 2023-03-31 17:58 UTC (permalink / raw)
  To: Christian Göttsche, selinux

On 3/31/2023 1:34 PM, Christian Göttsche wrote:
> Add the command line argument `-N/--disable-neverallow`, similar to
> secilc(8), to checkpolicy(8) and checkmodule(8) to skip the check of
> neverallow rule violations.
> 
> This is mainly useful in development, e.g. to quickly add rules to a
> policy without fulfilling all neverallow rules or build policies with
> known violations.

I think it might be helpful to print a quick warning along the lines of 
"Warning: neverallow checking is disabled, compiled policy may violate 
neverallow rules" or similar when the flag is set, just to double-check 
against accidental misuse.

-Daniel


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 1/3] checkpolicy: add option to skip checking neverallow rules
  2023-03-31 17:58 ` [PATCH 1/3] checkpolicy: add option to skip checking neverallow rules Daniel Burgener
@ 2023-04-24 19:02   ` James Carter
  0 siblings, 0 replies; 15+ messages in thread
From: James Carter @ 2023-04-24 19:02 UTC (permalink / raw)
  To: Daniel Burgener; +Cc: Christian Göttsche, selinux

On Fri, Mar 31, 2023 at 1:59 PM Daniel Burgener
<dburgener@linux.microsoft.com> wrote:
>
> On 3/31/2023 1:34 PM, Christian Göttsche wrote:
> > Add the command line argument `-N/--disable-neverallow`, similar to
> > secilc(8), to checkpolicy(8) and checkmodule(8) to skip the check of
> > neverallow rule violations.
> >
> > This is mainly useful in development, e.g. to quickly add rules to a
> > policy without fulfilling all neverallow rules or build policies with
> > known violations.
>
> I think it might be helpful to print a quick warning along the lines of
> "Warning: neverallow checking is disabled, compiled policy may violate
> neverallow rules" or similar when the flag is set, just to double-check
> against accidental misuse.
>
> -Daniel
>

I am ok without a warning. secilc doesn't warn when disabling neverallows.
Jim

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 1/3] checkpolicy: add option to skip checking neverallow rules
  2023-03-31 17:34 [PATCH 1/3] checkpolicy: add option to skip checking neverallow rules Christian Göttsche
                   ` (2 preceding siblings ...)
  2023-03-31 17:58 ` [PATCH 1/3] checkpolicy: add option to skip checking neverallow rules Daniel Burgener
@ 2023-04-24 19:06 ` James Carter
  2023-05-12  9:57 ` [PATCH v2] " Christian Göttsche
  4 siblings, 0 replies; 15+ messages in thread
From: James Carter @ 2023-04-24 19:06 UTC (permalink / raw)
  To: Christian Göttsche; +Cc: selinux

On Fri, Mar 31, 2023 at 1:37 PM Christian Göttsche
<cgzones@googlemail.com> wrote:
>
> Add the command line argument `-N/--disable-neverallow`, similar to
> secilc(8), to checkpolicy(8) and checkmodule(8) to skip the check of
> neverallow rule violations.
>
> This is mainly useful in development, e.g. to quickly add rules to a
> policy without fulfilling all neverallow rules or build policies with
> known violations.
>
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
> ---
>  checkpolicy/checkmodule.8 |  5 ++++-
>  checkpolicy/checkmodule.c | 13 +++++++++----
>  checkpolicy/checkpolicy.8 |  5 ++++-
>  checkpolicy/checkpolicy.c | 12 ++++++++----
>  4 files changed, 25 insertions(+), 10 deletions(-)
>
> diff --git a/checkpolicy/checkmodule.8 b/checkpolicy/checkmodule.8
> index 1061a6f2..ed9efd4c 100644
> --- a/checkpolicy/checkmodule.8
> +++ b/checkpolicy/checkmodule.8
> @@ -3,7 +3,7 @@
>  checkmodule \- SELinux policy module compiler
>  .SH SYNOPSIS
>  .B checkmodule
> -.I "[\-h] [\-b] [\-c policy_version] [\-C] [\-E] [\-m] [\-M] [\-U handle_unknown] [\-V] [\-o output_file] [input_file]"
> +.I "[\-h] [\-b] [\-c policy_version] [\-C] [\-E] [\-m] [\-M] [\-N] [\-U handle_unknown] [\-V] [\-o output_file] [input_file]"
>  .SH "DESCRIPTION"
>  This manual page describes the
>  .BR checkmodule
> @@ -43,6 +43,9 @@ Generate a non-base policy module.
>  .B \-M,\-\-mls
>  Enable the MLS/MCS support when checking and compiling the policy module.
>  .TP
> +.B \-N,\-\-disable-neverallow
> +Do not check neverallow rules.
> +.TP
>  .B \-V,\-\-version
>  Show policy versions created by this program.
>  .TP
> diff --git a/checkpolicy/checkmodule.c b/checkpolicy/checkmodule.c
> index 3432608b..4f0d7bbe 100644
> --- a/checkpolicy/checkmodule.c
> +++ b/checkpolicy/checkmodule.c
> @@ -123,7 +123,7 @@ static int write_binary_policy(policydb_t * p, FILE *outfp)
>
>  static __attribute__((__noreturn__)) void usage(const char *progname)
>  {
> -       printf("usage:  %s [-h] [-V] [-b] [-C] [-E] [-U handle_unknown] [-m] [-M] [-o FILE] [-c VERSION] [INPUT]\n", progname);
> +       printf("usage:  %s [-h] [-V] [-b] [-C] [-E] [-U handle_unknown] [-m] [-M] [-N] [-o FILE] [-c VERSION] [INPUT]\n", progname);
>         printf("Build base and policy modules.\n");
>         printf("Options:\n");
>         printf("  INPUT      build module from INPUT (else read from \"%s\")\n",
> @@ -139,6 +139,7 @@ static __attribute__((__noreturn__)) void usage(const char *progname)
>         printf("               allow: Allow unknown kernel checks\n");
>         printf("  -m         build a policy module instead of a base module\n");
>         printf("  -M         enable MLS policy\n");
> +       printf("  -N         do not check neverallow rules\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);
> @@ -148,7 +149,7 @@ static __attribute__((__noreturn__)) void usage(const char *progname)
>  int main(int argc, char **argv)
>  {
>         const char *file = txtfile, *outfile = NULL;
> -       unsigned int binary = 0, cil = 0;
> +       unsigned int binary = 0, cil = 0, check_neverallow = 1;

It is odd to use a variable named "check_neverallow" and to unset it
for the "-N" option. All other options set a variable when the option
is used.
I would rather call this "disable_neverallow" and set it with the
option. This is also what secilc does.

Thanks,
Jim

>         int ch;
>         int show_version = 0;
>         policydb_t modpolicydb;
> @@ -159,12 +160,13 @@ int main(int argc, char **argv)
>                 {"version", no_argument, NULL, 'V'},
>                 {"handle-unknown", required_argument, NULL, 'U'},
>                 {"mls", no_argument, NULL, 'M'},
> +               {"disable-neverallow", no_argument, NULL, 'N'},
>                 {"cil", no_argument, NULL, 'C'},
>                 {"werror", no_argument, NULL, 'E'},
>                 {NULL, 0, NULL, 0}
>         };
>
> -       while ((ch = getopt_long(argc, argv, "ho:bVEU:mMCc:", long_options, NULL)) != -1) {
> +       while ((ch = getopt_long(argc, argv, "ho:bVEU:mMNCc:", long_options, NULL)) != -1) {
>                 switch (ch) {
>                 case 'h':
>                         usage(argv[0]);
> @@ -202,6 +204,9 @@ int main(int argc, char **argv)
>                 case 'M':
>                         mlspol = 1;
>                         break;
> +               case 'N':
> +                       check_neverallow = 0;
> +                       break;
>                 case 'C':
>                         cil = 1;
>                         break;
> @@ -317,7 +322,7 @@ int main(int argc, char **argv)
>                         fprintf(stderr, "%s:  link modules failed\n", argv[0]);
>                         exit(1);
>                 }
> -               if (expand_module(NULL, &modpolicydb, &kernpolicydb, 0, 1)) {
> +               if (expand_module(NULL, &modpolicydb, &kernpolicydb, /*verbose=*/0, check_neverallow)) {
>                         fprintf(stderr, "%s:  expand module failed\n", argv[0]);
>                         exit(1);
>                 }
> diff --git a/checkpolicy/checkpolicy.8 b/checkpolicy/checkpolicy.8
> index 2984c238..c66e084b 100644
> --- a/checkpolicy/checkpolicy.8
> +++ b/checkpolicy/checkpolicy.8
> @@ -3,7 +3,7 @@
>  checkpolicy \- SELinux policy compiler
>  .SH SYNOPSIS
>  .B checkpolicy
> -.I "[\-b[F]] [\-C] [\-d] [\-U handle_unknown (allow,deny,reject)] [\-M] [\-c policyvers] [\-o output_file|\-] [\-S] [\-t target_platform (selinux,xen)] [\-O] [\-E] [\-V] [input_file]"
> +.I "[\-b[F]] [\-C] [\-d] [\-U handle_unknown (allow,deny,reject)] [\-M] [\-N] [\-c policyvers] [\-o output_file|\-] [\-S] [\-t target_platform (selinux,xen)] [\-O] [\-E] [\-V] [input_file]"
>  .br
>  .SH "DESCRIPTION"
>  This manual page describes the
> @@ -38,6 +38,9 @@ Specify how the kernel should handle unknown classes or permissions (deny, allow
>  .B \-M,\-\-mls
>  Enable the MLS policy when checking and compiling the policy.
>  .TP
> +.B \-N,\-\-disable-neverallow
> +Do not check neverallow rules.
> +.TP
>  .B \-c policyvers
>  Specify the policy version, defaults to the latest.
>  .TP
> diff --git a/checkpolicy/checkpolicy.c b/checkpolicy/checkpolicy.c
> index 48c31261..209f36d8 100644
> --- a/checkpolicy/checkpolicy.c
> +++ b/checkpolicy/checkpolicy.c
> @@ -109,7 +109,7 @@ static __attribute__((__noreturn__)) void usage(const char *progname)
>  {
>         printf
>             ("usage:  %s [-b[F]] [-C] [-d] [-U handle_unknown (allow,deny,reject)] [-M] "
> -            "[-c policyvers (%d-%d)] [-o output_file|-] [-S] [-O] "
> +            "[-N] [-c policyvers (%d-%d)] [-o output_file|-] [-S] [-O] "
>              "[-t target_platform (selinux,xen)] [-E] [-V] [input_file]\n",
>              progname, POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX);
>         exit(1);
> @@ -393,7 +393,7 @@ int main(int argc, char **argv)
>         size_t scontext_len, pathlen;
>         unsigned int i;
>         unsigned int protocol, port;
> -       unsigned int binary = 0, debug = 0, sort = 0, cil = 0, conf = 0, optimize = 0;
> +       unsigned int binary = 0, debug = 0, sort = 0, cil = 0, conf = 0, optimize = 0, check_neverallow = 1;
>         struct val_to_name v;
>         int ret, ch, fd, target = SEPOL_TARGET_SELINUX;
>         unsigned int nel, uret;
> @@ -415,6 +415,7 @@ int main(int argc, char **argv)
>                 {"version", no_argument, NULL, 'V'},
>                 {"handle-unknown", required_argument, NULL, 'U'},
>                 {"mls", no_argument, NULL, 'M'},
> +               {"disable-neverallow", no_argument, NULL, 'N'},
>                 {"cil", no_argument, NULL, 'C'},
>                 {"conf",no_argument, NULL, 'F'},
>                 {"sort", no_argument, NULL, 'S'},
> @@ -424,7 +425,7 @@ int main(int argc, char **argv)
>                 {NULL, 0, NULL, 0}
>         };
>
> -       while ((ch = getopt_long(argc, argv, "o:t:dbU:MCFSVc:OEh", long_options, NULL)) != -1) {
> +       while ((ch = getopt_long(argc, argv, "o:t:dbU:MNCFSVc:OEh", long_options, NULL)) != -1) {
>                 switch (ch) {
>                 case 'o':
>                         outfile = optarg;
> @@ -473,6 +474,9 @@ int main(int argc, char **argv)
>                 case 'M':
>                         mlspol = 1;
>                         break;
> +               case 'N':
> +                       check_neverallow = 0;
> +                       break;
>                 case 'C':
>                         cil = 1;
>                         break;
> @@ -630,7 +634,7 @@ int main(int argc, char **argv)
>                                 fprintf(stderr, "%s:  policydb_init failed\n", argv[0]);
>                                 exit(1);
>                         }
> -                       if (expand_module(NULL, policydbp, &policydb, 0, 1)) {
> +                       if (expand_module(NULL, policydbp, &policydb, /*verbose=*/0, check_neverallow)) {
>                                 fprintf(stderr, "Error while expanding policy\n");
>                                 exit(1);
>                         }
> --
> 2.40.0
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/3] checkpolicy/dispol: add output functions
  2023-03-31 17:34 ` [PATCH 2/3] checkpolicy/dispol: add output functions Christian Göttsche
@ 2023-04-24 19:07   ` James Carter
  2023-05-03 16:24     ` James Carter
  0 siblings, 1 reply; 15+ messages in thread
From: James Carter @ 2023-04-24 19:07 UTC (permalink / raw)
  To: Christian Göttsche; +Cc: selinux

On Fri, Mar 31, 2023 at 1:37 PM Christian Göttsche
<cgzones@googlemail.com> wrote:
>
> Add the ability to show booleans, classes, roles, types and type
> attributes of policies.
>
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>

Acked-by: James Carter <jwcart2@gmail.com>

> ---
> Almost all of the time seinfo(8) is a superior tool and several policy
> details are still not supported, e.g. genfscon, ocontexts and class
> constraints.
> dispol was however useful in the past to analyze some OSS-Fuzz generated
> policies, since seinfo trips over non-ascii identifier names.
> ---
>  checkpolicy/test/dispol.c | 94 +++++++++++++++++++++++++++++++++++++++
>  1 file changed, 94 insertions(+)
>
> diff --git a/checkpolicy/test/dispol.c b/checkpolicy/test/dispol.c
> index 36a3362c..adac2370 100644
> --- a/checkpolicy/test/dispol.c
> +++ b/checkpolicy/test/dispol.c
> @@ -274,6 +274,18 @@ static int change_bool(char *name, int state, policydb_t * p, FILE * fp)
>         return 0;
>  }
>
> +static int display_booleans(policydb_t * p, FILE *fp)
> +{
> +       uint32_t i;
> +
> +       fprintf(fp, "booleans:\n");
> +       for (i = 0; i < p->p_bools.nprim; i++) {
> +               fprintf(fp, "\t%s : %d\n", p->p_bool_val_to_name[i],
> +                       p->bool_val_to_struct[i]->state);
> +       }
> +       return 0;
> +}
> +
>  static void display_policycaps(policydb_t * p, FILE * fp)
>  {
>         ebitmap_node_t *node;
> @@ -292,6 +304,20 @@ static void display_policycaps(policydb_t * p, FILE * fp)
>         }
>  }
>
> +static int display_classes(policydb_t * p, FILE *fp)
> +{
> +       uint32_t i;
> +
> +       fprintf(fp, "classes:\n");
> +       for (i = 0; i < p->p_classes.nprim; i++) {
> +               if (!p->p_class_val_to_name[i])
> +                       continue;
> +
> +               fprintf(fp, "\t%s\n", p->p_class_val_to_name[i]);
> +       }
> +       return 0;
> +}
> +
>  static void display_id(policydb_t *p, FILE *fp, uint32_t symbol_type,
>                        uint32_t symbol_value, const char *prefix)
>  {
> @@ -312,6 +338,54 @@ static void display_permissive(policydb_t *p, FILE *fp)
>         }
>  }
>
> +static int display_roles(policydb_t * p, FILE *fp)
> +{
> +       uint32_t i;
> +
> +       fprintf(fp, "roles:\n");
> +       for (i = 0; i < p->p_roles.nprim; i++) {
> +               if (!p->p_role_val_to_name[i])
> +                       continue;
> +
> +               fprintf(fp, "\t%s\n", p->p_role_val_to_name[i]);
> +       }
> +       return 0;
> +}
> +
> +static int display_types(policydb_t * p, FILE *fp)
> +{
> +       uint32_t i;
> +
> +       fprintf(fp, "types:\n");
> +       for (i = 0; i < p->p_types.nprim; i++) {
> +               if (!p->p_type_val_to_name[i])
> +                       continue;
> +
> +               if (p->type_val_to_struct[i]->flavor == TYPE_ATTRIB)
> +                       continue;
> +
> +               fprintf(fp, "\t%s\n", p->p_type_val_to_name[i]);
> +       }
> +       return 0;
> +}
> +
> +static int display_attributes(policydb_t * p, FILE *fp)
> +{
> +       uint32_t i;
> +
> +       fprintf(fp, "attributes:\n");
> +       for (i = 0; i < p->p_types.nprim; i++) {
> +               if (!p->p_type_val_to_name[i])
> +                       continue;
> +
> +               if (p->type_val_to_struct[i]->flavor != TYPE_ATTRIB)
> +                       continue;
> +
> +               fprintf(fp, "\t%s\n", p->p_type_val_to_name[i]);
> +       }
> +       return 0;
> +}
> +
>  static void display_role_trans(policydb_t *p, FILE *fp)
>  {
>         role_trans_t *rt;
> @@ -381,6 +455,11 @@ static int menu(void)
>         printf("8)  display role transitions\n");
>         printf("\n");
>         printf("c)  display policy capabilities\n");
> +       printf("b)  display booleans\n");
> +       printf("C)  display classes\n");
> +       printf("r)  display roles\n");
> +       printf("t)  display types\n");
> +       printf("a)  display type attributes\n");
>         printf("p)  display the list of permissive types\n");
>         printf("u)  display unknown handling setting\n");
>         printf("F)  display filename_trans rules\n");
> @@ -511,12 +590,27 @@ int main(int argc, char **argv)
>                 case '8':
>                         display_role_trans(&policydb, out_fp);
>                         break;
> +               case 'a':
> +                       display_attributes(&policydb, out_fp);
> +                       break;
> +               case 'b':
> +                       display_booleans(&policydb, out_fp);
> +                       break;
>                 case 'c':
>                         display_policycaps(&policydb, out_fp);
>                         break;
> +               case 'C':
> +                       display_classes(&policydb, out_fp);
> +                       break;
>                 case 'p':
>                         display_permissive(&policydb, out_fp);
>                         break;
> +               case 'r':
> +                       display_roles(&policydb, out_fp);
> +                       break;
> +               case 't':
> +                       display_types(&policydb, out_fp);
> +                       break;
>                 case 'u':
>                 case 'U':
>                         display_handle_unknown(&policydb, out_fp);
> --
> 2.40.0
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 3/3] checkpolicy/dismod: misc improvements
  2023-03-31 17:34 ` [PATCH 3/3] checkpolicy/dismod: misc improvements Christian Göttsche
@ 2023-04-24 19:12   ` James Carter
  2023-05-12 10:08   ` [PATCH v2] " Christian Göttsche
  1 sibling, 0 replies; 15+ messages in thread
From: James Carter @ 2023-04-24 19:12 UTC (permalink / raw)
  To: Christian Göttsche; +Cc: selinux

On Fri, Mar 31, 2023 at 1:37 PM Christian Göttsche
<cgzones@googlemail.com> wrote:
>
> * fix minus self formatting in neverallow rules, avoiding `~ - self`
>
> * show neverallow and neverallowxperm rules
>
> * whitespace improvements in output
>   - avoid duplicate whitespaces before permission list, since
>     sepol_av_to_string() already adds a trailing one
>   - avoid duplicate whitespace after wildcard type
>   - unify indentation for xperm rules
>
> * drop unused global variables
>
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
> ---
>  checkpolicy/test/dismod.c | 33 ++++++++++++++++++---------------
>  1 file changed, 18 insertions(+), 15 deletions(-)
>
> diff --git a/checkpolicy/test/dismod.c b/checkpolicy/test/dismod.c
> index a2d74d42..ebc1eec3 100644
> --- a/checkpolicy/test/dismod.c
> +++ b/checkpolicy/test/dismod.c
> @@ -54,11 +54,8 @@
>  #define DISPLAY_AVBLOCK_FILENAME_TRANS 7
>
>  static policydb_t policydb;
> -extern unsigned int ss_initialized;
>
> -int policyvers = MOD_POLICYDB_VERSION_BASE;
> -
> -static const char *symbol_labels[9] = {
> +static const char *const symbol_labels[9] = {
>         "commons",
>         "classes", "roles  ", "types  ", "users  ", "bools  ",
>         "levels ", "cats   ", "attribs"
> @@ -86,12 +83,12 @@ static void render_access_bitmap(ebitmap_t * map, uint32_t class,
>  {
>         unsigned int i;
>         char *perm;
> -       fprintf(fp, "{");
> +       fprintf(fp, " {");
>         for (i = ebitmap_startbit(map); i < ebitmap_length(map); i++) {
>                 if (ebitmap_get_bit(map, i)) {
>                         perm = sepol_av_to_string(p, class, UINT32_C(1) << i);
>                         if (perm)
> -                               fprintf(fp, " %s", perm);
> +                               fprintf(fp, "%s", perm);
>                 }
>         }
>         fprintf(fp, " }");
> @@ -117,7 +114,7 @@ static int display_type_set(type_set_t * set, uint32_t flags, policydb_t * polic
>         unsigned int i, num_types;
>
>         if (set->flags & TYPE_STAR) {
> -               fprintf(fp, " * ");
> +               fprintf(fp, " *");
>                 return 0;
>         } else if (set->flags & TYPE_COMP) {
>                 fprintf(fp, " ~");
> @@ -149,7 +146,7 @@ static int display_type_set(type_set_t * set, uint32_t flags, policydb_t * polic
>         }
>
>         if (num_types > 1)
> -               fprintf(fp, "{");
> +               fprintf(fp, " {");
>

This causes a problem with a type set using "~". It gets displayed
with a space between the "~" and the "{".

Thanks,
Jim


>         for (i = ebitmap_startbit(&set->types); i < ebitmap_length(&set->types);
>              i++) {
> @@ -170,7 +167,10 @@ static int display_type_set(type_set_t * set, uint32_t flags, policydb_t * polic
>         }
>
>         if (flags & RULE_NOTSELF) {
> -               fprintf(fp, " -self");
> +               if (set->flags & TYPE_COMP)
> +                       fprintf(fp, " self");
> +               else
> +                       fprintf(fp, " -self");
>         }
>
>         if (num_types > 1)
> @@ -234,6 +234,9 @@ static int display_avrule(avrule_t * avrule, policydb_t * policy,
>                 if (avrule->specified & AVRULE_DONTAUDIT) {
>                         fprintf(fp, "  dontaudit");
>                 }
> +               if (avrule->specified & AVRULE_NEVERALLOW) {
> +                       fprintf(fp, "  neverallow");
> +               }
>         } else if (avrule->specified & AVRULE_TYPE) {
>                 if (avrule->specified & AVRULE_TRANSITION) {
>                         fprintf(fp, "  type_transition");
> @@ -244,15 +247,15 @@ static int display_avrule(avrule_t * avrule, policydb_t * policy,
>                 if (avrule->specified & AVRULE_CHANGE) {
>                         fprintf(fp, "  type_change");
>                 }
> -       } else if (avrule->specified & AVRULE_NEVERALLOW) {
> -               fprintf(fp, "  neverallow");
>         } else if (avrule->specified & AVRULE_XPERMS) {
>                 if (avrule->specified & AVRULE_XPERMS_ALLOWED)
> -                       fprintf(fp, "allowxperm ");
> +                       fprintf(fp, "  allowxperm");
>                 else if (avrule->specified & AVRULE_XPERMS_AUDITALLOW)
> -                       fprintf(fp, "auditallowxperm ");
> +                       fprintf(fp, "  auditallowxperm");
>                 else if (avrule->specified & AVRULE_XPERMS_DONTAUDIT)
> -                       fprintf(fp, "dontauditxperm ");
> +                       fprintf(fp, "  dontauditxperm");
> +               else if (avrule->specified & AVRULE_XPERMS_NEVERALLOW)
> +                       fprintf(fp, "  neverallowxperm");
>         } else {
>                 fprintf(fp, "     ERROR: no valid rule type specified\n");
>                 return -1;
> @@ -560,7 +563,7 @@ static int display_scope_index(scope_index_t * indices, policydb_t * p,
>                                                                      p, out_fp);
>                                         } else {
>                                                 fprintf(out_fp,
> -                                                       "<no perms known>");
> +                                                       " <no perms known>");
>                                         }
>                                 }
>                         }
> --
> 2.40.0
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/3] checkpolicy/dispol: add output functions
  2023-04-24 19:07   ` James Carter
@ 2023-05-03 16:24     ` James Carter
  0 siblings, 0 replies; 15+ messages in thread
From: James Carter @ 2023-05-03 16:24 UTC (permalink / raw)
  To: Christian Göttsche; +Cc: selinux

On Mon, Apr 24, 2023 at 3:07 PM James Carter <jwcart2@gmail.com> wrote:
>
> On Fri, Mar 31, 2023 at 1:37 PM Christian Göttsche
> <cgzones@googlemail.com> wrote:
> >
> > Add the ability to show booleans, classes, roles, types and type
> > attributes of policies.
> >
> > Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
>
> Acked-by: James Carter <jwcart2@gmail.com>
>

This patch has been merged since it was independent of the other two.
(The other two were not merged.)
Thanks,
Jim

> > ---
> > Almost all of the time seinfo(8) is a superior tool and several policy
> > details are still not supported, e.g. genfscon, ocontexts and class
> > constraints.
> > dispol was however useful in the past to analyze some OSS-Fuzz generated
> > policies, since seinfo trips over non-ascii identifier names.
> > ---
> >  checkpolicy/test/dispol.c | 94 +++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 94 insertions(+)
> >
> > diff --git a/checkpolicy/test/dispol.c b/checkpolicy/test/dispol.c
> > index 36a3362c..adac2370 100644
> > --- a/checkpolicy/test/dispol.c
> > +++ b/checkpolicy/test/dispol.c
> > @@ -274,6 +274,18 @@ static int change_bool(char *name, int state, policydb_t * p, FILE * fp)
> >         return 0;
> >  }
> >
> > +static int display_booleans(policydb_t * p, FILE *fp)
> > +{
> > +       uint32_t i;
> > +
> > +       fprintf(fp, "booleans:\n");
> > +       for (i = 0; i < p->p_bools.nprim; i++) {
> > +               fprintf(fp, "\t%s : %d\n", p->p_bool_val_to_name[i],
> > +                       p->bool_val_to_struct[i]->state);
> > +       }
> > +       return 0;
> > +}
> > +
> >  static void display_policycaps(policydb_t * p, FILE * fp)
> >  {
> >         ebitmap_node_t *node;
> > @@ -292,6 +304,20 @@ static void display_policycaps(policydb_t * p, FILE * fp)
> >         }
> >  }
> >
> > +static int display_classes(policydb_t * p, FILE *fp)
> > +{
> > +       uint32_t i;
> > +
> > +       fprintf(fp, "classes:\n");
> > +       for (i = 0; i < p->p_classes.nprim; i++) {
> > +               if (!p->p_class_val_to_name[i])
> > +                       continue;
> > +
> > +               fprintf(fp, "\t%s\n", p->p_class_val_to_name[i]);
> > +       }
> > +       return 0;
> > +}
> > +
> >  static void display_id(policydb_t *p, FILE *fp, uint32_t symbol_type,
> >                        uint32_t symbol_value, const char *prefix)
> >  {
> > @@ -312,6 +338,54 @@ static void display_permissive(policydb_t *p, FILE *fp)
> >         }
> >  }
> >
> > +static int display_roles(policydb_t * p, FILE *fp)
> > +{
> > +       uint32_t i;
> > +
> > +       fprintf(fp, "roles:\n");
> > +       for (i = 0; i < p->p_roles.nprim; i++) {
> > +               if (!p->p_role_val_to_name[i])
> > +                       continue;
> > +
> > +               fprintf(fp, "\t%s\n", p->p_role_val_to_name[i]);
> > +       }
> > +       return 0;
> > +}
> > +
> > +static int display_types(policydb_t * p, FILE *fp)
> > +{
> > +       uint32_t i;
> > +
> > +       fprintf(fp, "types:\n");
> > +       for (i = 0; i < p->p_types.nprim; i++) {
> > +               if (!p->p_type_val_to_name[i])
> > +                       continue;
> > +
> > +               if (p->type_val_to_struct[i]->flavor == TYPE_ATTRIB)
> > +                       continue;
> > +
> > +               fprintf(fp, "\t%s\n", p->p_type_val_to_name[i]);
> > +       }
> > +       return 0;
> > +}
> > +
> > +static int display_attributes(policydb_t * p, FILE *fp)
> > +{
> > +       uint32_t i;
> > +
> > +       fprintf(fp, "attributes:\n");
> > +       for (i = 0; i < p->p_types.nprim; i++) {
> > +               if (!p->p_type_val_to_name[i])
> > +                       continue;
> > +
> > +               if (p->type_val_to_struct[i]->flavor != TYPE_ATTRIB)
> > +                       continue;
> > +
> > +               fprintf(fp, "\t%s\n", p->p_type_val_to_name[i]);
> > +       }
> > +       return 0;
> > +}
> > +
> >  static void display_role_trans(policydb_t *p, FILE *fp)
> >  {
> >         role_trans_t *rt;
> > @@ -381,6 +455,11 @@ static int menu(void)
> >         printf("8)  display role transitions\n");
> >         printf("\n");
> >         printf("c)  display policy capabilities\n");
> > +       printf("b)  display booleans\n");
> > +       printf("C)  display classes\n");
> > +       printf("r)  display roles\n");
> > +       printf("t)  display types\n");
> > +       printf("a)  display type attributes\n");
> >         printf("p)  display the list of permissive types\n");
> >         printf("u)  display unknown handling setting\n");
> >         printf("F)  display filename_trans rules\n");
> > @@ -511,12 +590,27 @@ int main(int argc, char **argv)
> >                 case '8':
> >                         display_role_trans(&policydb, out_fp);
> >                         break;
> > +               case 'a':
> > +                       display_attributes(&policydb, out_fp);
> > +                       break;
> > +               case 'b':
> > +                       display_booleans(&policydb, out_fp);
> > +                       break;
> >                 case 'c':
> >                         display_policycaps(&policydb, out_fp);
> >                         break;
> > +               case 'C':
> > +                       display_classes(&policydb, out_fp);
> > +                       break;
> >                 case 'p':
> >                         display_permissive(&policydb, out_fp);
> >                         break;
> > +               case 'r':
> > +                       display_roles(&policydb, out_fp);
> > +                       break;
> > +               case 't':
> > +                       display_types(&policydb, out_fp);
> > +                       break;
> >                 case 'u':
> >                 case 'U':
> >                         display_handle_unknown(&policydb, out_fp);
> > --
> > 2.40.0
> >

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2] checkpolicy: add option to skip checking neverallow rules
  2023-03-31 17:34 [PATCH 1/3] checkpolicy: add option to skip checking neverallow rules Christian Göttsche
                   ` (3 preceding siblings ...)
  2023-04-24 19:06 ` James Carter
@ 2023-05-12  9:57 ` Christian Göttsche
  2023-06-08 20:59   ` James Carter
  4 siblings, 1 reply; 15+ messages in thread
From: Christian Göttsche @ 2023-05-12  9:57 UTC (permalink / raw)
  To: selinux

Add the command line argument `-N/--disable-neverallow`, similar to
secilc(8), to checkpolicy(8) and checkmodule(8) to skip the check of
neverallow rule violations.

This is mainly useful in development, e.g. to quickly add rules to a
policy without fulfilling all neverallow rules or build policies with
known violations.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
v2:
   invert variable logic from check_neverallow to disable_neverallow
---
 checkpolicy/checkmodule.8 |  5 ++++-
 checkpolicy/checkmodule.c | 13 +++++++++----
 checkpolicy/checkpolicy.8 |  5 ++++-
 checkpolicy/checkpolicy.c | 12 ++++++++----
 4 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/checkpolicy/checkmodule.8 b/checkpolicy/checkmodule.8
index 1061a6f2..ed9efd4c 100644
--- a/checkpolicy/checkmodule.8
+++ b/checkpolicy/checkmodule.8
@@ -3,7 +3,7 @@
 checkmodule \- SELinux policy module compiler
 .SH SYNOPSIS
 .B checkmodule
-.I "[\-h] [\-b] [\-c policy_version] [\-C] [\-E] [\-m] [\-M] [\-U handle_unknown] [\-V] [\-o output_file] [input_file]"
+.I "[\-h] [\-b] [\-c policy_version] [\-C] [\-E] [\-m] [\-M] [\-N] [\-U handle_unknown] [\-V] [\-o output_file] [input_file]"
 .SH "DESCRIPTION"
 This manual page describes the
 .BR checkmodule
@@ -43,6 +43,9 @@ Generate a non-base policy module.
 .B \-M,\-\-mls
 Enable the MLS/MCS support when checking and compiling the policy module.
 .TP
+.B \-N,\-\-disable-neverallow
+Do not check neverallow rules.
+.TP
 .B \-V,\-\-version
 Show policy versions created by this program.
 .TP
diff --git a/checkpolicy/checkmodule.c b/checkpolicy/checkmodule.c
index 3432608b..14e6c891 100644
--- a/checkpolicy/checkmodule.c
+++ b/checkpolicy/checkmodule.c
@@ -123,7 +123,7 @@ static int write_binary_policy(policydb_t * p, FILE *outfp)
 
 static __attribute__((__noreturn__)) void usage(const char *progname)
 {
-	printf("usage:  %s [-h] [-V] [-b] [-C] [-E] [-U handle_unknown] [-m] [-M] [-o FILE] [-c VERSION] [INPUT]\n", progname);
+	printf("usage:  %s [-h] [-V] [-b] [-C] [-E] [-U handle_unknown] [-m] [-M] [-N] [-o FILE] [-c VERSION] [INPUT]\n", progname);
 	printf("Build base and policy modules.\n");
 	printf("Options:\n");
 	printf("  INPUT      build module from INPUT (else read from \"%s\")\n",
@@ -139,6 +139,7 @@ static __attribute__((__noreturn__)) void usage(const char *progname)
 	printf("               allow: Allow unknown kernel checks\n");
 	printf("  -m         build a policy module instead of a base module\n");
 	printf("  -M         enable MLS policy\n");
+	printf("  -N         do not check neverallow rules\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);
@@ -148,7 +149,7 @@ static __attribute__((__noreturn__)) void usage(const char *progname)
 int main(int argc, char **argv)
 {
 	const char *file = txtfile, *outfile = NULL;
-	unsigned int binary = 0, cil = 0;
+	unsigned int binary = 0, cil = 0, disable_neverallow = 0;
 	int ch;
 	int show_version = 0;
 	policydb_t modpolicydb;
@@ -159,12 +160,13 @@ int main(int argc, char **argv)
 		{"version", no_argument, NULL, 'V'},
 		{"handle-unknown", required_argument, NULL, 'U'},
 		{"mls", no_argument, NULL, 'M'},
+		{"disable-neverallow", no_argument, NULL, 'N'},
 		{"cil", no_argument, NULL, 'C'},
 		{"werror", no_argument, NULL, 'E'},
 		{NULL, 0, NULL, 0}
 	};
 
-	while ((ch = getopt_long(argc, argv, "ho:bVEU:mMCc:", long_options, NULL)) != -1) {
+	while ((ch = getopt_long(argc, argv, "ho:bVEU:mMNCc:", long_options, NULL)) != -1) {
 		switch (ch) {
 		case 'h':
 			usage(argv[0]);
@@ -202,6 +204,9 @@ int main(int argc, char **argv)
 		case 'M':
 			mlspol = 1;
 			break;
+		case 'N':
+			disable_neverallow = 1;
+			break;
 		case 'C':
 			cil = 1;
 			break;
@@ -317,7 +322,7 @@ int main(int argc, char **argv)
 			fprintf(stderr, "%s:  link modules failed\n", argv[0]);
 			exit(1);
 		}
-		if (expand_module(NULL, &modpolicydb, &kernpolicydb, 0, 1)) {
+		if (expand_module(NULL, &modpolicydb, &kernpolicydb, /*verbose=*/0, !disable_neverallow)) {
 			fprintf(stderr, "%s:  expand module failed\n", argv[0]);
 			exit(1);
 		}
diff --git a/checkpolicy/checkpolicy.8 b/checkpolicy/checkpolicy.8
index 2984c238..c66e084b 100644
--- a/checkpolicy/checkpolicy.8
+++ b/checkpolicy/checkpolicy.8
@@ -3,7 +3,7 @@
 checkpolicy \- SELinux policy compiler
 .SH SYNOPSIS
 .B checkpolicy
-.I "[\-b[F]] [\-C] [\-d] [\-U handle_unknown (allow,deny,reject)] [\-M] [\-c policyvers] [\-o output_file|\-] [\-S] [\-t target_platform (selinux,xen)] [\-O] [\-E] [\-V] [input_file]"
+.I "[\-b[F]] [\-C] [\-d] [\-U handle_unknown (allow,deny,reject)] [\-M] [\-N] [\-c policyvers] [\-o output_file|\-] [\-S] [\-t target_platform (selinux,xen)] [\-O] [\-E] [\-V] [input_file]"
 .br
 .SH "DESCRIPTION"
 This manual page describes the
@@ -38,6 +38,9 @@ Specify how the kernel should handle unknown classes or permissions (deny, allow
 .B \-M,\-\-mls
 Enable the MLS policy when checking and compiling the policy.
 .TP
+.B \-N,\-\-disable-neverallow
+Do not check neverallow rules.
+.TP
 .B \-c policyvers
 Specify the policy version, defaults to the latest.
 .TP
diff --git a/checkpolicy/checkpolicy.c b/checkpolicy/checkpolicy.c
index 2485142d..623ba8b2 100644
--- a/checkpolicy/checkpolicy.c
+++ b/checkpolicy/checkpolicy.c
@@ -109,7 +109,7 @@ static __attribute__((__noreturn__)) void usage(const char *progname)
 {
 	printf
 	    ("usage:  %s [-b[F]] [-C] [-d] [-U handle_unknown (allow,deny,reject)] [-M] "
-	     "[-c policyvers (%d-%d)] [-o output_file|-] [-S] [-O] "
+	     "[-N] [-c policyvers (%d-%d)] [-o output_file|-] [-S] [-O] "
 	     "[-t target_platform (selinux,xen)] [-E] [-V] [input_file]\n",
 	     progname, POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX);
 	exit(1);
@@ -393,7 +393,7 @@ int main(int argc, char **argv)
 	size_t scontext_len, pathlen;
 	unsigned int i;
 	unsigned int protocol, port;
-	unsigned int binary = 0, debug = 0, sort = 0, cil = 0, conf = 0, optimize = 0;
+	unsigned int binary = 0, debug = 0, sort = 0, cil = 0, conf = 0, optimize = 0, disable_neverallow = 0;
 	struct val_to_name v;
 	int ret, ch, fd, target = SEPOL_TARGET_SELINUX;
 	unsigned int nel, uret;
@@ -415,6 +415,7 @@ int main(int argc, char **argv)
 		{"version", no_argument, NULL, 'V'},
 		{"handle-unknown", required_argument, NULL, 'U'},
 		{"mls", no_argument, NULL, 'M'},
+		{"disable-neverallow", no_argument, NULL, 'N'},
 		{"cil", no_argument, NULL, 'C'},
 		{"conf",no_argument, NULL, 'F'},
 		{"sort", no_argument, NULL, 'S'},
@@ -424,7 +425,7 @@ int main(int argc, char **argv)
 		{NULL, 0, NULL, 0}
 	};
 
-	while ((ch = getopt_long(argc, argv, "o:t:dbU:MCFSVc:OEh", long_options, NULL)) != -1) {
+	while ((ch = getopt_long(argc, argv, "o:t:dbU:MNCFSVc:OEh", long_options, NULL)) != -1) {
 		switch (ch) {
 		case 'o':
 			outfile = optarg;
@@ -473,6 +474,9 @@ int main(int argc, char **argv)
 		case 'M':
 			mlspol = 1;
 			break;
+		case 'N':
+			disable_neverallow = 1;
+			break;
 		case 'C':
 			cil = 1;
 			break;
@@ -630,7 +634,7 @@ int main(int argc, char **argv)
 				fprintf(stderr, "%s:  policydb_init failed\n", argv[0]);
 				exit(1);
 			}
-			if (expand_module(NULL, policydbp, &policydb, 0, 1)) {
+			if (expand_module(NULL, policydbp, &policydb, /*verbose=*/0, !disable_neverallow)) {
 				fprintf(stderr, "Error while expanding policy\n");
 				exit(1);
 			}
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2] checkpolicy/dismod: misc improvements
  2023-03-31 17:34 ` [PATCH 3/3] checkpolicy/dismod: misc improvements Christian Göttsche
  2023-04-24 19:12   ` James Carter
@ 2023-05-12 10:08   ` Christian Göttsche
  2023-06-08 21:00     ` James Carter
  1 sibling, 1 reply; 15+ messages in thread
From: Christian Göttsche @ 2023-05-12 10:08 UTC (permalink / raw)
  To: selinux

* fix minus self formatting in neverallow rules, avoiding `~ - self`

* show neverallow and neverallowxperm rules

* whitespace improvements in output
  - avoid duplicate whitespaces before permission list, since
    sepol_av_to_string() already adds a trailing one
  - avoid duplicate whitespace after wildcard type
  - unify indentation for xperm rules

* drop unused global variables

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
v2:
   drop extra whitespace in between ~ and { for type sets
   (there are still some minor spacing issues like
       neverallow  test1_t ~ self : file { read };
   but they would need an overhaul of the common display_id() function)
---
 checkpolicy/test/dismod.c | 33 +++++++++++++++++++--------------
 1 file changed, 19 insertions(+), 14 deletions(-)

diff --git a/checkpolicy/test/dismod.c b/checkpolicy/test/dismod.c
index 929ee308..5ec33860 100644
--- a/checkpolicy/test/dismod.c
+++ b/checkpolicy/test/dismod.c
@@ -54,11 +54,8 @@
 #define DISPLAY_AVBLOCK_FILENAME_TRANS	7
 
 static policydb_t policydb;
-extern unsigned int ss_initialized;
 
-int policyvers = MOD_POLICYDB_VERSION_BASE;
-
-static const char *symbol_labels[9] = {
+static const char *const symbol_labels[9] = {
 	"commons",
 	"classes", "roles  ", "types  ", "users  ", "bools  ",
 	"levels ", "cats   ", "attribs"
@@ -86,12 +83,12 @@ static void render_access_bitmap(ebitmap_t * map, uint32_t class,
 {
 	unsigned int i;
 	char *perm;
-	fprintf(fp, "{");
+	fprintf(fp, " {");
 	for (i = ebitmap_startbit(map); i < ebitmap_length(map); i++) {
 		if (ebitmap_get_bit(map, i)) {
 			perm = sepol_av_to_string(p, class, UINT32_C(1) << i);
 			if (perm)
-				fprintf(fp, " %s", perm);
+				fprintf(fp, "%s", perm);
 		}
 	}
 	fprintf(fp, " }");
@@ -117,10 +114,12 @@ static int display_type_set(type_set_t * set, uint32_t flags, policydb_t * polic
 	unsigned int i, num_types;
 
 	if (set->flags & TYPE_STAR) {
-		fprintf(fp, " * ");
+		fprintf(fp, " *");
 		return 0;
 	} else if (set->flags & TYPE_COMP) {
 		fprintf(fp, " ~");
+	} else {
+		fprintf(fp, " ");
 	}
 
 	num_types = 0;
@@ -170,7 +169,10 @@ static int display_type_set(type_set_t * set, uint32_t flags, policydb_t * polic
 	}
 
 	if (flags & RULE_NOTSELF) {
-		fprintf(fp, " -self");
+		if (set->flags & TYPE_COMP)
+			fprintf(fp, " self");
+		else
+			fprintf(fp, " -self");
 	}
 
 	if (num_types > 1)
@@ -234,6 +236,9 @@ static int display_avrule(avrule_t * avrule, policydb_t * policy,
 		if (avrule->specified & AVRULE_DONTAUDIT) {
 			fprintf(fp, "  dontaudit");
 		}
+		if (avrule->specified & AVRULE_NEVERALLOW) {
+			fprintf(fp, "  neverallow");
+		}
 	} else if (avrule->specified & AVRULE_TYPE) {
 		if (avrule->specified & AVRULE_TRANSITION) {
 			fprintf(fp, "  type_transition");
@@ -244,15 +249,15 @@ static int display_avrule(avrule_t * avrule, policydb_t * policy,
 		if (avrule->specified & AVRULE_CHANGE) {
 			fprintf(fp, "  type_change");
 		}
-	} else if (avrule->specified & AVRULE_NEVERALLOW) {
-		fprintf(fp, "  neverallow");
 	} else if (avrule->specified & AVRULE_XPERMS) {
 		if (avrule->specified & AVRULE_XPERMS_ALLOWED)
-			fprintf(fp, "allowxperm ");
+			fprintf(fp, "  allowxperm");
 		else if (avrule->specified & AVRULE_XPERMS_AUDITALLOW)
-			fprintf(fp, "auditallowxperm ");
+			fprintf(fp, "  auditallowxperm");
 		else if (avrule->specified & AVRULE_XPERMS_DONTAUDIT)
-			fprintf(fp, "dontauditxperm ");
+			fprintf(fp, "  dontauditxperm");
+		else if (avrule->specified & AVRULE_XPERMS_NEVERALLOW)
+			fprintf(fp, "  neverallowxperm");
 	} else {
 		fprintf(fp, "     ERROR: no valid rule type specified\n");
 		return -1;
@@ -560,7 +565,7 @@ static int display_scope_index(scope_index_t * indices, policydb_t * p,
 								     p, out_fp);
 					} else {
 						fprintf(out_fp,
-							"<no perms known>");
+							" <no perms known>");
 					}
 				}
 			}
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH v2] checkpolicy: add option to skip checking neverallow rules
  2023-05-12  9:57 ` [PATCH v2] " Christian Göttsche
@ 2023-06-08 20:59   ` James Carter
  2023-06-30  9:59     ` Petr Lautrbach
  0 siblings, 1 reply; 15+ messages in thread
From: James Carter @ 2023-06-08 20:59 UTC (permalink / raw)
  To: Christian Göttsche; +Cc: selinux

On Fri, May 12, 2023 at 5:59 AM Christian Göttsche
<cgzones@googlemail.com> wrote:
>
> Add the command line argument `-N/--disable-neverallow`, similar to
> secilc(8), to checkpolicy(8) and checkmodule(8) to skip the check of
> neverallow rule violations.
>
> This is mainly useful in development, e.g. to quickly add rules to a
> policy without fulfilling all neverallow rules or build policies with
> known violations.
>
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>

Acked-by: James Carter <jwcart2@gmail.com>

> ---
> v2:
>    invert variable logic from check_neverallow to disable_neverallow
> ---
>  checkpolicy/checkmodule.8 |  5 ++++-
>  checkpolicy/checkmodule.c | 13 +++++++++----
>  checkpolicy/checkpolicy.8 |  5 ++++-
>  checkpolicy/checkpolicy.c | 12 ++++++++----
>  4 files changed, 25 insertions(+), 10 deletions(-)
>
> diff --git a/checkpolicy/checkmodule.8 b/checkpolicy/checkmodule.8
> index 1061a6f2..ed9efd4c 100644
> --- a/checkpolicy/checkmodule.8
> +++ b/checkpolicy/checkmodule.8
> @@ -3,7 +3,7 @@
>  checkmodule \- SELinux policy module compiler
>  .SH SYNOPSIS
>  .B checkmodule
> -.I "[\-h] [\-b] [\-c policy_version] [\-C] [\-E] [\-m] [\-M] [\-U handle_unknown] [\-V] [\-o output_file] [input_file]"
> +.I "[\-h] [\-b] [\-c policy_version] [\-C] [\-E] [\-m] [\-M] [\-N] [\-U handle_unknown] [\-V] [\-o output_file] [input_file]"
>  .SH "DESCRIPTION"
>  This manual page describes the
>  .BR checkmodule
> @@ -43,6 +43,9 @@ Generate a non-base policy module.
>  .B \-M,\-\-mls
>  Enable the MLS/MCS support when checking and compiling the policy module.
>  .TP
> +.B \-N,\-\-disable-neverallow
> +Do not check neverallow rules.
> +.TP
>  .B \-V,\-\-version
>  Show policy versions created by this program.
>  .TP
> diff --git a/checkpolicy/checkmodule.c b/checkpolicy/checkmodule.c
> index 3432608b..14e6c891 100644
> --- a/checkpolicy/checkmodule.c
> +++ b/checkpolicy/checkmodule.c
> @@ -123,7 +123,7 @@ static int write_binary_policy(policydb_t * p, FILE *outfp)
>
>  static __attribute__((__noreturn__)) void usage(const char *progname)
>  {
> -       printf("usage:  %s [-h] [-V] [-b] [-C] [-E] [-U handle_unknown] [-m] [-M] [-o FILE] [-c VERSION] [INPUT]\n", progname);
> +       printf("usage:  %s [-h] [-V] [-b] [-C] [-E] [-U handle_unknown] [-m] [-M] [-N] [-o FILE] [-c VERSION] [INPUT]\n", progname);
>         printf("Build base and policy modules.\n");
>         printf("Options:\n");
>         printf("  INPUT      build module from INPUT (else read from \"%s\")\n",
> @@ -139,6 +139,7 @@ static __attribute__((__noreturn__)) void usage(const char *progname)
>         printf("               allow: Allow unknown kernel checks\n");
>         printf("  -m         build a policy module instead of a base module\n");
>         printf("  -M         enable MLS policy\n");
> +       printf("  -N         do not check neverallow rules\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);
> @@ -148,7 +149,7 @@ static __attribute__((__noreturn__)) void usage(const char *progname)
>  int main(int argc, char **argv)
>  {
>         const char *file = txtfile, *outfile = NULL;
> -       unsigned int binary = 0, cil = 0;
> +       unsigned int binary = 0, cil = 0, disable_neverallow = 0;
>         int ch;
>         int show_version = 0;
>         policydb_t modpolicydb;
> @@ -159,12 +160,13 @@ int main(int argc, char **argv)
>                 {"version", no_argument, NULL, 'V'},
>                 {"handle-unknown", required_argument, NULL, 'U'},
>                 {"mls", no_argument, NULL, 'M'},
> +               {"disable-neverallow", no_argument, NULL, 'N'},
>                 {"cil", no_argument, NULL, 'C'},
>                 {"werror", no_argument, NULL, 'E'},
>                 {NULL, 0, NULL, 0}
>         };
>
> -       while ((ch = getopt_long(argc, argv, "ho:bVEU:mMCc:", long_options, NULL)) != -1) {
> +       while ((ch = getopt_long(argc, argv, "ho:bVEU:mMNCc:", long_options, NULL)) != -1) {
>                 switch (ch) {
>                 case 'h':
>                         usage(argv[0]);
> @@ -202,6 +204,9 @@ int main(int argc, char **argv)
>                 case 'M':
>                         mlspol = 1;
>                         break;
> +               case 'N':
> +                       disable_neverallow = 1;
> +                       break;
>                 case 'C':
>                         cil = 1;
>                         break;
> @@ -317,7 +322,7 @@ int main(int argc, char **argv)
>                         fprintf(stderr, "%s:  link modules failed\n", argv[0]);
>                         exit(1);
>                 }
> -               if (expand_module(NULL, &modpolicydb, &kernpolicydb, 0, 1)) {
> +               if (expand_module(NULL, &modpolicydb, &kernpolicydb, /*verbose=*/0, !disable_neverallow)) {
>                         fprintf(stderr, "%s:  expand module failed\n", argv[0]);
>                         exit(1);
>                 }
> diff --git a/checkpolicy/checkpolicy.8 b/checkpolicy/checkpolicy.8
> index 2984c238..c66e084b 100644
> --- a/checkpolicy/checkpolicy.8
> +++ b/checkpolicy/checkpolicy.8
> @@ -3,7 +3,7 @@
>  checkpolicy \- SELinux policy compiler
>  .SH SYNOPSIS
>  .B checkpolicy
> -.I "[\-b[F]] [\-C] [\-d] [\-U handle_unknown (allow,deny,reject)] [\-M] [\-c policyvers] [\-o output_file|\-] [\-S] [\-t target_platform (selinux,xen)] [\-O] [\-E] [\-V] [input_file]"
> +.I "[\-b[F]] [\-C] [\-d] [\-U handle_unknown (allow,deny,reject)] [\-M] [\-N] [\-c policyvers] [\-o output_file|\-] [\-S] [\-t target_platform (selinux,xen)] [\-O] [\-E] [\-V] [input_file]"
>  .br
>  .SH "DESCRIPTION"
>  This manual page describes the
> @@ -38,6 +38,9 @@ Specify how the kernel should handle unknown classes or permissions (deny, allow
>  .B \-M,\-\-mls
>  Enable the MLS policy when checking and compiling the policy.
>  .TP
> +.B \-N,\-\-disable-neverallow
> +Do not check neverallow rules.
> +.TP
>  .B \-c policyvers
>  Specify the policy version, defaults to the latest.
>  .TP
> diff --git a/checkpolicy/checkpolicy.c b/checkpolicy/checkpolicy.c
> index 2485142d..623ba8b2 100644
> --- a/checkpolicy/checkpolicy.c
> +++ b/checkpolicy/checkpolicy.c
> @@ -109,7 +109,7 @@ static __attribute__((__noreturn__)) void usage(const char *progname)
>  {
>         printf
>             ("usage:  %s [-b[F]] [-C] [-d] [-U handle_unknown (allow,deny,reject)] [-M] "
> -            "[-c policyvers (%d-%d)] [-o output_file|-] [-S] [-O] "
> +            "[-N] [-c policyvers (%d-%d)] [-o output_file|-] [-S] [-O] "
>              "[-t target_platform (selinux,xen)] [-E] [-V] [input_file]\n",
>              progname, POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX);
>         exit(1);
> @@ -393,7 +393,7 @@ int main(int argc, char **argv)
>         size_t scontext_len, pathlen;
>         unsigned int i;
>         unsigned int protocol, port;
> -       unsigned int binary = 0, debug = 0, sort = 0, cil = 0, conf = 0, optimize = 0;
> +       unsigned int binary = 0, debug = 0, sort = 0, cil = 0, conf = 0, optimize = 0, disable_neverallow = 0;
>         struct val_to_name v;
>         int ret, ch, fd, target = SEPOL_TARGET_SELINUX;
>         unsigned int nel, uret;
> @@ -415,6 +415,7 @@ int main(int argc, char **argv)
>                 {"version", no_argument, NULL, 'V'},
>                 {"handle-unknown", required_argument, NULL, 'U'},
>                 {"mls", no_argument, NULL, 'M'},
> +               {"disable-neverallow", no_argument, NULL, 'N'},
>                 {"cil", no_argument, NULL, 'C'},
>                 {"conf",no_argument, NULL, 'F'},
>                 {"sort", no_argument, NULL, 'S'},
> @@ -424,7 +425,7 @@ int main(int argc, char **argv)
>                 {NULL, 0, NULL, 0}
>         };
>
> -       while ((ch = getopt_long(argc, argv, "o:t:dbU:MCFSVc:OEh", long_options, NULL)) != -1) {
> +       while ((ch = getopt_long(argc, argv, "o:t:dbU:MNCFSVc:OEh", long_options, NULL)) != -1) {
>                 switch (ch) {
>                 case 'o':
>                         outfile = optarg;
> @@ -473,6 +474,9 @@ int main(int argc, char **argv)
>                 case 'M':
>                         mlspol = 1;
>                         break;
> +               case 'N':
> +                       disable_neverallow = 1;
> +                       break;
>                 case 'C':
>                         cil = 1;
>                         break;
> @@ -630,7 +634,7 @@ int main(int argc, char **argv)
>                                 fprintf(stderr, "%s:  policydb_init failed\n", argv[0]);
>                                 exit(1);
>                         }
> -                       if (expand_module(NULL, policydbp, &policydb, 0, 1)) {
> +                       if (expand_module(NULL, policydbp, &policydb, /*verbose=*/0, !disable_neverallow)) {
>                                 fprintf(stderr, "Error while expanding policy\n");
>                                 exit(1);
>                         }
> --
> 2.40.1
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2] checkpolicy/dismod: misc improvements
  2023-05-12 10:08   ` [PATCH v2] " Christian Göttsche
@ 2023-06-08 21:00     ` James Carter
  2023-06-30  9:59       ` Petr Lautrbach
  0 siblings, 1 reply; 15+ messages in thread
From: James Carter @ 2023-06-08 21:00 UTC (permalink / raw)
  To: Christian Göttsche; +Cc: selinux

On Fri, May 12, 2023 at 6:12 AM Christian Göttsche
<cgzones@googlemail.com> wrote:
>
> * fix minus self formatting in neverallow rules, avoiding `~ - self`
>
> * show neverallow and neverallowxperm rules
>
> * whitespace improvements in output
>   - avoid duplicate whitespaces before permission list, since
>     sepol_av_to_string() already adds a trailing one
>   - avoid duplicate whitespace after wildcard type
>   - unify indentation for xperm rules
>
> * drop unused global variables
>
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>

Acked-by: James Carter <jwcart2@gmail.com>

> ---
> v2:
>    drop extra whitespace in between ~ and { for type sets
>    (there are still some minor spacing issues like
>        neverallow  test1_t ~ self : file { read };
>    but they would need an overhaul of the common display_id() function)
> ---
>  checkpolicy/test/dismod.c | 33 +++++++++++++++++++--------------
>  1 file changed, 19 insertions(+), 14 deletions(-)
>
> diff --git a/checkpolicy/test/dismod.c b/checkpolicy/test/dismod.c
> index 929ee308..5ec33860 100644
> --- a/checkpolicy/test/dismod.c
> +++ b/checkpolicy/test/dismod.c
> @@ -54,11 +54,8 @@
>  #define DISPLAY_AVBLOCK_FILENAME_TRANS 7
>
>  static policydb_t policydb;
> -extern unsigned int ss_initialized;
>
> -int policyvers = MOD_POLICYDB_VERSION_BASE;
> -
> -static const char *symbol_labels[9] = {
> +static const char *const symbol_labels[9] = {
>         "commons",
>         "classes", "roles  ", "types  ", "users  ", "bools  ",
>         "levels ", "cats   ", "attribs"
> @@ -86,12 +83,12 @@ static void render_access_bitmap(ebitmap_t * map, uint32_t class,
>  {
>         unsigned int i;
>         char *perm;
> -       fprintf(fp, "{");
> +       fprintf(fp, " {");
>         for (i = ebitmap_startbit(map); i < ebitmap_length(map); i++) {
>                 if (ebitmap_get_bit(map, i)) {
>                         perm = sepol_av_to_string(p, class, UINT32_C(1) << i);
>                         if (perm)
> -                               fprintf(fp, " %s", perm);
> +                               fprintf(fp, "%s", perm);
>                 }
>         }
>         fprintf(fp, " }");
> @@ -117,10 +114,12 @@ static int display_type_set(type_set_t * set, uint32_t flags, policydb_t * polic
>         unsigned int i, num_types;
>
>         if (set->flags & TYPE_STAR) {
> -               fprintf(fp, " * ");
> +               fprintf(fp, " *");
>                 return 0;
>         } else if (set->flags & TYPE_COMP) {
>                 fprintf(fp, " ~");
> +       } else {
> +               fprintf(fp, " ");
>         }
>
>         num_types = 0;
> @@ -170,7 +169,10 @@ static int display_type_set(type_set_t * set, uint32_t flags, policydb_t * polic
>         }
>
>         if (flags & RULE_NOTSELF) {
> -               fprintf(fp, " -self");
> +               if (set->flags & TYPE_COMP)
> +                       fprintf(fp, " self");
> +               else
> +                       fprintf(fp, " -self");
>         }
>
>         if (num_types > 1)
> @@ -234,6 +236,9 @@ static int display_avrule(avrule_t * avrule, policydb_t * policy,
>                 if (avrule->specified & AVRULE_DONTAUDIT) {
>                         fprintf(fp, "  dontaudit");
>                 }
> +               if (avrule->specified & AVRULE_NEVERALLOW) {
> +                       fprintf(fp, "  neverallow");
> +               }
>         } else if (avrule->specified & AVRULE_TYPE) {
>                 if (avrule->specified & AVRULE_TRANSITION) {
>                         fprintf(fp, "  type_transition");
> @@ -244,15 +249,15 @@ static int display_avrule(avrule_t * avrule, policydb_t * policy,
>                 if (avrule->specified & AVRULE_CHANGE) {
>                         fprintf(fp, "  type_change");
>                 }
> -       } else if (avrule->specified & AVRULE_NEVERALLOW) {
> -               fprintf(fp, "  neverallow");
>         } else if (avrule->specified & AVRULE_XPERMS) {
>                 if (avrule->specified & AVRULE_XPERMS_ALLOWED)
> -                       fprintf(fp, "allowxperm ");
> +                       fprintf(fp, "  allowxperm");
>                 else if (avrule->specified & AVRULE_XPERMS_AUDITALLOW)
> -                       fprintf(fp, "auditallowxperm ");
> +                       fprintf(fp, "  auditallowxperm");
>                 else if (avrule->specified & AVRULE_XPERMS_DONTAUDIT)
> -                       fprintf(fp, "dontauditxperm ");
> +                       fprintf(fp, "  dontauditxperm");
> +               else if (avrule->specified & AVRULE_XPERMS_NEVERALLOW)
> +                       fprintf(fp, "  neverallowxperm");
>         } else {
>                 fprintf(fp, "     ERROR: no valid rule type specified\n");
>                 return -1;
> @@ -560,7 +565,7 @@ static int display_scope_index(scope_index_t * indices, policydb_t * p,
>                                                                      p, out_fp);
>                                         } else {
>                                                 fprintf(out_fp,
> -                                                       "<no perms known>");
> +                                                       " <no perms known>");
>                                         }
>                                 }
>                         }
> --
> 2.40.1
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2] checkpolicy/dismod: misc improvements
  2023-06-08 21:00     ` James Carter
@ 2023-06-30  9:59       ` Petr Lautrbach
  0 siblings, 0 replies; 15+ messages in thread
From: Petr Lautrbach @ 2023-06-30  9:59 UTC (permalink / raw)
  To: James Carter, Christian Göttsche, selinux

James Carter <jwcart2@gmail.com> writes:

> On Fri, May 12, 2023 at 6:12 AM Christian Göttsche
> <cgzones@googlemail.com> wrote:
>>
>> * fix minus self formatting in neverallow rules, avoiding `~ - self`
>>
>> * show neverallow and neverallowxperm rules
>>
>> * whitespace improvements in output
>>   - avoid duplicate whitespaces before permission list, since
>>     sepol_av_to_string() already adds a trailing one
>>   - avoid duplicate whitespace after wildcard type
>>   - unify indentation for xperm rules
>>
>> * drop unused global variables
>>
>> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
>
> Acked-by: James Carter <jwcart2@gmail.com>

merged, thanks

>> ---
>> v2:
>>    drop extra whitespace in between ~ and { for type sets
>>    (there are still some minor spacing issues like
>>        neverallow  test1_t ~ self : file { read };
>>    but they would need an overhaul of the common display_id() function)
>> ---
>>  checkpolicy/test/dismod.c | 33 +++++++++++++++++++--------------
>>  1 file changed, 19 insertions(+), 14 deletions(-)
>>
>> diff --git a/checkpolicy/test/dismod.c b/checkpolicy/test/dismod.c
>> index 929ee308..5ec33860 100644
>> --- a/checkpolicy/test/dismod.c
>> +++ b/checkpolicy/test/dismod.c
>> @@ -54,11 +54,8 @@
>>  #define DISPLAY_AVBLOCK_FILENAME_TRANS 7
>>
>>  static policydb_t policydb;
>> -extern unsigned int ss_initialized;
>>
>> -int policyvers = MOD_POLICYDB_VERSION_BASE;
>> -
>> -static const char *symbol_labels[9] = {
>> +static const char *const symbol_labels[9] = {
>>         "commons",
>>         "classes", "roles  ", "types  ", "users  ", "bools  ",
>>         "levels ", "cats   ", "attribs"
>> @@ -86,12 +83,12 @@ static void render_access_bitmap(ebitmap_t * map, uint32_t class,
>>  {
>>         unsigned int i;
>>         char *perm;
>> -       fprintf(fp, "{");
>> +       fprintf(fp, " {");
>>         for (i = ebitmap_startbit(map); i < ebitmap_length(map); i++) {
>>                 if (ebitmap_get_bit(map, i)) {
>>                         perm = sepol_av_to_string(p, class, UINT32_C(1) << i);
>>                         if (perm)
>> -                               fprintf(fp, " %s", perm);
>> +                               fprintf(fp, "%s", perm);
>>                 }
>>         }
>>         fprintf(fp, " }");
>> @@ -117,10 +114,12 @@ static int display_type_set(type_set_t * set, uint32_t flags, policydb_t * polic
>>         unsigned int i, num_types;
>>
>>         if (set->flags & TYPE_STAR) {
>> -               fprintf(fp, " * ");
>> +               fprintf(fp, " *");
>>                 return 0;
>>         } else if (set->flags & TYPE_COMP) {
>>                 fprintf(fp, " ~");
>> +       } else {
>> +               fprintf(fp, " ");
>>         }
>>
>>         num_types = 0;
>> @@ -170,7 +169,10 @@ static int display_type_set(type_set_t * set, uint32_t flags, policydb_t * polic
>>         }
>>
>>         if (flags & RULE_NOTSELF) {
>> -               fprintf(fp, " -self");
>> +               if (set->flags & TYPE_COMP)
>> +                       fprintf(fp, " self");
>> +               else
>> +                       fprintf(fp, " -self");
>>         }
>>
>>         if (num_types > 1)
>> @@ -234,6 +236,9 @@ static int display_avrule(avrule_t * avrule, policydb_t * policy,
>>                 if (avrule->specified & AVRULE_DONTAUDIT) {
>>                         fprintf(fp, "  dontaudit");
>>                 }
>> +               if (avrule->specified & AVRULE_NEVERALLOW) {
>> +                       fprintf(fp, "  neverallow");
>> +               }
>>         } else if (avrule->specified & AVRULE_TYPE) {
>>                 if (avrule->specified & AVRULE_TRANSITION) {
>>                         fprintf(fp, "  type_transition");
>> @@ -244,15 +249,15 @@ static int display_avrule(avrule_t * avrule, policydb_t * policy,
>>                 if (avrule->specified & AVRULE_CHANGE) {
>>                         fprintf(fp, "  type_change");
>>                 }
>> -       } else if (avrule->specified & AVRULE_NEVERALLOW) {
>> -               fprintf(fp, "  neverallow");
>>         } else if (avrule->specified & AVRULE_XPERMS) {
>>                 if (avrule->specified & AVRULE_XPERMS_ALLOWED)
>> -                       fprintf(fp, "allowxperm ");
>> +                       fprintf(fp, "  allowxperm");
>>                 else if (avrule->specified & AVRULE_XPERMS_AUDITALLOW)
>> -                       fprintf(fp, "auditallowxperm ");
>> +                       fprintf(fp, "  auditallowxperm");
>>                 else if (avrule->specified & AVRULE_XPERMS_DONTAUDIT)
>> -                       fprintf(fp, "dontauditxperm ");
>> +                       fprintf(fp, "  dontauditxperm");
>> +               else if (avrule->specified & AVRULE_XPERMS_NEVERALLOW)
>> +                       fprintf(fp, "  neverallowxperm");
>>         } else {
>>                 fprintf(fp, "     ERROR: no valid rule type specified\n");
>>                 return -1;
>> @@ -560,7 +565,7 @@ static int display_scope_index(scope_index_t * indices, policydb_t * p,
>>                                                                      p, out_fp);
>>                                         } else {
>>                                                 fprintf(out_fp,
>> -                                                       "<no perms known>");
>> +                                                       " <no perms known>");
>>                                         }
>>                                 }
>>                         }
>> --
>> 2.40.1
>>


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2] checkpolicy: add option to skip checking neverallow rules
  2023-06-08 20:59   ` James Carter
@ 2023-06-30  9:59     ` Petr Lautrbach
  0 siblings, 0 replies; 15+ messages in thread
From: Petr Lautrbach @ 2023-06-30  9:59 UTC (permalink / raw)
  To: James Carter, Christian Göttsche, selinux

James Carter <jwcart2@gmail.com> writes:

> On Fri, May 12, 2023 at 5:59 AM Christian Göttsche
> <cgzones@googlemail.com> wrote:
>>
>> Add the command line argument `-N/--disable-neverallow`, similar to
>> secilc(8), to checkpolicy(8) and checkmodule(8) to skip the check of
>> neverallow rule violations.
>>
>> This is mainly useful in development, e.g. to quickly add rules to a
>> policy without fulfilling all neverallow rules or build policies with
>> known violations.
>>
>> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
>
> Acked-by: James Carter <jwcart2@gmail.com>

merged, thanks


>> ---
>> v2:
>>    invert variable logic from check_neverallow to disable_neverallow
>> ---
>>  checkpolicy/checkmodule.8 |  5 ++++-
>>  checkpolicy/checkmodule.c | 13 +++++++++----
>>  checkpolicy/checkpolicy.8 |  5 ++++-
>>  checkpolicy/checkpolicy.c | 12 ++++++++----
>>  4 files changed, 25 insertions(+), 10 deletions(-)
>>
>> diff --git a/checkpolicy/checkmodule.8 b/checkpolicy/checkmodule.8
>> index 1061a6f2..ed9efd4c 100644
>> --- a/checkpolicy/checkmodule.8
>> +++ b/checkpolicy/checkmodule.8
>> @@ -3,7 +3,7 @@
>>  checkmodule \- SELinux policy module compiler
>>  .SH SYNOPSIS
>>  .B checkmodule
>> -.I "[\-h] [\-b] [\-c policy_version] [\-C] [\-E] [\-m] [\-M] [\-U handle_unknown] [\-V] [\-o output_file] [input_file]"
>> +.I "[\-h] [\-b] [\-c policy_version] [\-C] [\-E] [\-m] [\-M] [\-N] [\-U handle_unknown] [\-V] [\-o output_file] [input_file]"
>>  .SH "DESCRIPTION"
>>  This manual page describes the
>>  .BR checkmodule
>> @@ -43,6 +43,9 @@ Generate a non-base policy module.
>>  .B \-M,\-\-mls
>>  Enable the MLS/MCS support when checking and compiling the policy module.
>>  .TP
>> +.B \-N,\-\-disable-neverallow
>> +Do not check neverallow rules.
>> +.TP
>>  .B \-V,\-\-version
>>  Show policy versions created by this program.
>>  .TP
>> diff --git a/checkpolicy/checkmodule.c b/checkpolicy/checkmodule.c
>> index 3432608b..14e6c891 100644
>> --- a/checkpolicy/checkmodule.c
>> +++ b/checkpolicy/checkmodule.c
>> @@ -123,7 +123,7 @@ static int write_binary_policy(policydb_t * p, FILE *outfp)
>>
>>  static __attribute__((__noreturn__)) void usage(const char *progname)
>>  {
>> -       printf("usage:  %s [-h] [-V] [-b] [-C] [-E] [-U handle_unknown] [-m] [-M] [-o FILE] [-c VERSION] [INPUT]\n", progname);
>> +       printf("usage:  %s [-h] [-V] [-b] [-C] [-E] [-U handle_unknown] [-m] [-M] [-N] [-o FILE] [-c VERSION] [INPUT]\n", progname);
>>         printf("Build base and policy modules.\n");
>>         printf("Options:\n");
>>         printf("  INPUT      build module from INPUT (else read from \"%s\")\n",
>> @@ -139,6 +139,7 @@ static __attribute__((__noreturn__)) void usage(const char *progname)
>>         printf("               allow: Allow unknown kernel checks\n");
>>         printf("  -m         build a policy module instead of a base module\n");
>>         printf("  -M         enable MLS policy\n");
>> +       printf("  -N         do not check neverallow rules\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);
>> @@ -148,7 +149,7 @@ static __attribute__((__noreturn__)) void usage(const char *progname)
>>  int main(int argc, char **argv)
>>  {
>>         const char *file = txtfile, *outfile = NULL;
>> -       unsigned int binary = 0, cil = 0;
>> +       unsigned int binary = 0, cil = 0, disable_neverallow = 0;
>>         int ch;
>>         int show_version = 0;
>>         policydb_t modpolicydb;
>> @@ -159,12 +160,13 @@ int main(int argc, char **argv)
>>                 {"version", no_argument, NULL, 'V'},
>>                 {"handle-unknown", required_argument, NULL, 'U'},
>>                 {"mls", no_argument, NULL, 'M'},
>> +               {"disable-neverallow", no_argument, NULL, 'N'},
>>                 {"cil", no_argument, NULL, 'C'},
>>                 {"werror", no_argument, NULL, 'E'},
>>                 {NULL, 0, NULL, 0}
>>         };
>>
>> -       while ((ch = getopt_long(argc, argv, "ho:bVEU:mMCc:", long_options, NULL)) != -1) {
>> +       while ((ch = getopt_long(argc, argv, "ho:bVEU:mMNCc:", long_options, NULL)) != -1) {
>>                 switch (ch) {
>>                 case 'h':
>>                         usage(argv[0]);
>> @@ -202,6 +204,9 @@ int main(int argc, char **argv)
>>                 case 'M':
>>                         mlspol = 1;
>>                         break;
>> +               case 'N':
>> +                       disable_neverallow = 1;
>> +                       break;
>>                 case 'C':
>>                         cil = 1;
>>                         break;
>> @@ -317,7 +322,7 @@ int main(int argc, char **argv)
>>                         fprintf(stderr, "%s:  link modules failed\n", argv[0]);
>>                         exit(1);
>>                 }
>> -               if (expand_module(NULL, &modpolicydb, &kernpolicydb, 0, 1)) {
>> +               if (expand_module(NULL, &modpolicydb, &kernpolicydb, /*verbose=*/0, !disable_neverallow)) {
>>                         fprintf(stderr, "%s:  expand module failed\n", argv[0]);
>>                         exit(1);
>>                 }
>> diff --git a/checkpolicy/checkpolicy.8 b/checkpolicy/checkpolicy.8
>> index 2984c238..c66e084b 100644
>> --- a/checkpolicy/checkpolicy.8
>> +++ b/checkpolicy/checkpolicy.8
>> @@ -3,7 +3,7 @@
>>  checkpolicy \- SELinux policy compiler
>>  .SH SYNOPSIS
>>  .B checkpolicy
>> -.I "[\-b[F]] [\-C] [\-d] [\-U handle_unknown (allow,deny,reject)] [\-M] [\-c policyvers] [\-o output_file|\-] [\-S] [\-t target_platform (selinux,xen)] [\-O] [\-E] [\-V] [input_file]"
>> +.I "[\-b[F]] [\-C] [\-d] [\-U handle_unknown (allow,deny,reject)] [\-M] [\-N] [\-c policyvers] [\-o output_file|\-] [\-S] [\-t target_platform (selinux,xen)] [\-O] [\-E] [\-V] [input_file]"
>>  .br
>>  .SH "DESCRIPTION"
>>  This manual page describes the
>> @@ -38,6 +38,9 @@ Specify how the kernel should handle unknown classes or permissions (deny, allow
>>  .B \-M,\-\-mls
>>  Enable the MLS policy when checking and compiling the policy.
>>  .TP
>> +.B \-N,\-\-disable-neverallow
>> +Do not check neverallow rules.
>> +.TP
>>  .B \-c policyvers
>>  Specify the policy version, defaults to the latest.
>>  .TP
>> diff --git a/checkpolicy/checkpolicy.c b/checkpolicy/checkpolicy.c
>> index 2485142d..623ba8b2 100644
>> --- a/checkpolicy/checkpolicy.c
>> +++ b/checkpolicy/checkpolicy.c
>> @@ -109,7 +109,7 @@ static __attribute__((__noreturn__)) void usage(const char *progname)
>>  {
>>         printf
>>             ("usage:  %s [-b[F]] [-C] [-d] [-U handle_unknown (allow,deny,reject)] [-M] "
>> -            "[-c policyvers (%d-%d)] [-o output_file|-] [-S] [-O] "
>> +            "[-N] [-c policyvers (%d-%d)] [-o output_file|-] [-S] [-O] "
>>              "[-t target_platform (selinux,xen)] [-E] [-V] [input_file]\n",
>>              progname, POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX);
>>         exit(1);
>> @@ -393,7 +393,7 @@ int main(int argc, char **argv)
>>         size_t scontext_len, pathlen;
>>         unsigned int i;
>>         unsigned int protocol, port;
>> -       unsigned int binary = 0, debug = 0, sort = 0, cil = 0, conf = 0, optimize = 0;
>> +       unsigned int binary = 0, debug = 0, sort = 0, cil = 0, conf = 0, optimize = 0, disable_neverallow = 0;
>>         struct val_to_name v;
>>         int ret, ch, fd, target = SEPOL_TARGET_SELINUX;
>>         unsigned int nel, uret;
>> @@ -415,6 +415,7 @@ int main(int argc, char **argv)
>>                 {"version", no_argument, NULL, 'V'},
>>                 {"handle-unknown", required_argument, NULL, 'U'},
>>                 {"mls", no_argument, NULL, 'M'},
>> +               {"disable-neverallow", no_argument, NULL, 'N'},
>>                 {"cil", no_argument, NULL, 'C'},
>>                 {"conf",no_argument, NULL, 'F'},
>>                 {"sort", no_argument, NULL, 'S'},
>> @@ -424,7 +425,7 @@ int main(int argc, char **argv)
>>                 {NULL, 0, NULL, 0}
>>         };
>>
>> -       while ((ch = getopt_long(argc, argv, "o:t:dbU:MCFSVc:OEh", long_options, NULL)) != -1) {
>> +       while ((ch = getopt_long(argc, argv, "o:t:dbU:MNCFSVc:OEh", long_options, NULL)) != -1) {
>>                 switch (ch) {
>>                 case 'o':
>>                         outfile = optarg;
>> @@ -473,6 +474,9 @@ int main(int argc, char **argv)
>>                 case 'M':
>>                         mlspol = 1;
>>                         break;
>> +               case 'N':
>> +                       disable_neverallow = 1;
>> +                       break;
>>                 case 'C':
>>                         cil = 1;
>>                         break;
>> @@ -630,7 +634,7 @@ int main(int argc, char **argv)
>>                                 fprintf(stderr, "%s:  policydb_init failed\n", argv[0]);
>>                                 exit(1);
>>                         }
>> -                       if (expand_module(NULL, policydbp, &policydb, 0, 1)) {
>> +                       if (expand_module(NULL, policydbp, &policydb, /*verbose=*/0, !disable_neverallow)) {
>>                                 fprintf(stderr, "Error while expanding policy\n");
>>                                 exit(1);
>>                         }
>> --
>> 2.40.1
>>


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2023-06-30 10:01 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-31 17:34 [PATCH 1/3] checkpolicy: add option to skip checking neverallow rules Christian Göttsche
2023-03-31 17:34 ` [PATCH 2/3] checkpolicy/dispol: add output functions Christian Göttsche
2023-04-24 19:07   ` James Carter
2023-05-03 16:24     ` James Carter
2023-03-31 17:34 ` [PATCH 3/3] checkpolicy/dismod: misc improvements Christian Göttsche
2023-04-24 19:12   ` James Carter
2023-05-12 10:08   ` [PATCH v2] " Christian Göttsche
2023-06-08 21:00     ` James Carter
2023-06-30  9:59       ` Petr Lautrbach
2023-03-31 17:58 ` [PATCH 1/3] checkpolicy: add option to skip checking neverallow rules Daniel Burgener
2023-04-24 19:02   ` James Carter
2023-04-24 19:06 ` James Carter
2023-05-12  9:57 ` [PATCH v2] " Christian Göttsche
2023-06-08 20:59   ` James Carter
2023-06-30  9:59     ` Petr Lautrbach

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).