Hello community,

here is the log from the commit of package libsepol for openSUSE:Factory 
checked in at 2013-11-07 14:44:54
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libsepol (Old)
 and      /work/SRC/openSUSE:Factory/.libsepol.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libsepol"

Changes:
--------
--- /work/SRC/openSUSE:Factory/libsepol/libsepol.changes        2013-07-02 
07:39:07.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.libsepol.new/libsepol.changes   2013-11-07 
14:44:55.000000000 +0100
@@ -1,0 +2,13 @@
+Thu Oct 31 13:36:48 UTC 2013 - [email protected]
+
+- Update to version 2.2
+  * Allow constraint denial cause to be determined
+         - Add kernel policy version 29.
+         - Add modular policy version 17.
+         - Add sepol_compute_av_reason_buffer(), sepol_string_to_security
+       _class(), sepol_string_to_av_perm().
+  * Support overriding Makefile RANLIB
+  * Fix man pages
+- Remove libsepol-rhat.patch; merged on upstream
+
+-------------------------------------------------------------------

Old:
----
  libsepol-2.1.9.tar.gz
  libsepol-rhat.patch

New:
----
  libsepol-2.2.tar.gz

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

Other differences:
------------------
++++++ libsepol.spec ++++++
--- /var/tmp/diff_new_pack.2xq4of/_old  2013-11-07 14:45:01.000000000 +0100
+++ /var/tmp/diff_new_pack.2xq4of/_new  2013-11-07 14:45:01.000000000 +0100
@@ -17,16 +17,15 @@
 
 
 Name:           libsepol
-Version:        2.1.9
+Version:        2.2
 Release:        0
 Url:            http://www.nsa.gov/selinux/
 Summary:        SELinux binary policy manipulation library
 License:        LGPL-2.1+
 Group:          System/Libraries
-Source:         
http://userspace.selinuxproject.org/releases/20130423/%{name}-%{version}.tar.gz
+Source:         
http://userspace.selinuxproject.org/releases/20131030/%{name}-%{version}.tar.gz
 Source2:        baselibs.conf
 Patch:          libsepol-2.1.4-role_fix_callback.patch
-Patch2:         libsepol-rhat.patch
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 BuildRequires:  pkg-config
 
@@ -101,7 +100,6 @@
 %prep
 %setup -q
 %patch -p1
-%patch2 -p2
 
 %build
 make %{?_smp_mflags} CC="%{__cc}" CFLAGS="$RPM_OPT_FLAGS $(getconf LFS_CFLAGS)"

++++++ libsepol-2.1.9.tar.gz -> libsepol-2.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsepol-2.1.9/ChangeLog new/libsepol-2.2/ChangeLog
--- old/libsepol-2.1.9/ChangeLog        2013-02-06 02:43:22.000000000 +0100
+++ new/libsepol-2.2/ChangeLog  2013-10-30 17:51:19.000000000 +0100
@@ -1,3 +1,11 @@
+2.2 2013-10-30
+       * Allow constraint denial cause to be determined from Richard Haines.
+         - Add kernel policy version 29.
+         - Add modular policy version 17.
+         - Add sepol_compute_av_reason_buffer(), 
sepol_string_to_security_class(), sepol_string_to_av_perm().
+       * Support overriding Makefile RANLIB from Sven Vermeulen.
+       * Fix man pages from Laurent Bigonville.
+
 2.1.9 2013-02-01
        * filename_trans: use some better sorting to compare and merge
        * coverity fixes
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsepol-2.1.9/VERSION new/libsepol-2.2/VERSION
--- old/libsepol-2.1.9/VERSION  2013-02-06 02:43:22.000000000 +0100
+++ new/libsepol-2.2/VERSION    2013-10-30 17:51:19.000000000 +0100
@@ -1 +1 @@
-2.1.9
+2.2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsepol-2.1.9/include/sepol/policydb/policydb.h 
new/libsepol-2.2/include/sepol/policydb/policydb.h
--- old/libsepol-2.1.9/include/sepol/policydb/policydb.h        2013-02-06 
02:43:22.000000000 +0100
+++ new/libsepol-2.2/include/sepol/policydb/policydb.h  2013-10-30 
17:51:19.000000000 +0100
@@ -683,10 +683,11 @@
 #define POLICYDB_VERSION_ROLETRANS     26
 #define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS   27
 #define POLICYDB_VERSION_DEFAULT_TYPE  28
+#define POLICYDB_VERSION_CONSTRAINT_NAMES      29
 
 /* Range of policy versions we understand*/
 #define POLICYDB_VERSION_MIN   POLICYDB_VERSION_BASE
-#define POLICYDB_VERSION_MAX   POLICYDB_VERSION_DEFAULT_TYPE
+#define POLICYDB_VERSION_MAX   POLICYDB_VERSION_CONSTRAINT_NAMES
 
 /* Module versions and specific changes*/
 #define MOD_POLICYDB_VERSION_BASE              4
@@ -704,9 +705,10 @@
 #define MOD_POLICYDB_VERSION_TUNABLE_SEP       14
 #define MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS       15
 #define MOD_POLICYDB_VERSION_DEFAULT_TYPE      16
+#define MOD_POLICYDB_VERSION_CONSTRAINT_NAMES  17
 
 #define MOD_POLICYDB_VERSION_MIN MOD_POLICYDB_VERSION_BASE
-#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_DEFAULT_TYPE
+#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_CONSTRAINT_NAMES
 
 #define POLICYDB_CONFIG_MLS    1
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsepol-2.1.9/include/sepol/policydb/services.h 
new/libsepol-2.2/include/sepol/policydb/services.h
--- old/libsepol-2.1.9/include/sepol/policydb/services.h        2013-02-06 
02:43:22.000000000 +0100
+++ new/libsepol-2.2/include/sepol/policydb/services.h  2013-10-30 
17:51:19.000000000 +0100
@@ -59,6 +59,38 @@
                                   unsigned int *reason);
 
 /*
+ * Same as above, but also returns the constraint expression calculations
+ * whether allowed or denied in a buffer. This buffer is allocated by
+ * this call and must be free'd by the caller using free(3). The contraint
+ * buffer will contain any constraints in infix notation.
+ * If the SHOW_GRANTED flag is set it will show granted and denied
+ * constraints. The default is to show only denied constraints.
+ */
+#define SHOW_GRANTED 1
+extern int sepol_compute_av_reason_buffer(sepol_security_id_t ssid,
+                                  sepol_security_id_t tsid,
+                                  sepol_security_class_t tclass,
+                                  sepol_access_vector_t requested,
+                                  struct sepol_av_decision *avd,
+                                  unsigned int *reason,
+                                  char **reason_buf,
+                                  unsigned int flags);
+/*
+ * Return a class ID associated with the class string representation
+ * specified by `class_name'.
+ */
+extern int sepol_string_to_security_class(const char *class_name,
+                                       sepol_security_class_t  *tclass);
+
+/*
+ * Return a permission av bit associated with tclass and the string
+ * representation of the `perm_name'.
+ */
+extern int sepol_string_to_av_perm(sepol_security_class_t tclass,
+                                       const char *perm_name,
+                                       sepol_access_vector_t *av);
+
+/*
  * Compute a SID to use for labeling a new object in the 
  * class `tclass' based on a SID pair.  
  */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsepol-2.1.9/man/man3/sepol_check_context.3 
