Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package cil for openSUSE:Factory checked in 
at 2026-07-13 14:25:19
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/cil (Old)
 and      /work/SRC/openSUSE:Factory/.cil.new.1991 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "cil"

Mon Jul 13 14:25:19 2026 rev:8 rq:1364574 version:3.11

Changes:
--------
--- /work/SRC/openSUSE:Factory/cil/cil.changes  2026-02-09 11:43:25.009890471 
+0100
+++ /work/SRC/openSUSE:Factory/.cil.new.1991/cil.changes        2026-07-13 
14:25:23.681935096 +0200
@@ -1,0 +2,24 @@
+Tue Jul  7 15:30:46 UTC 2026 - Cathy Hu <[email protected]>
+
+- Fix secilcheck double-free (bsc#1270622)
+  - Add patch: 1270622-Fix-double-free-in-secilcheck.patch
+  - was merged upstream, can be dropped once the new release is out
+
+-------------------------------------------------------------------
+Mon Jul  6 12:34:23 UTC 2026 - Cathy Hu <[email protected]>
+
+- Update to version 3.11
+  https://github.com/SELinuxProject/selinux/releases/tag/3.11
+  - User-visible changes:
+    - Added `secilcheck` program to check CIL neverallows against binary 
policies
+    - Multiple documentation improvements.
+  - Development-relevant changes:
+    - Reformatted entire tree based on .clang-format and added new
+      check-format/format make targets to check and/or reformat code to match.
+      This is now a requirement for new patches.
+  - Notable Bugfixes:
+    - secilc: Use fstat instead of stat to avoid TOCTOU issues
+- Packaging changes:
+  - Add secilcheck
+
+-------------------------------------------------------------------

Old:
----
  secilc-3.10.tar.gz
  secilc-3.10.tar.gz.asc

New:
----
  1270622-Fix-double-free-in-secilcheck.patch
  secilc-3.11.tar.gz
  secilc-3.11.tar.gz.asc

----------(New B)----------
  New:- Fix secilcheck double-free (bsc#1270622)
  - Add patch: 1270622-Fix-double-free-in-secilcheck.patch
  - was merged upstream, can be dropped once the new release is out
----------(New E)----------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ cil.spec ++++++
--- /var/tmp/diff_new_pack.P4iwE5/_old  2026-07-13 14:25:24.621967236 +0200
+++ /var/tmp/diff_new_pack.P4iwE5/_new  2026-07-13 14:25:24.621967236 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           cil
-Version:        3.10
+Version:        3.11
 Release:        0
 Summary:        SELinux Common Intermediate Language compiler
 License:        BSD-2-Clause
@@ -26,6 +26,8 @@
 Source0:        
https://github.com/SELinuxProject/selinux/releases/download/%{version}/se%{name}c-%{version}.tar.gz
 Source1:        
https://github.com/SELinuxProject/selinux/releases/download/%{version}/se%{name}c-%{version}.tar.gz.asc
 Source2:        cil.keyring
+# PATCH-FIX-UPSTREAM 1270622-Fix-double-free-in-secilcheck.patch bsc#1270622 
[email protected]
+Patch0:         1270622-Fix-double-free-in-secilcheck.patch
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 BuildRequires:  flex
 BuildRequires:  libsepol-devel
@@ -40,7 +42,7 @@
 This is a compiler for CIL.
 
 %prep
-%setup -q -n secilc-%{version}/
+%autosetup -n secilc-%{version}/
 
 %build
 make
@@ -54,4 +56,5 @@
 %doc %{_mandir}/man8/*
 /usr/bin/secil2conf
 /usr/bin/secil2tree
+/usr/bin/secilcheck
 

++++++ 1270622-Fix-double-free-in-secilcheck.patch ++++++
>From 835e8920ed1582c754f603d8f77769be4176bc9f Mon Sep 17 00:00:00 2001
From: Cathy Hu <[email protected]>
Date: Tue, 7 Jul 2026 14:15:33 +0200
Subject: [PATCH] Fix double-free in secilcheck

If the file size of the cil file is zero, fclose was called twice.

Fixes:
```
localhost:~ # touch ~/.empty.cil
localhost:~ # secilcheck  /etc/selinux/targeted/policy/policy.35 ./empty.cil
free(): double free detected in tcache 2
Aborted                    (core dumped) secilcheck 
/etc/selinux/targeted/policy/policy.35 ./empty.cil
```

Signed-off-by: Cathy Hu <[email protected]>
---
 secilc/secilcheck.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/secilc/secilcheck.c b/secilc/secilcheck.c
index ee141bc0..b7c32bc6 100644
--- a/secilc/secilcheck.c
+++ b/secilc/secilcheck.c
@@ -155,7 +155,6 @@ static int add_cil_file(const char *filename, struct cil_db 
*cdb)
        file_size = filedata.st_size;
 
        if (!file_size) {
-               fclose(file);
                rc = 0;
                goto exit;
        }
-- 
2.54.0



++++++ secilc-3.10.tar.gz -> secilc-3.11.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/secilc-3.10/.gitignore new/secilc-3.11/.gitignore
--- old/secilc-3.10/.gitignore  2026-02-02 03:01:16.000000000 +0100
+++ new/secilc-3.11/.gitignore  2026-07-01 18:51:05.000000000 +0200
@@ -4,6 +4,8 @@
 secil2conf.8
 secil2tree
 secil2tree.8
+secilcheck
+secilcheck.8
 policy.*
 file_contexts
 docs/html
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/secilc-3.10/Makefile new/secilc-3.11/Makefile
--- old/secilc-3.10/Makefile    2026-02-02 03:01:16.000000000 +0100
+++ new/secilc-3.11/Makefile    2026-07-01 18:51:05.000000000 +0200
@@ -14,9 +14,14 @@
 SECIL2TREE_SRCS := secil2tree.c
 SECIL2TREE_OBJS := $(patsubst %.c,%.o,$(SECIL2TREE_SRCS))
 
+SECILCHECK = secilcheck
+SECILCHECK_SRCS := secilcheck.c
+SECILCHECK_OBJS := $(patsubst %.c,%.o,$(SECILCHECK_SRCS))
+
 SECILC_MANPAGE = secilc.8
 SECIL2CONF_MANPAGE = secil2conf.8
 SECIL2TREE_MANPAGE = secil2tree.8
+SECILCHECK_MANPAGE = secilcheck.8
 XMLTO = xmlto
 DIFF = diff
 
@@ -28,7 +33,7 @@
 override CFLAGS += -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64
 override LDLIBS += -lsepol
 
-all: $(SECILC) $(SECIL2CONF) $(SECIL2TREE) man
+all: $(SECILC) $(SECIL2CONF) $(SECIL2TREE) $(SECILCHECK) man
 
 $(SECILC): $(SECILC_OBJS)
        $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS)
@@ -45,7 +50,10 @@
 $(SECIL2TREE): $(SECIL2TREE_OBJS)
        $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS)
 
-man: $(SECILC_MANPAGE) $(SECIL2CONF_MANPAGE) $(SECIL2TREE_MANPAGE)
+$(SECILCHECK): $(SECILCHECK_OBJS)
+       $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS)
+
+man: $(SECILC_MANPAGE) $(SECIL2CONF_MANPAGE) $(SECIL2TREE_MANPAGE) 
$(SECILCHECK_MANPAGE)
 
 $(SECILC_MANPAGE): $(SECILC_MANPAGE).xml
        $(XMLTO) man $(SECILC_MANPAGE).xml
@@ -56,15 +64,20 @@
 $(SECIL2TREE_MANPAGE): $(SECIL2TREE_MANPAGE).xml
        $(XMLTO) man $(SECIL2TREE_MANPAGE).xml
 
+$(SECILCHECK_MANPAGE): $(SECILCHECK_MANPAGE).xml
+       $(XMLTO) man $(SECILCHECK_MANPAGE).xml
+
 install: all man
        -mkdir -p $(DESTDIR)$(BINDIR)
        -mkdir -p $(DESTDIR)$(MANDIR)/man8
        install -m 755 $(SECILC) $(DESTDIR)$(BINDIR)
        install -m 755 $(SECIL2CONF) $(DESTDIR)$(BINDIR)
        install -m 755 $(SECIL2TREE) $(DESTDIR)$(BINDIR)
+       install -m 755 $(SECILCHECK) $(DESTDIR)$(BINDIR)
        install -m 644 $(SECILC_MANPAGE) $(DESTDIR)$(MANDIR)/man8
        install -m 644 $(SECIL2CONF_MANPAGE) $(DESTDIR)$(MANDIR)/man8
        install -m 644 $(SECIL2TREE_MANPAGE) $(DESTDIR)$(MANDIR)/man8
+       install -m 644 $(SECILCHECK_MANPAGE) $(DESTDIR)$(MANDIR)/man8
 
 doc:
        $(MAKE) -C docs
@@ -76,11 +89,14 @@
        rm -f $(SECIL2CONF_OBJS)
        rm -f $(SECIL2TREE)
        rm -f $(SECIL2TREE_OBJS)
+       rm -f $(SECILCHECK)
+       rm -f $(SECILCHECK_OBJS)
        rm -f policy.*
        rm -f file_contexts
        rm -f $(SECILC_MANPAGE)
        rm -f $(SECIL2CONF_MANPAGE)
        rm -f $(SECIL2TREE_MANPAGE)
+       rm -f $(SECILCHECK_MANPAGE)
        rm -f opt-actual.cil
        rm -f opt-actual.bin
        $(MAKE) -C docs clean
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/secilc-3.10/VERSION new/secilc-3.11/VERSION
--- old/secilc-3.10/VERSION     2026-02-02 03:01:16.000000000 +0100
+++ new/secilc-3.11/VERSION     2026-07-01 18:51:05.000000000 +0200
@@ -1 +1 @@
-3.10
+3.11
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/secilc-3.10/docs/cil_access_vector_rules.md 
new/secilc-3.11/docs/cil_access_vector_rules.md
--- old/secilc-3.10/docs/cil_access_vector_rules.md     2026-02-02 
03:01:16.000000000 +0100
+++ new/secilc-3.11/docs/cil_access_vector_rules.md     2026-07-01 
18:51:05.000000000 +0200
@@ -168,7 +168,7 @@
         (type type_2)
         (type type_3)
         (typeattribute all_types)
-        (typeattributeset all_types ((all)))
+        (typeattributeset all_types (all))
 
         (neverallow type_3 all_types (property_service (set)))
         ; This rule will fail compilation:
@@ -313,7 +313,7 @@
                (type type_2)
                (type type_3)
                (typeattribute all_types)
-               (typeattributeset all_types ((all)))
+               (typeattributeset all_types (all))
                (neverallowx type_3 all_types (ioctl property_service (range 
0x2000 0x20FF)))
                ; This rule will fail compilation:
                (allowx type_3 self (ioctl property_service (0x20A0)))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/secilc-3.10/docs/cil_class_and_permission_statements.md 
new/secilc-3.11/docs/cil_class_and_permission_statements.md
--- old/secilc-3.10/docs/cil_class_and_permission_statements.md 2026-02-02 
03:01:16.000000000 +0100
+++ new/secilc-3.11/docs/cil_class_and_permission_statements.md 2026-07-01 
18:51:05.000000000 +0200
@@ -529,7 +529,11 @@
 <tbody>
 <tr class="odd">
 <td align="left"><p>ioctl</p></td>
-<td align="left"><p>Permissions define a whitelist of ioctl values. Permission 
values must range from <code>0x0000</code> to <code>0xFFFF</code>, 
inclusive.</p></td>
+<td align="left"><p>Permissions define a whitelist of ioctl command values. 
Permission values must range from <code>0x0000</code> to <code>0xFFFF</code>, 
inclusive.</p></td>
+</tr>
+<tr class="even">
+<td align="left"><p>nlmsg</p></td>
+<td align="left"><p>Permissions define a whitelist of netlink message type 
values. Permission values must range from <code>0x0000</code> to 
<code>0xFFFF</code>, inclusive.</p></td>
 </tr>
 </tbody>
 </table></td>
@@ -561,4 +565,5 @@
     (permissionx ioctl_1 (ioctl tcp_socket (0x2000 0x3000 0x4000)))
     (permissionx ioctl_2 (ioctl tcp_socket (range 0x6000 0x60FF)))
     (permissionx ioctl_3 (ioctl tcp_socket (and (range 0x8000 0x90FF) (not 
(range 0x8100 0x82FF)))))
+    (permissionx nlmsg_1 (nlmsg netlink_route_socket (range 0x0010 0x0018)))
 ```
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/secilc-3.10/docs/cil_default_object_statements.md 
new/secilc-3.11/docs/cil_default_object_statements.md
--- old/secilc-3.10/docs/cil_default_object_statements.md       2026-02-02 
03:01:16.000000000 +0100
+++ new/secilc-3.11/docs/cil_default_object_statements.md       2026-07-01 
18:51:05.000000000 +0200
@@ -195,7 +195,7 @@
 When creating a new `file` object, the appropriate `range` component of the 
new security context will be taken from the `target` context:
 
 ```secil
-    (defaultrange file target low_high)
+    (defaultrange file target low-high)
 ```
 
 MLS userspace object managers may need to compute the common parts of a range 
such that the object is created with the range common to the subject and 
containing object:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/secilc-3.10/docs/cil_mls_labeling_statements.md 
new/secilc-3.11/docs/cil_mls_labeling_statements.md
--- old/secilc-3.10/docs/cil_mls_labeling_statements.md 2026-02-02 
03:01:16.000000000 +0100
+++ new/secilc-3.11/docs/cil_mls_labeling_statements.md 2026-07-01 
18:51:05.000000000 +0200
@@ -319,7 +319,7 @@
 This example orders one category alias and nine categories:
 
 ```secil
-    (categoryorder (documents c1 c2 c3 c4 c5 c6 c7 c8 c9)
+    (categoryorder (documents c1 c2 c3 c4 c5 c6 c7 c8 c9))
 ```
 
 categoryset
@@ -675,7 +675,7 @@
 ```secil
     (sensitivity s0)
     (sensitivity s1)
-    (sensitivityorder s0 s1)
+    (sensitivityorder (s0 s1))
     (category c0)
     ...
     (level systemlow (s0))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/secilc-3.10/docs/cil_reference_guide.md 
new/secilc-3.11/docs/cil_reference_guide.md
--- old/secilc-3.10/docs/cil_reference_guide.md 2026-02-02 03:01:16.000000000 
+0100
+++ new/secilc-3.11/docs/cil_reference_guide.md 2026-07-01 18:51:05.000000000 
+0200
@@ -93,7 +93,7 @@
 Symbol Character Set
 --------------------
 
-Symbols (any string not enclosed in double quotes) must only contain 
alphanumeric `[a-z A-Z] [0-9]` characters plus the following special 
characters: `\.=/-_$%@+!|&^:`
+Symbols (any string not enclosed in double quotes) must only contain 
alphanumeric `[a-z A-Z] [0-9]` characters plus the following special 
characters: `` [].@=/*-_$%+-!|&^:~`#{}'<>?, ``
 
 However symbols are checked for any specific character set limitations, for 
example:
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/secilc-3.10/docs/cil_role_statements.md 
new/secilc-3.11/docs/cil_role_statements.md
--- old/secilc-3.10/docs/cil_role_statements.md 2026-02-02 03:01:16.000000000 
+0100
+++ new/secilc-3.11/docs/cil_role_statements.md 2026-07-01 18:51:05.000000000 
+0200
@@ -51,7 +51,7 @@
 **Statement definition:**
 
 ```secil
-    (role role_id type_id)
+    (roletype role_id type_id)
 ```
 
 **Where:**
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/secilc-3.10/secil2conf.c new/secilc-3.11/secil2conf.c
--- old/secilc-3.10/secil2conf.c        2026-02-02 03:01:16.000000000 +0100
+++ new/secilc-3.11/secil2conf.c        2026-07-01 18:51:05.000000000 +0200
@@ -76,51 +76,54 @@
        int opt_index = 0;
        enum cil_log_level log_level = CIL_ERR;
        static struct option long_opts[] = {
-               {"help", no_argument, 0, 'h'},
-               {"verbose", no_argument, 0, 'v'},
-               {"mls", required_argument, 0, 'M'},
-               {"preserve-tunables", no_argument, 0, 'P'},
-               {"qualified-names", no_argument, 0, 'Q'},
-               {"output", required_argument, 0, 'o'},
-               {0, 0, 0, 0}
+               { "help", no_argument, NULL, 'h' },
+               { "verbose", no_argument, NULL, 'v' },
+               { "mls", required_argument, NULL, 'M' },
+               { "preserve-tunables", no_argument, NULL, 'P' },
+               { "qualified-names", no_argument, NULL, 'Q' },
+               { "output", required_argument, NULL, 'o' },
+               { NULL, 0, NULL, 0 }
        };
        int i;
 
        while (1) {
-               opt_char = getopt_long(argc, argv, "o:hvM:PQ", long_opts, 
&opt_index);
+               opt_char = getopt_long(argc, argv, "o:hvM:PQ", long_opts,
+                                      &opt_index);
                if (opt_char == -1) {
                        break;
                }
                switch (opt_char) {
-                       case 'v':
-                               log_level++;
-                               break;
-                       case 'M':
-                               if (!strcasecmp(optarg, "true") || 
!strcasecmp(optarg, "1")) {
-                                       mls = 1;
-                               } else if (!strcasecmp(optarg, "false") || 
!strcasecmp(optarg, "0")) {
-                                       mls = 0;
-                               } else {
-                                       usage(argv[0]);
-                               }
-                               break;
-                       case 'P':
-                               preserve_tunables = 1;
-                               break;
-                       case 'Q':
-                               qualified_names = 1;
-                               break;
-                       case 'o':
-                               free(output);
-                               output = strdup(optarg);
-                               break;
-                       case 'h':
-                               usage(argv[0]);
-                       case '?':
-                               break;
-                       default:
-                                       fprintf(stderr, "Unsupported option: 
%s\n", optarg);
+               case 'v':
+                       log_level++;
+                       break;
+               case 'M':
+                       if (!strcasecmp(optarg, "true") ||
+                           !strcasecmp(optarg, "1")) {
+                               mls = 1;
+                       } else if (!strcasecmp(optarg, "false") ||
+                                  !strcasecmp(optarg, "0")) {
+                               mls = 0;
+                       } else {
                                usage(argv[0]);
+                       }
+                       break;
+               case 'P':
+                       preserve_tunables = 1;
+                       break;
+               case 'Q':
+                       qualified_names = 1;
+                       break;
+               case 'o':
+                       free(output);
+                       output = strdup(optarg);
+                       break;
+               case 'h':
+                       usage(argv[0]);
+               case '?':
+                       break;
+               default:
+                       fprintf(stderr, "Unsupported option: %s\n", optarg);
+                       usage(argv[0]);
                }
        }
        if (optind >= argc) {
@@ -144,7 +147,7 @@
                        rc = SEPOL_ERR;
                        goto exit;
                }
-               rc = stat(argv[i], &filedata);
+               rc = fstat(fileno(file), &filedata);
                if (rc == -1) {
                        fprintf(stderr, "Could not stat file: %s\n", argv[i]);
                        goto exit;
@@ -188,7 +191,8 @@
                file = fopen(output, "w");
        }
        if (file == NULL) {
-               fprintf(stderr, "Failure opening policy.conf file for 
writing\n");
+               fprintf(stderr,
+                       "Failure opening policy.conf file for writing\n");
                rc = SEPOL_ERR;
                goto exit;
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/secilc-3.10/secil2tree.c new/secilc-3.11/secil2tree.c
--- old/secilc-3.10/secil2tree.c        2026-02-02 03:01:16.000000000 +0100
+++ new/secilc-3.11/secil2tree.c        2026-07-01 18:51:05.000000000 +0200
@@ -81,55 +81,57 @@
        int opt_index = 0;
        enum cil_log_level log_level = CIL_ERR;
        static struct option long_opts[] = {
-               {"help", no_argument, 0, 'h'},
-               {"verbose", no_argument, 0, 'v'},
-               {"preserve-tunables", no_argument, 0, 'P'},
-               {"qualified-names", no_argument, 0, 'Q'},
-               {"output", required_argument, 0, 'o'},
-               {"ast-phase", required_argument, 0, 'A'},
-               {0, 0, 0, 0}
+               { "help", no_argument, NULL, 'h' },
+               { "verbose", no_argument, NULL, 'v' },
+               { "preserve-tunables", no_argument, NULL, 'P' },
+               { "qualified-names", no_argument, NULL, 'Q' },
+               { "output", required_argument, NULL, 'o' },
+               { "ast-phase", required_argument, NULL, 'A' },
+               { NULL, 0, NULL, 0 }
        };
        int i;
 
        while (1) {
-               opt_char = getopt_long(argc, argv, "o:hvPQA:", long_opts, 
&opt_index);
+               opt_char = getopt_long(argc, argv, "o:hvPQA:", long_opts,
+                                      &opt_index);
                if (opt_char == -1) {
                        break;
                }
                switch (opt_char) {
-                       case 'v':
-                               log_level++;
-                               break;
-                       case 'P':
-                               preserve_tunables = 1;
-                               break;
-                       case 'Q':
-                               qualified_names = 1;
-                               break;
-                       case 'o':
-                               output = strdup(optarg);
-                               break;
-                       case 'A':
-                               if (!strcasecmp(optarg, "parse")) {
-                                       write_ast = WRITE_AST_PHASE_PARSE;
-                               } else if (!strcasecmp(optarg, "build")) {
-                                       write_ast = WRITE_AST_PHASE_BUILD;
-                               } else if (!strcasecmp(optarg, "resolve")) {
-                                       write_ast = WRITE_AST_PHASE_RESOLVE;
-                               } else if (!strcasecmp(optarg, "post")) {
-                                       write_ast = WRITE_AST_PHASE_POST;
-                               } else {
-                                       fprintf(stderr, "Invalid AST phase: 
%s\n", optarg);
-                                       usage(argv[0]);
-                               }
-                               break;
-                       case 'h':
-                               usage(argv[0]);
-                       case '?':
-                               break;
-                       default:
-                               fprintf(stderr, "Unsupported option: %s\n", 
optarg);
+               case 'v':
+                       log_level++;
+                       break;
+               case 'P':
+                       preserve_tunables = 1;
+                       break;
+               case 'Q':
+                       qualified_names = 1;
+                       break;
+               case 'o':
+                       output = strdup(optarg);
+                       break;
+               case 'A':
+                       if (!strcasecmp(optarg, "parse")) {
+                               write_ast = WRITE_AST_PHASE_PARSE;
+                       } else if (!strcasecmp(optarg, "build")) {
+                               write_ast = WRITE_AST_PHASE_BUILD;
+                       } else if (!strcasecmp(optarg, "resolve")) {
+                               write_ast = WRITE_AST_PHASE_RESOLVE;
+                       } else if (!strcasecmp(optarg, "post")) {
+                               write_ast = WRITE_AST_PHASE_POST;
+                       } else {
+                               fprintf(stderr, "Invalid AST phase: %s\n",
+                                       optarg);
                                usage(argv[0]);
+                       }
+                       break;
+               case 'h':
+                       usage(argv[0]);
+               case '?':
+                       break;
+               default:
+                       fprintf(stderr, "Unsupported option: %s\n", optarg);
+                       usage(argv[0]);
                }
        }
 
@@ -153,7 +155,7 @@
                        rc = SEPOL_ERR;
                        goto exit;
                }
-               rc = stat(argv[i], &filedata);
+               rc = fstat(fileno(file), &filedata);
                if (rc == -1) {
                        fprintf(stderr, "Could not stat file: %s\n", argv[i]);
                        goto exit;
@@ -190,7 +192,8 @@
        } else {
                file = fopen(output, "w");
                if (file == NULL) {
-                       fprintf(stderr, "Failure opening file %s for 
writing\n", output);
+                       fprintf(stderr, "Failure opening file %s for writing\n",
+                               output);
                        rc = SEPOL_ERR;
                        goto exit;
                }
@@ -217,7 +220,7 @@
        }
 
 exit:
-       if (file != NULL && file != stdin) {
+       if (file != NULL && file != stdout) {
                fclose(file);
        }
        free(buffer);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/secilc-3.10/secilc.c new/secilc-3.11/secilc.c
--- old/secilc-3.10/secilc.c    2026-02-02 03:01:16.000000000 +0100
+++ new/secilc-3.11/secilc.c    2026-07-01 18:51:05.000000000 +0200
@@ -56,7 +56,8 @@
        printf("                                 This will override the (mls 
boolean) statement\n");
        printf("                                 if present in the policy\n");
        printf("  -c, --policyvers=<version>     build a binary policy with a 
given <version>\n");
-       printf("                                 (default: %i)\n", 
POLICYDB_VERSION_MAX);
+       printf("                                 (default: %i)\n",
+              POLICYDB_VERSION_MAX);
        printf("  -U, --handle-unknown=<action>  how to handle unknown classes 
or permissions.\n");
        printf("                                 may be deny, allow, or reject. 
(default: deny)\n");
        printf("                                 This will override the 
(handleunknown action)\n");
@@ -109,131 +110,141 @@
        size_t fc_size;
        enum cil_log_level log_level = CIL_ERR;
        static struct option long_opts[] = {
-               {"help", no_argument, 0, 'h'},
-               {"verbose", no_argument, 0, 'v'},
-               {"target", required_argument, 0, 't'},
-               {"mls", required_argument, 0, 'M'},
-               {"policyversion", required_argument, 0, 'c'},
-               {"handle-unknown", required_argument, 0, 'U'},
-               {"disable-dontaudit", no_argument, 0, 'D'},
-               {"multiple-decls", no_argument, 0, 'm'},
-               {"disable-neverallow", no_argument, 0, 'N'},
-               {"preserve-tunables", no_argument, 0, 'P'},
-               {"qualified-names", no_argument, 0, 'Q'},
-               {"output", required_argument, 0, 'o'},
-               {"filecontexts", required_argument, 0, 'f'},
-               {"expand-generated", no_argument, 0, 'G'},
-               {"expand-size", required_argument, 0, 'X'},
-               {"optimize", no_argument, 0, 'O'},
-               {0, 0, 0, 0}
+               { "help", no_argument, NULL, 'h' },
+               { "verbose", no_argument, NULL, 'v' },
+               { "target", required_argument, NULL, 't' },
+               { "mls", required_argument, NULL, 'M' },
+               { "policyversion", required_argument, NULL, 'c' },
+               { "handle-unknown", required_argument, NULL, 'U' },
+               { "disable-dontaudit", no_argument, NULL, 'D' },
+               { "multiple-decls", no_argument, NULL, 'm' },
+               { "disable-neverallow", no_argument, NULL, 'N' },
+               { "preserve-tunables", no_argument, NULL, 'P' },
+               { "qualified-names", no_argument, NULL, 'Q' },
+               { "output", required_argument, NULL, 'o' },
+               { "filecontexts", required_argument, NULL, 'f' },
+               { "expand-generated", no_argument, NULL, 'G' },
+               { "expand-size", required_argument, NULL, 'X' },
+               { "optimize", no_argument, NULL, 'O' },
+               { NULL, 0, NULL, 0 }
        };
        int i;
 
        while (1) {
-               opt_char = getopt_long(argc, argv, "o:f:U:hvt:M:PQDmNOc:GX:n", 
long_opts, &opt_index);
+               opt_char = getopt_long(argc, argv, "o:f:U:hvt:M:PQDmNOc:GX:n",
+                                      long_opts, &opt_index);
                if (opt_char == -1) {
                        break;
                }
                switch (opt_char) {
-                       case 'v':
-                               log_level++;
-                               break;
-                       case 't':
-                               if (!strcmp(optarg, "selinux")) {
-                                       target = SEPOL_TARGET_SELINUX;
-                               } else if (!strcmp(optarg, "xen")) {
-                                       target = SEPOL_TARGET_XEN;
-                               } else {
-                                       fprintf(stderr, "Unknown target: %s\n", 
optarg);
-                                       usage(argv[0]);
-                               }
-                               break;
-                       case 'M':
-                               if (!strcasecmp(optarg, "true") || 
!strcasecmp(optarg, "1")) {
-                                       mls = 1;
-                               } else if (!strcasecmp(optarg, "false") || 
!strcasecmp(optarg, "0")) {
-                                       mls = 0;
-                               } else {
-                                       usage(argv[0]);
-                               }
-                               break;
-                       case 'c': {
-                               char *endptr = NULL;
-                               errno = 0;
-                               policyvers = strtol(optarg, &endptr, 10);
-                               if (errno != 0 || endptr == optarg || *endptr 
!= '\0') {
-                                       fprintf(stderr, "Bad policy version: 
%s\n", optarg);
-                                       usage(argv[0]);
-                               }
-                               if (policyvers > POLICYDB_VERSION_MAX || 
policyvers < POLICYDB_VERSION_MIN) {
-                                       fprintf(stderr, "Policy version must be 
between %d and %d\n",
-                                              POLICYDB_VERSION_MIN, 
POLICYDB_VERSION_MAX);
-                                       usage(argv[0]);
-                               }
-                               break;
+               case 'v':
+                       log_level++;
+                       break;
+               case 't':
+                       if (!strcmp(optarg, "selinux")) {
+                               target = SEPOL_TARGET_SELINUX;
+                       } else if (!strcmp(optarg, "xen")) {
+                               target = SEPOL_TARGET_XEN;
+                       } else {
+                               fprintf(stderr, "Unknown target: %s\n", optarg);
+                               usage(argv[0]);
                        }
-                       case 'U':
-                               if (!strcasecmp(optarg, "deny")) {
-                                       handle_unknown = SEPOL_DENY_UNKNOWN;
-                               } else if (!strcasecmp(optarg, "allow")) {
-                                       handle_unknown = SEPOL_ALLOW_UNKNOWN;
-                               } else if (!strcasecmp(optarg, "reject")) {
-                                       handle_unknown = SEPOL_REJECT_UNKNOWN;
-                               } else {
-                                       usage(argv[0]);
-                               }
-                               break;
-                       case 'D':
-                               disable_dontaudit = 1;
-                               break;
-                       case 'm':
-                               multiple_decls = 1;
-                               break;
-                       case 'N':
-                               disable_neverallow = 1;
-                               break;
-                       case 'P':
-                               preserve_tunables = 1;
-                               break;
-                       case 'Q':
-                               qualified_names = 1;
-                               break;
-                       case 'o':
-                               free(output);
-                               output = strdup(optarg);
-                               break;
-                       case 'f':
-                               free(filecontexts);
-                               filecontexts = strdup(optarg);
-                               break;
-                       case 'G':
-                               attrs_expand_generated = 1;
-                               break;
-                       case 'X': {
-                               char *endptr = NULL;
-                               errno = 0;
-                               attrs_expand_size = strtol(optarg, &endptr, 10);
-                               if (errno != 0 || endptr == optarg || *endptr 
!= '\0') {
-                                       fprintf(stderr, "Bad attribute expand 
size: %s\n", optarg);
-                                       usage(argv[0]);
-                               }
-
-                               if (attrs_expand_size < 0) {
-                                       fprintf(stderr, "Attribute expand size 
must be > 0\n");
-                                       usage(argv[0]);
-                               }
-                               break;
+                       break;
+               case 'M':
+                       if (!strcasecmp(optarg, "true") ||
+                           !strcasecmp(optarg, "1")) {
+                               mls = 1;
+                       } else if (!strcasecmp(optarg, "false") ||
+                                  !strcasecmp(optarg, "0")) {
+                               mls = 0;
+                       } else {
+                               usage(argv[0]);
                        }
-                       case 'O':
-                               optimize = 1;
-                               break;
-                       case 'h':
+                       break;
+               case 'c': {
+                       char *endptr = NULL;
+                       errno = 0;
+                       policyvers = strtol(optarg, &endptr, 10);
+                       if (errno != 0 || endptr == optarg || *endptr != '\0') {
+                               fprintf(stderr, "Bad policy version: %s\n",
+                                       optarg);
                                usage(argv[0]);
-                       case '?':
-                               break;
-                       default:
-                                       fprintf(stderr, "Unsupported option: 
%s\n", optarg);
+                       }
+                       if (policyvers > POLICYDB_VERSION_MAX ||
+                           policyvers < POLICYDB_VERSION_MIN) {
+                               fprintf(stderr,
+                                       "Policy version must be between %d and 
%d\n",
+                                       POLICYDB_VERSION_MIN,
+                                       POLICYDB_VERSION_MAX);
                                usage(argv[0]);
+                       }
+                       break;
+               }
+               case 'U':
+                       if (!strcasecmp(optarg, "deny")) {
+                               handle_unknown = SEPOL_DENY_UNKNOWN;
+                       } else if (!strcasecmp(optarg, "allow")) {
+                               handle_unknown = SEPOL_ALLOW_UNKNOWN;
+                       } else if (!strcasecmp(optarg, "reject")) {
+                               handle_unknown = SEPOL_REJECT_UNKNOWN;
+                       } else {
+                               usage(argv[0]);
+                       }
+                       break;
+               case 'D':
+                       disable_dontaudit = 1;
+                       break;
+               case 'm':
+                       multiple_decls = 1;
+                       break;
+               case 'N':
+                       disable_neverallow = 1;
+                       break;
+               case 'P':
+                       preserve_tunables = 1;
+                       break;
+               case 'Q':
+                       qualified_names = 1;
+                       break;
+               case 'o':
+                       free(output);
+                       output = strdup(optarg);
+                       break;
+               case 'f':
+                       free(filecontexts);
+                       filecontexts = strdup(optarg);
+                       break;
+               case 'G':
+                       attrs_expand_generated = 1;
+                       break;
+               case 'X': {
+                       char *endptr = NULL;
+                       errno = 0;
+                       attrs_expand_size = strtol(optarg, &endptr, 10);
+                       if (errno != 0 || endptr == optarg || *endptr != '\0') {
+                               fprintf(stderr,
+                                       "Bad attribute expand size: %s\n",
+                                       optarg);
+                               usage(argv[0]);
+                       }
+
+                       if (attrs_expand_size < 0) {
+                               fprintf(stderr,
+                                       "Attribute expand size must be > 0\n");
+                               usage(argv[0]);
+                       }
+                       break;
+               }
+               case 'O':
+                       optimize = 1;
+                       break;
+               case 'h':
+                       usage(argv[0]);
+               case '?':
+                       break;
+               default:
+                       fprintf(stderr, "Unsupported option: %s\n", optarg);
+                       usage(argv[0]);
                }
        }
        if (optind >= argc) {
@@ -271,7 +282,7 @@
                        rc = SEPOL_ERR;
                        goto exit;
                }
-               rc = stat(argv[i], &filedata);
+               rc = fstat(fileno(file), &filedata);
                if (rc == -1) {
                        fprintf(stderr, "Could not stat file: %s\n", argv[i]);
                        rc = SEPOL_ERR;
@@ -339,7 +350,8 @@
                        rc = SEPOL_ERR;
                        goto exit;
                }
-               if (snprintf(output, size + 1, "policy.%d", policyvers) != 
size) {
+               if (snprintf(output, size + 1, "policy.%d", policyvers) !=
+                   size) {
                        fprintf(stderr, "Failed to create output filename\n");
                        rc = SEPOL_ERR;
                        goto exit;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/secilc-3.10/secilcheck.8.xml 
new/secilc-3.11/secilcheck.8.xml
--- old/secilc-3.10/secilcheck.8.xml    1970-01-01 01:00:00.000000000 +0100
+++ new/secilc-3.11/secilcheck.8.xml    2026-07-01 18:51:05.000000000 +0200
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+               "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd";>
+
+<refentry>
+   <refentryinfo>
+      <author>
+         
<firstname>James</firstname><surname>Carter</surname><contrib></contrib>
+      </author>
+   </refentryinfo>
+
+   <refmeta>
+      <refentrytitle>SECILCHECK</refentrytitle>
+      <manvolnum>8</manvolnum>
+      <refmiscinfo class="date">29 May 2026</refmiscinfo>
+      <refmiscinfo class="source">secilcheck</refmiscinfo>
+      <refmiscinfo class="manual">Check binary policy file against CIL 
neverallow files</refmiscinfo>
+   </refmeta>
+   <refnamediv id="name">
+      <refname>secilcheck</refname>
+      <refpurpose>invoke the CIL neverallow checker</refpurpose>
+   </refnamediv>
+
+   <refsynopsisdiv id="synopsis">
+      <cmdsynopsis>
+        <command>secilcheck</command>
+          <arg choice="opt" 
rep="repeat"><replaceable>OPTION</replaceable></arg>
+          <arg choice="plain"><replaceable>binary</replaceable></arg>
+          <arg choice="plain" 
rep="repeat"><replaceable>file</replaceable></arg>
+      </cmdsynopsis>
+   </refsynopsisdiv>
+
+   <refsect1 id="description"><title>DESCRIPTION</title>
+      <para><emphasis role="italic">secilcheck</emphasis> invokes the CIL 
neverallow checker with specified <emphasis 
role="italic">argument</emphasis>s.</para>
+   </refsect1>
+
+   <refsect1 id="options"><title>OPTIONS</title>
+      <variablelist>
+         <varlistentry>
+            <term><option>-Q, --qualified-names</option></term>
+            <listitem><para>Allow names containing dots (qualified names). 
Blocks, blockinherits, blockabstracts, and in-statements will not be 
allowed.</para></listitem>
+         </varlistentry>
+
+         <varlistentry>
+            <term><option>-m, --multiple-decls</option></term>
+            <listitem><para>Allow some statements to be 
re-declared.</para></listitem>
+         </varlistentry>
+
+         <varlistentry>
+            <term><option>-v, --verbose</option></term>
+            <listitem><para>Increment verbosity level.</para></listitem>
+         </varlistentry>
+
+         <varlistentry>
+            <term><option>-h, --help</option></term>
+            <listitem><para>Display usage information.</para></listitem>
+         </varlistentry>
+      </variablelist>
+   </refsect1>
+
+   <refsect1 id="see_also"><title>SEE ALSO</title>
+      <para>
+      <simplelist type="inline">
+         <member><citerefentry>
+            <refentrytitle>secilc</refentrytitle>
+            <manvolnum>8</manvolnum>
+         </citerefentry></member>
+         <member><citerefentry>
+            <refentrytitle>secil2tree</refentrytitle>
+            <manvolnum>8</manvolnum>
+         </citerefentry></member>
+         <member><citerefentry>
+            <refentrytitle>secil2conf</refentrytitle>
+            <manvolnum>8</manvolnum>
+         </citerefentry></member>
+      </simplelist>
+      </para>
+      <para>HTML documentation describing the CIL language statements is 
available starting with <emphasis 
role="italic">docs/html/index.html</emphasis>.</para>
+      <para>PDF documentation describing the CIL language statements is 
available at: <emphasis 
role="italic">docs/pdf/CIL_Reference_Guide.pdf</emphasis>.</para>
+   </refsect1>
+</refentry>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/secilc-3.10/secilcheck.c new/secilc-3.11/secilcheck.c
--- old/secilc-3.10/secilcheck.c        1970-01-01 01:00:00.000000000 +0100
+++ new/secilc-3.11/secilcheck.c        2026-07-01 18:51:05.000000000 +0200
@@ -0,0 +1,309 @@
+/*
+ * Copyright 2011 Tresys Technology, LLC. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright notice,
+ *       this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright 
notice,
+ *       this list of conditions and the following disclaimer in the 
documentation
+ *       and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY 
EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
(INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 
USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are 
those
+ * of the authors and should not be interpreted as representing official 
policies,
+ * either expressed or implied, of Tresys Technology, LLC.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <string.h>
+#include <getopt.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#ifdef ANDROID
+#include <cil/cil.h>
+#else
+#include <sepol/cil/cil.h>
+#endif
+#include <sepol/policydb.h>
+#include <sepol/kernel_to_cil.h>
+
+static int get_binary_policy_db(const char *filename, sepol_policydb_t *pdb)
+{
+       int fd;
+       struct stat sb;
+       void *map = NULL;
+       sepol_policy_file_t *pf = NULL;
+       int rc = SEPOL_ERR;
+
+       /* Read binary policy */
+       fd = open(filename, O_RDONLY);
+       if (fd < 0) {
+               fprintf(stderr, "Could not open file: %s\n", filename);
+               goto exit;
+       }
+       if (fstat(fd, &sb) < 0) {
+               fprintf(stderr, "Could not stat file: %s\n", filename);
+               goto exit;
+       }
+       map = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd,
+                  0);
+       if (map == MAP_FAILED) {
+               fprintf(stderr, "Could not map file: %s\n", filename);
+               goto exit;
+       }
+
+       if (sepol_policy_file_create(&pf) < 0) {
+               fprintf(stderr, "Out of memory");
+               goto exit;
+       }
+       sepol_policy_file_set_mem(pf, map, sb.st_size);
+
+       if (sepol_policydb_read(pdb, pf) < 0) {
+               fprintf(stderr, "Error reading binary policy: %s\n", filename);
+               rc = SEPOL_ERR;
+               goto exit;
+       }
+
+       rc = SEPOL_OK;
+
+exit:
+       if (fd >= 0)
+               close(fd);
+       if (map)
+               munmap(map, sb.st_size);
+       sepol_policy_file_free(pf);
+       return rc;
+}
+
+static int add_decls_to_cil(const char *filename, sepol_policydb_t *pdb,
+                           struct cil_db *db)
+{
+       FILE *cfp = NULL;
+       char *cptr = NULL;
+       size_t csize;
+       int rc = SEPOL_ERR;
+
+       cfp = open_memstream(&cptr, &csize);
+       if (!cfp) {
+               fprintf(stderr,
+                       "Failed to open dynamic memory buffer stream\n");
+               goto exit;
+       }
+
+       if (sepol_kernel_policydb_decls_to_cil(cfp, &pdb->p) < 0) {
+               fprintf(stderr, "Failed to convert binary policy to CIL\n");
+               goto exit;
+       }
+
+       if (fflush(cfp) < 0) {
+               fprintf(stderr, "Failed to flush CIL memory buffer stream\n");
+               goto exit;
+       }
+
+       /* Add to CIL db */
+       if (cil_add_file(db, filename, cptr, csize) < 0) {
+               fprintf(stderr, "Failed to add binary policy file: %s\n",
+                       filename);
+               goto exit;
+       }
+
+       rc = 0;
+
+exit:
+       if (cfp)
+               fclose(cfp);
+       if (cptr)
+               free(cptr);
+       return rc;
+}
+
+static int add_cil_file(const char *filename, struct cil_db *cdb)
+{
+       FILE *file;
+       struct stat filedata;
+       char *buffer = NULL;
+       size_t file_size;
+       int rc = -1;
+
+       file = fopen(filename, "r");
+       if (!file) {
+               fprintf(stderr, "Could not open file: %s\n", filename);
+               goto exit;
+       }
+       if (fstat(fileno(file), &filedata) < 0) {
+               fprintf(stderr, "Could not stat file: %s\n", filename);
+               goto exit;
+       }
+       file_size = filedata.st_size;
+
+       if (!file_size) {
+               fclose(file);
+               rc = 0;
+               goto exit;
+       }
+
+       buffer = malloc(file_size);
+       if (!buffer) {
+               fprintf(stderr, "Out of memory\n");
+               goto exit;
+       }
+
+       if (fread(buffer, file_size, 1, file) != 1) {
+               fprintf(stderr, "Failure reading file: %s\n", filename);
+               goto exit;
+       }
+
+       if (cil_add_file(cdb, filename, buffer, file_size) < 0) {
+               fprintf(stderr, "Failure adding %s\n", filename);
+               goto exit;
+       }
+
+       rc = 0;
+
+exit:
+       if (file)
+               fclose(file);
+       if (buffer)
+               free(buffer);
+       return rc;
+}
+
+static __attribute__((__noreturn__)) void usage(const char *prog)
+{
+       printf("Usage: %s [OPTION]... BIN_POLICY CIL_NEVERALLOW_FILE1...\n",
+              prog);
+       printf("\n");
+       printf("Options:\n");
+       printf("  -Q, --qualified-names          Allow names containing dots 
(qualified names).\n");
+       printf("                                 Blocks, blockinherits, 
blockabstracts, and\n");
+       printf("                                 in-statements will not be 
allowed.\n");
+       printf("  -m, --multiple-decls           allow some statements to be 
re-declared\n");
+       printf("  -v, --verbose                  increment verbosity level\n");
+       printf("  -h, --help                     display usage information\n");
+       exit(1);
+}
+
+int main(int argc, char *argv[])
+{
+       int rc = SEPOL_ERR;
+       sepol_policydb_t *pdb = NULL;
+       int violation = 0;
+       struct cil_db *db = NULL;
+       int multiple_decls = 0;
+       int qualified_names = 0;
+       int opt_char;
+       int opt_index = 0;
+       enum cil_log_level log_level = CIL_ERR;
+       static struct option long_opts[] = {
+               { "help", no_argument, NULL, 'h' },
+               { "verbose", no_argument, NULL, 'v' },
+               { "multiple-decls", no_argument, NULL, 'm' },
+               { "qualified-names", no_argument, NULL, 'Q' },
+               { NULL, 0, NULL, 0 }
+       };
+
+       while (1) {
+               opt_char =
+                       getopt_long(argc, argv, "hvQm", long_opts, &opt_index);
+               if (opt_char == -1) {
+                       break;
+               }
+               switch (opt_char) {
+               case 'v':
+                       log_level++;
+                       break;
+               case 'm':
+                       multiple_decls = 1;
+                       break;
+               case 'Q':
+                       qualified_names = 1;
+                       break;
+               case 'h':
+                       usage(argv[0]);
+               case '?':
+                       break;
+               default:
+                       fprintf(stderr, "Unsupported option: %s\n", optarg);
+                       usage(argv[0]);
+               }
+       }
+
+       if (argc < optind + 2) {
+               fprintf(stderr, "Not enough files specified\n");
+               usage(argv[0]);
+       }
+
+       cil_set_log_level(log_level);
+
+       cil_db_init(&db);
+       cil_set_multiple_decls(db, multiple_decls);
+       cil_set_qualified_names(db, qualified_names);
+
+       if (sepol_policydb_create(&pdb) < 0) {
+               fprintf(stderr, "Out of memory\n");
+               goto exit;
+       }
+       if (get_binary_policy_db(argv[optind], pdb) < 0) {
+               fprintf(stderr, "Failed to get binary policy db\n");
+               rc = SEPOL_ERR;
+               goto exit;
+       }
+       if (add_decls_to_cil(argv[optind], pdb, db) < 0) {
+               fprintf(stderr, "Failed to convert decls to CIL\n");
+               rc = SEPOL_ERR;
+               goto exit;
+       }
+       optind++;
+
+       do {
+               if (add_cil_file(argv[optind], db) < 0) {
+                       fprintf(stderr,
+                               "Failed to add cil file to CIL files\n");
+                       rc = SEPOL_ERR;
+                       goto exit;
+               }
+               optind++;
+       } while (optind < argc);
+
+       rc = cil_compile(db);
+       if (rc != SEPOL_OK) {
+               fprintf(stderr, "Failed to compile cildb: %d\n", rc);
+               goto exit;
+       }
+
+       rc = cil_check_neverallows_against_pdb(db, &pdb->p, &violation);
+       if (rc != SEPOL_OK) {
+               fprintf(stderr, "Failed to complete neverallow checking\n");
+               goto exit;
+       }
+       if (violation == 1) {
+               fprintf(stderr, "There was a neverallow violation\n");
+               rc = SEPOL_ERR;
+               goto exit;
+       }
+
+       rc = SEPOL_OK;
+
+exit:
+       cil_db_destroy(&db);
+       sepol_policydb_free(pdb);
+       return rc;
+}

Reply via email to