diff mbox series

[v2] checkpolicy: add option to skip checking neverallow rules

Message ID 20230512095749.59577-1-cgzones@googlemail.com (mailing list archive)
State Accepted
Delegated to: Petr Lautrbach
Headers show
Series [v2] checkpolicy: add option to skip checking neverallow rules | expand

Commit Message

Christian Göttsche May 12, 2023, 9:57 a.m. UTC
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(-)

Comments

James Carter June 8, 2023, 8:59 p.m. UTC | #1
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
>
Petr Lautrbach June 30, 2023, 9:59 a.m. UTC | #2
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
>>
diff mbox series

Patch

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);
 			}