new/libsepol-2.2/man/man3/sepol_check_context.3
--- old/libsepol-2.1.9/man/man3/sepol_check_context.3   2013-02-06 
02:43:22.000000000 +0100
+++ new/libsepol-2.2/man/man3/sepol_check_context.3     2013-10-30 
17:51:19.000000000 +0100
@@ -22,4 +22,4 @@
 from libselinux instead.
 
 .SH "RETURN VALUE"
-Returns 0 on success or -1 with errno set otherwise.
+Returns 0 on success or \-1 with errno set otherwise.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsepol-2.1.9/man/man3/sepol_genbools.3 
new/libsepol-2.2/man/man3/sepol_genbools.3
--- old/libsepol-2.1.9/man/man3/sepol_genbools.3        2013-02-06 
02:43:22.000000000 +0100
+++ new/libsepol-2.2/man/man3/sepol_genbools.3  2013-10-30 17:51:19.000000000 
+0100
@@ -21,7 +21,7 @@
 (names, values) with nel elements each.
 
 .SH "RETURN VALUE"
-Returns 0 on success or -1 otherwise, with errno set appropriately.
+Returns 0 on success or \-1 otherwise, with errno set appropriately.
 An errno of ENOENT indicates that the boolean file did not exist.
 An errno of EINVAL indicates that one or more booleans listed in the
 boolean file was undefined in the policy or had an invalid value specified;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsepol-2.1.9/man/man3/sepol_genusers.3 
new/libsepol-2.2/man/man3/sepol_genusers.3
--- old/libsepol-2.1.9/man/man3/sepol_genusers.3        2013-02-06 
02:43:22.000000000 +0100
+++ new/libsepol-2.2/man/man3/sepol_genusers.3  2013-10-30 17:51:19.000000000 
+0100
@@ -44,7 +44,7 @@
 in order to enable deletion of such users.
 
 .SH "RETURN VALUE"
-Returns 0 on success or -1 otherwise, with errno set appropriately.
+Returns 0 on success or \-1 otherwise, with errno set appropriately.
 An errno of ENOENT indicates that one or both of the user
 configuration files did not exist.  An errno of EINVAL indicates that
 either the original binary policy image or the generated one were
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsepol-2.1.9/src/Makefile 
new/libsepol-2.2/src/Makefile
--- old/libsepol-2.1.9/src/Makefile     2013-02-06 02:43:22.000000000 +0100
+++ new/libsepol-2.2/src/Makefile       2013-10-30 17:51:19.000000000 +0100
@@ -3,7 +3,8 @@
 INCLUDEDIR ?= $(PREFIX)/include
 LIBDIR ?= $(PREFIX)/lib
 SHLIBDIR ?= $(DESTDIR)/lib
-LIBBASE=$(shell basename $(LIBDIR))
+RANLIB ?= ranlib
+LIBBASE ?= $(shell basename $(LIBDIR))
 
 VERSION = $(shell cat ../VERSION)
 LIBVERSION = 1
@@ -21,7 +22,7 @@
 
 $(LIBA):  $(OBJS)
        $(AR) rcs $@ $^
-       ranlib $@
+       $(RANLIB) $@
 
 $(LIBSO): $(LOBJS)
        $(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $^ 
-Wl,-soname,$(LIBSO),--version-script=libsepol.map,-z,defs
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsepol-2.1.9/src/expand.c 
new/libsepol-2.2/src/expand.c
--- old/libsepol-2.1.9/src/expand.c     2013-02-06 02:43:22.000000000 +0100
+++ new/libsepol-2.2/src/expand.c       2013-10-30 17:51:19.000000000 +0100
@@ -384,6 +384,17 @@
                        new_expr->op = expr->op;
                        if (new_expr->expr_type == CEXPR_NAMES) {
                                if (new_expr->attr & CEXPR_TYPE) {
+                                       /*
+                                        * Copy over constraint policy source 
types and/or
+                                        * attributes for 
sepol_compute_av_reason_buffer(3)
+                                        * so that utilities can analyse 
constraint errors.
+                                        */
+                                       if 
(map_ebitmap(&expr->type_names->types,
+                                                       
&new_expr->type_names->types,
+                                                       state->typemap)) {
+                                               ERR(NULL, "Failed to map 
type_names->types");
+                                               goto out_of_mem;
+                                       }
                                        /* Type sets require expansion and 
conversion. */
                                        if (expand_convert_type_set(state->out,
                                                                    state->
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsepol-2.1.9/src/policydb.c 
new/libsepol-2.2/src/policydb.c
--- old/libsepol-2.1.9/src/policydb.c   2013-02-06 02:43:22.000000000 +0100
+++ new/libsepol-2.2/src/policydb.c     2013-10-30 17:51:19.000000000 +0100
@@ -165,6 +165,13 @@
         .target_platform = SEPOL_TARGET_SELINUX,
        },
        {
+        .type = POLICY_KERN,
+        .version = POLICYDB_VERSION_CONSTRAINT_NAMES,
+        .sym_num = SYM_NUM,
+        .ocon_num = OCON_NODE6 + 1,
+        .target_platform = SEPOL_TARGET_SELINUX,
+       },
+       {
         .type = POLICY_BASE,
         .version = MOD_POLICYDB_VERSION_BASE,
         .sym_num = SYM_NUM,
@@ -256,6 +263,13 @@
         .target_platform = SEPOL_TARGET_SELINUX,
        },
        {
+        .type = POLICY_BASE,
+        .version = MOD_POLICYDB_VERSION_CONSTRAINT_NAMES,
+        .sym_num = SYM_NUM,
+        .ocon_num = OCON_NODE6 + 1,
+        .target_platform = SEPOL_TARGET_SELINUX,
+       },
+       {
         .type = POLICY_MOD,
         .version = MOD_POLICYDB_VERSION_BASE,
         .sym_num = SYM_NUM,
@@ -346,6 +360,13 @@
         .ocon_num = 0,
         .target_platform = SEPOL_TARGET_SELINUX,
        },
+       {
+        .type = POLICY_MOD,
+        .version = MOD_POLICYDB_VERSION_CONSTRAINT_NAMES,
+        .sym_num = SYM_NUM,
+        .ocon_num = 0,
+        .target_platform = SEPOL_TARGET_SELINUX,
+       },
 };
 
 #if 0
@@ -2019,6 +2040,10 @@
                                if (p->policy_type != POLICY_KERN &&
                                    type_set_read(e->type_names, fp))
                                        return -1;
+                               else if (p->policy_type == POLICY_KERN &&
+                                        p->policyvers >= 
POLICYDB_VERSION_CONSTRAINT_NAMES &&
+                                        type_set_read(e->type_names, fp))
+                                       return -1;
                                break;
                        default:
                                return -1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsepol-2.1.9/src/services.c 
new/libsepol-2.2/src/services.c
--- old/libsepol-2.1.9/src/services.c   2013-02-06 02:43:22.000000000 +0100
+++ new/libsepol-2.2/src/services.c     2013-10-30 17:51:19.000000000 +0100
@@ -43,6 +43,11 @@
  * Implementation of the security services.
  */
 
+/* Initial sizes malloc'd for sepol_compute_av_reason_buffer() support */
+#define REASON_BUF_SIZE 2048
+#define EXPR_BUF_SIZE 1024
+#define STACK_LEN 32
+
 #include <stdlib.h>
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -54,6 +59,7 @@
 #include <sepol/policydb/services.h>
 #include <sepol/policydb/conditional.h>
 #include <sepol/policydb/flask.h>
+#include <sepol/policydb/util.h>
 
 #include "debug.h"
 #include "private.h"
@@ -70,6 +76,50 @@
 static sidtab_t mysidtab, *sidtab = &mysidtab;
 static policydb_t mypolicydb, *policydb = &mypolicydb;
 
+/* Used by sepol_compute_av_reason_buffer() to keep track of entries */
+static int reason_buf_used;
+static int reason_buf_len;
+
+/* Stack services for RPN to infix conversion. */
+static char **stack;
+static int stack_len;
+static int next_stack_entry;
+
+static void push(char *expr_ptr)
+{
+       if (next_stack_entry >= stack_len) {
+               char **new_stack = stack;
+               int new_stack_len;
+
+               if (stack_len == 0)
+                       new_stack_len = STACK_LEN;
+               else
+                       new_stack_len = stack_len * 2;
+
+               new_stack = realloc(stack, new_stack_len * sizeof(*stack));
+               if (!new_stack) {
+                       ERR(NULL, "unable to allocate stack space");
+                       return;
+               }
+               stack_len = new_stack_len;
+               stack = new_stack;
+       }
+       stack[next_stack_entry] = expr_ptr;
+       next_stack_entry++;
+}
+
+static char *pop(void)
+{
+       next_stack_entry--;
+       if (next_stack_entry < 0) {
+               next_stack_entry = 0;
+               ERR(NULL, "pop called with no stack entries");
+               return NULL;
+       }
+       return stack[next_stack_entry];
+}
+/* End Stack services */
+
 int hidden sepol_set_sidtab(sidtab_t * s)
 {
        sidtab = s;
@@ -113,20 +163,227 @@
 static uint32_t latest_granting = 0;
 
 /*
- * Return the boolean value of a constraint expression 
- * when it is applied to the specified source and target 
+ * cat_expr_buf adds a string to an expression buffer and handles
+ * realloc's if buffer is too small. The array of expression text
+ * buffer pointers and its counter are globally defined here as
+ * constraint_expr_eval_reason() sets them up and cat_expr_buf
+ * updates the e_buf pointer.
+ */
+static int expr_counter;
+static char **expr_list;
+static int expr_buf_used;
+static int expr_buf_len;
+
+static void cat_expr_buf(char *e_buf, char *string)
+{
+       int len, new_buf_len;
+       char *p, *new_buf = e_buf;
+
+       while (1) {
+               p = e_buf + expr_buf_used;
+               len = snprintf(p, expr_buf_len - expr_buf_used, "%s", string);
+               if (len < 0 || len >= expr_buf_len - expr_buf_used) {
+                       new_buf_len = expr_buf_len + EXPR_BUF_SIZE;
+                       new_buf = realloc(e_buf, new_buf_len);
+                       if (!new_buf) {
+                               ERR(NULL, "failed to realloc expr buffer");
+                               return;
+                       }
+                       /* Update new ptr in expr list and locally + new len */
+                       expr_list[expr_counter] = new_buf;
+                       e_buf = new_buf;
+                       expr_buf_len = new_buf_len;
+               } else {
+                       expr_buf_used += len;
+                       return;
+               }
+       }
+}
+
+/*
+ * If the POLICY_KERN version is >= POLICYDB_VERSION_CONSTRAINT_NAMES,
+ * then for 'types' only, read the types_names->types list as it will
+ * contain a list of types and attributes that were defined in the
+ * policy source.
+ * For user and role plus types (for policy vers <
+ * POLICYDB_VERSION_CONSTRAINT_NAMES) just read the e->names list.
+ */
+static void get_name_list(constraint_expr_t *e, int type,
+                                                       char *src, char *op, 
int failed)
+{
+       ebitmap_t *types;
+       int rc = 0;
+       unsigned int i;
+       char tmp_buf[128];
+       int counter = 0;
+
+       if (policydb->policy_type == POLICY_KERN &&
+                       policydb->policyvers >= 
POLICYDB_VERSION_CONSTRAINT_NAMES &&
+                       type == CEXPR_TYPE)
+               types = &e->type_names->types;
+       else
+               types = &e->names;
+
+       /* Find out how many entries */
+       for (i = ebitmap_startbit(types); i < ebitmap_length(types); i++) {
+               rc = ebitmap_get_bit(types, i);
+               if (rc == 0)
+                       continue;
+               else
+                       counter++;
+       }
+       snprintf(tmp_buf, sizeof(tmp_buf), "(%s%s", src, op);
+       cat_expr_buf(expr_list[expr_counter], tmp_buf);
+
+       if (counter == 0)
+               cat_expr_buf(expr_list[expr_counter], "<empty_set> ");
+       if (counter > 1)
+               cat_expr_buf(expr_list[expr_counter], " {");
+       if (counter >= 1) {
+               for (i = ebitmap_startbit(types); i < ebitmap_length(types); 
i++) {
+                       rc = ebitmap_get_bit(types, i);
+                       if (rc == 0)
+                               continue;
+
+                       /* Collect entries */
+                       switch (type) {
+                       case CEXPR_USER:
+                               snprintf(tmp_buf, sizeof(tmp_buf), " %s",
+                                                       
policydb->p_user_val_to_name[i]);
+                               break;
+                       case CEXPR_ROLE:
+                               snprintf(tmp_buf, sizeof(tmp_buf), " %s",
+                                                       
policydb->p_role_val_to_name[i]);
+                               break;
+                       case CEXPR_TYPE:
+                               snprintf(tmp_buf, sizeof(tmp_buf), " %s",
+                                                       
policydb->p_type_val_to_name[i]);
+                               break;
+                       }
+                       cat_expr_buf(expr_list[expr_counter], tmp_buf);
+               }
+       }
+       if (counter > 1)
+               cat_expr_buf(expr_list[expr_counter], " }");
+       if (failed)
+               cat_expr_buf(expr_list[expr_counter], " -Fail-) ");
+       else
+               cat_expr_buf(expr_list[expr_counter], ") ");
+
+       return;
+}
+
+static void msgcat(char *src, char *tgt, char *op, int failed)
+{
+       char tmp_buf[128];
+       if (failed)
+               snprintf(tmp_buf, sizeof(tmp_buf), "(%s %s %s -Fail-) ",
+                               src, op, tgt);
+       else
+               snprintf(tmp_buf, sizeof(tmp_buf), "(%s %s %s) ",
+                               src, op, tgt);
+       cat_expr_buf(expr_list[expr_counter], tmp_buf);
+}
+
+/* Returns a buffer with class, statement type and permissions */
+static char *get_class_info(sepol_security_class_t tclass,
+                                                       constraint_node_t 
*constraint,
+                                                       context_struct_t 
*xcontext)
+{
+       constraint_expr_t *e;
+       int mls, state_num;
+
+       /* Find if MLS statement or not */
+       mls = 0;
+       for (e = constraint->expr; e; e = e->next) {
+               if (e->attr >= CEXPR_L1L2) {
+                       mls = 1;
+                       break;
+               }
+       }
+
+       /* Determine statement type */
+       char *statements[] = {
+               "constrain ",                   /* 0 */
+               "mlsconstrain ",                /* 1 */
+               "validatetrans ",               /* 2 */
+               "mlsvalidatetrans ",    /* 3 */
+               0 };
+
+       if (xcontext == NULL)
+               state_num = mls + 0;
+       else
+               state_num = mls + 2;
+
+       int class_buf_len = 0;
+       int new_class_buf_len;
+       int len, buf_used;
+       char *class_buf = NULL, *p;
+       char *new_class_buf = NULL;
+
+       while (1) {
+               new_class_buf_len = class_buf_len + EXPR_BUF_SIZE;
+               new_class_buf = realloc(class_buf, new_class_buf_len);
+                       if (!new_class_buf)
+                               return NULL;
+               class_buf_len = new_class_buf_len;
+               class_buf = new_class_buf;
+               buf_used = 0;
+               p = class_buf;
+
+               /* Add statement type */
+               len = snprintf(p, class_buf_len - buf_used, "%s", 
statements[state_num]);
+               if (len < 0 || len >= class_buf_len - buf_used)
+                       continue;
+
+               /* Add class entry */
+               p += len;
+               buf_used += len;
+               len = snprintf(p, class_buf_len - buf_used, "%s ",
+                               policydb->p_class_val_to_name[tclass - 1]);
+               if (len < 0 || len >= class_buf_len - buf_used)
+                       continue;
+
+               /* Add permission entries */
+               p += len;
+               buf_used += len;
+               len = snprintf(p, class_buf_len - buf_used, "{%s } (",
+                               sepol_av_to_string(policydb, tclass, 
constraint->permissions));
+               if (len < 0 || len >= class_buf_len - buf_used)
+                       continue;
+               break;
+       }
+       return class_buf;
+}
+
+/*
+ * Modified version of constraint_expr_eval that will process each
+ * constraint as before but adds the information to text buffers that
+ * will hold various components. The expression will be in RPN format,
+ * therefore there is a stack based RPN to infix converter to produce
+ * the final readable constraint.
+ *
+ * Return the boolean value of a constraint expression
+ * when it is applied to the specified source and target
  * security contexts.
  *
  * xcontext is a special beast...  It is used by the validatetrans rules
  * only.  For these rules, scontext is the context before the transition,
- * tcontext is the context after the transition, and xcontext is the context
- * of the process performing the transition.  All other callers of
- * constraint_expr_eval should pass in NULL for xcontext.
- */
-static int constraint_expr_eval(context_struct_t * scontext,
-                               context_struct_t * tcontext,
-                               context_struct_t * xcontext,
-                               constraint_expr_t * cexpr)
+ * tcontext is the context after the transition, and xcontext is the
+ * context of the process performing the transition.  All other callers
+ * of constraint_expr_eval_reason should pass in NULL for xcontext.
+ *
+ * This function will also build a buffer as the constraint is processed
+ * for analysis. If this option is not required, then:
+ *      'tclass' should be '0' and r_buf MUST be NULL.
+ */
+static int constraint_expr_eval_reason(context_struct_t *scontext,
+                               context_struct_t *tcontext,
+                               context_struct_t *xcontext,
+                               sepol_security_class_t tclass,
+                               constraint_node_t *constraint,
+                               char **r_buf,
+                               unsigned int flags)
 {
        uint32_t val1, val2;
        context_struct_t *c;
@@ -135,57 +392,131 @@
        constraint_expr_t *e;
        int s[CEXPR_MAXDEPTH];
        int sp = -1;
+       char tmp_buf[128];
 
-       for (e = cexpr; e; e = e->next) {
+/*
+ * Define the s_t_x_num values that make up r1, t2 etc. in text strings
+ * Set 1 = source, 2 = target, 3 = xcontext for validatetrans
+ */
+#define SOURCE  1
+#define TARGET  2
+#define XTARGET 3
+
+       int s_t_x_num = SOURCE;
+
+       /* Set 0 = fail, u = CEXPR_USER, r = CEXPR_ROLE, t = CEXPR_TYPE */
+       int u_r_t = 0;
+
+       char *src = NULL;
+       char *tgt = NULL;
+       int rc = 0, x;
+       char *class_buf = NULL;
+
+       class_buf = get_class_info(tclass, constraint, xcontext);
+       if (!class_buf) {
+               ERR(NULL, "failed to allocate class buffer");
+               return -ENOMEM;
+       }
+
+       /* Original function but with buffer support */
+       int expr_list_len = 0;
+       expr_counter = 0;
+       expr_list = NULL;
+       for (e = constraint->expr; e; e = e->next) {
+               /* Allocate a stack to hold expression buffer entries */
+               if (expr_counter >= expr_list_len) {
+                       char **new_expr_list = expr_list;
+                       int new_expr_list_len;
+
+                       if (expr_list_len == 0)
+                               new_expr_list_len = STACK_LEN;
+                       else
+                               new_expr_list_len = expr_list_len * 2;
+
+                       new_expr_list = realloc(expr_list,
+                                       new_expr_list_len * sizeof(*expr_list));
+                       if (!new_expr_list) {
+                               ERR(NULL, "failed to allocate expr buffer 
stack");
+                               rc = -ENOMEM;
+                               goto out;
+                       }
+                       expr_list_len = new_expr_list_len;
+                       expr_list = new_expr_list;
+               }
+
+               /*
+                * malloc a buffer to store each expression text component. If
+                * buffer is too small cat_expr_buf() will realloc extra space.
+                */
+               expr_buf_len = EXPR_BUF_SIZE;
+               expr_list[expr_counter] = malloc(expr_buf_len);
+               if (!expr_list[expr_counter]) {
+                       ERR(NULL, "failed to allocate expr buffer");
+                       rc = -ENOMEM;
+                       goto out;
+               }
+               expr_buf_used = 0;
+
+               /* Now process each expression of the constraint */
                switch (e->expr_type) {
                case CEXPR_NOT:
                        BUG_ON(sp < 0);
                        s[sp] = !s[sp];
+                       cat_expr_buf(expr_list[expr_counter], "not");
                        break;
                case CEXPR_AND:
                        BUG_ON(sp < 1);
                        sp--;
                        s[sp] &= s[sp + 1];
+                       cat_expr_buf(expr_list[expr_counter], "and");
                        break;
                case CEXPR_OR:
                        BUG_ON(sp < 1);
                        sp--;
                        s[sp] |= s[sp + 1];
+                       cat_expr_buf(expr_list[expr_counter], "or");
                        break;
                case CEXPR_ATTR:
                        if (sp == (CEXPR_MAXDEPTH - 1))
-                               return 0;
+                               goto out;
+
                        switch (e->attr) {
                        case CEXPR_USER:
                                val1 = scontext->user;
                                val2 = tcontext->user;
+                               free(src); src = strdup("u1");
+                               free(tgt); tgt = strdup("u2");
                                break;
                        case CEXPR_TYPE:
                                val1 = scontext->type;
                                val2 = tcontext->type;
+                               free(src); src = strdup("t1");
+                               free(tgt); tgt = strdup("t2");
                                break;
                        case CEXPR_ROLE:
                                val1 = scontext->role;
                                val2 = tcontext->role;
                                r1 = policydb->role_val_to_struct[val1 - 1];
                                r2 = policydb->role_val_to_struct[val2 - 1];
+                               free(src); src = strdup("r1");
+                               free(tgt); tgt = strdup("r2");
+
                                switch (e->op) {
                                case CEXPR_DOM:
-                                       s[++sp] =
-                                           ebitmap_get_bit(&r1->dominates,
-                                                           val2 - 1);
+                                       s[++sp] = 
ebitmap_get_bit(&r1->dominates, val2 - 1);
+                                       msgcat(src, tgt, "dom", s[sp] == 0);
+                                       expr_counter++;
                                        continue;
                                case CEXPR_DOMBY:
-                                       s[++sp] =
-                                           ebitmap_get_bit(&r2->dominates,
-                                                           val1 - 1);
+                                       s[++sp] = 
ebitmap_get_bit(&r2->dominates, val1 - 1);
+                                       msgcat(src, tgt, "domby", s[sp] == 0);
+                                       expr_counter++;
                                        continue;
                                case CEXPR_INCOMP:
-                                       s[++sp] =
-                                           (!ebitmap_get_bit
-                                            (&r1->dominates, val2 - 1)
-                                            && !ebitmap_get_bit(&r2->dominates,
-                                                                val1 - 1));
+                                       s[++sp] = 
(!ebitmap_get_bit(&r1->dominates, val2 - 1)
+                                                && 
!ebitmap_get_bit(&r2->dominates, val1 - 1));
+                                       msgcat(src, tgt, "incomp", s[sp] == 0);
+                                       expr_counter++;
                                        continue;
                                default:
                                        break;
@@ -194,110 +525,289 @@
                        case CEXPR_L1L2:
                                l1 = &(scontext->range.level[0]);
                                l2 = &(tcontext->range.level[0]);
+                               free(src); src = strdup("l1");
+                               free(tgt); tgt = strdup("l2");
                                goto mls_ops;
                        case CEXPR_L1H2:
                                l1 = &(scontext->range.level[0]);
                                l2 = &(tcontext->range.level[1]);
+                               free(src); src = strdup("l1");
+                               free(tgt); tgt = strdup("h2");
                                goto mls_ops;
                        case CEXPR_H1L2:
                                l1 = &(scontext->range.level[1]);
                                l2 = &(tcontext->range.level[0]);
+                               free(src); src = strdup("h1");
+                               free(tgt); tgt = strdup("l2");
                                goto mls_ops;
                        case CEXPR_H1H2:
                                l1 = &(scontext->range.level[1]);
                                l2 = &(tcontext->range.level[1]);
+                               free(src); src = strdup("h1");
+                               free(tgt); tgt = strdup("h2");
                                goto mls_ops;
                        case CEXPR_L1H1:
                                l1 = &(scontext->range.level[0]);
                                l2 = &(scontext->range.level[1]);
+                               free(src); src = strdup("l1");
+                               free(tgt); tgt = strdup("h1");
                                goto mls_ops;
                        case CEXPR_L2H2:
                                l1 = &(tcontext->range.level[0]);
                                l2 = &(tcontext->range.level[1]);
-                               goto mls_ops;
-                             mls_ops:
+                               free(src); src = strdup("l2");
+                               free(tgt); tgt = strdup("h2");
+mls_ops:
                                switch (e->op) {
                                case CEXPR_EQ:
                                        s[++sp] = mls_level_eq(l1, l2);
+                                       msgcat(src, tgt, "eq", s[sp] == 0);
+                                       expr_counter++;
                                        continue;
                                case CEXPR_NEQ:
                                        s[++sp] = !mls_level_eq(l1, l2);
+                                       msgcat(src, tgt, "!=", s[sp] == 0);
+                                       expr_counter++;
                                        continue;
                                case CEXPR_DOM:
                                        s[++sp] = mls_level_dom(l1, l2);
+                                       msgcat(src, tgt, "dom", s[sp] == 0);
+                                       expr_counter++;
                                        continue;
                                case CEXPR_DOMBY:
                                        s[++sp] = mls_level_dom(l2, l1);
+                                       msgcat(src, tgt, "domby", s[sp] == 0);
+                                       expr_counter++;
                                        continue;
                                case CEXPR_INCOMP:
                                        s[++sp] = mls_level_incomp(l2, l1);
+                                       msgcat(src, tgt, "incomp", s[sp] == 0);
+                                       expr_counter++;
                                        continue;
                                default:
                                        BUG();
-                                       return 0;
+                                       goto out;
                                }
                                break;
                        default:
                                BUG();
-                               return 0;
+                               goto out;
                        }
 
                        switch (e->op) {
                        case CEXPR_EQ:
                                s[++sp] = (val1 == val2);
+                               msgcat(src, tgt, "==", s[sp] == 0);
                                break;
                        case CEXPR_NEQ:
                                s[++sp] = (val1 != val2);
+                               msgcat(src, tgt, "!=", s[sp] == 0);
                                break;
                        default:
                                BUG();
-                               return 0;
+                               goto out;
                        }
                        break;
                case CEXPR_NAMES:
                        if (sp == (CEXPR_MAXDEPTH - 1))
-                               return 0;
+                               goto out;
+                       s_t_x_num = SOURCE;
                        c = scontext;
-                       if (e->attr & CEXPR_TARGET)
+                       if (e->attr & CEXPR_TARGET) {
+                               s_t_x_num = TARGET;
                                c = tcontext;
-                       else if (e->attr & CEXPR_XTARGET) {
+                       } else if (e->attr & CEXPR_XTARGET) {
+                               s_t_x_num = XTARGET;
                                c = xcontext;
-                               if (!c) {
-                                       BUG();
-                                       return 0;
-                               }
                        }
-                       if (e->attr & CEXPR_USER)
+                       if (!c) {
+                               BUG();
+                               goto out;
+                       }
+                       if (e->attr & CEXPR_USER) {
+                               u_r_t = CEXPR_USER;
                                val1 = c->user;
-                       else if (e->attr & CEXPR_ROLE)
+                               snprintf(tmp_buf, sizeof(tmp_buf), "u%d ", 
s_t_x_num);
+                               free(src); src = strdup(tmp_buf);
+                       } else if (e->attr & CEXPR_ROLE) {
+                               u_r_t = CEXPR_ROLE;
                                val1 = c->role;
-                       else if (e->attr & CEXPR_TYPE)
+                               snprintf(tmp_buf, sizeof(tmp_buf), "r%d ", 
s_t_x_num);
+                               free(src); src = strdup(tmp_buf);
+                       } else if (e->attr & CEXPR_TYPE) {
+                               u_r_t = CEXPR_TYPE;
                                val1 = c->type;
-                       else {
+                               snprintf(tmp_buf, sizeof(tmp_buf), "t%d ", 
s_t_x_num);
+                               free(src); src = strdup(tmp_buf);
+                       } else {
                                BUG();
-                               return 0;
+                               goto out;
                        }
 
                        switch (e->op) {
                        case CEXPR_EQ:
                                s[++sp] = ebitmap_get_bit(&e->names, val1 - 1);
+                               get_name_list(e, u_r_t, src, "==", s[sp] == 0);
                                break;
+
                        case CEXPR_NEQ:
                                s[++sp] = !ebitmap_get_bit(&e->names, val1 - 1);
+                               get_name_list(e, u_r_t, src, "!=", s[sp] == 0);
                                break;
                        default:
                                BUG();
-                               return 0;
+                               goto out;
                        }
                        break;
                default:
                        BUG();
-                       return 0;
+                       goto out;
                }
+               expr_counter++;
        }
 
-       BUG_ON(sp != 0);
-       return s[0];
+       /*
+        * At this point each expression of the constraint is in
+        * expr_list[n+1] and in RPN format. Now convert to 'infix'
+        */
+
+       /*
+        * Save expr count but zero expr_counter to detect if
+        * 'BUG(); goto out;' was called as we need to release any used
+        * expr_list malloc's. Normally they are released by the RPN to
+        * infix code.
+        */
+       int expr_count = expr_counter;
+       expr_counter = 0;
+
+       /*
+        * The array of expression answer buffer pointers and counter.
+        * Generate the same number of answer buffer entries as expression
+        * buffers (as there will never be more).
+        */
+       char **answer_list;
+       int answer_counter = 0;
+
+       answer_list = malloc(expr_count * sizeof(*answer_list));
+       if (!answer_list) {
+               ERR(NULL, "failed to allocate answer stack");
+               rc = -ENOMEM;
+               goto out;
+       }
+
+       /* The pop operands */
+       char *a;
+       char *b;
+       int a_len, b_len;
+
+       /* Convert constraint from RPN to infix notation. */
+       for (x = 0; x != expr_count; x++) {
+               if (strncmp(expr_list[x], "and", 3) == 0 || 
strncmp(expr_list[x],
+                                       "or", 2) == 0) {
+                       b = pop();
+                       b_len = strlen(b);
+                       a = pop();
+                       a_len = strlen(a);
+
+                       /* get a buffer to hold the answer */
+                       answer_list[answer_counter] = malloc(a_len + b_len + 8);
+                       if (!answer_list[answer_counter]) {
+                               ERR(NULL, "failed to allocate answer buffer");
+                               rc = -ENOMEM;
+                               goto out;
+                       }
+                       memset(answer_list[answer_counter], '\0', a_len + b_len 
+ 8);
+
+                       sprintf(answer_list[answer_counter], "%s %s %s", a,
+                                       expr_list[x], b);
+                       push(answer_list[answer_counter++]);
+                       free(a);
+                       free(b);
+               } else if (strncmp(expr_list[x], "not", 3) == 0) {
+                       b = pop();
+                       b_len = strlen(b);
+
+                       answer_list[answer_counter] = malloc(b_len + 8);
+                       if (!answer_list[answer_counter]) {
+                               ERR(NULL, "failed to allocate answer buffer");
+                               rc = -ENOMEM;
+                               goto out;
+                       }
+                       memset(answer_list[answer_counter], '\0', b_len + 8);
+
+                       if (strncmp(b, "not", 3) == 0)
+                               sprintf(answer_list[answer_counter], "%s (%s)",
+                                               expr_list[x], b);
+                       else
+                               sprintf(answer_list[answer_counter], "%s%s",
+                                               expr_list[x], b);
+                       push(answer_list[answer_counter++]);
+                       free(b);
+               } else {
+                       push(expr_list[x]);
+               }
+       }
+       /* Get the final answer from tos and build constraint text */
+       a = pop();
+
+       /* Constraint calculation: rc = 0 is denied, rc = 1 is granted */
+       sprintf(tmp_buf, "Constraint %s\n", s[0] ? "GRANTED" : "DENIED");
+
+       int len, new_buf_len;
+       char *p, **new_buf = r_buf;
+       /*
+        * These contain the constraint components that are added to the
+        * callers reason buffer.
+        */
+       char *buffers[] = { class_buf, a, "); ", tmp_buf, 0 };
+
+       /*
+        * This will add the constraints to the callers reason buffer (who is
+        * responsible for freeing the memory). It will handle any realloc's
+        * should the buffer be too short.
+        * The reason_buf_used and reason_buf_len counters are defined
+        * globally as multiple constraints can be in the buffer.
+        */
+
+       if (r_buf && ((s[0] == 0) || ((s[0] == 1 &&
+                               (flags & SHOW_GRANTED) == SHOW_GRANTED)))) {
+               for (x = 0; buffers[x] != NULL; x++) {
+                       while (1) {
+                               p = *r_buf + reason_buf_used;
+                               len = snprintf(p, reason_buf_len - 
reason_buf_used,
+                                               "%s", buffers[x]);
+                               if (len < 0 || len >= reason_buf_len - 
reason_buf_used) {
+                                       new_buf_len = reason_buf_len + 
REASON_BUF_SIZE;
+                                       *new_buf = realloc(*r_buf, new_buf_len);
+                                       if (!new_buf) {
+                                               ERR(NULL, "failed to realloc 
reason buffer");
+                                               goto out1;
+                                       }
+                                       **r_buf = **new_buf;
+                                       reason_buf_len = new_buf_len;
+                                       continue;
+                               } else {
+                                       reason_buf_used += len;
+                                       break;
+                               }
+                       }
+               }
+       }
+
+out1:
+       rc = s[0];
+       free(a);
+
+out:
+       free(class_buf);
+       free(src);
+       free(tgt);
+
+       if (expr_counter) {
+               for (x = 0; expr_list[x] != NULL; x++)
+                       free(expr_list[x]);
+       }
+       return rc;
 }
 
 /*
@@ -309,7 +819,9 @@
                                     sepol_security_class_t tclass,
                                     sepol_access_vector_t requested,
                                     struct sepol_av_decision *avd,
-                                    unsigned int *reason)
+                                    unsigned int *reason,
+                                    char **r_buf,
+                                        unsigned int flags)
 {
        constraint_node_t *constraint;
        struct role_allow *ra;
@@ -384,8 +896,8 @@
        constraint = tclass_datum->constraints;
        while (constraint) {
                if ((constraint->permissions & (avd->allowed)) &&
-                   !constraint_expr_eval(scontext, tcontext, NULL,
-                                         constraint->expr)) {
+                   !constraint_expr_eval_reason(scontext, tcontext, NULL,
+                                         tclass, constraint, r_buf, flags)) {
                        avd->allowed =
                            (avd->allowed) & ~(constraint->permissions);
                }
@@ -460,8 +972,8 @@
 
        constraint = tclass_datum->validatetrans;
        while (constraint) {
-               if (!constraint_expr_eval(ocontext, ncontext, tcontext,
-                                         constraint->expr)) {
+               if (!constraint_expr_eval_reason(ocontext, ncontext, tcontext,
+                                         0, constraint, NULL, 0)) {
                        return -EPERM;
                }
                constraint = constraint->next;
@@ -494,11 +1006,58 @@
        }
 
        rc = context_struct_compute_av(scontext, tcontext, tclass,
-                                      requested, avd, reason);
+                                       requested, avd, reason, NULL, 0);
       out:
        return rc;
 }
 
+/*
+ * sepol_compute_av_reason_buffer - the reason buffer is malloc'd to
+ * REASON_BUF_SIZE. If the buffer size is exceeded, then it is realloc'd
+ * in the constraint_expr_eval_reason() function.
+ */
+int hidden sepol_compute_av_reason_buffer(sepol_security_id_t ssid,
+                                  sepol_security_id_t tsid,
+                                  sepol_security_class_t tclass,
+                                  sepol_access_vector_t requested,
+                                  struct sepol_av_decision *avd,
+                                  unsigned int *reason,
+                                  char **reason_buf,
+                                  unsigned int flags)
+{
+       context_struct_t *scontext = 0, *tcontext = 0;
+       int rc = 0;
+
+       scontext = sepol_sidtab_search(sidtab, ssid);
+       if (!scontext) {
+               ERR(NULL, "unrecognized SID %d", ssid);
+               rc = -EINVAL;
+               goto out;
+       }
+       tcontext = sepol_sidtab_search(sidtab, tsid);
+       if (!tcontext) {
+               ERR(NULL, "unrecognized SID %d", tsid);
+               rc = -EINVAL;
+               goto out;
+       }
+
+       /*
+        * Set the buffer to NULL as constraints may not be processed.
+        * If a buffer is required, then the routines in
+        * constraint_expr_eval_reason will realloc in REASON_BUF_SIZE
+        * chunks (as it gets called for each constraint processed).
+        * We just make sure these start from zero.
+        */
+       *reason_buf = NULL;
+       reason_buf_used = 0;
+       reason_buf_len = 0;
+
+       rc = context_struct_compute_av(scontext, tcontext, tclass,
+                                          requested, avd, reason, reason_buf, 
flags);
+out:
+       return rc;
+}
+
 int hidden sepol_compute_av(sepol_security_id_t ssid,
                            sepol_security_id_t tsid,
                            sepol_security_class_t tclass,
@@ -511,6 +1070,71 @@
 }
 
 /*
+ * Return a class ID associated with the class string specified by
+ * class_name.
+ */
+int hidden sepol_string_to_security_class(const char *class_name,
+                       sepol_security_class_t *tclass)
+{
+       char *class = NULL;
+       sepol_security_class_t id;
+
+       for (id = 1;; id++) {
+               class = policydb->p_class_val_to_name[id - 1];
+               if (class == NULL) {
+                       ERR(NULL, "could not convert %s to class id", 
class_name);
+                       return STATUS_ERR;
+               }
+               if ((strcmp(class, class_name)) == 0) {
+                       *tclass = id;
+                       return STATUS_SUCCESS;
+               }
+       }
+}
+
+/*
+ * Return access vector bit associated with the class ID and permission
+ * string.
+ */
+int hidden sepol_string_to_av_perm(sepol_security_class_t tclass,
+                                       const char *perm_name,
+                                       sepol_access_vector_t *av)
+{
+       class_datum_t *tclass_datum;
+       perm_datum_t *perm_datum;
+
+       if (!tclass || tclass > policydb->p_classes.nprim) {
+               ERR(NULL, "unrecognized class %d", tclass);
+               return -EINVAL;
+       }
+       tclass_datum = policydb->class_val_to_struct[tclass - 1];
+
+       /* Check for unique perms then the common ones (if any) */
+       perm_datum = (perm_datum_t *)
+                       hashtab_search(tclass_datum->permissions.table,
+                       (hashtab_key_t)perm_name);
+       if (perm_datum != NULL) {
+               *av = 0x1 << (perm_datum->s.value - 1);
+               return STATUS_SUCCESS;
+       }
+
+       if (tclass_datum->comdatum == NULL)
+               goto out;
+
+       perm_datum = (perm_datum_t *)
+                       
hashtab_search(tclass_datum->comdatum->permissions.table,
+                       (hashtab_key_t)perm_name);
+
+       if (perm_datum != NULL) {
+               *av = 0x1 << (perm_datum->s.value - 1);
+               return STATUS_SUCCESS;
+       }
+out:
+       ERR(NULL, "could not convert %s to av bit", perm_name);
+       return STATUS_ERR;
+}
+
+/*
  * Write the security context string representation of 
  * the context associated with `sid' into a dynamically
  * allocated string of the correct size.  Set `*scontext'
@@ -1339,7 +1963,7 @@
                        rc = context_struct_compute_av(fromcon, &usercon,
                                                       SECCLASS_PROCESS,
                                                       PROCESS__TRANSITION,
-                                                      &avd, &reason);
+                                                      &avd, &reason, NULL, 0);
                        if (rc || !(avd.allowed & PROCESS__TRANSITION))
                                continue;
                        rc = sepol_sidtab_context_to_sid(sidtab, &usercon,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsepol-2.1.9/src/write.c 
new/libsepol-2.2/src/write.c
--- old/libsepol-2.1.9/src/write.c      2013-02-06 02:43:22.000000000 +0100
+++ new/libsepol-2.2/src/write.c        2013-10-30 17:51:19.000000000 +0100
@@ -893,8 +893,11 @@
                                if (ebitmap_write(&e->names, fp)) {
                                        return POLICYDB_ERROR;
                                }
-                               if (p->policy_type != POLICY_KERN &&
-                                   type_set_write(e->type_names, fp)) {
+                               if ((p->policy_type != POLICY_KERN &&
+                                               type_set_write(e->type_names, 
fp)) ||
+                                               (p->policy_type == POLICY_KERN 
&&
+                                               (p->policyvers >= 
POLICYDB_VERSION_CONSTRAINT_NAMES) &&
+                                               type_set_write(e->type_names, 
fp))) {
                                        return POLICYDB_ERROR;
                                }
                                break;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libsepol-2.1.9/tests/policies/test-cond/refpolicy-base.conf 
new/libsepol-2.2/tests/policies/test-cond/refpolicy-base.conf
--- old/libsepol-2.1.9/tests/policies/test-cond/refpolicy-base.conf     
2013-02-06 02:43:22.000000000 +0100
+++ new/libsepol-2.2/tests/policies/test-cond/refpolicy-base.conf       
2013-10-30 17:51:19.000000000 +0100
@@ -1393,6 +1393,7 @@
 role sysadm_r;
 role staff_r;
 role user_r;
+role secadm_r;
        typeattribute kernel_t domain;
        allow kernel_t self:dir { read getattr lock search ioctl };
        allow kernel_t self:lnk_file { read getattr lock ioctl };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libsepol-2.1.9/tests/policies/test-deps/base-metreq.conf 
new/libsepol-2.2/tests/policies/test-deps/base-metreq.conf
--- old/libsepol-2.1.9/tests/policies/test-deps/base-metreq.conf        
2013-02-06 02:43:22.000000000 +0100
+++ new/libsepol-2.2/tests/policies/test-deps/base-metreq.conf  2013-10-30 
17:51:19.000000000 +0100
@@ -426,15 +426,19 @@
 
 type net_foo_t, foo;
 type sys_foo_t, foo, system;
+role system_r;
 role system_r types sys_foo_t;
 
 type user_t, domain;
+role user_r;
 role user_r types user_t;
 
 type sysadm_t, domain, system;
+role sysadm_r;
 role sysadm_r types sysadm_t;
 
 type system_t, domain, system, foo;
+role system_r;
 role system_r types { system_t sys_foo_t };
 
 type file_t;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libsepol-2.1.9/tests/policies/test-deps/base-notmetreq.conf 
new/libsepol-2.2/tests/policies/test-deps/base-notmetreq.conf
--- old/libsepol-2.1.9/tests/policies/test-deps/base-notmetreq.conf     
2013-02-06 02:43:22.000000000 +0100
+++ new/libsepol-2.2/tests/policies/test-deps/base-notmetreq.conf       
2013-10-30 17:51:19.000000000 +0100
@@ -421,15 +421,19 @@
 
 type net_foo_t, foo;
 type sys_foo_t, foo, system;
+role system_r;
 role system_r types sys_foo_t;
 
 type user_t, domain;
+role user_r;
 role user_r types user_t;
 
 type sysadm_t, domain, system;
+role sysadm_r;
 role sysadm_r types sysadm_t;
 
 type system_t, domain, system, foo;
+role system_r;
 role system_r types { system_t sys_foo_t };
 
 type file_t;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libsepol-2.1.9/tests/policies/test-expander/alias-base.conf 
new/libsepol-2.2/tests/policies/test-expander/alias-base.conf
--- old/libsepol-2.1.9/tests/policies/test-expander/alias-base.conf     
2013-02-06 02:43:22.000000000 +0100
+++ new/libsepol-2.2/tests/policies/test-expander/alias-base.conf       
2013-10-30 17:51:19.000000000 +0100
@@ -440,6 +440,9 @@
 type fs_t;
 type system_t;
 type user_t;
+role system_r;
+role user_r;
+role sysadm_r;
 role system_r types system_t;
 role user_r types user_t;
 role sysadm_r types system_t;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libsepol-2.1.9/tests/policies/test-expander/base-base-only.conf 
new/libsepol-2.2/tests/policies/test-expander/base-base-only.conf
--- old/libsepol-2.1.9/tests/policies/test-expander/base-base-only.conf 
2013-02-06 02:43:22.000000000 +0100
+++ new/libsepol-2.2/tests/policies/test-expander/base-base-only.conf   
2013-10-30 17:51:19.000000000 +0100
@@ -34,6 +34,7 @@
 
 attribute myattr;
 type mytype_t;
+role myrole_r;
 role myrole_r types mytype_t;
 bool mybool true;
 gen_user(myuser_u,, myrole_r, s0, s0 - s0:c0)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libsepol-2.1.9/tests/policies/test-expander/role-base.conf 
new/libsepol-2.2/tests/policies/test-expander/role-base.conf
--- old/libsepol-2.1.9/tests/policies/test-expander/role-base.conf      
2013-02-06 02:43:22.000000000 +0100
+++ new/libsepol-2.2/tests/policies/test-expander/role-base.conf        
2013-10-30 17:51:19.000000000 +0100
@@ -415,12 +415,16 @@
 
 # Role mapping test
 type role_check_1_1_t;
+role role_check_1;
 role role_check_1 types role_check_1_1_t;
 
 ########
 type fs_t;
 type system_t;
 type user_t;
+role system_r;
+role user_r;
+role sysadm_r;
 role system_r types system_t;
 role user_r types user_t;
 role sysadm_r types system_t;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libsepol-2.1.9/tests/policies/test-expander/small-base.conf 
new/libsepol-2.2/tests/policies/test-expander/small-base.conf
--- old/libsepol-2.1.9/tests/policies/test-expander/small-base.conf     
2013-02-06 02:43:22.000000000 +0100
+++ new/libsepol-2.2/tests/policies/test-expander/small-base.conf       
2013-10-30 17:51:19.000000000 +0100
@@ -467,12 +467,15 @@
 
 type net_foo_t, foo;
 type sys_foo_t, foo, system;
+role system_r;
 role system_r types sys_foo_t;
 
 type user_t, domain;
+role user_r;
 role user_r types user_t;
 
 type sysadm_t, domain, system;
+role sysadm_r;
 role sysadm_r types sysadm_t;
 
 type system_t, domain, system, foo;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libsepol-2.1.9/tests/policies/test-expander/user-base.conf 
new/libsepol-2.2/tests/policies/test-expander/user-base.conf
--- old/libsepol-2.1.9/tests/policies/test-expander/user-base.conf      
2013-02-06 02:43:22.000000000 +0100
+++ new/libsepol-2.2/tests/policies/test-expander/user-base.conf        
2013-10-30 17:51:19.000000000 +0100
@@ -416,6 +416,8 @@
 # User mapping test
 type user_check_1_1_t;
 type user_check_1_2_t;
+role user_check_1_1_r;
+role user_check_1_2_r;
 role user_check_1_1_r types user_check_1_1_t;
 role user_check_1_2_r types user_check_1_2_t;
 
@@ -423,6 +425,9 @@
 type fs_t;
 type system_t;
 type user_t;
+role system_r;
+role user_r;
+role sysadm_r;
 role system_r types system_t;
 role user_r types user_t;
 role sysadm_r types system_t;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libsepol-2.1.9/tests/policies/test-linker/module1.conf 
new/libsepol-2.2/tests/policies/test-linker/module1.conf
--- old/libsepol-2.1.9/tests/policies/test-linker/module1.conf  2013-02-06 
02:43:22.000000000 +0100
+++ new/libsepol-2.2/tests/policies/test-linker/module1.conf    2013-10-30 
17:51:19.000000000 +0100
@@ -19,6 +19,7 @@
 typeattribute g_m1_type_2 g_m1_attr_1;
 
 #add role in module test
+role g_m1_role_1;
 role g_m1_role_1 types g_m1_type_1;
 
 # test for attr declared in base, added to in module
@@ -38,12 +39,15 @@
 
 #add type to base role test
 role g_b_role_2 types g_m1_type_1;
+role g_b_role_3;
 role g_b_role_3 types g_m1_type_2;
 
 #add type to base optional role test
+role o1_b_role_2;
 role o1_b_role_2 types g_m1_type_1;
 
 #optional base role w/ adds in 2 modules
+role o4_b_role_1;
 role o4_b_role_1 types g_m1_type_2;
 
 # attr a added to in base optional, declared/added to in module, added to in 
other module
@@ -78,6 +82,7 @@
        type o1_m1_type_2, o1_m1_attr_1;
        
        type o1_m1_type_1;
+       role o1_m1_role_1;
        role o1_m1_role_1 types o1_m1_type_1;
 
        type o1_m1_type_3;
@@ -101,6 +106,7 @@
        
        type tag_o2_m1;
 
+       role g_b_role_4;
        role g_b_role_4 types g_m1_type_2;
 }
 
@@ -112,6 +118,7 @@
        type tag_o3_m1;
 
        type o3_m1_type_1;      
+       role o3_b_role_1;
         role o3_b_role_1 types o3_m1_type_1;
 
        type o3_m1_type_2, g_b_attr_6;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libsepol-2.1.9/tests/policies/test-linker/module2.conf 
new/libsepol-2.2/tests/policies/test-linker/module2.conf
--- old/libsepol-2.1.9/tests/policies/test-linker/module2.conf  2013-02-06 
02:43:22.000000000 +0100
+++ new/libsepol-2.2/tests/policies/test-linker/module2.conf    2013-10-30 
17:51:19.000000000 +0100
@@ -12,6 +12,7 @@
 type tag_g_m2;
 
 type g_m2_type_1;
+role g_m2_role_1;
 role g_m2_role_1 types g_m2_type_1;
 
 type g_m2_type_4, g_b_attr_5;
@@ -19,9 +20,11 @@
 
 #add types to role declared in base test
 type g_m2_type_2;
+role g_b_role_3;
 role g_b_role_3 types g_m2_type_2;
 
 #optional base role w/ adds in 2 modules
+role o4_b_role_1;
 role o4_b_role_1 types g_m2_type_1;
 
 # attr a added to in base optional, declared/added to in module, added to in 
other module
@@ -45,6 +48,7 @@
        type tag_o1_m2;
 
        type o1_m2_type_1;
+       role o1_m2_role_1;
        role o1_m2_role_1 types o1_m2_type_1;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libsepol-2.1.9/tests/policies/test-linker/small-base.conf 
new/libsepol-2.2/tests/policies/test-linker/small-base.conf
--- old/libsepol-2.1.9/tests/policies/test-linker/small-base.conf       
2013-02-06 02:43:22.000000000 +0100
+++ new/libsepol-2.2/tests/policies/test-linker/small-base.conf 2013-10-30 
17:51:19.000000000 +0100
@@ -435,6 +435,10 @@
 type g_b_type_2, g_b_attr_2;
 type g_b_type_3;
 
+role g_b_role_1;
+role g_b_role_2;
+role g_b_role_3;
+role g_b_role_4;
 role g_b_role_1 types g_b_type_1;
 role g_b_role_2 types g_b_type_2;
 role g_b_role_3 types g_b_type_2;
@@ -464,8 +468,9 @@
        attribute o1_b_attr_1;
        type o1_b_type_1, o1_b_attr_1;
        bool o1_b_bool_1 true;
+       role o1_b_role_1;
        role o1_b_role_1 types o1_b_type_1;
-
+       role o1_b_role_2;
        role o1_b_role_2 types o1_b_type_1;
 
        attribute o1_b_attr_2;
@@ -501,6 +506,7 @@
        type o3_b_type_1;
        bool o3_b_bool_1 true;
 
+       role o3_b_role_1;
        role o3_b_role_1 types o3_b_type_1;
 
        allow g_b_type_1 invalid_type : sem { create destroy };
@@ -519,6 +525,7 @@
 
        attribute o4_b_attr_1;
 
+       role o4_b_role_1;
        role o4_b_role_1 types g_m1_type_1;
 
        # test for attr declared in module optional, added to in base optional

-- 
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to