[PATCH 3/4] libsepol: Check that initial sid indexes are within the valid range

2018-10-11 Thread James Carter
When writing CIL from a policy module or when writing CIL or policy.conf
from a kernel binary policy, check that the initial sid index is within
the valid range of the selinux_sid_to_str[] array (or xen_sid_to_str[]
array for a XEN policy). If it is not, then create a unique name
("UNKNOWN"+index) for the initial sid.

Signed-off-by: James Carter 
---
 libsepol/src/kernel_to_cil.c| 42 +
 libsepol/src/kernel_to_common.h |  4 
 libsepol/src/kernel_to_conf.c   | 42 +
 libsepol/src/module_to_cil.c| 25 ++--
 4 files changed, 86 insertions(+), 27 deletions(-)

diff --git a/libsepol/src/kernel_to_cil.c b/libsepol/src/kernel_to_cil.c
index c2a733ee..d173144e 100644
--- a/libsepol/src/kernel_to_cil.c
+++ b/libsepol/src/kernel_to_cil.c
@@ -529,23 +529,31 @@ exit:
return rc;
 }
 
-static int write_sids_to_cil(FILE *out, const char *const *sid_to_str, struct 
ocontext *isids)
+static int write_sids_to_cil(FILE *out, const char *const *sid_to_str,
+unsigned num_sids, struct ocontext *isids)
 {
struct ocontext *isid;
struct strs *strs;
char *sid;
char *prev;
+   char unknown[17];
unsigned i;
int rc;
 
-   rc = strs_init(, SECINITSID_NUM+1);
+   rc = strs_init(, num_sids+1);
if (rc != 0) {
goto exit;
}
 
for (isid = isids; isid != NULL; isid = isid->next) {
i = isid->sid[0];
-   rc = strs_add_at_index(strs, (char *)sid_to_str[i], i);
+   if (i < num_sids) {
+   sid = (char *)sid_to_str[i];
+   } else {
+   snprintf(unknown, 17, "%s%u", "UNKNOWN", i);
+   sid = strdup(unknown);
+   }
+   rc = strs_add_at_index(strs, sid, i);
if (rc != 0) {
goto exit;
}
@@ -577,6 +585,10 @@ static int write_sids_to_cil(FILE *out, const char *const 
*sid_to_str, struct oc
sepol_printf(out, "))\n");
 
 exit:
+   for (i=num_sids; itarget_platform == SEPOL_TARGET_SELINUX) {
-   rc = write_sids_to_cil(out, selinux_sid_to_str, 
pdb->ocontexts[0]);
+   rc = write_sids_to_cil(out, selinux_sid_to_str, SELINUX_SID_SZ,
+  pdb->ocontexts[0]);
} else if (pdb->target_platform == SEPOL_TARGET_XEN) {
-   rc = write_sids_to_cil(out, xen_sid_to_str, pdb->ocontexts[0]);
+   rc = write_sids_to_cil(out, xen_sid_to_str, XEN_SID_SZ,
+  pdb->ocontexts[0]);
} else {
sepol_log_err("Unknown target platform: %i", 
pdb->target_platform);
rc = -1;
@@ -2479,11 +2493,12 @@ exit:
return ctx;
 }
 
-static int write_sid_context_rules_to_cil(FILE *out, struct policydb *pdb, 
const char *const *sid_to_str)
+static int write_sid_context_rules_to_cil(FILE *out, struct policydb *pdb, 
const char *const *sid_to_str, unsigned num_sids)
 {
struct ocontext *isid;
struct strs *strs;
-   const char *sid;
+   char *sid;
+   char unknown[17];
char *ctx, *rule;
unsigned i;
int rc = -1;
@@ -2495,7 +2510,13 @@ static int write_sid_context_rules_to_cil(FILE *out, 
struct policydb *pdb, const
 
for (isid = pdb->ocontexts[0]; isid != NULL; isid = isid->next) {
i = isid->sid[0];
-   sid = sid_to_str[i];
+   if (i < num_sids) {
+   sid = (char *)sid_to_str[i];
+   } else {
+   snprintf(unknown, 17, "%s%u", "UNKNOWN", i);
+   sid = unknown;
+   }
+
ctx = context_to_str(pdb, >context[0]);
if (!ctx) {
rc = -1;
@@ -2531,7 +2552,8 @@ exit:
 
 static int write_selinux_isid_rules_to_cil(FILE *out, struct policydb *pdb)
 {
-   return write_sid_context_rules_to_cil(out, pdb, selinux_sid_to_str);
+   return write_sid_context_rules_to_cil(out, pdb, selinux_sid_to_str,
+ SELINUX_SID_SZ);
 }
 
 static int write_selinux_fsuse_rules_to_cil(FILE *out, struct policydb *pdb)
@@ -2884,7 +2906,7 @@ exit:
 
 static int write_xen_isid_rules_to_cil(FILE *out, struct policydb *pdb)
 {
-   return write_sid_context_rules_to_cil(out, pdb, xen_sid_to_str);
+   return write_sid_context_rules_to_cil(out, pdb, xen_sid_to_str, 
XEN_SID_SZ);
 }
 
 static int write_xen_pirq_rules_to_cil(FILE *out, struct policydb *pdb)
diff --git a/libsepol/src/kernel_to_common.h b/libsepol/src/kernel_to_common.h
index 7c5edbd6..dacfe97e 100644
--- a/libsepol/src/kernel_to_common.h
+++ b/libsepol/src/kernel_to_common.h
@@ -43,6 +43,8

[PATCH 4/4] libsepol: Add two new Xen initial SIDs

2018-10-11 Thread James Carter
Xen uses the initial SIDs domU and domDM in its toolstack, so it makes
sense to add these to xen_sid_to_str[] in kernel_to_common.h

Signed-off-by: James Carter 
---
 libsepol/src/kernel_to_common.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/libsepol/src/kernel_to_common.h b/libsepol/src/kernel_to_common.h
index dacfe97e..8aa483fa 100644
--- a/libsepol/src/kernel_to_common.h
+++ b/libsepol/src/kernel_to_common.h
@@ -57,6 +57,8 @@ static const char * const xen_sid_to_str[] = {
"iomem",
"irq",
"device",
+   "domU",
+   "domDM",
 };
 
 #define XEN_SID_SZ (sizeof(xen_sid_to_str)/sizeof(xen_sid_to_str[0]))
-- 
2.17.1

___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


[PATCH 2/4] libsepol: Eliminate initial sid string definitions in module_to_cil.c

2018-10-11 Thread James Carter
Since the initial sid strings are defined in kernel_to_common.h,
module_to_cil.c can use those and its initial sid string definitions
can be removed.

Signed-off-by: James Carter 
---
 libsepol/src/module_to_cil.c | 59 +++-
 1 file changed, 5 insertions(+), 54 deletions(-)

diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c
index dcf6ebb1..8ab0dfce 100644
--- a/libsepol/src/module_to_cil.c
+++ b/libsepol/src/module_to_cil.c
@@ -52,6 +52,7 @@
 #include 
 #include 
 
+#include "kernel_to_common.h"
 #include "private.h"
 
 #ifdef __GNUC__
@@ -2546,7 +2547,8 @@ static int context_to_cil(struct policydb *pdb, struct 
context_struct *con)
return 0;
 }
 
-static int ocontext_isid_to_cil(struct policydb *pdb, const char 
**sid_to_string, struct ocontext *isids)
+static int ocontext_isid_to_cil(struct policydb *pdb, const char *const 
*sid_to_string,
+   struct ocontext *isids)
 {
int rc = -1;
 
@@ -2602,41 +2604,7 @@ static int ocontext_selinux_isid_to_cil(struct policydb 
*pdb, struct ocontext *i
 {
int rc = -1;
 
-   // initial sid names aren't actually stored in the pp files, need to a 
have
-   // a mapping, taken from the linux kernel
-   static const char *selinux_sid_to_string[] = {
-   "null",
-   "kernel",
-   "security",
-   "unlabeled",
-   "fs",
-   "file",
-   "file_labels",
-   "init",
-   "any_socket",
-   "port",
-   "netif",
-   "netmsg",
-   "node",
-   "igmp_packet",
-   "icmp_socket",
-   "tcp_socket",
-   "sysctl_modprobe",
-   "sysctl",
-   "sysctl_fs",
-   "sysctl_kernel",
-   "sysctl_net",
-   "sysctl_net_unix",
-   "sysctl_vm",
-   "sysctl_dev",
-   "kmod",
-   "policy",
-   "scmp_packet",
-   "devnull",
-   NULL
-   };
-
-   rc = ocontext_isid_to_cil(pdb, selinux_sid_to_string, isids);
+   rc = ocontext_isid_to_cil(pdb, selinux_sid_to_str, isids);
if (rc != 0) {
goto exit;
}
@@ -2865,24 +2833,7 @@ static int ocontext_xen_isid_to_cil(struct policydb 
*pdb, struct ocontext *isids
 {
int rc = -1;
 
-   // initial sid names aren't actually stored in the pp files, need to a 
have
-   // a mapping, taken from the xen kernel
-   static const char *xen_sid_to_string[] = {
-   "null",
-   "xen",
-   "dom0",
-   "domio",
-   "domxen",
-   "unlabeled",
-   "security",
-   "ioport",
-   "iomem",
-   "irq",
-   "device",
-   NULL,
-   };
-
-   rc = ocontext_isid_to_cil(pdb, xen_sid_to_string, isids);
+   rc = ocontext_isid_to_cil(pdb, xen_sid_to_str, isids);
if (rc != 0) {
goto exit;
}
-- 
2.17.1

___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


[PATCH 1/4] libsepol: Rename kernel_to_common.c stack functions

2018-10-11 Thread James Carter
Want to make use of selinux_sid_to_str[] and xen_sid_to_str[] from
kernel_to_common.h in module_to_cil.c, but stack functions with the
same names exist in module_to_cil.c and kernel_to_common.c (with
the function prototypes in kernel_to_common.h).

Since the stack functions in kernel_to_common.c are less general and
only work with strings, rename those functions from stack_* to
strs_stack_*.

Signed-off-by: James Carter 
---
 libsepol/src/kernel_to_cil.c| 36 -
 libsepol/src/kernel_to_common.c | 10 -
 libsepol/src/kernel_to_common.h | 10 -
 libsepol/src/kernel_to_conf.c   | 36 -
 4 files changed, 46 insertions(+), 46 deletions(-)

diff --git a/libsepol/src/kernel_to_cil.c b/libsepol/src/kernel_to_cil.c
index b1eb66d6..c2a733ee 100644
--- a/libsepol/src/kernel_to_cil.c
+++ b/libsepol/src/kernel_to_cil.c
@@ -36,7 +36,7 @@ static char *cond_expr_to_str(struct policydb *pdb, struct 
cond_expr *expr)
char *str = NULL;
int rc;
 
-   rc = stack_init();
+   rc = strs_stack_init();
if (rc != 0) {
goto exit;
}
@@ -65,13 +65,13 @@ static char *cond_expr_to_str(struct policydb *pdb, struct 
cond_expr *expr)
}
 
if (num_params == 2) {
-   val2 = stack_pop(stack);
+   val2 = strs_stack_pop(stack);
if (!val2) {
sepol_log_err("Invalid conditional 
expression");
goto exit;
}
}
-   val1 = stack_pop(stack);
+   val1 = strs_stack_pop(stack);
if (!val1) {
sepol_log_err("Invalid conditional expression");
free(val2);
@@ -89,29 +89,29 @@ static char *cond_expr_to_str(struct policydb *pdb, struct 
cond_expr *expr)
sepol_log_err("Invalid conditional expression");
goto exit;
}
-   rc = stack_push(stack, new_val);
+   rc = strs_stack_push(stack, new_val);
if (rc != 0) {
sepol_log_err("Out of memory");
goto exit;
}
}
 
-   new_val = stack_pop(stack);
-   if (!new_val || !stack_empty(stack)) {
+   new_val = strs_stack_pop(stack);
+   if (!new_val || !strs_stack_empty(stack)) {
sepol_log_err("Invalid conditional expression");
goto exit;
}
 
str = new_val;
 
-   stack_destroy();
+   strs_stack_destroy();
return str;
 
 exit:
-   while ((new_val = stack_pop(stack)) != NULL) {
+   while ((new_val = strs_stack_pop(stack)) != NULL) {
free(new_val);
}
-   stack_destroy();
+   strs_stack_destroy();
 
return NULL;
 }
@@ -127,7 +127,7 @@ static char *constraint_expr_to_str(struct policydb *pdb, 
struct constraint_expr
 
*use_mls = 0;
 
-   rc = stack_init();
+   rc = strs_stack_init();
if (rc != 0) {
goto exit;
}
@@ -208,13 +208,13 @@ static char *constraint_expr_to_str(struct policydb *pdb, 
struct constraint_expr
}
 
if (num_params == 2) {
-   val2 = stack_pop(stack);
+   val2 = strs_stack_pop(stack);
if (!val2) {
sepol_log_err("Invalid constraint 
expression");
goto exit;
}
}
-   val1 = stack_pop(stack);
+   val1 = strs_stack_pop(stack);
if (!val1) {
sepol_log_err("Invalid constraint expression");
goto exit;
@@ -231,30 +231,30 @@ static char *constraint_expr_to_str(struct policydb *pdb, 
struct constraint_expr
if (!new_val) {
goto exit;
}
-   rc = stack_push(stack, new_val);
+   rc = strs_stack_push(stack, new_val);
if (rc != 0) {
sepol_log_err("Out of memory");
goto exit;
}
}
 
-   new_val = stack_pop(stack);
-   if (!new_val || !stack_empty(stack)) {
+   new_val = strs_stack_pop(stack);
+   if (!new_val || !strs_stack_empty(stack)) {
sepol_log_err("Invalid constraint expression");
goto exit;
}
 
str = new_val;
 
-   stack_destroy();
+   strs

[PATCH 2/2] checkpolicy: Add option to sort ocontexts when creating a binary policy

2018-10-11 Thread James Carter
Add an option, specified by "-S" or "--sort", to sort the ocontexts
before writing out the binary policy.

Binary policies created by semanage and secilc are always sorted, so
this option allows checkpolicy to be consistent with those. It has
not been made the default to maintain backwards compatibility for
anyone who might be depending on the unsorted behavior of checkpolicy.

Signed-off-by: James Carter 
---
 checkpolicy/checkpolicy.c | 22 +-
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/checkpolicy/checkpolicy.c b/checkpolicy/checkpolicy.c
index 12c4c405..14dc91a3 100644
--- a/checkpolicy/checkpolicy.c
+++ b/checkpolicy/checkpolicy.c
@@ -111,9 +111,9 @@ unsigned int policyvers = POLICYDB_VERSION_MAX;
 static __attribute__((__noreturn__)) void usage(const char *progname)
 {
printf
-   ("usage:  %s [-b[F]] [-C] [-d] [-U handle_unknown 
(allow,deny,reject)] [-M]"
-"[-c policyvers (%d-%d)] [-o output_file] [-t target_platform 
(selinux,xen)]"
-"[input_file]\n",
+   ("usage:  %s [-b[F]] [-C] [-d] [-U handle_unknown 
(allow,deny,reject)] [-M] "
+"[-c policyvers (%d-%d)] [-o output_file] [-S] "
+"[-t target_platform (selinux,xen)] [input_file]\n",
 progname, POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX);
exit(1);
 }
@@ -394,7 +394,7 @@ int main(int argc, char **argv)
size_t scontext_len, pathlen;
unsigned int i;
unsigned int protocol, port;
-   unsigned int binary = 0, debug = 0, cil = 0, conf = 0;
+   unsigned int binary = 0, debug = 0, sort = 0, cil = 0, conf = 0;
struct val_to_name v;
int ret, ch, fd, target = SEPOL_TARGET_SELINUX;
unsigned int nel, uret;
@@ -418,11 +418,12 @@ int main(int argc, char **argv)
{"mls", no_argument, NULL, 'M'},
{"cil", no_argument, NULL, 'C'},
{"conf",no_argument, NULL, 'F'},
+   {"sort", no_argument, NULL, 'S'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0}
};
 
-   while ((ch = getopt_long(argc, argv, "o:t:dbU:MCFVc:h", long_options, 
NULL)) != -1) {
+   while ((ch = getopt_long(argc, argv, "o:t:dbU:MCFSVc:h", long_options, 
NULL)) != -1) {
switch (ch) {
case 'o':
outfile = optarg;
@@ -462,6 +463,9 @@ int main(int argc, char **argv)
break;
}
usage(argv[0]);
+   case 'S':
+   sort = 1;
+   break;
case 'M':
mlspol = 1;
break;
@@ -637,6 +641,14 @@ int main(int argc, char **argv)
policy_file_init();
pf.type = PF_USE_STDIO;
pf.fp = outfp;
+   if (sort) {
+   ret = 
policydb_sort_ocontexts();
+   if (ret) {
+   fprintf(stderr, "%s:  error 
sorting ocontexts\n",
+   argv[0]);
+   exit(1);
+   }
+   }
ret = policydb_write(, );
} else {
ret = sepol_kernel_policydb_to_conf(outfp, 
policydbp);
-- 
2.17.1

___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


[PATCH 0/4] libsepol: Cleanup initial sid handling when writing CIL and policy.conf files

2018-10-11 Thread James Carter
[Resending because I originally only sent these to the new list]

- Removes some redundent definitions of initial sid name strings
- Adds range checking when looking up an initial sid name string for an index
- Adds two new Xen initial sids

James Carter (4):
  libsepol: Rename kernel_to_common.c stack functions
  libsepol: Eliminate initial sid string definitions in module_to_cil.c
  libsepol: Check that initial sid indexes are within the valid range
  libsepol: Add two new Xen initial SIDs

 libsepol/src/kernel_to_cil.c| 78 +
 libsepol/src/kernel_to_common.c | 10 ++---
 libsepol/src/kernel_to_common.h | 16 ---
 libsepol/src/kernel_to_conf.c   | 78 +
 libsepol/src/module_to_cil.c| 78 +
 5 files changed, 136 insertions(+), 124 deletions(-)

-- 
2.17.1

___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


[PATCH 1/2] libsepol: Create policydb_sort_ocontexts()

2018-10-11 Thread James Carter
Create the function called policydb_sort_ocontexts() that calls
the internal function sort_ocontexts() to sort the ocontexts of
a policydb.

The function sort_ocontexts() is already used by
sepol_kernel_policydb_to_conf() and sepol_kernel_policydb_to_cil()
when converting a binary policy to cil or policy.conf format.

Signed-off-by: James Carter 
---
 libsepol/include/sepol/policydb/policydb.h | 2 ++
 libsepol/src/policydb.c| 5 +
 2 files changed, 7 insertions(+)

diff --git a/libsepol/include/sepol/policydb/policydb.h 
b/libsepol/include/sepol/policydb/policydb.h
index 271a82c9..591ce6e0 100644
--- a/libsepol/include/sepol/policydb/policydb.h
+++ b/libsepol/include/sepol/policydb/policydb.h
@@ -640,6 +640,8 @@ extern void policydb_destroy(policydb_t * p);
 
 extern int policydb_load_isids(policydb_t * p, sidtab_t * s);
 
+extern int policydb_sort_ocontexts(policydb_t *p);
+
 /* Deprecated */
 extern int policydb_context_isvalid(const policydb_t * p,
const context_struct_t * c);
diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
index dfedfafe..a6d76ca3 100644
--- a/libsepol/src/policydb.c
+++ b/libsepol/src/policydb.c
@@ -51,6 +51,7 @@
 #include 
 #include 
 
+#include "kernel_to_common.h"
 #include "private.h"
 #include "debug.h"
 #include "mls.h"
@@ -4301,3 +4302,7 @@ int policydb_set_target_platform(policydb_t *p, int 
platform)
return 0;
 }
 
+int policydb_sort_ocontexts(policydb_t *p)
+{
+   return sort_ocontexts(p);
+}
-- 
2.17.1

___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


[PATCH 0/2] libsepol: Add ability to sort ocontexts in libsepol and add option to use it in checkpolicy

2018-10-11 Thread James Carter
[Resending because I originally only sent these to the new list]

ocontexts (initial sids, fs_use_*, genfscon, portcon, etc) are sorted by 
libsemanage when using policy modules and by libsepol when using CIL, but they 
are not sorted by checkpolicy when creating a policy from a policy.conf.

Checkpolicy's behavior allows control over the ordering which determines the 
matching order for portcons and other ocontext rules, but there are times when 
that specific control is not desired.

This patch set exposes an internal ocontext sorting function and adds a command 
line option to checkpolicy to sort ocontexts.


James Carter (2):
  libsepol: Create policydb_sort_ocontexts()
  checkpolicy: Add option to sort ocontexts when creating a binary
policy

 checkpolicy/checkpolicy.c  | 22 +-
 libsepol/include/sepol/policydb/policydb.h |  2 ++
 libsepol/src/policydb.c|  5 +
 3 files changed, 24 insertions(+), 5 deletions(-)

-- 
2.17.1

___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


[PATCH 1/1] libsepol/cil: Improve processing of context rules

2018-03-29 Thread James Carter
Improve the processing of netifcon, genfscon, ibpkeycon, ibendportcon,
portcon, nodecon, fsuse, filecon, iomemcon, ioportcon, pcidevicecon,
and devicetreecon rules.

If the multiple-decls option is not used then report errors if duplicate
context rules are found. If it is used then remove duplicate context rules
and report errors when two rules are identical except for the context.

This also changes the ordering of portcon and filecon rules. The protocol
of portcon rules will be compared if the port numbers are the same and the
path strings of filecon rules will be compared if the number of meta
characters, the stem length, string length and file types are the same.

Based on an initial patch by Pierre-Hugues Husson (p...@phh.me)

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 libsepol/cil/src/cil_post.c | 331 ++--
 1 file changed, 318 insertions(+), 13 deletions(-)

diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c
index a2122454..0b09cecc 100644
--- a/libsepol/cil/src/cil_post.c
+++ b/libsepol/cil/src/cil_post.c
@@ -53,6 +53,83 @@
 static int __cil_expr_to_bitmap(struct cil_list *expr, ebitmap_t *out, int 
max, struct cil_db *db);
 static int __cil_expr_list_to_bitmap(struct cil_list *expr_list, ebitmap_t 
*out, int max, struct cil_db *db);
 
+static int cats_compare(struct cil_cats *a, struct cil_cats *b)
+{
+   struct cil_list_item *i, *j;
+   int rc;
+
+   if (a == b) return 0;
+   if (!a) return -1;
+   if (!b) return 1;
+
+   /* Expects cat expression to have been evaluated */
+   cil_list_for_each(i, a->datum_expr) {
+   cil_list_for_each(j, b->datum_expr) {
+   rc = strcmp(DATUM(i->data)->fqn, DATUM(j->data)->fqn);
+   if (!rc) return rc;
+   }
+   }
+   return 0;
+}
+
+static int level_compare(struct cil_level *a, struct cil_level *b)
+{
+   int rc;
+
+   if (a == b) return 0;
+   if (!a) return -1;
+   if (!b) return 1;
+
+   if (a->sens != b->sens) {
+   rc = strcmp(DATUM(a->sens)->fqn, DATUM(b->sens)->fqn);
+   if (rc != 0) return rc;
+   }
+   if (a->cats != b->cats) {
+   return cats_compare(a->cats, b->cats);
+   }
+   return 0;
+}
+
+static int range_compare(struct cil_levelrange *a, struct cil_levelrange *b)
+{
+   int rc;
+
+   if (a == b) return 0;
+   if (!a) return -1;
+   if (!b) return 1;
+
+   if (a->low != b->low) {
+   rc = level_compare(a->low, b->low);
+   if (rc != 0) return rc;
+   }
+   if (a->high != b->high) {
+   return level_compare(a->high, b->high);
+   }
+   return 0;
+}
+
+static int context_compare(struct cil_context *a, struct cil_context *b)
+{
+   int rc;
+
+   if (a->user != b->user) {
+   rc = strcmp(DATUM(a->user)->fqn, DATUM(b->user)->fqn);
+   if (rc != 0) return rc;
+   }
+   if (a->role != b->role) {
+   rc = strcmp(DATUM(a->role)->fqn, DATUM(b->role)->fqn);
+   if (rc != 0) return rc;
+   }
+   if (a->type != b->type) {
+   rc = strcmp(DATUM(a->type)->fqn, DATUM(b->type)->fqn);
+   if (rc != 0) return rc;
+   }
+   if (a->range != b->range) {
+   return range_compare(a->range, b->range);
+   }
+   return 0;
+}
+
 static int cil_verify_is_list(struct cil_list *list, enum cil_flavor flavor)
 {
struct cil_list_item *curr;
@@ -145,6 +222,8 @@ int cil_post_filecon_compare(const void *a, const void *b)
rc = -1;
} else if (b_filecon->type < a_filecon->type) {
rc = 1;
+   } else {
+   rc = strcmp(a_filecon->path_str, b_filecon->path_str);
}
 
free(a_path);
@@ -190,6 +269,10 @@ int cil_post_portcon_compare(const void *a, const void *b)
rc = -1;
} else if (bportcon->port_low < aportcon->port_low) {
rc = 1;
+   } else if (aportcon->proto < bportcon->proto) {
+   rc = -1;
+   } else if (aportcon->proto > bportcon->proto) {
+   rc = 1;
}
}
 
@@ -369,6 +452,102 @@ int cil_post_fsuse_compare(const void *a, const void *b)
return rc;
 }
 
+int cil_post_filecon_context_compare(const void *a, const void *b)
+{
+   struct cil_filecon *a_filecon = *(struct cil_filecon**)a;
+   struct cil_filecon *b_filecon = *(struct cil_filecon**)b;
+   return context_compare(a_filecon->context, b_filecon->context);
+}
+
+int cil_post_ibpkeycon_context_compare(const void *a, const void *b)
+{
+   struct cil_ibpkeyco

[PATCH] libsepol: Prevent freeing unitialized value in ibendport handling

2018-03-07 Thread James Carter
Nicolas Iooss reports:
In sepol_ibendport_key_create(), if sepol_ibendport_alloc_ibdev_name()
fails to allocate tmp_key->ibdev_name, sepol_ibendport_key_free() is
called to free the memory associated with tmp_key, which results in
free() being called on uninitialized tmp_key->ibdev_name.

This issue is reported by clang's static analyzer with the following
message:

ibendport_record.c:115:2: warning: 1st function call argument is an
uninitialized value
free(key->ibdev_name);
^

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 libsepol/src/ibendport_record.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/libsepol/src/ibendport_record.c b/libsepol/src/ibendport_record.c
index 912aeb53..bc56f090 100644
--- a/libsepol/src/ibendport_record.c
+++ b/libsepol/src/ibendport_record.c
@@ -32,14 +32,11 @@ struct sepol_ibendport_key {
 int sepol_ibendport_alloc_ibdev_name(sepol_handle_t *handle,
 char **ibdev_name)
 {
-   char *tmp_ibdev_name = NULL;
-
-   tmp_ibdev_name = calloc(1, IB_DEVICE_NAME_MAX);
+   *ibdev_name = calloc(1, IB_DEVICE_NAME_MAX);
 
-   if (!tmp_ibdev_name)
+   if (!*ibdev_name)
goto omem;
 
-   *ibdev_name = tmp_ibdev_name;
return STATUS_SUCCESS;
 
 omem:
-- 
2.13.6



[PATCH] libsepol/cil: Create new keep field for type attribute sets

2017-11-17 Thread James Carter
Daniel Cashman <dcash...@android.com> discovered the following:
When using cil_db multiple_decls, the different cil_attribute nodes
all point to the same underlying cil_attribute struct.  This leads
to problems, though, when modifying the used value in the struct.
__cil_post_db_attr() changes the value of the field to based on
the output of cil_typeattribute_used(), for use later in
cil_typeattribute_to_policydb and cil_typeattribute_to_bitmap, but
due to the multiple declarations, cil_typeattribute_used() could be
called again by a second node.  In this second call, the value used
is the modifed value of CIL_TRUE or CIL_FALSE, not the flags actually
needed. This could result in the field being reset again, to an
incorrect CIL_FALSE value.

Add the field "keep" to struct cil_typeattributeset, set its value
using cil_typeattribute_used(), and use it when determining whether
the attribute is to be kept or if it should be expanded.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 libsepol/cil/src/cil.c   | 1 +
 libsepol/cil/src/cil_binary.c| 8 
 libsepol/cil/src/cil_internal.h  | 1 +
 libsepol/cil/src/cil_policy.c| 2 +-
 libsepol/cil/src/cil_post.c  | 2 +-
 libsepol/cil/src/cil_reset_ast.c | 1 +
 6 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c
index 3fe68af8..5a64c2bc 100644
--- a/libsepol/cil/src/cil.c
+++ b/libsepol/cil/src/cil.c
@@ -2064,6 +2064,7 @@ void cil_typeattribute_init(struct cil_typeattribute 
**attr)
(*attr)->expr_list = NULL;
(*attr)->types = NULL;
(*attr)->used = CIL_FALSE;
+   (*attr)->keep = CIL_FALSE;
 }
 
 void cil_typeattributeset_init(struct cil_typeattributeset **attrset)
diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c
index c0ca60f2..431cd9cd 100644
--- a/libsepol/cil/src/cil_binary.c
+++ b/libsepol/cil/src/cil_binary.c
@@ -567,7 +567,7 @@ int cil_typeattribute_to_policydb(policydb_t *pdb, struct 
cil_typeattribute *cil
char *key = NULL;
type_datum_t *sepol_attr = NULL;
 
-   if (!cil_attr->used) {
+   if (!cil_attr->keep) {
return SEPOL_OK;
}
 
@@ -632,7 +632,7 @@ int cil_typeattribute_to_bitmap(policydb_t *pdb, const 
struct cil_db *db, struct
ebitmap_node_t *tnode;
unsigned int i;
 
-   if (!cil_attr->used) {
+   if (!cil_attr->keep) {
return SEPOL_OK;
}
 
@@ -1442,7 +1442,7 @@ static int __cil_should_expand_attribute( const struct 
cil_db *db, struct cil_sy
 
attr = (struct cil_typeattribute *)datum;
 
-   return !attr->used || (ebitmap_cardinality(attr->types) < 
db->attrs_expand_size);
+   return !attr->keep || (ebitmap_cardinality(attr->types) < 
db->attrs_expand_size);
 }
 
 int __cil_avrule_to_avtab(policydb_t *pdb, const struct cil_db *db, struct 
cil_avrule *cil_avrule, cond_node_t *cond_node, enum cil_flavor cond_flavor)
@@ -2525,7 +2525,7 @@ int __cil_constrain_expr_datum_to_sepol_expr(policydb_t 
*pdb, const struct cil_d
if (rc != SEPOL_OK) {
if (FLAVOR(item->data) == CIL_TYPEATTRIBUTE) {
struct cil_typeattribute *attr = 
item->data;
-   if (!attr->used) {
+   if (!attr->keep) {
rc = 0;
}
}
diff --git a/libsepol/cil/src/cil_internal.h b/libsepol/cil/src/cil_internal.h
index 136a0049..8393e391 100644
--- a/libsepol/cil/src/cil_internal.h
+++ b/libsepol/cil/src/cil_internal.h
@@ -531,6 +531,7 @@ struct cil_typeattribute {
struct cil_list *expr_list;
ebitmap_t *types;
int used;   // whether or not this attribute was used in a binary 
policy rule
+   int keep;
 };
 
 struct cil_typeattributeset {
diff --git a/libsepol/cil/src/cil_policy.c b/libsepol/cil/src/cil_policy.c
index 6d4987c4..99eb53c2 100644
--- a/libsepol/cil/src/cil_policy.c
+++ b/libsepol/cil/src/cil_policy.c
@@ -1085,7 +1085,7 @@ static void cil_typeattributes_to_policy(FILE *out, 
struct cil_list *types, stru
type = i1->data;
cil_list_for_each(i2, attributes) {
attribute = i2->data;
-   if (!attribute->used)
+   if (!attribute->keep)
continue;
if (ebitmap_get_bit(attribute->types, type->value)) {
if (first) {
diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c
index 3e013c97..a2122454 100644
--- a/libsepol/cil/src/cil_post.c
+++ b/libsepol/cil/src/cil_post.c
@@ -1369,7 +1369,7 @@ static int __cil_post_db_attr_helper(struc

[PATCH] libsepol/cil: Keep attributes used by generated attributes in neverallow rules

2017-08-30 Thread James Carter
In order to reduce policy size, CIL removes attributes that are not used
by a policy rule in the generated binary policy. However, CIL keeps
attributes used by neverallow rules (which are checked at compile time
and not in the binary policy) even if the attribute is not used anywhere
else in the policy. This behavior is useful to Google who pulls neverallow
rules out of the original policy.conf for compatibility testing, but
converts the policy.conf to CIL and uses the CIL compiler to generate
policy. Without this behavior, the generated binary policy might not have
an attribute referred to by one of the neverallow rules used for testing.

The one exception to this behavior is for attributes generated in
module_to_cil (these have an "_typeattr_" in the middle of their name).
Since these attributes are only created because CIL does not allow a
type expression in an AV rule, they are removed if they only appear in
a neverallow rule (which is the case for most of them) or if the
option to expand generated attributes (-G or --expand-generated) is
specified for secilc when compiling the policy.

Removing generated attributes causes a problem, however, if the type
expression that the generated attribute is replacing uses an attribute
that is removed. In this case, the original neverallow rule will refer
to an attribute that does not exist in the generated binary policy.

Now any non-generated attribute used in a typeattributeset rule for a
generated attribute which is used in a neverallow rule will be treated
like it was used in a neverallow rule.

This does not change the behavior of an expandtypeattribute rule for
the attribute. That rule, if it exists, will take precedence.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 libsepol/cil/src/cil_post.c | 57 +
 1 file changed, 57 insertions(+)

diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c
index ad073e8..ee693d4 100644
--- a/libsepol/cil/src/cil_post.c
+++ b/libsepol/cil/src/cil_post.c
@@ -1297,6 +1297,57 @@ static int cil_typeattribute_used(struct 
cil_typeattribute *attr, struct cil_db
return CIL_TRUE;
 }
 
+static void __mark_neverallow_attrs(struct cil_list *expr_list)
+{
+   struct cil_list_item *curr;
+
+   cil_list_for_each(curr, expr_list) {
+   if (curr->flavor == CIL_DATUM) {
+   if (NODE(curr->data)->flavor == CIL_TYPEATTRIBUTE) {
+   struct cil_typeattribute *attr = curr->data;
+   if (strstr(DATUM(attr)->name, TYPEATTR_INFIX)) {
+   
__mark_neverallow_attrs(attr->expr_list);
+   } else {
+   attr->used |= CIL_ATTR_NEVERALLOW;
+   }
+   }
+   } else if (curr->flavor == CIL_LIST) {
+__mark_neverallow_attrs(curr->data);
+   }
+   }
+}
+
+static int __cil_post_db_neverallow_attr_helper(struct cil_tree_node *node, 
uint32_t *finished, void *extra_args)
+{
+   struct cil_db *db = extra_args;
+
+   switch (node->flavor) {
+   case CIL_BLOCK: {
+   struct cil_block *blk = node->data;
+   if (blk->is_abstract == CIL_TRUE) {
+   *finished = CIL_TREE_SKIP_HEAD;
+   }
+   break;
+   }
+   case CIL_MACRO: {
+   *finished = CIL_TREE_SKIP_HEAD;
+   break;
+   }
+   case CIL_TYPEATTRIBUTE: {
+   struct cil_typeattribute *attr = node->data;
+   if ((attr->used & CIL_ATTR_NEVERALLOW) &&
+   strstr(DATUM(attr)->name, TYPEATTR_INFIX)) {
+   __mark_neverallow_attrs(attr->expr_list);
+   }
+   break;
+   }
+   default:
+   break;
+   }
+
+   return SEPOL_OK;
+}
+
 static int __cil_post_db_attr_helper(struct cil_tree_node *node, uint32_t 
*finished, void *extra_args)
 {
int rc = SEPOL_ERR;
@@ -2031,6 +2082,12 @@ static int cil_post_db(struct cil_db *db)
goto exit;
}
 
+   rc = cil_tree_walk(db->ast->root, __cil_post_db_neverallow_attr_helper, 
NULL, NULL, db);
+   if (rc != SEPOL_OK) {
+   cil_log(CIL_INFO, "Failed to mark attributes used by generated 
attributes used in neverallow rules\n");
+   goto exit;
+   }
+
rc = cil_tree_walk(db->ast->root, __cil_post_db_attr_helper, NULL, 
NULL, db);
if (rc != SEPOL_OK) {
cil_log(CIL_INFO, "Failed to create attribute bitmaps\n");
-- 
2.9.5



[PATCH] Fixed bad reference in roleattribute

2017-08-17 Thread James Carter
From: Grégoire Colbert 

"roleattribute" was referencing "typeattributeset", but I believe it should be 
referencing "roleattributeset" instead.
---
 secilc/docs/cil_role_statements.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/secilc/docs/cil_role_statements.md 
b/secilc/docs/cil_role_statements.md
index 0c4cadb..d92f628 100644
--- a/secilc/docs/cil_role_statements.md
+++ b/secilc/docs/cil_role_statements.md
@@ -84,7 +84,7 @@ This example will declare 
[`role`](cil_role_statements.md#role) and [`type`](cil
 roleattribute
 -
 
-Declares a role attribute identifier in the current namespace. The identifier 
may have zero or more [`role`](cil_role_statements.md#role) and 
[`roleattribute`](cil_role_statements.md#roleattribute) identifiers associated 
to it via the [`typeattributeset`](cil_type_statements.md#typeattributeset) 
statement.
+Declares a role attribute identifier in the current namespace. The identifier 
may have zero or more [`role`](cil_role_statements.md#role) and 
[`roleattribute`](cil_role_statements.md#roleattribute) identifiers associated 
to it via the [`roleattributeset`](cil_role_statements.md#roleattributeset) 
statement.
 
 **Statement definition:**
 
-- 
2.9.4



[PATCH v2] libsepol/cil: Fix bugs when writing policy.conf rules

2017-06-14 Thread James Carter
The typebounds rules should end with a ";".

The netifcon and nodecon rules should not end with a ";".

The default rules are missing a "_". They should be "default_user",
"default_role" and "default_type".

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
v2: "default_user", not "default_usr"

 libsepol/cil/src/cil_policy.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/libsepol/cil/src/cil_policy.c b/libsepol/cil/src/cil_policy.c
index 2196ae8..729b6e0 100644
--- a/libsepol/cil/src/cil_policy.c
+++ b/libsepol/cil/src/cil_policy.c
@@ -1069,7 +1069,7 @@ static void cil_typebounds_to_policy(FILE *out, struct 
cil_list *types)
child = i1->data;
if (child->bounds != NULL) {
parent = child->bounds;
-   fprintf(out, "typebounds %s %s\n", parent->datum.fqn, 
child->datum.fqn);
+   fprintf(out, "typebounds %s %s;\n", parent->datum.fqn, 
child->datum.fqn);
}
}
 }
@@ -1779,7 +1779,7 @@ static void cil_netifcons_to_policy(FILE *out, struct 
cil_sort *netifcons, int m
cil_context_to_policy(out, netifcon->if_context, mls);
fprintf(out, " ");
cil_context_to_policy(out, netifcon->packet_context, mls);
-   fprintf(out, ";\n");
+   fprintf(out, "\n");
}
 }
 
@@ -1836,7 +1836,7 @@ static void cil_nodecons_to_policy(FILE *out, struct 
cil_sort *nodecons, int mls
}
 
cil_context_to_policy(out, nodecon->context, mls);
-   fprintf(out, ";\n");
+   fprintf(out, "\n");
}
 }
 
@@ -1928,9 +1928,9 @@ void cil_gen_policy(FILE *out, struct cil_db *db)
cil_commons_to_policy(out, lists[CIL_LIST_COMMON]);
cil_classes_to_policy(out, db->classorder);
 
-   cil_defaults_to_policy(out, lists[CIL_LIST_DEFAULT_USER], 
CIL_KEY_DEFAULTUSER);
-   cil_defaults_to_policy(out, lists[CIL_LIST_DEFAULT_ROLE], 
CIL_KEY_DEFAULTROLE);
-   cil_defaults_to_policy(out, lists[CIL_LIST_DEFAULT_TYPE], 
CIL_KEY_DEFAULTTYPE);
+   cil_defaults_to_policy(out, lists[CIL_LIST_DEFAULT_USER], 
"default_user");
+   cil_defaults_to_policy(out, lists[CIL_LIST_DEFAULT_ROLE], 
"default_role");
+   cil_defaults_to_policy(out, lists[CIL_LIST_DEFAULT_TYPE], 
"default_type");
 
if (db->mls == CIL_TRUE) {
cil_default_ranges_to_policy(out, 
lists[CIL_LIST_DEFAULT_RANGE]);
-- 
2.9.4



[PATCH] libsepol/cil: Fix bugs when writing policy.conf rules

2017-06-14 Thread James Carter
The typebounds rules should end with a ";".

The netifcon and nodecon rules should not end with a ";".

The default rules are missing a "_". They should be "default_usr",
"default_role" and "default_type".

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 libsepol/cil/src/cil_policy.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/libsepol/cil/src/cil_policy.c b/libsepol/cil/src/cil_policy.c
index 2196ae8..f7fe24e 100644
--- a/libsepol/cil/src/cil_policy.c
+++ b/libsepol/cil/src/cil_policy.c
@@ -1069,7 +1069,7 @@ static void cil_typebounds_to_policy(FILE *out, struct 
cil_list *types)
child = i1->data;
if (child->bounds != NULL) {
parent = child->bounds;
-   fprintf(out, "typebounds %s %s\n", parent->datum.fqn, 
child->datum.fqn);
+   fprintf(out, "typebounds %s %s;\n", parent->datum.fqn, 
child->datum.fqn);
}
}
 }
@@ -1779,7 +1779,7 @@ static void cil_netifcons_to_policy(FILE *out, struct 
cil_sort *netifcons, int m
cil_context_to_policy(out, netifcon->if_context, mls);
fprintf(out, " ");
cil_context_to_policy(out, netifcon->packet_context, mls);
-   fprintf(out, ";\n");
+   fprintf(out, "\n");
}
 }
 
@@ -1836,7 +1836,7 @@ static void cil_nodecons_to_policy(FILE *out, struct 
cil_sort *nodecons, int mls
}
 
cil_context_to_policy(out, nodecon->context, mls);
-   fprintf(out, ";\n");
+   fprintf(out, "\n");
}
 }
 
@@ -1928,9 +1928,9 @@ void cil_gen_policy(FILE *out, struct cil_db *db)
cil_commons_to_policy(out, lists[CIL_LIST_COMMON]);
cil_classes_to_policy(out, db->classorder);
 
-   cil_defaults_to_policy(out, lists[CIL_LIST_DEFAULT_USER], 
CIL_KEY_DEFAULTUSER);
-   cil_defaults_to_policy(out, lists[CIL_LIST_DEFAULT_ROLE], 
CIL_KEY_DEFAULTROLE);
-   cil_defaults_to_policy(out, lists[CIL_LIST_DEFAULT_TYPE], 
CIL_KEY_DEFAULTTYPE);
+   cil_defaults_to_policy(out, lists[CIL_LIST_DEFAULT_USER], 
"default_usr");
+   cil_defaults_to_policy(out, lists[CIL_LIST_DEFAULT_ROLE], 
"default_role");
+   cil_defaults_to_policy(out, lists[CIL_LIST_DEFAULT_TYPE], 
"default_type");
 
if (db->mls == CIL_TRUE) {
cil_default_ranges_to_policy(out, 
lists[CIL_LIST_DEFAULT_RANGE]);
-- 
2.9.4



[PATCH v2] libsepol: Fix neverallow bug when checking conditional policy

2017-06-12 Thread James Carter
Commit 9e6840e refactored neverallow checking. In the process a bug
was introduced that causes enabled conditional rules to be skipped.
The bug is that the avtab key is checked by comparing the specified
field of the key to the value AVTAB_ALLOWED. Since enabled conditional
rules have an additional bit set as well, these rules are not
considered to match.

The fix is to use a bitwise AND (&) to only check the desired bit.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
v2: Pay attention to precedence rules

 libsepol/src/assertion.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libsepol/src/assertion.c b/libsepol/src/assertion.c
index 27c39e7..b08757b 100644
--- a/libsepol/src/assertion.c
+++ b/libsepol/src/assertion.c
@@ -222,7 +222,7 @@ static int report_assertion_avtab_matches(avtab_key_t *k, 
avtab_datum_t *d, void
ebitmap_node_t *snode, *tnode;
unsigned int i, j;
 
-   if (k->specified != AVTAB_ALLOWED)
+   if ((k->specified & AVTAB_ALLOWED) == 0)
return 0;
 
if (!match_any_class_permissions(avrule->perms, k->target_class, 
d->data))
@@ -471,7 +471,7 @@ static int check_assertion_avtab_match(avtab_key_t *k, 
avtab_datum_t *d, void *a
avrule_t *avrule = a->avrule;
avtab_t *avtab = a->avtab;
 
-   if (k->specified != AVTAB_ALLOWED)
+   if ((k->specified & AVTAB_ALLOWED) == 0)
goto exit;
 
if (!match_any_class_permissions(avrule->perms, k->target_class, 
d->data))
-- 
2.9.4



[PATCH] libsepol: Fix neverallow bug when checking conditional policy

2017-06-09 Thread James Carter
Commit 9e6840e refactored neverallow checking. In the process a bug
was introduced that causes enabled conditional rules to be skipped.
The bug is that the avtab key is checked by comparing the specified
field of the key to the value AVTAB_ALLOWED. Since enabled conditional
rules have an additional bit set as well, these rules are not
considered to match.

The fix is to use a bitwise AND (&) to only check the desired bit.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 libsepol/src/assertion.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libsepol/src/assertion.c b/libsepol/src/assertion.c
index 27c39e7..ba8f927 100644
--- a/libsepol/src/assertion.c
+++ b/libsepol/src/assertion.c
@@ -222,7 +222,7 @@ static int report_assertion_avtab_matches(avtab_key_t *k, 
avtab_datum_t *d, void
ebitmap_node_t *snode, *tnode;
unsigned int i, j;
 
-   if (k->specified != AVTAB_ALLOWED)
+   if (k->specified & AVTAB_ALLOWED == 0)
return 0;
 
if (!match_any_class_permissions(avrule->perms, k->target_class, 
d->data))
@@ -471,7 +471,7 @@ static int check_assertion_avtab_match(avtab_key_t *k, 
avtab_datum_t *d, void *a
avrule_t *avrule = a->avrule;
avtab_t *avtab = a->avtab;
 
-   if (k->specified != AVTAB_ALLOWED)
+   if (k->specified & AVTAB_ALLOWED == 0)
goto exit;
 
if (!match_any_class_permissions(avrule->perms, k->target_class, 
d->data))
-- 
2.9.4



[PATCH 2/2 v2] libsepol: Fix module_to_cil's handling of type aliases

2017-05-31 Thread James Carter
Type aliases present a problem for module_to_cil because they are not
in the sym_val_to_name table that it uses to write declarations. Type
aliases are gathered by going through the decl_ids list and then
the alias declaration is written out when the block with that scope
id is handled. This doesn't work if a type alias appears in a require
block, since the require cannot be distinguished from the declaration.
The result is two declarations of the alias and an error when secilc
compiles the policy.

Because of the work cleaning up scope handling, the alias declaration
will always be at the end of the decl_ids list, so now only gather
the last scope id.

Also, when an alias is used in a module it is required as a type and
it will appear in the sym_val_to_name table. When that occurs, just
skip the alias when writing out types.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 libsepol/src/module_to_cil.c | 18 +-
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c
index 77e1219..51e7853 100644
--- a/libsepol/src/module_to_cil.c
+++ b/libsepol/src/module_to_cil.c
@@ -323,7 +323,7 @@ static int typealiases_gather_map(char *key, void *data, 
void *arg)
struct type_datum *type = data;
struct policydb *pdb = arg;
struct scope_datum *scope;
-   uint32_t i;
+   uint32_t len;
uint32_t scope_id;
 
if (type->primary != 1) {
@@ -332,8 +332,9 @@ static int typealiases_gather_map(char *key, void *data, 
void *arg)
return -1;
}
 
-   for (i = 0; i < scope->decl_ids_len; i++) {
-   scope_id = scope->decl_ids[i];
+   len = scope->decl_ids_len;
+   if (len > 0) {
+   scope_id = scope->decl_ids[len-1];
if (typealias_lists[scope_id] == NULL) {
rc = list_init(_lists[scope_id]);
if (rc != 0) {
@@ -2274,6 +2275,8 @@ static int type_to_cil(int indent, struct policydb *pdb, 
struct avrule_block *UN
cil_printf("))\n");
}
break;
+   case TYPE_ALIAS:
+   break;
default:
log_err("Unknown flavor (%i) of type %s", type->flavor, key);
rc = -1;
@@ -3387,6 +3390,7 @@ static int typealiases_to_cil(int indent, struct policydb 
*pdb, struct avrule_bl
 {
struct type_datum *alias_datum;
char *alias_name;
+   char *type_name;
struct list_node *curr;
struct avrule_decl *decl = stack_peek(decl_stack);
struct list *alias_list = typealias_lists[decl->decl_id];
@@ -3403,9 +3407,13 @@ static int typealiases_to_cil(int indent, struct 
policydb *pdb, struct avrule_bl
rc = -1;
goto exit;
}
-
+   if (alias_datum->flavor == TYPE_ALIAS) {
+   type_name = 
pdb->p_type_val_to_name[alias_datum->primary - 1];
+   } else {
+   type_name = 
pdb->p_type_val_to_name[alias_datum->s.value - 1];
+   }
cil_println(indent, "(typealias %s)", alias_name);
-   cil_println(indent, "(typealiasactual %s %s)", alias_name, 
pdb->p_type_val_to_name[alias_datum->s.value - 1]);
+   cil_println(indent, "(typealiasactual %s %s)", alias_name, 
type_name);
}
 
return 0;
-- 
2.9.4



[PATCH 1/2 v2] libsepol: Clean up scope handling

2017-05-31 Thread James Carter
Currently, when checking if an identifier is enabled, each scope in
the decl_ids list is checked. This means that if any block that
requires the identifier is enabled, then the identifier will be treated
as being declared.

Now, declarations will be kept at the end of the decl_ids list and
when checking if an identifier is enabled, only the last scope will
be checked (Except for roles and users which allow multiple declarations,
they will have to keep the old behavior.)

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
v2: Removed duplicate declaration

 libsepol/src/avrule_block.c | 23 +++
 libsepol/src/policydb.c | 13 +
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/libsepol/src/avrule_block.c b/libsepol/src/avrule_block.c
index 224e999..5a873af 100644
--- a/libsepol/src/avrule_block.c
+++ b/libsepol/src/avrule_block.c
@@ -156,20 +156,35 @@ int is_id_enabled(char *id, policydb_t * p, int 
symbol_table)
 {
scope_datum_t *scope =
(scope_datum_t *) hashtab_search(p->scope[symbol_table].table, id);
-   uint32_t i;
+   avrule_decl_t *decl;
+   uint32_t len = scope->decl_ids_len;
+
if (scope == NULL) {
return 0;
}
if (scope->scope != SCOPE_DECL) {
return 0;
}
-   for (i = 0; i < scope->decl_ids_len; i++) {
-   avrule_decl_t *decl =
-   p->decl_val_to_struct[scope->decl_ids[i] - 1];
+
+   if (len < 1) {
+   return 0;
+   }
+
+   if (symbol_table == SYM_ROLES || symbol_table == SYM_USERS) {
+   uint32_t i;
+   for (i = 0; i < len; i++) {
+   decl = p->decl_val_to_struct[scope->decl_ids[i] - 1];
+   if (decl != NULL && decl->enabled) {
+   return 1;
+   }
+   }
+   } else {
+   decl = p->decl_val_to_struct[scope->decl_ids[len-1] - 1];
if (decl != NULL && decl->enabled) {
return 1;
}
}
+
return 0;
 }
 
diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
index ab3b31f..691101e 100644
--- a/libsepol/src/policydb.c
+++ b/libsepol/src/policydb.c
@@ -1720,6 +1720,19 @@ int symtab_insert(policydb_t * pol, uint32_t sym,
return -ENOMEM;
}
 
+   if (scope_datum->scope == SCOPE_DECL && scope == SCOPE_REQ) {
+   /* Need to keep the decl at the end of the list */
+   uint32_t len, tmp;
+   len = scope_datum->decl_ids_len;
+   if (len < 2) {
+   /* This should be impossible here */
+   return -1;
+   }
+   tmp = scope_datum->decl_ids[len-2];
+   scope_datum->decl_ids[len-2] = scope_datum->decl_ids[len-1];
+   scope_datum->decl_ids[len-1] = tmp;
+   }
+
return retval;
 }
 
-- 
2.9.4



[PATCH 2/2] libsepol: Fix module_to_cil's handling of type aliases

2017-05-30 Thread James Carter
Type aliases present a problem for module_to_cil because they are not
in the sym_val_to_name table that it uses to write declarations. Type
aliases are gathered by going through the decl_ids list and then
the alias declaration is written out when the block with that scope
id is handled. This doesn't work if a type alias appears in a require
block, since the require cannot be distinguished from the declaration.
The result is two declarations of the alias and an error when secilc
compiles the policy.

Because of the work cleaning up scope handling, the alias declaration
will always be at the end of the decl_ids list, so now only gather
the last scope id.

Also, when an alias is used in a module it is required as a type and
it will appear in the sym_val_to_name table. When that occurs, just
skip the alias when writing out types.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 libsepol/src/module_to_cil.c | 18 +-
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c
index 7d8eb20..429d164 100644
--- a/libsepol/src/module_to_cil.c
+++ b/libsepol/src/module_to_cil.c
@@ -317,7 +317,7 @@ static int typealiases_gather_map(char *key, void *data, 
void *arg)
struct type_datum *type = data;
struct policydb *pdb = arg;
struct scope_datum *scope;
-   uint32_t i;
+   uint32_t len;
uint32_t scope_id;
 
if (type->primary != 1) {
@@ -326,8 +326,9 @@ static int typealiases_gather_map(char *key, void *data, 
void *arg)
return -1;
}
 
-   for (i = 0; i < scope->decl_ids_len; i++) {
-   scope_id = scope->decl_ids[i];
+   len = scope->decl_ids_len;
+   if (len > 0) {
+   scope_id = scope->decl_ids[len-1];
if (typealias_lists[scope_id] == NULL) {
rc = list_init(_lists[scope_id]);
if (rc != 0) {
@@ -2262,6 +2263,8 @@ static int type_to_cil(int indent, struct policydb *pdb, 
struct avrule_block *UN
cil_printf("))\n");
}
break;
+   case TYPE_ALIAS:
+   break;
default:
log_err("Unknown flavor (%i) of type %s", type->flavor, key);
rc = -1;
@@ -3321,6 +3324,7 @@ static int typealiases_to_cil(int indent, struct policydb 
*pdb, struct avrule_bl
 {
struct type_datum *alias_datum;
char *alias_name;
+   char *type_name;
struct list_node *curr;
struct avrule_decl *decl = stack_peek(decl_stack);
struct list *alias_list = typealias_lists[decl->decl_id];
@@ -3337,9 +3341,13 @@ static int typealiases_to_cil(int indent, struct 
policydb *pdb, struct avrule_bl
rc = -1;
goto exit;
}
-
+   if (alias_datum->flavor == TYPE_ALIAS) {
+   type_name = 
pdb->p_type_val_to_name[alias_datum->primary - 1];
+   } else {
+   type_name = 
pdb->p_type_val_to_name[alias_datum->s.value - 1];
+   }
cil_println(indent, "(typealias %s)", alias_name);
-   cil_println(indent, "(typealiasactual %s %s)", alias_name, 
pdb->p_type_val_to_name[alias_datum->s.value - 1]);
+   cil_println(indent, "(typealiasactual %s %s)", alias_name, 
type_name);
}
 
return 0;
-- 
2.9.4



[PATCH 1/2] libsepol: Clean up scope handling

2017-05-30 Thread James Carter
Currently, when checking if an identifier is enabled, each scope in
the decl_ids list is checked. This means that if any block that
requires the identifier is enabled, then the identifier will be treated
as being declared.

Now, declarations will be kept at the end of the decl_ids list and
when checking if an identifier is enabled, only the last scope will
be checked (Except for roles and users which allow multiple declarations,
they will have to keep the old behavior.)

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 libsepol/src/avrule_block.c | 24 
 libsepol/src/policydb.c | 13 +
 2 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/libsepol/src/avrule_block.c b/libsepol/src/avrule_block.c
index 224e999..e1f460e 100644
--- a/libsepol/src/avrule_block.c
+++ b/libsepol/src/avrule_block.c
@@ -156,20 +156,36 @@ int is_id_enabled(char *id, policydb_t * p, int 
symbol_table)
 {
scope_datum_t *scope =
(scope_datum_t *) hashtab_search(p->scope[symbol_table].table, id);
-   uint32_t i;
+   avrule_decl_t *decl;
+   uint32_t len = scope->decl_ids_len;
+
if (scope == NULL) {
return 0;
}
if (scope->scope != SCOPE_DECL) {
return 0;
}
-   for (i = 0; i < scope->decl_ids_len; i++) {
-   avrule_decl_t *decl =
-   p->decl_val_to_struct[scope->decl_ids[i] - 1];
+
+   if (len < 1) {
+   return 0;
+   }
+
+   if (symbol_table == SYM_ROLES || symbol_table == SYM_USERS) {
+   uint32_t i;
+   for (i = 0; i < len; i++) {
+   avrule_decl_t *decl =
+   p->decl_val_to_struct[scope->decl_ids[i] - 1];
+   if (decl != NULL && decl->enabled) {
+   return 1;
+   }
+   }
+   } else {
+   decl = p->decl_val_to_struct[scope->decl_ids[len-1] - 1];
if (decl != NULL && decl->enabled) {
return 1;
}
}
+
return 0;
 }
 
diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
index b153095..ff4fc4e 100644
--- a/libsepol/src/policydb.c
+++ b/libsepol/src/policydb.c
@@ -1698,6 +1698,19 @@ int symtab_insert(policydb_t * pol, uint32_t sym,
return -ENOMEM;
}
 
+   if (scope_datum->scope == SCOPE_DECL && scope == SCOPE_REQ) {
+   /* Need to keep the decl at the end of the list */
+   uint32_t len, tmp;
+   len = scope_datum->decl_ids_len;
+   if (len < 2) {
+   /* This should be impossible here */
+   return -1;
+   }
+   tmp = scope_datum->decl_ids[len-2];
+   scope_datum->decl_ids[len-2] = scope_datum->decl_ids[len-1];
+   scope_datum->decl_ids[len-1] = tmp;
+   }
+
return retval;
 }
 
-- 
2.9.4



Re: [PATCH v1 5/9] libsepol: Add ibendport ocontext handling

2017-05-17 Thread James Carter

On 05/15/2017 04:42 PM, Dan Jurgens wrote:

From: Daniel Jurgens <dani...@mellanox.com>

Add support for reading, writing, and copying IB end port ocontext data.
Also add support for querying a IB end port sid to checkpolicy.

Signed-off-by: Daniel Jurgens <dani...@mellanox.com>

---
v1:
Stephen Smalley:
- Removed unused domain and type params from sepol_ibendport_sid.
- Remove ibendport initial sid from ocontext_selinux_isid_to_cil
- Check the length provide for the device name in ocontext_read_selinux
- Used strcmp for dev_name comparison.

James Carter:
- Added ibendport handling to kernel_to_cil.c and kernel_to_conf.c

Signed-off-by: Daniel Jurgens <dani...@mellanox.com>
---
  checkpolicy/checkpolicy.c  | 20 ++
  libsepol/include/sepol/policydb/services.h |  8 ++
  libsepol/src/expand.c  |  8 ++
  libsepol/src/kernel_to_cil.c   | 42 ++
  libsepol/src/kernel_to_conf.c  | 41 +
  libsepol/src/libsepol.map.in   |  1 +
  libsepol/src/module_to_cil.c   | 14 ++
  libsepol/src/policydb.c| 26 +++---
  libsepol/src/services.c| 37 ++
  libsepol/src/write.c   | 14 ++
  10 files changed, 208 insertions(+), 3 deletions(-)

diff --git a/checkpolicy/checkpolicy.c b/checkpolicy/checkpolicy.c
index d0e46ba..94bf083 100644
--- a/checkpolicy/checkpolicy.c
+++ b/checkpolicy/checkpolicy.c
@@ -701,6 +701,7 @@ int main(int argc, char **argv)
printf("i)  display constraint expressions\n");
printf("j)  display validatetrans expressions\n");
printf("k)  Call ibpkey_sid\n");
+   printf("l)  Call ibendport_sid\n");
  #ifdef EQUIVTYPES
printf("z)  Show equivalent types\n");
  #endif
@@ -1245,6 +1246,25 @@ int main(int argc, char **argv)
printf("sid %d\n", ssid);
}
break;
+   case 'l':
+   printf("device name (eg. mlx4_0)?  ");
+   FGETS(ans, sizeof(ans), stdin);
+   ans[strlen(ans) - 1] = 0;
+
+   name = malloc((strlen(ans) + 1) * sizeof(char));
+   if (!name) {
+   fprintf(stderr, "couldn't malloc string.\n");
+   break;
+   }
+   strcpy(name, ans);
+
+   printf("port? ");
+   FGETS(ans, sizeof(ans), stdin);
+   port = atoi(ans);
+   sepol_ibendport_sid(name, port, );
+   printf("sid %d\n", ssid);
+   free(name);
+   break;
  #ifdef EQUIVTYPES
case 'z':
identify_equiv_types();
diff --git a/libsepol/include/sepol/policydb/services.h 
b/libsepol/include/sepol/policydb/services.h
index 459254e..e4f2f11 100644
--- a/libsepol/include/sepol/policydb/services.h
+++ b/libsepol/include/sepol/policydb/services.h
@@ -196,6 +196,14 @@ extern int sepol_ibpkey_sid(void *subnet_prefix_p,
sepol_security_id_t *out_sid);
  
  /*

+ * Return the SID of the ibendport specified by
+ * `dev_name', and `port'.
+ */
+extern int sepol_ibendport_sid(char *dev_name,
+  uint8_t port,
+  sepol_security_id_t *out_sid);
+
+/*
   * Return the SIDs to use for a network interface
   * with the name `name'.  The `if_sid' SID is returned for
   * the interface and the `msg_sid' SID is returned as
diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c
index c45ecbe..061945e 100644
--- a/libsepol/src/expand.c
+++ b/libsepol/src/expand.c
@@ -2226,6 +2226,14 @@ static int ocontext_copy_selinux(expand_state_t *state)
n->u.ibpkey.low_pkey = c->u.ibpkey.low_pkey;
n->u.ibpkey.high_pkey = c->u.ibpkey.high_pkey;
break;
+   case OCON_IBENDPORT:
+   n->u.ibendport.dev_name = 
strdup(c->u.ibendport.dev_name);
+   if (!n->u.ibendport.dev_name) {
+   ERR(state->handle, "Out of memory!");
+   return -1;
+   }
+   n->u.ibendport.port = c->u.ibendport.port;
+   break;
case OCON_PORT:
n->u.port.protocol = c->u.port.protocol;
n->u.port.low_port = c->u.port.low_port;
di

Re: [PATCH v1 2/9] libsepol: Add ibpkey ocontext handling

2017-05-17 Thread James Carter

On 05/15/2017 04:42 PM, Dan Jurgens wrote:

From: Daniel Jurgens <dani...@mellanox.com>

Add support for reading, writing, and copying Infinabinda Pkey ocontext
data. Also add support for querying a Pkey sid to checkpolicy.

Signed-off-by: Daniel Jurgens <dani...@mellanox.com>

---
v1:
Stephen Smalley:
- Removed domain and type params from sepol_ibpkey_sid.
- Removed splen param from sepol_ibpkey_sid, it never varied.
- Removed extra XPERMS_IOCTL version from policydb_compat_info.
- Confirm that low order bytes of IPv6 addr for subnet prefix is 0's.

James Carter:
- Added ibpkey handling to kernel_to_cil.c and kernel_to_conf.c

Signed-off-by: Daniel Jurgens <dani...@mellanox.com>
---
  checkpolicy/checkpolicy.c  | 25 +
  libsepol/include/sepol/policydb/services.h |  8 
  libsepol/src/expand.c  |  9 +
  libsepol/src/kernel_to_cil.c   | 58 +
  libsepol/src/kernel_to_conf.c  | 59 ++
  libsepol/src/libsepol.map.in   |  1 +
  libsepol/src/module_to_cil.c   | 38 +++
  libsepol/src/policydb.c| 37 +++
  libsepol/src/services.c| 51 ++
  libsepol/src/write.c   | 16 
  10 files changed, 302 insertions(+)

diff --git a/checkpolicy/checkpolicy.c b/checkpolicy/checkpolicy.c
index 534fc22..d0e46ba 100644
--- a/checkpolicy/checkpolicy.c
+++ b/checkpolicy/checkpolicy.c
@@ -22,6 +22,7 @@
   *
   *Policy Module support.
   *
+ * Copyright (C) 2017 Mellanox Technologies Inc.
   * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
   * Copyright (C) 2003 - 2005 Tresys Technology, LLC
   * Copyright (C) 2003 Red Hat, Inc., James Morris <jmor...@redhat.com>
@@ -699,6 +700,7 @@ int main(int argc, char **argv)
printf("h)  change a boolean value\n");
printf("i)  display constraint expressions\n");
printf("j)  display validatetrans expressions\n");
+   printf("k)  Call ibpkey_sid\n");
  #ifdef EQUIVTYPES
printf("z)  Show equivalent types\n");
  #endif
@@ -1220,6 +1222,29 @@ int main(int argc, char **argv)
"\nNo validatetrans expressions found.\n");
}
break;
+   case 'k':
+   {
+   char *p;
+   struct in6_addr addr6;
+   unsigned int pkey;
+
+   printf("subnet prefix?  ");
+   FGETS(ans, sizeof(ans), stdin);
+   ans[strlen(ans) - 1] = 0;
+   p = (char *)
+
+   if (inet_pton(AF_INET6, ans, p) < 1) {
+   printf("error parsing subnet prefix\n");
+   break;
+   }
+
+   printf("pkey? ");
+   FGETS(ans, sizeof(ans), stdin);
+   pkey = atoi(ans);
+   sepol_ibpkey_sid(p, pkey, );
+   printf("sid %d\n", ssid);
+   }
+   break;
  #ifdef EQUIVTYPES
case 'z':
identify_equiv_types();
diff --git a/libsepol/include/sepol/policydb/services.h 
b/libsepol/include/sepol/policydb/services.h
index 9162149..459254e 100644
--- a/libsepol/include/sepol/policydb/services.h
+++ b/libsepol/include/sepol/policydb/services.h
@@ -188,6 +188,14 @@ extern int sepol_port_sid(uint16_t domain,
  uint16_t port, sepol_security_id_t * out_sid);
  
  /*

+ * Return the SID of the ibpkey specified by
+ * `subnet prefix', and `pkey'.
+ */
+extern int sepol_ibpkey_sid(void *subnet_prefix_p,
+   uint16_t pkey,
+   sepol_security_id_t *out_sid);
+
+/*
   * Return the SIDs to use for a network interface
   * with the name `name'.  The `if_sid' SID is returned for
   * the interface and the `msg_sid' SID is returned as
diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c
index 54bf781..c45ecbe 100644
--- a/libsepol/src/expand.c
+++ b/libsepol/src/expand.c
@@ -4,6 +4,7 @@
   *
   * Copyright (C) 2004-2005 Tresys Technology, LLC
   * Copyright (C) 2007 Red Hat, Inc.
+ * Copyright (C) 2017 Mellanox Technologies, Inc.
   *
   *  This library is free software; you can redistribute it and/or
   *  modify it under the terms of the GNU Lesser General Public
@@ -2217,6 +2218,14 @@ static int ocontext_copy_selinux(expand_state_t *state)
return -1;
 

Re: [PATCH 5/9] libsepol: Add ibendport ocontext handling

2017-05-11 Thread James Carter
   >sid[0]);
+   if (rc)
+   goto out;
+   }
+   *out_sid = c->sid[0];
+   } else {
+   *out_sid = SECINITSID_UNLABELED;
+   }
+
+out:
+   return rc;
+}
+
+
+/*
   * Return the SID of the port specified by
   * `domain', `type', `protocol', and `port'.
   */
diff --git a/libsepol/src/write.c b/libsepol/src/write.c
index fa1b7d1..e3ff389 100644
--- a/libsepol/src/write.c
+++ b/libsepol/src/write.c
@@ -1426,6 +1426,20 @@ static int ocontext_write_selinux(struct 
policydb_compat_info *info,
if (context_write(p, >context[0], fp))
return POLICYDB_ERROR;
break;
+   case OCON_IBENDPORT:
+   len = strlen(c->u.ibendport.dev_name);
+   buf[0] = cpu_to_le32(len);
+   buf[1] = cpu_to_le32(c->u.ibendport.port);
+   items = put_entry(buf, sizeof(uint32_t), 2, fp);
+   if (items != 2)
+   return POLICYDB_ERROR;
+   items = put_entry(c->u.ibendport.dev_name, 1, 
len, fp);
+   if (items != len)
+   return POLICYDB_ERROR;
+
+   if (context_write(p, >context[0], fp))
+   return POLICYDB_ERROR;
+   break;
case OCON_PORT:
buf[0] = c->u.port.protocol;
buf[1] = c->u.port.low_port;




--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency


Re: [PATCH 2/9] libsepol: Add ibpkey ocontext handling

2017-05-11 Thread James Carter
olutions, Inc.
   * Copyright (C) 2003-2005 Tresys Technology, LLC
+ * Copyright (C) 2017 Mellanox Technologies Inc.
   *
   *  This library is free software; you can redistribute it and/or
   *  modify it under the terms of the GNU Lesser General Public
@@ -1410,6 +1411,21 @@ static int ocontext_write_selinux(struct 
policydb_compat_info *info,
if (context_write(p, >context[1], fp))
return POLICYDB_ERROR;
break;
+   case OCON_IBPKEY:
+/* The subnet prefix is in network order */
+   for (j = 0; j < 4; j++)
+   buf[j] = c->u.ibpkey.subnet_prefix[j];
+
+   buf[4] = cpu_to_le32(c->u.ibpkey.low_pkey);
+   buf[5] = cpu_to_le32(c->u.ibpkey.high_pkey);
+
+   items = put_entry(buf, sizeof(uint32_t), 6, fp);
+   if (items != 6)
+   return POLICYDB_ERROR;
+
+   if (context_write(p, >context[0], fp))
+   return POLICYDB_ERROR;
+   break;
case OCON_PORT:
buf[0] = c->u.port.protocol;
buf[1] = c->u.port.low_port;




--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency


[PATCH v2] libsepol: Expand attributes with TYPE_FLAGS_EXPAND_ATTR_TRUE set

2017-05-10 Thread James Carter
Commit 1089665e31a647a5f0ba2eabe8ac6232b384bed9 (Add attribute
expansion options) adds an expandattribute rule to the policy.conf
language which sets a type_datum flag. Currently the flag is used
only when writing out CIL policy from a policy.conf.

Make use of the flag when expanding policy to expand policy rules
and remove all type associations for an attribute that has
TYPE_FLAGS_EXPAND_ATTR_TRUE set. (The attribute will remain in the
policy, but have no types associated with it.)

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
v2 Just check if each attribute should be expanded in type_attr_map(). No need
to destroy the types ebitmap.

 libsepol/src/expand.c | 76 ++-
 libsepol/src/link.c   |  8 +++---
 2 files changed, 43 insertions(+), 41 deletions(-)

diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c
index 54bf781..c55226b 100644
--- a/libsepol/src/expand.c
+++ b/libsepol/src/expand.c
@@ -2337,13 +2337,20 @@ static int type_attr_map(hashtab_key_t key
value = type->s.value;
 
if (type->flavor == TYPE_ATTRIB) {
-   if (ebitmap_cpy(>attr_type_map[value - 1], >types)) {
-   goto oom;
-   }
-   ebitmap_for_each_bit(>types, tnode, i) {
-   if (!ebitmap_node_get_bit(tnode, i))
-   continue;
-   if (ebitmap_set_bit(>type_attr_map[i], value - 1, 
1)) {
+   if (!(type->flags & TYPE_FLAGS_EXPAND_ATTR_TRUE)) {
+   if (ebitmap_cpy(>attr_type_map[value - 1], 
>types)) {
+   goto oom;
+   }
+   ebitmap_for_each_bit(>types, tnode, i) {
+   if (!ebitmap_node_get_bit(tnode, i))
+   continue;
+   if (ebitmap_set_bit(>type_attr_map[i], value 
- 1, 1)) {
+   goto oom;
+   }
+   }
+   } else {
+   /* Attribute is being expanded, so remove */
+   if (ebitmap_set_bit(>type_attr_map[value - 1], value 
- 1, 0)) {
goto oom;
}
}
@@ -2513,46 +2520,41 @@ int type_set_expand(type_set_t * set, ebitmap_t * t, 
policydb_t * p,
unsigned int i;
ebitmap_t types, neg_types;
ebitmap_node_t *tnode;
+   unsigned char expand = alwaysexpand || ebitmap_length(>negset) || 
set->flags;
+   type_datum_t *type;
int rc =-1;
 
ebitmap_init();
ebitmap_init(t);
 
-   if (alwaysexpand || ebitmap_length(>negset) || set->flags) {
-   /* First go through the types and OR all the attributes to 
types */
-   ebitmap_for_each_bit(>types, tnode, i) {
-   if (ebitmap_node_get_bit(tnode, i)) {
+   /* First go through the types and OR all the attributes to types */
+   ebitmap_for_each_bit(>types, tnode, i) {
+   if (!ebitmap_node_get_bit(tnode, i))
+   continue;
 
-   /*
-* invalid policies might have more types set 
in the ebitmap than
-* what's available in the type_val_to_struct 
mapping
-*/
-   if (i >= p->p_types.nprim)
-   goto err_types;
+   /*
+* invalid policies might have more types set in the ebitmap 
than
+* what's available in the type_val_to_struct mapping
+*/
+   if (i >= p->p_types.nprim)
+   goto err_types;
 
-   if (!p->type_val_to_struct[i]) {
-   goto err_types;
-   }
+   type = p->type_val_to_struct[i];
 
-   if (p->type_val_to_struct[i]->flavor ==
-   TYPE_ATTRIB) {
-   if (ebitmap_union
-   (,
->type_val_to_struct[i]->
-types)) {
-   goto err_types;
-   }
-   } else {
-   if (ebitmap_set_bit(, i, 1)) {
-   goto err_types;
-   }
-   }
+   if (!type) {
+   goto err_types;
+   }
+
+   if (type->f

Re: [PATCH 01/10] policycoreutils: fixfiles: tidy up usage(), manpage synopsis

2017-05-09 Thread James Carter
We normally add a "signed-off-by" line to patches. Can I add "Signed-off-by: 
Alan Jenkins <alan.christopher.jenk...@gmail.com>" to your patches?


Jim

On 05/07/2017 07:05 AM, Alan Jenkins wrote:

Make sure usage() in fixfiles shows all the current options.
It's printed when there's a user error, so it needs to be
helpful!  (Excluding the deprecated option - see below).

manpage:

Remove the deprecated option `-l logfile`.

Add missing space in `restore|[-f] relabel`.

It's not clear why `-R rpmpackagename` was considered optional in the
second invocation.  (If the user omits it, they are just performing the
first invocation).  It desn't match usage() in fixfiles either.

Clean up bolding for `fixfiles onboot`.

Disable justification (troff "adjustment") in the synopsis.  We want the
common options in the different invocations to line up consistently.
---
  policycoreutils/scripts/fixfiles   |  2 +-
  policycoreutils/scripts/fixfiles.8 | 18 +-
  2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/policycoreutils/scripts/fixfiles b/policycoreutils/scripts/fixfiles
index c876432..e416dfc 100755
--- a/policycoreutils/scripts/fixfiles
+++ b/policycoreutils/scripts/fixfiles
@@ -311,7 +311,7 @@ esac
  }
  usage() {
echo $"""
-Usage: $0 [-v] [-F] [-N time ] { check | restore| [-f] relabel | verify } 
[[dir/file] ... ]
+Usage: $0 [-v] [-F] [-B | -N time ] { check | restore | [-f] relabel | verify 
} [[dir/file] ... ]
  or
  Usage: $0 [-v] [-F] -R rpmpackage[,rpmpackage...] { check | restore | verify }
  or
diff --git a/policycoreutils/scripts/fixfiles.8 
b/policycoreutils/scripts/fixfiles.8
index 0099b9b..c58cb7d 100644
--- a/policycoreutils/scripts/fixfiles.8
+++ b/policycoreutils/scripts/fixfiles.8
@@ -3,18 +3,21 @@
  fixfiles \- fix file SELinux security contexts.
  
  .SH "SYNOPSIS"

+.na
  
  .B fixfiles

-.I [\-v] [\-F] [-B] [ -N time ] [\-l logfile ] { check | restore|[\-f] relabel 
| verify } [[dir/file] ... ]
+.I [\-v] [\-F] [\-B | \-N time ] { check | restore | [\-f] relabel | verify } 
[[dir/file] ... ]
  
  .B fixfiles

-.I [\-v] [\-F] [ \-R rpmpackagename[,rpmpackagename...] ] [\-l logfile ] { 
check | restore | verify }
+.I [\-v] [\-F] \-R rpmpackagename[,rpmpackagename...] { check | restore | 
verify }
  
-.B fixfiles

-.I [\-v] [\-F] \-C PREVIOUS_FILECONTEXT [\-l logfile ] { check | restore | 
verify }
+.B fixfiles
+.I [\-v] [\-F] \-C PREVIOUS_FILECONTEXT  { check | restore | verify }
+
+.B fixfiles
+.I [-F] [-B] onboot
  
-.B fixfiles [-F] [-B]

-.I onboot
+.ad
  
  .SH "DESCRIPTION"

  This manual page describes the
@@ -40,9 +43,6 @@ will setup the machine to relabel on the next reboot.
  .B \-B
  If specified with onboot, this fixfiles will record the current date in the 
/.autorelabel file, so that it can be used later to speed up labeling. If used 
with restore, the restore will only affect files that were modified today.
  .TP
-.B \-l logfile
-Save the output to the specified logfile
-.TP
  .B \-F
  Force reset of context to match file_context for customizable files
  




--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency


Re: [PATCH] Add attribute expansion options

2017-05-09 Thread James Carter
 struct cil_expandtypeattribute *attr = node->data;
+
+   fprintf(stderr, "%s %u\n", __func__, __LINE__);
+   cil_log(CIL_INFO, "(EXPANDTYPEATTRIBUTE ");
+   cil_tree_print_expr(attr->attr_datums, attr->attr_strs);
+   cil_log(CIL_INFO, "%s)\n",attr->expand ?
+   CIL_KEY_CONDTRUE : CIL_KEY_CONDFALSE);
+
+   return;
+   }
case CIL_TYPEATTRIBUTESET: {
struct cil_typeattributeset *attr = node->data;
  
diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h

index 4336a3f2..37e0c9e5 100644
--- a/libsepol/include/sepol/policydb/policydb.h
+++ b/libsepol/include/sepol/policydb/policydb.h
@@ -178,7 +178,11 @@ typedef struct type_datum {
  #define TYPE_ALIAS 2  /* alias in modular policy */
uint32_t flavor;
ebitmap_t types;/* types with this attribute */
-#define TYPE_FLAGS_PERMISSIVE  0x01
+#define TYPE_FLAGS_PERMISSIVE  (1 << 0)
+#define TYPE_FLAGS_EXPAND_ATTR_TRUE(1 << 1)
+#define TYPE_FLAGS_EXPAND_ATTR_FALSE   (1 << 2)
+#define TYPE_FLAGS_EXPAND_ATTR (TYPE_FLAGS_EXPAND_ATTR_TRUE | \
+   TYPE_FLAGS_EXPAND_ATTR_FALSE)
uint32_t flags;
uint32_t bounds;/* bounds type, if exist */
  } type_datum_t;
diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c
index ac095c30..7d8eb204 100644
--- a/libsepol/src/module_to_cil.c
+++ b/libsepol/src/module_to_cil.c
@@ -2244,6 +2244,17 @@ static int type_to_cil(int indent, struct policydb *pdb, 
struct avrule_block *UN
cil_println(indent, "(typeattribute %s)", key);
}
  
+		if (type->flags & TYPE_FLAGS_EXPAND_ATTR) {

+   cil_indent(indent);
+   cil_printf("(expandtypeattribute (%s) ", key);
+   if (type->flags & TYPE_FLAGS_EXPAND_ATTR_TRUE) {
+   cil_printf("true");
+   } else if (type->flags & TYPE_FLAGS_EXPAND_ATTR_FALSE) {
+   cil_printf("false");
+   }
+   cil_printf(")\n");
+   }
+
if (ebitmap_cardinality(>types) > 0) {
cil_indent(indent);
cil_printf("(typeattributeset %s (", key);




--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency


[PATCH] libsepol: Expand attributes with TYPE_FLAGS_EXPAND_ATTR_TRUE set

2017-05-09 Thread James Carter
Commit 1089665e31a647a5f0ba2eabe8ac6232b384bed9 (Add attribute
expansion options) adds an expandattribute rule to the policy.conf
language which sets a type_datum flag. Currently the flag is used
only when writing out CIL policy from a policy.conf.

Make use of the flag when expanding policy to expand policy rules
and remove all type associations for an attribute that has
TYPE_FLAGS_EXPAND_ATTR_TRUE set. (The attribute will remain in the
policy, but have no types associated with it.)

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 libsepol/src/expand.c | 72 ++-
 libsepol/src/link.c   |  8 +++---
 2 files changed, 46 insertions(+), 34 deletions(-)

diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c
index 54bf781..74a650f 100644
--- a/libsepol/src/expand.c
+++ b/libsepol/src/expand.c
@@ -2360,6 +2360,20 @@ oom:
return -1;
 }
 
+static int remove_types_from_expanded(hashtab_key_t key
+ __attribute__ ((unused)), hashtab_datum_t 
datum,
+ void *ptr)
+{
+   type_datum_t *type = (type_datum_t *) datum;
+
+   if (type->flavor == TYPE_ATTRIB && (type->flags & 
TYPE_FLAGS_EXPAND_ATTR_TRUE)) {
+   ebitmap_destroy(>types);
+   ebitmap_init(>types);
+   }
+
+   return 0;
+}
+
 /* converts typeset using typemap and expands into ebitmap_t types using the 
attributes in the passed in policy.
  * this should not be called until after all the blocks have been processed 
and the attributes in target policy
  * are complete. */
@@ -2513,46 +2527,41 @@ int type_set_expand(type_set_t * set, ebitmap_t * t, 
policydb_t * p,
unsigned int i;
ebitmap_t types, neg_types;
ebitmap_node_t *tnode;
+   unsigned char expand = alwaysexpand || ebitmap_length(>negset) || 
set->flags;
+   type_datum_t *type;
int rc =-1;
 
ebitmap_init();
ebitmap_init(t);
 
-   if (alwaysexpand || ebitmap_length(>negset) || set->flags) {
-   /* First go through the types and OR all the attributes to 
types */
-   ebitmap_for_each_bit(>types, tnode, i) {
-   if (ebitmap_node_get_bit(tnode, i)) {
+   /* First go through the types and OR all the attributes to types */
+   ebitmap_for_each_bit(>types, tnode, i) {
+   if (!ebitmap_node_get_bit(tnode, i))
+   continue;
+
+   /*
+* invalid policies might have more types set in the ebitmap 
than
+* what's available in the type_val_to_struct mapping
+*/
+   if (i >= p->p_types.nprim)
+   goto err_types;
 
-   /*
-* invalid policies might have more types set 
in the ebitmap than
-* what's available in the type_val_to_struct 
mapping
-*/
-   if (i >= p->p_types.nprim)
-   goto err_types;
+   type = p->type_val_to_struct[i];
 
-   if (!p->type_val_to_struct[i]) {
-   goto err_types;
-   }
+   if (!type) {
+   goto err_types;
+   }
 
-   if (p->type_val_to_struct[i]->flavor ==
-   TYPE_ATTRIB) {
-   if (ebitmap_union
-   (,
->type_val_to_struct[i]->
-types)) {
-   goto err_types;
-   }
-   } else {
-   if (ebitmap_set_bit(, i, 1)) {
-   goto err_types;
-   }
-   }
+   if (type->flavor == TYPE_ATTRIB && 
+   (expand || (type->flags & TYPE_FLAGS_EXPAND_ATTR_TRUE))) {
+   if (ebitmap_union(, >types)) {
+   goto err_types;
+   }
+   } else {
+   if (ebitmap_set_bit(, i, 1)) {
+   goto err_types;
}
}
-   } else {
-   /* No expansion of attributes, just copy the set as is. */
-   if (ebitmap_cpy(, >types))
-   goto err_types;
}
 
/* Now do the same thing for negset */
@@ -3160,6 +3169,9 @@ int expand_module(sepol_handle_t * handle,
if (genfs_copy())
  

Re: [PATCH] Add attribute expansion options

2017-05-05 Thread James Carter
tree_print_node(struct cil_tree_node *node)
cil_log(CIL_INFO, "TYPE: %s\n", type->datum.name);
return;
}
+   case CIL_EXPANDTYPEATTRIBUTE: {
+   struct cil_expandtypeattribute *attr = node->data;
+
+   fprintf(stderr, "%s %u\n", __func__, __LINE__);
+   cil_log(CIL_INFO, "(EXPANDTYPEATTRIBUTE ");
+   cil_tree_print_expr(attr->attr_datums, attr->attr_strs);
+   cil_log(CIL_INFO, "%s)\n",attr->expand ?
+   CIL_KEY_CONDTRUE : CIL_KEY_CONDFALSE);
+
+   return;
+   }
case CIL_TYPEATTRIBUTESET: {
struct cil_typeattributeset *attr = node->data;
  
diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h

index 4336a3f2..37e0c9e5 100644
--- a/libsepol/include/sepol/policydb/policydb.h
+++ b/libsepol/include/sepol/policydb/policydb.h
@@ -178,7 +178,11 @@ typedef struct type_datum {
  #define TYPE_ALIAS 2  /* alias in modular policy */
uint32_t flavor;
ebitmap_t types;/* types with this attribute */
-#define TYPE_FLAGS_PERMISSIVE  0x01
+#define TYPE_FLAGS_PERMISSIVE  (1 << 0)
+#define TYPE_FLAGS_EXPAND_ATTR_TRUE(1 << 1)
+#define TYPE_FLAGS_EXPAND_ATTR_FALSE   (1 << 2)
+#define TYPE_FLAGS_EXPAND_ATTR (TYPE_FLAGS_EXPAND_ATTR_TRUE | \
+   TYPE_FLAGS_EXPAND_ATTR_FALSE)
uint32_t flags;
uint32_t bounds;/* bounds type, if exist */
  } type_datum_t;
diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c
index ac095c30..7d8eb204 100644
--- a/libsepol/src/module_to_cil.c
+++ b/libsepol/src/module_to_cil.c
@@ -2244,6 +2244,17 @@ static int type_to_cil(int indent, struct policydb *pdb, 
struct avrule_block *UN
cil_println(indent, "(typeattribute %s)", key);
}
  
+		if (type->flags & TYPE_FLAGS_EXPAND_ATTR) {

+   cil_indent(indent);
+   cil_printf("(expandtypeattribute (%s) ", key);
+   if (type->flags & TYPE_FLAGS_EXPAND_ATTR_TRUE) {
+   cil_printf("true");
+   } else if (type->flags & TYPE_FLAGS_EXPAND_ATTR_FALSE) {
+   cil_printf("false");
+   }
+   cil_printf(")\n");
+   }
+
if (ebitmap_cardinality(>types) > 0) {
cil_indent(indent);
cil_printf("(typeattributeset %s (", key);




--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency


Re: [PATCH 1/6] Revert "policycoreutils: let output of `fixfiles` be redirected (as normal)"

2017-05-05 Thread James Carter

On 05/04/2017 01:01 PM, Alan Jenkins wrote:

This reverts commit ac7899fc3ad6221e195dd13cdf14b346897314ae,
which is not yet part of an officially tagged release
(or release candidate).

`LOGFILE=/proc/self/fd/1` was wrong.

`LOGFILE=$(tty)` was being relied on in one case (exclude_dirs),
to log messages from a function run specifically with stdout redirected
(captured into a variable).

Having `logit "message"` break inside redirected functions
is a nasty leaky abstraction.

This caused e.g. `fixfiles restore` to terminate early with the error

 skipping: No such file or directory

if the user had configured any excluded paths in
/etc/selinux/fixfiles_exclude_dirs


These six patches have been applied.

Thanks,
Jim


---
  policycoreutils/scripts/fixfiles | 10 +++---
  1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/policycoreutils/scripts/fixfiles b/policycoreutils/scripts/fixfiles
index bc74d69..75d7762 100755
--- a/policycoreutils/scripts/fixfiles
+++ b/policycoreutils/scripts/fixfiles
@@ -119,7 +119,11 @@ VERBOSE="-p"
  FORCEFLAG=""
  DIRS=""
  RPMILES=""
-LOGFILE=/proc/self/fd/1
+LOGFILE=`tty`
+if [ $? != 0 ]; then
+LOGFILE="/dev/null"
+fi
+LOGGER=/usr/sbin/logger
  SETFILES=/sbin/setfiles
  RESTORECON=/sbin/restorecon
  FILESYSTEMSRW=`get_rw_labeled_mounts`
@@ -134,11 +138,11 @@ else
  fi
  
  #

-# Write to LOGFILE
+# Log to either syslog or a LOGFILE
  #
  logit () {
  if [ -n $LOGFILE ]; then
-echo $1 >> "$LOGFILE"
+echo $1 >> $LOGFILE
  fi
  }
  #




--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency


Re: Policy capabilities: when to use and complications with using

2017-05-03 Thread James Carter
names as strings in the kernel policy (new binary format version), then
we would no longer need to update libsepol for each new policy
capability.  The kernel would then turn the list into the bitmap
internally.  The downside is that we would lose validation of the
capability names when policy is built, and it isn't clear how the
kernel should handle unknown names (presently the kernel will simply
ignore any unknown capabilities in the bitmap).  Failing at policy load
time would mean we can't enable the capability in policy without making
it depend on a particular kernel version.



I wonder if in the case of a new permission being added whether the kernel could 
revert to the previous behavior if the new permission is not in the policy. The 
new permission would be an implicit policy capability.


Even if we just included strings in the kernel policy it would still be nice to 
have something in libsepol, so that typos would be caught.



The lack of any direct relationship between policy capabilities and the
classes/permissions they affect also can be misleading.  For example,
someone booting a recent kernel might see warnings about undefined
classes introduced by the extended_socket_class feature and add those
class definitions to their policy, which will silence the kernel
warning and make them think that they are actually using those classes
now.  But they won't actually get used until they declare the
capability too in their policy, and the kernel doesn't warn about that
(nor does it necessarily make sense to do so, since that may be a
conscious choice by the policy author).  The kernel could however log
each policy capability and its state as part of its normal logging and
leave it up to the reader to decide whether those values are correct or
not.  We also had talked originally about checkpolicy and friends
possibly warning on inconsistencies, while leaving it up to the policy
author.



If the permissions acted as an implicit policy capability, that would take care 
of this problem. The kernel could warn that since the new permission is missing 
then these checks would be different.



So:

1) Should we investigate lighter weight support for policy
capabilities, and if so, how?

2) Should the kernel log information about enabled/disabled policy
capabilities in much the same manner as it does for undefined
classes/permissions?

3) Should the policy compiler toolchain warn the user if a policy
capability is not declared and classes/permissions are used in rules
that will only be used if that policy capability is declared?  And
similarly if a policy capability is declared but the corresponding
classes/permissions are not used in any rules?

4) Do we need/want a policy capability for map permission and other
cases where we are only adding a new permission check? Or should we
continue to reserve them for cases not addressed via handle_unknown?



I know you also want this:
5) Should CIL support adding a permission to a new class, so we don't need to 
grab a source rpm and rebuild the whole policy from source just to test a new 
permission?


Jim


[1] https://github.com/SELinuxProject/selinux-kernel/issues/13




--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency


Re: [PATCH 0/2] libsepol and checkpolicy: Add ability to expand some attributes in binary policy

2017-04-12 Thread James Carter

On 04/12/2017 03:12 PM, Dominick Grift wrote:

On Wed, Apr 12, 2017 at 02:20:32PM -0400, James Carter wrote:

On 04/12/2017 09:35 AM, Dominick Grift wrote:

On Wed, Apr 12, 2017 at 09:26:17AM -0400, James Carter wrote:

On 04/12/2017 02:11 AM, Dominick Grift wrote:

On Tue, Apr 11, 2017 at 01:53:41PM -0400, James Carter wrote:

The number of type attributes included in the binary policy is becomming a 
performance issue in some cases.

This patch set more aggressives removes attributes and gives the options to 
expand and remove all auto-generated attributes and all attributes with fewer 
than a given amount of attributes assigned.

Comparison of the number of attributes remaining in the binary policy
 mls   normal  android
org  310 286 255
old  268 251 130
max  154  20  17
min  226 173 119
def  224 170  80
gen  221 170  46
u5   191 112  59

Org - Number of attributes in the CIL policy
Old - Results without this patch set
Max - Remove the maximum number of attributes: "-G -X "
Min - Remove the minimum number of attributes: "-X 0"
Def - The new defaults for CIL
Gen - Just removing auto-generated attributes: "-G"
U5  - Remove attributes with less than five members: "-X 5"


I tried this with my policy:

old defaults

size: 949K
typeattributes: 765
types: 1420
allow rules: 24812

new defaults

size: 876K
typeattributes: 641
types: 1418
allow rules: 20998

I cannot imagine where the difference went.. every aspect improved. I expected 
to see some trade-offs instead here.



I hope that the number of types going from 1420 to 1418 is a typo. I don't
see how my patch set would remove any types, but, if it is, then that is a
problem.

With your dssp1-standard policy, I see:
Before : 1178K, 9938 attributes, and 534 types
After (default):  574K, 3209 attributes, and 534 types
After (-X5):  471K, 2206 attributes, and 534 types

Jim


The test that i did was with dssp2-standard (my current work). So if you want 
you can see for yourself on github.

you can then also see that I , with dssp2-standard, still have attributes 
without types associated with it

At least:

seinfo -a | grep adm_subj_type | grep -v service.service | wc -l
90



Thanks, this was do to an older bug. If an attribute had already been
evaluated in an expression, then cil_typeattribute_used() would not be
called on it.

So now I have for your dssp1-standard policy:
Before : 1178K, 9938 attributes, and 534 types
After (default):  420K, 1621 attributes, and 534 types
After (-X5):  275K,  248 attributes, and 534 types


The above is where my dssp1 model really shines. These stats are what i 
envisioned when I started to design it at first, I abandoned it because of this 
bug but also because of one other fundamental limitation:

namely that one cannot associate typeattributes in booleanif. Is this really 
something that we cannot overcome?



Sorry, but that would be very difficult to do in the kernel policy.

What were you trying to accomplish with them?

Jim



So now I have for your dssp2-standard policy:
Before :  918K, 772 attributes, and 1426 types
After (default):  889K, 551 attributes, and 1426 types
After (-X5):  901K, 160 attributes, and 1426 types

And:
seinfo -a policy.30 | grep adm_subj_type | grep -v service.service | wc -l
0

Jim






James Carter (2):
  libsepol/cil: Add ability to expand some attributes in binary policy
  secilc: Add options to control the expansion of attributes

 libsepol/cil/include/cil/cil.h |   2 +
 libsepol/cil/src/cil.c |  12 ++
 libsepol/cil/src/cil_binary.c  | 253 +++--
 libsepol/cil/src/cil_internal.h|   7 +-
 libsepol/cil/src/cil_post.c|  32 +++--
 libsepol/cil/src/cil_resolve_ast.c |  25 ++--
 libsepol/src/libsepol.map.in   |   2 +
 secilc/secil2conf.c|   2 +
 secilc/secilc.8.xml|  10 ++
 secilc/secilc.c|  31 -
 10 files changed, 275 insertions(+), 101 deletions(-)

--
2.7.4

___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.




___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.




--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.




___
Selinux mailing list
Selinux@tycho.ns

[PATCH 1/2 v2] libsepol/cil: Add ability to expand some attributes in binary policy

2017-04-12 Thread James Carter
Originally, all type attributes were expanded when building a binary
policy. As the policy grew, binary policy sizes became too large, so
changes were made to keep attributes in the binary policy to minimize
policy size.

Keeping attributes works well as long as each type does not have too
many attributes. If an access check fails for types t1 and t2, then
additional checks must be made for every attribute that t1 is a member
of against t2 and all the attributes that t2 is a member of. This is
O(n*m) behavior and there are cases now where this is becoming a
performance issue.

Attributes are more aggressively removed than before. An attribute
will now be removed if it only appears in rules where attributes are
always expanded (typetransition, typechange, typemember, roletransition,
rangetransition, roletype, and AV Rules with self).

Attributes that are used in constraints are always kept because the
attribute name is stored for debugging purposes in the binary policy.

Attributes that are used in neverallow rules, but not in other AV rules,
will be kept unless the attribute is auto-generated.

Attributes that are only used in AV rules other than neverallow rules
are kept unless the number of types assigned to them is less than the
value of attrs_expand_size in the CIL db. The default is 1, which means
that any attribute that has no types assigned to it will be expanded (and
the rule removed from the policy), which is CIL's current behavior. The
value can be set using the function cil_set_attrs_expand_size().

Auto-generated attributes that are used only in neverallow rules are
always expanded. The rest are kept by default, but if the value of
attrs_expand_generated in the CIL db is set to true, they will be
expanded. The function cil_set_attrs_expand_generated() can be used
to set the value.

When creating the binary policy, CIL will expand all attributes that
are being removed and it will expand all attributes with less members
than the value specified by attrs_expand_size. So even if an attribute
is used in a constraint or neverallow and the attribute itself will be
included in the binary policy, it will be expanded when writing AV
rules if it has less members than attrs_expand_size.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 libsepol/cil/include/cil/cil.h |   2 +
 libsepol/cil/src/cil.c |  12 ++
 libsepol/cil/src/cil_binary.c  | 253 +++--
 libsepol/cil/src/cil_internal.h|   7 +-
 libsepol/cil/src/cil_post.c|  32 +++--
 libsepol/cil/src/cil_resolve_ast.c |  25 ++--
 libsepol/src/libsepol.map.in   |   2 +
 7 files changed, 233 insertions(+), 100 deletions(-)

diff --git a/libsepol/cil/include/cil/cil.h b/libsepol/cil/include/cil/cil.h
index c4a6fb9..4507892 100644
--- a/libsepol/cil/include/cil/cil.h
+++ b/libsepol/cil/include/cil/cil.h
@@ -50,6 +50,8 @@ extern void cil_set_disable_neverallow(cil_db_t *db, int 
disable_neverallow);
 extern void cil_set_preserve_tunables(cil_db_t *db, int preserve_tunables);
 extern int cil_set_handle_unknown(cil_db_t *db, int handle_unknown);
 extern void cil_set_mls(cil_db_t *db, int mls);
+extern void cil_set_attrs_expand_generated(struct cil_db *db, int 
attrs_expand_generated);
+extern void cil_set_attrs_expand_size(struct cil_db *db, unsigned 
attrs_expand_size);
 extern void cil_set_target_platform(cil_db_t *db, int target_platform);
 extern void cil_set_policy_version(cil_db_t *db, int policy_version);
 extern void cil_write_policy_conf(FILE *out, struct cil_db *db);
diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c
index 7c40ad0..a64c528 100644
--- a/libsepol/cil/src/cil.c
+++ b/libsepol/cil/src/cil.c
@@ -282,6 +282,8 @@ void cil_db_init(struct cil_db **db)
 
(*db)->disable_dontaudit = CIL_FALSE;
(*db)->disable_neverallow = CIL_FALSE;
+   (*db)->attrs_expand_generated = CIL_FALSE;
+   (*db)->attrs_expand_size = 1;
(*db)->preserve_tunables = CIL_FALSE;
(*db)->handle_unknown = -1;
(*db)->mls = -1;
@@ -1629,6 +1631,16 @@ void cil_set_disable_neverallow(struct cil_db *db, int 
disable_neverallow)
db->disable_neverallow = disable_neverallow;
 }
 
+void cil_set_attrs_expand_generated(struct cil_db *db, int 
attrs_expand_generated)
+{
+   db->attrs_expand_generated = attrs_expand_generated;
+}
+
+void cil_set_attrs_expand_size(struct cil_db *db, unsigned attrs_expand_size)
+{
+   db->attrs_expand_size = attrs_expand_size;
+}
+
 void cil_set_preserve_tunables(struct cil_db *db, int preserve_tunables)
 {
db->preserve_tunables = preserve_tunables;
diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c
index ac18c4e..e1481a4 100644
--- a/libsepol/cil/src/cil_binary.c
+++ b/libsepol/cil/src/cil_binary.c
@@ -567,7 +567,7 @@ int cil_typeattribute_to_policydb(policydb_t *pdb, struct 
cil_typeattribute *cil
char *key = NULL;
type_datum_t *se

[PATCH 2/2 v2] secilc: Add options to control the expansion of attributes

2017-04-12 Thread James Carter
Added "-G, --expand_generated" option to specify that all automatically
generated attributes should be expanded and removed.

Added "-X, --expand_size " option to specify which attributes
are expanded when building a kernel policy. All attributes that have
less types assigned to it than SIZE will be expanded when writing AV
rules.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 secilc/secil2conf.c |  2 ++
 secilc/secilc.8.xml | 10 ++
 secilc/secilc.c | 31 ++-
 3 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/secilc/secil2conf.c b/secilc/secil2conf.c
index 5d8fe87..4e97dd6 100644
--- a/secilc/secil2conf.c
+++ b/secilc/secil2conf.c
@@ -124,6 +124,8 @@ int main(int argc, char *argv[])
cil_db_init();
cil_set_preserve_tunables(db, preserve_tunables);
cil_set_mls(db, mls);
+   cil_set_attrs_expand_generated(db, 0);
+   cil_set_attrs_expand_size(db, 0);
 
for (i = optind; i < argc; i++) {
file = fopen(argv[i], "r");
diff --git a/secilc/secilc.8.xml b/secilc/secilc.8.xml
index 9e2670b..4c779b6 100644
--- a/secilc/secilc.8.xml
+++ b/secilc/secilc.8.xml
@@ -81,6 +81,16 @@
  
 
  
+-G, --expand-generated
+Expand and remove auto-generated 
attributes
+ 
+
+ 
+-X, --attrs-size size>
+Expand type attributes with fewer than SIZE> members.
+ 
+
+ 
 -v, --verbose
 Increment verbosity level.
  
diff --git a/secilc/secilc.c b/secilc/secilc.c
index f4ecbee..f2232e7 100644
--- a/secilc/secilc.c
+++ b/secilc/secilc.c
@@ -64,6 +64,9 @@ static __attribute__((__noreturn__)) void usage(const char 
*prog)
printf("  -D, --disable-dontauditdo not add dontaudit rules to 
the binary policy\n");
printf("  -P, --preserve-tunablestreat tunables as booleans\n");
printf("  -N, --disable-neverallow   do not check neverallow 
rules\n");
+   printf("  -G, --expand-generated Expand and remove 
auto-generated attributes\n");
+   printf("  -X, --expand-sizeExpand type attributes with 
fewer than \n");
+   printf(" members.\n");
printf("  -v, --verbose  increment verbosity level\n");
printf("  -h, --help display usage information\n");
exit(1);
@@ -90,6 +93,8 @@ int main(int argc, char *argv[])
int preserve_tunables = 0;
int handle_unknown = -1;
int policyvers = POLICYDB_VERSION_MAX;
+   int attrs_expand_generated = 0;
+   int attrs_expand_size = -1;
int opt_char;
int opt_index = 0;
char *fc_buf = NULL;
@@ -107,12 +112,14 @@ int main(int argc, char *argv[])
{"preserve-tunables", no_argument, 0, 'P'},
{"output", required_argument, 0, 'o'},
{"filecontexts", required_argument, 0, 'f'},
+   {"expand-generated", no_argument, 0, 'G'},
+   {"expand-size", required_argument, 0, 'X'},
{0, 0, 0, 0}
};
int i;
 
while (1) {
-   opt_char = getopt_long(argc, argv, "o:f:U:hvt:M:PDNc:", 
long_opts, _index);
+   opt_char = getopt_long(argc, argv, "o:f:U:hvt:M:PDNc:GX:", 
long_opts, _index);
if (opt_char == -1) {
break;
}
@@ -180,6 +187,24 @@ int main(int argc, char *argv[])
case 'f':
filecontexts = strdup(optarg);
break;
+   case 'G':
+   attrs_expand_generated = 1;
+   break;
+   case 'X': {
+   char *endptr = NULL;
+   errno = 0;
+   attrs_expand_size = strtol(optarg, , 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 'h':
usage(argv[0]);
case '?':
@@ -210,6 +235,10 @@ int main(int argc, char *argv[])

[PATCH 0/2 v2] libsepol and checkpolicy: Add ability to expand some attributes in binary policy

2017-04-12 Thread James Carter
The number of type attributes included in the binary policy is becomming a 
performance issue in some cases.

This patch set more aggressives removes attributes and gives the options to 
expand and remove all auto-generated attributes and all attributes with fewer 
than a given amount of attributes assigned.

Comparison of the number of attributes remaining in the binary policy
 mls   normal  android
org  310 286 255
old  268 251 130 
max   71  20  17
min  226 173 119
def  223 170  80
gen  220 170  46
u5   164 112  59 

Org - Number of attributes in the CIL policy 
Old - Results without this patch set
Max - Remove the maximum number of attributes: "-G -X "
Min - Remove the minimum number of attributes: "-X 0"
Def - The new defaults for CIL
Gen - Just removing auto-generated attributes: "-G"
U5  - Remove attributes with less than five members: "-X 5"

v2:
- Use "--expand-generated" and "--expand-size" as options for consistency.
- Fixed bug in cil_post.c:__cil_post_db_attr_helper() where 
cil_typeattribute_used() would not be called if the attribute type bitmap was 
already created.

James Carter (2):
  libsepol/cil: Add ability to expand some attributes in binary policy
  secilc: Add options to control the expansion of attributes

 libsepol/cil/include/cil/cil.h |   2 +
 libsepol/cil/src/cil.c |  12 ++
 libsepol/cil/src/cil_binary.c  | 253 +++--
 libsepol/cil/src/cil_internal.h|   7 +-
 libsepol/cil/src/cil_post.c|  32 +++--
 libsepol/cil/src/cil_resolve_ast.c |  25 ++--
 libsepol/src/libsepol.map.in   |   2 +
 secilc/secil2conf.c|   2 +
 secilc/secilc.8.xml|  10 ++
 secilc/secilc.c|  31 -
 10 files changed, 275 insertions(+), 101 deletions(-)

-- 
2.7.4

___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: [PATCH 0/2] libsepol and checkpolicy: Add ability to expand some attributes in binary policy

2017-04-12 Thread James Carter

On 04/12/2017 09:35 AM, Dominick Grift wrote:

On Wed, Apr 12, 2017 at 09:26:17AM -0400, James Carter wrote:

On 04/12/2017 02:11 AM, Dominick Grift wrote:

On Tue, Apr 11, 2017 at 01:53:41PM -0400, James Carter wrote:

The number of type attributes included in the binary policy is becomming a 
performance issue in some cases.

This patch set more aggressives removes attributes and gives the options to 
expand and remove all auto-generated attributes and all attributes with fewer 
than a given amount of attributes assigned.

Comparison of the number of attributes remaining in the binary policy
 mls   normal  android
org  310 286 255
old  268 251 130
max  154  20  17
min  226 173 119
def  224 170  80
gen  221 170  46
u5   191 112  59

Org - Number of attributes in the CIL policy
Old - Results without this patch set
Max - Remove the maximum number of attributes: "-G -X "
Min - Remove the minimum number of attributes: "-X 0"
Def - The new defaults for CIL
Gen - Just removing auto-generated attributes: "-G"
U5  - Remove attributes with less than five members: "-X 5"


I tried this with my policy:

old defaults

size: 949K
typeattributes: 765
types: 1420
allow rules: 24812

new defaults

size: 876K
typeattributes: 641
types: 1418
allow rules: 20998

I cannot imagine where the difference went.. every aspect improved. I expected 
to see some trade-offs instead here.



I hope that the number of types going from 1420 to 1418 is a typo. I don't
see how my patch set would remove any types, but, if it is, then that is a
problem.

With your dssp1-standard policy, I see:
Before : 1178K, 9938 attributes, and 534 types
After (default):  574K, 3209 attributes, and 534 types
After (-X5):  471K, 2206 attributes, and 534 types

Jim


The test that i did was with dssp2-standard (my current work). So if you want 
you can see for yourself on github.

you can then also see that I , with dssp2-standard, still have attributes 
without types associated with it

At least:

seinfo -a | grep adm_subj_type | grep -v service.service | wc -l
90



Thanks, this was do to an older bug. If an attribute had already been evaluated 
in an expression, then cil_typeattribute_used() would not be called on it.


So now I have for your dssp1-standard policy:
Before : 1178K, 9938 attributes, and 534 types
After (default):  420K, 1621 attributes, and 534 types
After (-X5):  275K,  248 attributes, and 534 types

So now I have for your dssp2-standard policy:
Before :  918K, 772 attributes, and 1426 types
After (default):  889K, 551 attributes, and 1426 types
After (-X5):  901K, 160 attributes, and 1426 types

And:
seinfo -a policy.30 | grep adm_subj_type | grep -v service.service | wc -l
0

Jim






James Carter (2):
  libsepol/cil: Add ability to expand some attributes in binary policy
  secilc: Add options to control the expansion of attributes

 libsepol/cil/include/cil/cil.h |   2 +
 libsepol/cil/src/cil.c |  12 ++
 libsepol/cil/src/cil_binary.c  | 253 +++--
 libsepol/cil/src/cil_internal.h|   7 +-
 libsepol/cil/src/cil_post.c|  32 +++--
 libsepol/cil/src/cil_resolve_ast.c |  25 ++--
 libsepol/src/libsepol.map.in   |   2 +
 secilc/secil2conf.c|   2 +
 secilc/secilc.8.xml|  10 ++
 secilc/secilc.c|  31 -
 10 files changed, 275 insertions(+), 101 deletions(-)

--
2.7.4

___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.




___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.




--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.




___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.




--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: [PATCH 0/2] libsepol and checkpolicy: Add ability to expand some attributes in binary policy

2017-04-12 Thread James Carter

On 04/12/2017 09:26 AM, James Carter wrote:

On 04/12/2017 02:11 AM, Dominick Grift wrote:

On Tue, Apr 11, 2017 at 01:53:41PM -0400, James Carter wrote:

The number of type attributes included in the binary policy is becomming a
performance issue in some cases.

This patch set more aggressives removes attributes and gives the options to
expand and remove all auto-generated attributes and all attributes with fewer
than a given amount of attributes assigned.

Comparison of the number of attributes remaining in the binary policy
 mls   normal  android
org  310 286 255
old  268 251 130
max  154  20  17
min  226 173 119
def  224 170  80
gen  221 170  46
u5   191 112  59

Org - Number of attributes in the CIL policy
Old - Results without this patch set
Max - Remove the maximum number of attributes: "-G -X "
Min - Remove the minimum number of attributes: "-X 0"
Def - The new defaults for CIL
Gen - Just removing auto-generated attributes: "-G"
U5  - Remove attributes with less than five members: "-X 5"


I tried this with my policy:

old defaults

size: 949K
typeattributes: 765
types: 1420
allow rules: 24812

new defaults

size: 876K
typeattributes: 641
types: 1418
allow rules: 20998

I cannot imagine where the difference went.. every aspect improved. I expected
to see some trade-offs instead here.



I hope that the number of types going from 1420 to 1418 is a typo. I don't see
how my patch set would remove any types, but, if it is, then that is a problem.



I should point out that in all of my testing I have not had sediff report any 
differences in allow rules. The only differences that should be seen with this 
patch set is in the attributes that a type is associated with and the attributes 
that are actually defined in the policy. Any change seen outside of the Types 
and Attribute sections of the sediff output would be a bug.


Jim


With your dssp1-standard policy, I see:
Before : 1178K, 9938 attributes, and 534 types
After (default):  574K, 3209 attributes, and 534 types
After (-X5):  471K, 2206 attributes, and 534 types

Jim




James Carter (2):
  libsepol/cil: Add ability to expand some attributes in binary policy
  secilc: Add options to control the expansion of attributes

 libsepol/cil/include/cil/cil.h |   2 +
 libsepol/cil/src/cil.c |  12 ++
 libsepol/cil/src/cil_binary.c  | 253 +++--
 libsepol/cil/src/cil_internal.h|   7 +-
 libsepol/cil/src/cil_post.c|  32 +++--
 libsepol/cil/src/cil_resolve_ast.c |  25 ++--
 libsepol/src/libsepol.map.in   |   2 +
 secilc/secil2conf.c|   2 +
 secilc/secilc.8.xml|  10 ++
 secilc/secilc.c|  31 -
 10 files changed, 275 insertions(+), 101 deletions(-)

--
2.7.4

___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.




___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.







--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: [PATCH 0/2] libsepol and checkpolicy: Add ability to expand some attributes in binary policy

2017-04-12 Thread James Carter

On 04/12/2017 02:11 AM, Dominick Grift wrote:

On Tue, Apr 11, 2017 at 01:53:41PM -0400, James Carter wrote:

The number of type attributes included in the binary policy is becomming a 
performance issue in some cases.

This patch set more aggressives removes attributes and gives the options to 
expand and remove all auto-generated attributes and all attributes with fewer 
than a given amount of attributes assigned.

Comparison of the number of attributes remaining in the binary policy
 mls   normal  android
org  310 286 255
old  268 251 130
max  154  20  17
min  226 173 119
def  224 170  80
gen  221 170  46
u5   191 112  59

Org - Number of attributes in the CIL policy
Old - Results without this patch set
Max - Remove the maximum number of attributes: "-G -X "
Min - Remove the minimum number of attributes: "-X 0"
Def - The new defaults for CIL
Gen - Just removing auto-generated attributes: "-G"
U5  - Remove attributes with less than five members: "-X 5"


I tried this with my policy:

old defaults

size: 949K
typeattributes: 765
types: 1420
allow rules: 24812

new defaults

size: 876K
typeattributes: 641
types: 1418
allow rules: 20998

I cannot imagine where the difference went.. every aspect improved. I expected 
to see some trade-offs instead here.



I hope that the number of types going from 1420 to 1418 is a typo. I don't see 
how my patch set would remove any types, but, if it is, then that is a problem.


With your dssp1-standard policy, I see:
Before : 1178K, 9938 attributes, and 534 types
After (default):  574K, 3209 attributes, and 534 types
After (-X5):  471K, 2206 attributes, and 534 types

Jim




James Carter (2):
  libsepol/cil: Add ability to expand some attributes in binary policy
  secilc: Add options to control the expansion of attributes

 libsepol/cil/include/cil/cil.h |   2 +
 libsepol/cil/src/cil.c |  12 ++
 libsepol/cil/src/cil_binary.c  | 253 +++--
 libsepol/cil/src/cil_internal.h|   7 +-
 libsepol/cil/src/cil_post.c|  32 +++--
 libsepol/cil/src/cil_resolve_ast.c |  25 ++--
 libsepol/src/libsepol.map.in   |   2 +
 secilc/secil2conf.c|   2 +
 secilc/secilc.8.xml|  10 ++
 secilc/secilc.c|  31 -
 10 files changed, 275 insertions(+), 101 deletions(-)

--
2.7.4

___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.




___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.




--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: [PATCH 0/2] libsepol and checkpolicy: Add ability to expand some attributes in binary policy

2017-04-11 Thread James Carter

On 04/11/2017 01:53 PM, James Carter wrote:

The number of type attributes included in the binary policy is becomming a 
performance issue in some cases.

This patch set more aggressives removes attributes and gives the options to 
expand and remove all auto-generated attributes and all attributes with fewer 
than a given amount of attributes assigned.

Comparison of the number of attributes remaining in the binary policy
 mls   normal  android
org  310 286 255
old  268 251 130
max  154  20  17
min  226 173 119
def  224 170  80
gen  221 170  46
u5   191 112  59

Org - Number of attributes in the CIL policy
Old - Results without this patch set
Max - Remove the maximum number of attributes: "-G -X "
Min - Remove the minimum number of attributes: "-X 0"
Def - The new defaults for CIL
Gen - Just removing auto-generated attributes: "-G"
U5  - Remove attributes with less than five members: "-X 5"




In case you are interested in sizes:

   mls  normal  android
old   2.1M   2.0M 113K
max  68.3M  63.4M5041K
min   2.1M   2.0M 122K
def   2.1M   2.0M 115K
gen   2.2M   2.0M 136K
u52.2M   2.0M 116K

I would not recommend expanding all attributes.

Jim


James Carter (2):
  libsepol/cil: Add ability to expand some attributes in binary policy
  secilc: Add options to control the expansion of attributes

 libsepol/cil/include/cil/cil.h |   2 +
 libsepol/cil/src/cil.c |  12 ++
 libsepol/cil/src/cil_binary.c  | 253 +++--
 libsepol/cil/src/cil_internal.h|   7 +-
 libsepol/cil/src/cil_post.c|  32 +++--
 libsepol/cil/src/cil_resolve_ast.c |  25 ++--
 libsepol/src/libsepol.map.in   |   2 +
 secilc/secil2conf.c|   2 +
 secilc/secilc.8.xml|  10 ++
 secilc/secilc.c|  31 -
 10 files changed, 275 insertions(+), 101 deletions(-)




--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: [PATCH 1/2] libsepol/cil: Add ability to expand some attributes in binary policy

2017-04-11 Thread James Carter

On 04/11/2017 02:46 PM, Dominick Grift wrote:

On Tue, Apr 11, 2017 at 08:37:22PM +0200, Dominick Grift wrote:

On Tue, Apr 11, 2017 at 01:53:42PM -0400, James Carter wrote:

Originally, all type attributes were expanded when building a binary
policy. As the policy grew, binary policy sizes became too large, so
changes were made to keep attributes in the binary policy to minimize
policy size.

Keeping attributes works well as long as each type does not have too
many attributes. If an access check fails for types t1 and t2, then
additional checks must be made for every attribute that t1 is a member
of against t2 and all the attributes that t2 is a member of. This is
O(n*m) behavior and there are cases now where this is becoming a
performance issue.

Attributes are more aggressively removed than before. An attribute
will now be removed if it only appears in rules where attributes are
always expanded (typetransition, typechange, typemember, roletransition,
rangetransition, roletype, and AV Rules with self).

Attributes that are used in constraints are always kept because the
attribute name is stored for debugging purposes in the binary policy.

Attributes that are used in neverallow rules, but not in other AV rules,
will be kept unless the attribute is auto-generated.

Attributes that are only used in AV rules other than neverallow rules
are kept unless the number of types assigned to them is less than the
value of attrs_expand_size in the CIL db. The default is 1, which means
that any attribute that has no types assigned to it will be expanded (and
the rule removed from the policy), which is CIL's current behavior.


I might be misunderstanding here but how is that CIL's current behavior.

With my dssp1 policy I ended up with many rules that were associated with type 
attributes that had no types associated with them. The attributes and rules 
associated with them were not removed.


I suppose that my dssp1 scenario was slightly different. As these rules used 
type attributes in both source as well as target, the target type attribute had 
a type associated with it but the source type attribute didn't. Wondering 
whether the source isnt actually what should count in this case ...



I am not sure that I understand. Everything that I did applies to an attribute 
whether it is used as a src or a tgt.


Jim




 The

value can be set using the function cil_set_attrs_expand_size().

Auto-generated attributes that are used only in neverallow rules are
always expanded. The rest are kept by default, but if the value of
attrs_expand_generated in the CIL db is set to true, they will be
expanded. The function cil_set_attrs_expand_generated() can be used
to set the value.

When creating the binary policy, CIL will expand all attributes that
are being removed and it will expand all attributes with less members
than the value specified by attrs_expand_size. So even if an attribute
is used in a constraint or neverallow and the attribute itself will be
included in the binary policy, it will be expanded when writing AV
rules if it has less members than attrs_expand_size.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 libsepol/cil/include/cil/cil.h |   2 +
 libsepol/cil/src/cil.c |  12 ++
 libsepol/cil/src/cil_binary.c  | 253 +++--
 libsepol/cil/src/cil_internal.h|   7 +-
 libsepol/cil/src/cil_post.c|  32 +++--
 libsepol/cil/src/cil_resolve_ast.c |  25 ++--
 libsepol/src/libsepol.map.in   |   2 +
 7 files changed, 233 insertions(+), 100 deletions(-)

diff --git a/libsepol/cil/include/cil/cil.h b/libsepol/cil/include/cil/cil.h
index c4a6fb9..4507892 100644
--- a/libsepol/cil/include/cil/cil.h
+++ b/libsepol/cil/include/cil/cil.h
@@ -50,6 +50,8 @@ extern void cil_set_disable_neverallow(cil_db_t *db, int 
disable_neverallow);
 extern void cil_set_preserve_tunables(cil_db_t *db, int preserve_tunables);
 extern int cil_set_handle_unknown(cil_db_t *db, int handle_unknown);
 extern void cil_set_mls(cil_db_t *db, int mls);
+extern void cil_set_attrs_expand_generated(struct cil_db *db, int 
attrs_expand_generated);
+extern void cil_set_attrs_expand_size(struct cil_db *db, unsigned 
attrs_expand_size);
 extern void cil_set_target_platform(cil_db_t *db, int target_platform);
 extern void cil_set_policy_version(cil_db_t *db, int policy_version);
 extern void cil_write_policy_conf(FILE *out, struct cil_db *db);
diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c
index 7c40ad0..a64c528 100644
--- a/libsepol/cil/src/cil.c
+++ b/libsepol/cil/src/cil.c
@@ -282,6 +282,8 @@ void cil_db_init(struct cil_db **db)

(*db)->disable_dontaudit = CIL_FALSE;
(*db)->disable_neverallow = CIL_FALSE;
+   (*db)->attrs_expand_generated = CIL_FALSE;
+   (*db)->attrs_expand_size = 1;
(*db)->preserve_tunables = CIL_FALSE;
(*db)->handle_unknown = -1;
(*db)->mls = -1;
@@ -1629,6 +1631,16 @@ void cil_se

Re: [PATCH 1/2] libsepol/cil: Add ability to expand some attributes in binary policy

2017-04-11 Thread James Carter

On 04/11/2017 02:37 PM, Dominick Grift wrote:

On Tue, Apr 11, 2017 at 01:53:42PM -0400, James Carter wrote:

Originally, all type attributes were expanded when building a binary
policy. As the policy grew, binary policy sizes became too large, so
changes were made to keep attributes in the binary policy to minimize
policy size.

Keeping attributes works well as long as each type does not have too
many attributes. If an access check fails for types t1 and t2, then
additional checks must be made for every attribute that t1 is a member
of against t2 and all the attributes that t2 is a member of. This is
O(n*m) behavior and there are cases now where this is becoming a
performance issue.

Attributes are more aggressively removed than before. An attribute
will now be removed if it only appears in rules where attributes are
always expanded (typetransition, typechange, typemember, roletransition,
rangetransition, roletype, and AV Rules with self).

Attributes that are used in constraints are always kept because the
attribute name is stored for debugging purposes in the binary policy.

Attributes that are used in neverallow rules, but not in other AV rules,
will be kept unless the attribute is auto-generated.

Attributes that are only used in AV rules other than neverallow rules
are kept unless the number of types assigned to them is less than the
value of attrs_expand_size in the CIL db. The default is 1, which means
that any attribute that has no types assigned to it will be expanded (and
the rule removed from the policy), which is CIL's current behavior.


I might be misunderstanding here but how is that CIL's current behavior.

With my dssp1 policy I ended up with many rules that were associated with type 
attributes that had no types associated with them. The attributes and rules 
associated with them were not removed.




All of this is describing what the behavior is with this patch set.

Currently, attributes are not removed if they are in typetransition, typechange, 
and the other rules listed above that are expanded. Also, attributes with no 
members assigned are only removed if they are not used, but rules using 
attributes with no types are removed.


Jim


 The

value can be set using the function cil_set_attrs_expand_size().

Auto-generated attributes that are used only in neverallow rules are
always expanded. The rest are kept by default, but if the value of
attrs_expand_generated in the CIL db is set to true, they will be
expanded. The function cil_set_attrs_expand_generated() can be used
to set the value.

When creating the binary policy, CIL will expand all attributes that
are being removed and it will expand all attributes with less members
than the value specified by attrs_expand_size. So even if an attribute
is used in a constraint or neverallow and the attribute itself will be
included in the binary policy, it will be expanded when writing AV
rules if it has less members than attrs_expand_size.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 libsepol/cil/include/cil/cil.h |   2 +
 libsepol/cil/src/cil.c |  12 ++
 libsepol/cil/src/cil_binary.c  | 253 +++--
 libsepol/cil/src/cil_internal.h|   7 +-
 libsepol/cil/src/cil_post.c|  32 +++--
 libsepol/cil/src/cil_resolve_ast.c |  25 ++--
 libsepol/src/libsepol.map.in   |   2 +
 7 files changed, 233 insertions(+), 100 deletions(-)

diff --git a/libsepol/cil/include/cil/cil.h b/libsepol/cil/include/cil/cil.h
index c4a6fb9..4507892 100644
--- a/libsepol/cil/include/cil/cil.h
+++ b/libsepol/cil/include/cil/cil.h
@@ -50,6 +50,8 @@ extern void cil_set_disable_neverallow(cil_db_t *db, int 
disable_neverallow);
 extern void cil_set_preserve_tunables(cil_db_t *db, int preserve_tunables);
 extern int cil_set_handle_unknown(cil_db_t *db, int handle_unknown);
 extern void cil_set_mls(cil_db_t *db, int mls);
+extern void cil_set_attrs_expand_generated(struct cil_db *db, int 
attrs_expand_generated);
+extern void cil_set_attrs_expand_size(struct cil_db *db, unsigned 
attrs_expand_size);
 extern void cil_set_target_platform(cil_db_t *db, int target_platform);
 extern void cil_set_policy_version(cil_db_t *db, int policy_version);
 extern void cil_write_policy_conf(FILE *out, struct cil_db *db);
diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c
index 7c40ad0..a64c528 100644
--- a/libsepol/cil/src/cil.c
+++ b/libsepol/cil/src/cil.c
@@ -282,6 +282,8 @@ void cil_db_init(struct cil_db **db)

(*db)->disable_dontaudit = CIL_FALSE;
(*db)->disable_neverallow = CIL_FALSE;
+   (*db)->attrs_expand_generated = CIL_FALSE;
+   (*db)->attrs_expand_size = 1;
(*db)->preserve_tunables = CIL_FALSE;
(*db)->handle_unknown = -1;
(*db)->mls = -1;
@@ -1629,6 +1631,16 @@ void cil_set_disable_neverallow(struct cil_db *db, int 
disable_neverallow)
db->disable_neverallow = disable_neverallow;
 }

+void cil_set_attrs_

[PATCH 1/2] libsepol/cil: Add ability to expand some attributes in binary policy

2017-04-11 Thread James Carter
Originally, all type attributes were expanded when building a binary
policy. As the policy grew, binary policy sizes became too large, so
changes were made to keep attributes in the binary policy to minimize
policy size.

Keeping attributes works well as long as each type does not have too
many attributes. If an access check fails for types t1 and t2, then
additional checks must be made for every attribute that t1 is a member
of against t2 and all the attributes that t2 is a member of. This is
O(n*m) behavior and there are cases now where this is becoming a
performance issue.

Attributes are more aggressively removed than before. An attribute
will now be removed if it only appears in rules where attributes are
always expanded (typetransition, typechange, typemember, roletransition,
rangetransition, roletype, and AV Rules with self).

Attributes that are used in constraints are always kept because the
attribute name is stored for debugging purposes in the binary policy.

Attributes that are used in neverallow rules, but not in other AV rules,
will be kept unless the attribute is auto-generated.

Attributes that are only used in AV rules other than neverallow rules
are kept unless the number of types assigned to them is less than the
value of attrs_expand_size in the CIL db. The default is 1, which means
that any attribute that has no types assigned to it will be expanded (and
the rule removed from the policy), which is CIL's current behavior. The
value can be set using the function cil_set_attrs_expand_size().

Auto-generated attributes that are used only in neverallow rules are
always expanded. The rest are kept by default, but if the value of
attrs_expand_generated in the CIL db is set to true, they will be
expanded. The function cil_set_attrs_expand_generated() can be used
to set the value.

When creating the binary policy, CIL will expand all attributes that
are being removed and it will expand all attributes with less members
than the value specified by attrs_expand_size. So even if an attribute
is used in a constraint or neverallow and the attribute itself will be
included in the binary policy, it will be expanded when writing AV
rules if it has less members than attrs_expand_size.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 libsepol/cil/include/cil/cil.h |   2 +
 libsepol/cil/src/cil.c |  12 ++
 libsepol/cil/src/cil_binary.c  | 253 +++--
 libsepol/cil/src/cil_internal.h|   7 +-
 libsepol/cil/src/cil_post.c|  32 +++--
 libsepol/cil/src/cil_resolve_ast.c |  25 ++--
 libsepol/src/libsepol.map.in   |   2 +
 7 files changed, 233 insertions(+), 100 deletions(-)

diff --git a/libsepol/cil/include/cil/cil.h b/libsepol/cil/include/cil/cil.h
index c4a6fb9..4507892 100644
--- a/libsepol/cil/include/cil/cil.h
+++ b/libsepol/cil/include/cil/cil.h
@@ -50,6 +50,8 @@ extern void cil_set_disable_neverallow(cil_db_t *db, int 
disable_neverallow);
 extern void cil_set_preserve_tunables(cil_db_t *db, int preserve_tunables);
 extern int cil_set_handle_unknown(cil_db_t *db, int handle_unknown);
 extern void cil_set_mls(cil_db_t *db, int mls);
+extern void cil_set_attrs_expand_generated(struct cil_db *db, int 
attrs_expand_generated);
+extern void cil_set_attrs_expand_size(struct cil_db *db, unsigned 
attrs_expand_size);
 extern void cil_set_target_platform(cil_db_t *db, int target_platform);
 extern void cil_set_policy_version(cil_db_t *db, int policy_version);
 extern void cil_write_policy_conf(FILE *out, struct cil_db *db);
diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c
index 7c40ad0..a64c528 100644
--- a/libsepol/cil/src/cil.c
+++ b/libsepol/cil/src/cil.c
@@ -282,6 +282,8 @@ void cil_db_init(struct cil_db **db)
 
(*db)->disable_dontaudit = CIL_FALSE;
(*db)->disable_neverallow = CIL_FALSE;
+   (*db)->attrs_expand_generated = CIL_FALSE;
+   (*db)->attrs_expand_size = 1;
(*db)->preserve_tunables = CIL_FALSE;
(*db)->handle_unknown = -1;
(*db)->mls = -1;
@@ -1629,6 +1631,16 @@ void cil_set_disable_neverallow(struct cil_db *db, int 
disable_neverallow)
db->disable_neverallow = disable_neverallow;
 }
 
+void cil_set_attrs_expand_generated(struct cil_db *db, int 
attrs_expand_generated)
+{
+   db->attrs_expand_generated = attrs_expand_generated;
+}
+
+void cil_set_attrs_expand_size(struct cil_db *db, unsigned attrs_expand_size)
+{
+   db->attrs_expand_size = attrs_expand_size;
+}
+
 void cil_set_preserve_tunables(struct cil_db *db, int preserve_tunables)
 {
db->preserve_tunables = preserve_tunables;
diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c
index ac18c4e..e1481a4 100644
--- a/libsepol/cil/src/cil_binary.c
+++ b/libsepol/cil/src/cil_binary.c
@@ -567,7 +567,7 @@ int cil_typeattribute_to_policydb(policydb_t *pdb, struct 
cil_typeattribute *cil
char *key = NULL;
type_datum_t *se

[PATCH 2/2] secilc: Add options to control the expansion of attributes

2017-04-11 Thread James Carter
Added "-G, --expand_generated" option to specify that all automatically
generated attributes should be expanded and removed.

Added "-X, --expand_size " option to specify which attributes
are expanded when building a kernel policy. All attributes that have
less types assigned to it than SIZE will be expanded when writing AV
rules.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 secilc/secil2conf.c |  2 ++
 secilc/secilc.8.xml | 10 ++
 secilc/secilc.c | 31 ++-
 3 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/secilc/secil2conf.c b/secilc/secil2conf.c
index 5d8fe87..4e97dd6 100644
--- a/secilc/secil2conf.c
+++ b/secilc/secil2conf.c
@@ -124,6 +124,8 @@ int main(int argc, char *argv[])
cil_db_init();
cil_set_preserve_tunables(db, preserve_tunables);
cil_set_mls(db, mls);
+   cil_set_attrs_expand_generated(db, 0);
+   cil_set_attrs_expand_size(db, 0);
 
for (i = optind; i < argc; i++) {
file = fopen(argv[i], "r");
diff --git a/secilc/secilc.8.xml b/secilc/secilc.8.xml
index 9e2670b..5d52e59 100644
--- a/secilc/secilc.8.xml
+++ b/secilc/secilc.8.xml
@@ -81,6 +81,16 @@
  
 
  
+-G, --expand_generated
+Expand and remove auto-generated 
attributes
+ 
+
+ 
+-X, --attrs_size size>
+Expand type attributes with fewer than SIZE> members.
+ 
+
+ 
 -v, --verbose
 Increment verbosity level.
  
diff --git a/secilc/secilc.c b/secilc/secilc.c
index f4ecbee..894f174 100644
--- a/secilc/secilc.c
+++ b/secilc/secilc.c
@@ -64,6 +64,9 @@ static __attribute__((__noreturn__)) void usage(const char 
*prog)
printf("  -D, --disable-dontauditdo not add dontaudit rules to 
the binary policy\n");
printf("  -P, --preserve-tunablestreat tunables as booleans\n");
printf("  -N, --disable-neverallow   do not check neverallow 
rules\n");
+   printf("  -G, --expand_generated Expand and remove 
auto-generated attributes\n");
+   printf("  -X, --expand_sizeExpand type attributes with 
fewer than \n");
+   printf(" members.\n");
printf("  -v, --verbose  increment verbosity level\n");
printf("  -h, --help display usage information\n");
exit(1);
@@ -90,6 +93,8 @@ int main(int argc, char *argv[])
int preserve_tunables = 0;
int handle_unknown = -1;
int policyvers = POLICYDB_VERSION_MAX;
+   int attrs_expand_generated = 0;
+   int attrs_expand_size = -1;
int opt_char;
int opt_index = 0;
char *fc_buf = NULL;
@@ -107,12 +112,14 @@ int main(int argc, char *argv[])
{"preserve-tunables", no_argument, 0, 'P'},
{"output", required_argument, 0, 'o'},
{"filecontexts", required_argument, 0, 'f'},
+   {"expand_generated", no_argument, 0, 'G'},
+   {"expand_size", required_argument, 0, 'X'},
{0, 0, 0, 0}
};
int i;
 
while (1) {
-   opt_char = getopt_long(argc, argv, "o:f:U:hvt:M:PDNc:", 
long_opts, _index);
+   opt_char = getopt_long(argc, argv, "o:f:U:hvt:M:PDNc:GX:", 
long_opts, _index);
if (opt_char == -1) {
break;
}
@@ -180,6 +187,24 @@ int main(int argc, char *argv[])
case 'f':
filecontexts = strdup(optarg);
break;
+   case 'G':
+   attrs_expand_generated = 1;
+   break;
+   case 'X': {
+   char *endptr = NULL;
+   errno = 0;
+   attrs_expand_size = strtol(optarg, , 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 'h':
usage(argv[0]);
case '?':
@@ -210,6 +235,10 @@ int main(int argc, char *argv[])

[PATCH 0/2] libsepol and checkpolicy: Add ability to expand some attributes in binary policy

2017-04-11 Thread James Carter
The number of type attributes included in the binary policy is becomming a 
performance issue in some cases.

This patch set more aggressives removes attributes and gives the options to 
expand and remove all auto-generated attributes and all attributes with fewer 
than a given amount of attributes assigned.

Comparison of the number of attributes remaining in the binary policy
 mls   normal  android
org  310 286 255
old  268 251 130 
max  154  20  17
min  226 173 119
def  224 170  80
gen  221 170  46
u5   191 112  59 

Org - Number of attributes in the CIL policy 
Old - Results without this patch set
Max - Remove the maximum number of attributes: "-G -X "
Min - Remove the minimum number of attributes: "-X 0"
Def - The new defaults for CIL
Gen - Just removing auto-generated attributes: "-G"
U5  - Remove attributes with less than five members: "-X 5"


James Carter (2):
  libsepol/cil: Add ability to expand some attributes in binary policy
  secilc: Add options to control the expansion of attributes

 libsepol/cil/include/cil/cil.h |   2 +
 libsepol/cil/src/cil.c |  12 ++
 libsepol/cil/src/cil_binary.c  | 253 +++--
 libsepol/cil/src/cil_internal.h|   7 +-
 libsepol/cil/src/cil_post.c|  32 +++--
 libsepol/cil/src/cil_resolve_ast.c |  25 ++--
 libsepol/src/libsepol.map.in   |   2 +
 secilc/secil2conf.c|   2 +
 secilc/secilc.8.xml|  10 ++
 secilc/secilc.c|  31 -
 10 files changed, 275 insertions(+), 101 deletions(-)

-- 
2.7.4

___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: [PATCH 0/3 v3] libsepol and checkpolicy: Output CIL or policy.conf from kernel policy

2017-04-05 Thread James Carter

On 03/23/2017 12:48 PM, James Carter wrote:

It would sometimes be helpful for debugging or verification purposes to be able 
to convert
a binary policy to a human-readable form.

This patchset adds libsepol functions that take a kernel policydb in and 
outputs either
a CIL or policy.conf text.

Checkpolicy is modified to generate CIL text from a binary policy if using the 
"-C" option
and to add the "-F" option to generate policy.conf text from a binary policy.

Where possible rules are sorted in alphabetical or numerical order to aid in 
debugging.

Changes from v1:
- Moved __attribute__((format(printf...))) for printf-like functions to 
kernel_to_common.h
- Incorporated patch from Nicolas Iooss to make const char* variables where 
appropriate
- Fixed conditional block formatting problems when generating policy.conf
- Initialize mls_constraints and non_mls_constraints to NULL in 
kernel_to_conf.c and kernel_to_cil.c so they are not accessed without 
initializaton if an error occurs.
- Updated checkpolicy manpage to include the new option
- Removed commented-out block from checkpolicy.c

Changes from v2:
- Fixed conditional block formatting problems when generating CIL.
- Fixed improper range syntax for non-mls CIL policies.
- Write types in alphabetical order in roletype rules for CIL and role rules 
for policy.conf.
- Write roles in alphabetical order in userrole rules for CIL and user rules 
for policy.conf.
- Write policy capability rules in alphabetical order
- Separated writing of constrain and validatetrans constraint rules for both 
CIL and policy.conf.
- Write constraints in alphabetical order for both CIL and policy.conf
- Now continously creating a policy.conf and then a binary produces an 
identical binary (although for CIL, secilc will remove unused attributes during 
the first cycle.)

James Carter (3):
  libsepol: Add ability to convert binary policy to CIL
  libsepol: Add ability to convert binary policy to policy.conf file
  checkpolicy: Add options to convert binary policy to CIL or a
policy.conf

 checkpolicy/checkpolicy.8   |5 +-
 checkpolicy/checkpolicy.c   |   55 +-
 libsepol/include/sepol/kernel_to_cil.h  |5 +
 libsepol/include/sepol/kernel_to_conf.h |5 +
 libsepol/src/kernel_to_cil.c| 3226 +++
 libsepol/src/kernel_to_common.c |  677 +++
 libsepol/src/kernel_to_common.h |  114 ++
 libsepol/src/kernel_to_conf.c   | 3096 +
 libsepol/src/libsepol.map.in|2 +
 9 files changed, 7166 insertions(+), 19 deletions(-)
 create mode 100644 libsepol/include/sepol/kernel_to_cil.h
 create mode 100644 libsepol/include/sepol/kernel_to_conf.h
 create mode 100644 libsepol/src/kernel_to_cil.c
 create mode 100644 libsepol/src/kernel_to_common.c
 create mode 100644 libsepol/src/kernel_to_common.h
 create mode 100644 libsepol/src/kernel_to_conf.c



This series has been applied.

Jim


--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: [PATCH v2] libsepol: In module_to_cil create one attribute for each unique set

2017-04-05 Thread James Carter

On 03/29/2017 02:58 PM, James Carter wrote:

CIL does not allow type or role sets in certain rules (such as allow
rules). It does, however, allow sets in typeattributeset and
roleattributeset statements. Because of this, when module_to_cil
translates a policy into CIL, it creates a new attribute for each
set that it encounters. But often the same set is used multiple times
which means that more attributes are created then necessary. As the
number of attributes increases the time required for the kernel to
make each policy decision increases which can be a problem.

To help reduce the number of attributes in a kernel policy,
when module_to_cil encounters a role or type set search to see if the
set was encountered already and, if it was, use the previously
generated attribute instead of creating a new one.

Testing on Android and Refpolicy policies show that this reduces the
number of attributes generated by about 40%.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>


This has now been applied.

Jim


---
 libsepol/src/module_to_cil.c | 593 +--
 1 file changed, 283 insertions(+), 310 deletions(-)

diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c
index 5c98c29..3f633fb 100644
--- a/libsepol/src/module_to_cil.c
+++ b/libsepol/src/module_to_cil.c
@@ -174,12 +174,9 @@ struct role_list_node {
 };

 struct attr_list_node {
-   char *attribute;
+   char *attr_name;
int is_type;
-   union {
-   struct type_set *ts;
-   struct role_set *rs;
-   } set;
+   void *set;
 };

 struct list_node {
@@ -237,7 +234,7 @@ static void attr_list_destroy(struct list **attr_list)
while (curr != NULL) {
attr = curr->data;
if (attr != NULL) {
-   free(attr->attribute);
+   free(attr->attr_name);
}

free(curr->data);
@@ -711,54 +708,85 @@ static int num_digits(int n)
return num;
 }

-static int set_to_cil_attr(struct policydb *pdb, int is_type, char ***names, 
uint32_t *num_names)
+static int ebitmap_to_cil(struct policydb *pdb, struct ebitmap *map, int type)
+{
+   struct ebitmap_node *node;
+   uint32_t i;
+   char **val_to_name = pdb->sym_val_to_name[type];
+
+   ebitmap_for_each_bit(map, node, i) {
+   if (!ebitmap_get_bit(map, i)) {
+   continue;
+   }
+   cil_printf("%s ", val_to_name[i]);
+   }
+
+   return 0;
+}
+
+static char *get_new_attr_name(struct policydb *pdb, int is_type)
 {
static unsigned int num_attrs = 0;
-   int rc = -1;
int len, rlen;
-   const char *attr_infix;
-   char *attr;
+   const char *infix;
+   char *attr_name = NULL;

num_attrs++;

if (is_type) {
-   attr_infix = TYPEATTR_INFIX;
+   infix = TYPEATTR_INFIX;
} else {
-   attr_infix = ROLEATTR_INFIX;
+   infix = ROLEATTR_INFIX;
}

-   len = strlen(pdb->name) + strlen(attr_infix) + num_digits(num_attrs) + 
1;
-   attr = malloc(len);
-   if (attr == NULL) {
+   len = strlen(pdb->name) + strlen(infix) + num_digits(num_attrs) + 1;
+   attr_name = malloc(len);
+   if (!attr_name) {
log_err("Out of memory");
-   rc = -1;
goto exit;
}
-   rlen = snprintf(attr, len, "%s%s%i", pdb->name, attr_infix, num_attrs);
+
+   rlen = snprintf(attr_name, len, "%s%s%i", pdb->name, infix, num_attrs);
if (rlen < 0 || rlen >= len) {
log_err("Failed to generate attribute name");
-   rc = -1;
+   free(attr_name);
+   attr_name = NULL;
goto exit;
}

-   *names = malloc(sizeof(**names));
-   if (*names == NULL) {
+exit:
+   return attr_name;
+}
+
+static int cil_add_attr_to_list(struct list *attr_list, char *attr_name, int 
is_type, void *set)
+{
+   struct attr_list_node *attr_list_node = NULL;
+   int rc = 0;
+
+   attr_list_node = calloc(1, sizeof(*attr_list_node));
+   if (attr_list_node == NULL) {
log_err("Out of memory");
rc = -1;
goto exit;
}

+   rc = list_prepend(attr_list, attr_list_node);
+   if (rc != 0) {
+   goto exit;
+   }

-   *names[0] = attr;
-   *num_names = 1;
+   attr_list_node->attr_name = attr_name;
+   attr_list_node->is_type = is_type;
+   attr_list_node->set = set;

-   rc = 0;
+   return rc;

 exit:
+   free(attr_list_node);
return rc;
 }

-static int cil_print_attr_strs(int indent, struct policydb *pdb, int is_type, 
struct ebitmap *pos, struct ebitmap *neg, uint32_t flags, char *attr)
+static int cil_p

Re: [PATCH v2] libsepol: In module_to_cil create one attribute for each unique set

2017-04-05 Thread James Carter

On 04/05/2017 11:42 AM, Nick Kralevich wrote:

I noticed that this change hasn't landed in the selinux git repository
yet. It helps solve some problems we're seeing with regards to
excessive number of attributes. Is there something holding up this
change from being committed?



No. I've just been busy working on another patch that should also help with an 
excessive number of attributes.


Jim


-- Nick

On Wed, Mar 29, 2017 at 11:58 AM, James Carter <jwca...@tycho.nsa.gov> wrote:

CIL does not allow type or role sets in certain rules (such as allow
rules). It does, however, allow sets in typeattributeset and
roleattributeset statements. Because of this, when module_to_cil
translates a policy into CIL, it creates a new attribute for each
set that it encounters. But often the same set is used multiple times
which means that more attributes are created then necessary. As the
number of attributes increases the time required for the kernel to
make each policy decision increases which can be a problem.

To help reduce the number of attributes in a kernel policy,
when module_to_cil encounters a role or type set search to see if the
set was encountered already and, if it was, use the previously
generated attribute instead of creating a new one.

Testing on Android and Refpolicy policies show that this reduces the
number of attributes generated by about 40%.



--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: userspace object manager confused

2017-03-31 Thread James Carter

On 03/31/2017 10:39 AM, Dominick Grift wrote:

On Fri, Mar 31, 2017 at 10:30:22AM -0400, James Carter wrote:

On 03/31/2017 10:17 AM, Dominick Grift wrote:

On Fri, Mar 31, 2017 at 10:12:50AM -0400, James Carter wrote:

On 03/31/2017 10:10 AM, Stephen Smalley wrote:

On Fri, 2017-03-31 at 15:59 +0200, Dominick Grift wrote:

On Fri, Mar 31, 2017 at 09:53:26AM -0400, Stephen Smalley wrote:

On Fri, 2017-03-31 at 15:36 +0200, Dominick Grift wrote:

On Fri, Mar 31, 2017 at 09:30:56AM -0400, Stephen Smalley wrote:

On Fri, 2017-03-31 at 09:25 -0400, Stephen Smalley wrote:

On Fri, 2017-03-31 at 14:09 +0200, Dominick Grift wrote:

I vaguely recall that we discussed this issue or at least
that
i
mentioned it here but i can't recall the outcome if any:

So today on my rawhide system i noticed that i somehow
forgot
to
add
support for the smc_socket class (i suspect that is part of
the
extended socket class patches)

I added the class (which i suppose is unordered like the
othe
extended socket classes) but as soon as I loaded up the
policy
with
the new unordered smc_socket class the system became
unusable.

This is because the dbus object manager became confused due
to
my
adding a new (unordered) class at runtime, and that the
dbus
class
was no longer working.

Modern systems heavily rely on dbus at the heart and so it
is
undesire-able that this happens.

A reboot clears this issue up but adding (unordered)
classes at
runtime should not cause these issues i suspect


dbusd doesn't use selinux_check_access() and therefore does
not
yet
support reordering of their classes/permissions at
runtime.  The
same
is true of all userspace object managers created before
selinux_check_access() was introduced - anything that
directly
calls
security_compute_av() or avc_has_perm(). dbusd does call
selinux_set_mapping() at startup, so it can correctly handle
reordering of classes/permissions across restarts, but not
while
it
is
running.  Calling selinux_set_mapping() again upon policy
reloads
(e.g.
from policy_reload_callback() if (event ==
AVC_CALLBACK_RESET)
before
returning) may fix this problem, but requires proper
locking.  Even
better would be to rid the dbusd selinux implementation of
threading
entirely, see https://bugs.freedesktop.org/show_bug.cgi?id=92
831#
c4


Thank you, I suppose i should take this to them then.


No, someone who uses SELinux will need to develop a patch and test
it
for them; dbusd maintainer doesn't use SELinux himself.

Looks like I'm also wrong about being able to call
selinux_set_mapping() from an AVC callback, since
selinux_set_mapping()
itself calls avc_reset() to flush any cache entries before
reloading
the mapping, so that would produce infinite
recursion.  Sigh.  Could
change selinux_set_mapping() to not do that in libselinux, but that
won't help on existing releases.  Maybe we should just convert it
over
to using selinux_check_access() and drop all direct usage of the
AVC.



smc_socket was added by the kernel developers as part of the
merge
with
net-next since we now trigger a build failure in the kernel
if
any
new
address families are introduced without adding a
corresponding
security
class (so that SELinux always supports a separate class per
network
address family going forward). So there have been no policy
patches
submitted yet to define it in refpolicy even AFAIK.

[1] https://github.com/SELinuxProject/selinux/issues/34


So i suppose its an unordered class? or do i have to order this
one
to avoid future issues?



BTW, I'm not sure what you did to trigger the problem.  When I
tested
the extended socket classes, I added them to my running policy
via
a
CIL module like this:


Well i just added this commit (ignore the typo in the name) which
adds the new class to the unordered socket list

https://github.com/DefenSec/dssp2-base/commit/5e3ada7d12525c8c659
f347
863f09ec9caeceb56

then i built rpms using this script:

https://github.com/DefenSec/dssp2-standard/blob/master/support/rp
m/ds
sp2-standard.sh

and just rpm -Uvh the new rpm



(policycap extended_socket_class)

(classcommon sctp_socket socket)
(class sctp_socket (node_bind))



(classcommon qipcrtr_socket socket)
(class qipcrtr_socket ())

(classorder (unordered sctp_socket icmp_socket ax25_socket
ipx_socket
netrom_socket bridge_socket atmpvc_socket x25_socket
rose_socket
decnet_socket atmsvc_socket rds_socket irda_socket pppox_socket
llc_socket ib_socket mpls_socket can_socket tipc_socket
bluetooth_socket iucv_socket rxrpc_socket isdn_socket
phonet_socket
ieee802154_socket caif_socket alg_socket nfc_socket
vsock_socket
kcm_socket qipcrtr_socket))

The classorder statement at the end ensured that they were
appended
to
the end of the class list and therefore did not break anything.



Looks like you failed to include a classorder statement for it as I
did
above.  That's still required to avoid breaking legacy userspace
object
managers.




No I added "scm_socket" (i renamed it later to smc_socket) to my list
or unordered 

Re: userspace object manager confused

2017-03-31 Thread James Carter

On 03/31/2017 10:17 AM, Dominick Grift wrote:

On Fri, Mar 31, 2017 at 10:12:50AM -0400, James Carter wrote:

On 03/31/2017 10:10 AM, Stephen Smalley wrote:

On Fri, 2017-03-31 at 15:59 +0200, Dominick Grift wrote:

On Fri, Mar 31, 2017 at 09:53:26AM -0400, Stephen Smalley wrote:

On Fri, 2017-03-31 at 15:36 +0200, Dominick Grift wrote:

On Fri, Mar 31, 2017 at 09:30:56AM -0400, Stephen Smalley wrote:

On Fri, 2017-03-31 at 09:25 -0400, Stephen Smalley wrote:

On Fri, 2017-03-31 at 14:09 +0200, Dominick Grift wrote:

I vaguely recall that we discussed this issue or at least
that
i
mentioned it here but i can't recall the outcome if any:

So today on my rawhide system i noticed that i somehow
forgot
to
add
support for the smc_socket class (i suspect that is part of
the
extended socket class patches)

I added the class (which i suppose is unordered like the
othe
extended socket classes) but as soon as I loaded up the
policy
with
the new unordered smc_socket class the system became
unusable.

This is because the dbus object manager became confused due
to
my
adding a new (unordered) class at runtime, and that the
dbus
class
was no longer working.

Modern systems heavily rely on dbus at the heart and so it
is
undesire-able that this happens.

A reboot clears this issue up but adding (unordered)
classes at
runtime should not cause these issues i suspect


dbusd doesn't use selinux_check_access() and therefore does
not
yet
support reordering of their classes/permissions at
runtime.  The
same
is true of all userspace object managers created before
selinux_check_access() was introduced - anything that
directly
calls
security_compute_av() or avc_has_perm(). dbusd does call
selinux_set_mapping() at startup, so it can correctly handle
reordering of classes/permissions across restarts, but not
while
it
is
running.  Calling selinux_set_mapping() again upon policy
reloads
(e.g.
from policy_reload_callback() if (event ==
AVC_CALLBACK_RESET)
before
returning) may fix this problem, but requires proper
locking.  Even
better would be to rid the dbusd selinux implementation of
threading
entirely, see https://bugs.freedesktop.org/show_bug.cgi?id=92
831#
c4


Thank you, I suppose i should take this to them then.


No, someone who uses SELinux will need to develop a patch and test
it
for them; dbusd maintainer doesn't use SELinux himself.

Looks like I'm also wrong about being able to call
selinux_set_mapping() from an AVC callback, since
selinux_set_mapping()
itself calls avc_reset() to flush any cache entries before
reloading
the mapping, so that would produce infinite
recursion.  Sigh.  Could
change selinux_set_mapping() to not do that in libselinux, but that
won't help on existing releases.  Maybe we should just convert it
over
to using selinux_check_access() and drop all direct usage of the
AVC.



smc_socket was added by the kernel developers as part of the
merge
with
net-next since we now trigger a build failure in the kernel
if
any
new
address families are introduced without adding a
corresponding
security
class (so that SELinux always supports a separate class per
network
address family going forward). So there have been no policy
patches
submitted yet to define it in refpolicy even AFAIK.

[1] https://github.com/SELinuxProject/selinux/issues/34


So i suppose its an unordered class? or do i have to order this
one
to avoid future issues?



BTW, I'm not sure what you did to trigger the problem.  When I
tested
the extended socket classes, I added them to my running policy
via
a
CIL module like this:


Well i just added this commit (ignore the typo in the name) which
adds the new class to the unordered socket list

https://github.com/DefenSec/dssp2-base/commit/5e3ada7d12525c8c659
f347
863f09ec9caeceb56

then i built rpms using this script:

https://github.com/DefenSec/dssp2-standard/blob/master/support/rp
m/ds
sp2-standard.sh

and just rpm -Uvh the new rpm



(policycap extended_socket_class)

(classcommon sctp_socket socket)
(class sctp_socket (node_bind))



(classcommon qipcrtr_socket socket)
(class qipcrtr_socket ())

(classorder (unordered sctp_socket icmp_socket ax25_socket
ipx_socket
netrom_socket bridge_socket atmpvc_socket x25_socket
rose_socket
decnet_socket atmsvc_socket rds_socket irda_socket pppox_socket
llc_socket ib_socket mpls_socket can_socket tipc_socket
bluetooth_socket iucv_socket rxrpc_socket isdn_socket
phonet_socket
ieee802154_socket caif_socket alg_socket nfc_socket
vsock_socket
kcm_socket qipcrtr_socket))

The classorder statement at the end ensured that they were
appended
to
the end of the class list and therefore did not break anything.



Looks like you failed to include a classorder statement for it as I
did
above.  That's still required to avoid breaking legacy userspace
object
managers.




No I added "scm_socket" (i renamed it later to smc_socket) to my list
or unordered classorder:

;
; Class order of unordered Linux access vectors
;

(classorder
(unordered

Re: userspace object manager confused

2017-03-31 Thread James Carter
aif_socket
can_socket
decnet_socket
icmp_socket
ieee802154_socket
ipx_socket
irda_socket
isdn_socket
iucv_socket
kcm_socket
llc_socket
netrom_socket
nfc_socket
phonet_socket
pppox_socket
qipcrtr_socket
rds_socket
rose_socket
rxrpc_socket
scm_socket
sctp_socket
tipc_socket
vsock_socket
x25_socket
)
)


Then I'm confused as to why you encountered breakage.  Doesn't CIL
ensure that all of those classes are appended to the existing class
list?  In which case it won't disturb the dbus class definitions.



CIL appends unordered classes to the existing class list, so I am not sure what 
is going on.


Jim



--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


[PATCH v2] libsepol: In module_to_cil create one attribute for each unique set

2017-03-29 Thread James Carter
CIL does not allow type or role sets in certain rules (such as allow
rules). It does, however, allow sets in typeattributeset and
roleattributeset statements. Because of this, when module_to_cil
translates a policy into CIL, it creates a new attribute for each
set that it encounters. But often the same set is used multiple times
which means that more attributes are created then necessary. As the
number of attributes increases the time required for the kernel to
make each policy decision increases which can be a problem.

To help reduce the number of attributes in a kernel policy,
when module_to_cil encounters a role or type set search to see if the
set was encountered already and, if it was, use the previously
generated attribute instead of creating a new one.

Testing on Android and Refpolicy policies show that this reduces the
number of attributes generated by about 40%.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 libsepol/src/module_to_cil.c | 593 +--
 1 file changed, 283 insertions(+), 310 deletions(-)

diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c
index 5c98c29..3f633fb 100644
--- a/libsepol/src/module_to_cil.c
+++ b/libsepol/src/module_to_cil.c
@@ -174,12 +174,9 @@ struct role_list_node {
 };
 
 struct attr_list_node {
-   char *attribute;
+   char *attr_name;
int is_type;
-   union {
-   struct type_set *ts;
-   struct role_set *rs;
-   } set;
+   void *set;
 };
 
 struct list_node {
@@ -237,7 +234,7 @@ static void attr_list_destroy(struct list **attr_list)
while (curr != NULL) {
attr = curr->data;
if (attr != NULL) {
-   free(attr->attribute);
+   free(attr->attr_name);
}
 
free(curr->data);
@@ -711,54 +708,85 @@ static int num_digits(int n)
return num;
 }
 
-static int set_to_cil_attr(struct policydb *pdb, int is_type, char ***names, 
uint32_t *num_names)
+static int ebitmap_to_cil(struct policydb *pdb, struct ebitmap *map, int type)
+{
+   struct ebitmap_node *node;
+   uint32_t i;
+   char **val_to_name = pdb->sym_val_to_name[type];
+
+   ebitmap_for_each_bit(map, node, i) {
+   if (!ebitmap_get_bit(map, i)) {
+   continue;
+   }
+   cil_printf("%s ", val_to_name[i]);
+   }
+
+   return 0;
+}
+
+static char *get_new_attr_name(struct policydb *pdb, int is_type)
 {
static unsigned int num_attrs = 0;
-   int rc = -1;
int len, rlen;
-   const char *attr_infix;
-   char *attr;
+   const char *infix;
+   char *attr_name = NULL;
 
num_attrs++;
 
if (is_type) {
-   attr_infix = TYPEATTR_INFIX;
+   infix = TYPEATTR_INFIX;
} else {
-   attr_infix = ROLEATTR_INFIX;
+   infix = ROLEATTR_INFIX;
}
 
-   len = strlen(pdb->name) + strlen(attr_infix) + num_digits(num_attrs) + 
1;
-   attr = malloc(len);
-   if (attr == NULL) {
+   len = strlen(pdb->name) + strlen(infix) + num_digits(num_attrs) + 1;
+   attr_name = malloc(len);
+   if (!attr_name) {
log_err("Out of memory");
-   rc = -1;
goto exit;
}
-   rlen = snprintf(attr, len, "%s%s%i", pdb->name, attr_infix, num_attrs);
+
+   rlen = snprintf(attr_name, len, "%s%s%i", pdb->name, infix, num_attrs);
if (rlen < 0 || rlen >= len) {
log_err("Failed to generate attribute name");
-   rc = -1;
+   free(attr_name);
+   attr_name = NULL;
goto exit;
}
 
-   *names = malloc(sizeof(**names));
-   if (*names == NULL) {
+exit:
+   return attr_name;
+}
+
+static int cil_add_attr_to_list(struct list *attr_list, char *attr_name, int 
is_type, void *set)
+{
+   struct attr_list_node *attr_list_node = NULL;
+   int rc = 0;
+
+   attr_list_node = calloc(1, sizeof(*attr_list_node));
+   if (attr_list_node == NULL) {
log_err("Out of memory");
rc = -1;
goto exit;
}
 
+   rc = list_prepend(attr_list, attr_list_node);
+   if (rc != 0) {
+   goto exit;
+   }
 
-   *names[0] = attr;
-   *num_names = 1;
+   attr_list_node->attr_name = attr_name;
+   attr_list_node->is_type = is_type;
+   attr_list_node->set = set;
 
-   rc = 0;
+   return rc;
 
 exit:
+   free(attr_list_node);
return rc;
 }
 
-static int cil_print_attr_strs(int indent, struct policydb *pdb, int is_type, 
struct ebitmap *pos, struct ebitmap *neg, uint32_t flags, char *attr)
+static int cil_print_attr_strs(int indent, struct policydb *pdb, int is_type, 
void 

Re: [PATCH 1/7] libsepol: do not dereference a NULL pointer when stack_init() fails

2017-03-29 Thread James Carter

On 03/28/2017 05:41 PM, Nicolas Iooss wrote:

In cond_expr_to_cil() when stack_init() fails, stack is set to
NULL and the execution flow jumps to label "exit". This triggers a call
to stack_pop(stack) which dereferences a NULL pointer in "if (stack->pos
== -1)".

This issue has been found using clang's static analyzer.

Signed-off-by: Nicolas Iooss <nicolas.io...@m4x.org>


I applied these seven patches.

Thanks,
Jim


---
 libsepol/src/module_to_cil.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c
index 308ada4f1381..5c98c29bcf13 100644
--- a/libsepol/src/module_to_cil.c
+++ b/libsepol/src/module_to_cil.c
@@ -1363,11 +1363,12 @@ exit:
free(new_val);
free(val1);
free(val2);
-   while ((val1 = stack_pop(stack)) != NULL) {
-   free(val1);
+   if (stack != NULL) {
+   while ((val1 = stack_pop(stack)) != NULL) {
+   free(val1);
+   }
+   stack_destroy();
}
-   stack_destroy();
-
    return rc;
 }





--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: [PATCH] mcstrans: fix typo in mcstransd.8 man page

2017-03-28 Thread James Carter

On 03/24/2017 10:27 AM, Nikola ForrĂ³ wrote:

Signed-off-by: Nikola ForrĂ³ <nfo...@redhat.com>


Applied.

Thanks,
Jim


---
 mcstrans/man/man8/mcstransd.8 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mcstrans/man/man8/mcstransd.8 b/mcstrans/man/man8/mcstransd.8
index c1dc483..64774a5 100644
--- a/mcstrans/man/man8/mcstransd.8
+++ b/mcstrans/man/man8/mcstransd.8
@@ -23,7 +23,7 @@ Output a short summary of available command line options\&.
 .SH "AUTHOR"
 This man page was written by Dan Walsh <dwa...@redhat.com>.
 The program was originally written by Dan Walsh <dwa...@redhat.com>.
-The program was enhanced/rwwritten by Joe Nall <j...@nall.com>.
+The program was enhanced/rewritten by Joe Nall <j...@nall.com>.

 .SH "FILES"
 /etc/selinux/{SELINUXTYPE}/setrans.conf




--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.

Re: [PATCH] libsepol/cil: Add hexadecimal support for Xen ioportcon statements

2017-03-28 Thread James Carter

On 03/22/2017 03:01 PM, James Carter wrote:

Add hexadecimal support for Xen ioportcon statements which was
left out of commit c408c70.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>


This has been applied.

Jim


---
 libsepol/cil/src/cil_build_ast.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
index 442f100..8a19df4 100644
--- a/libsepol/cil/src/cil_build_ast.c
+++ b/libsepol/cil/src/cil_build_ast.c
@@ -4689,12 +4689,12 @@ int cil_gen_ioportcon(struct cil_db *db, struct 
cil_tree_node *parse_current, st
if (parse_current->next->cl_head != NULL) {
if (parse_current->next->cl_head->next != NULL &&
parse_current->next->cl_head->next->next == NULL) {
-   rc = cil_fill_integer(parse_current->next->cl_head, 
>ioport_low, 10);
+   rc = cil_fill_integer(parse_current->next->cl_head, 
>ioport_low, 0);
if (rc != SEPOL_OK) {
cil_log(CIL_ERR, "Improper ioport specified\n");
goto exit;
}
-   rc = cil_fill_integer(parse_current->next->cl_head->next, 
>ioport_high, 10);
+   rc = cil_fill_integer(parse_current->next->cl_head->next, 
>ioport_high, 0);
if (rc != SEPOL_OK) {
cil_log(CIL_ERR, "Improper ioport specified\n");
goto exit;
@@ -4705,7 +4705,7 @@ int cil_gen_ioportcon(struct cil_db *db, struct 
cil_tree_node *parse_current, st
goto exit;
}
} else {
-   rc = cil_fill_integer(parse_current->next, 
>ioport_low, 10);
+   rc = cil_fill_integer(parse_current->next, 
>ioport_low, 0);
if (rc != SEPOL_OK) {
    cil_log(CIL_ERR, "Improper ioport specified\n");
goto exit;




--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: [PATCH 1/2] policycoreutils: fixfiles should handle path arguments more robustly

2017-03-28 Thread James Carter

On 03/26/2017 10:35 AM, Alan Jenkins wrote:

E.g. `fixfiles restore -v /usr` - before:

Warning: Skipping the following R/O filesystems:
/sys/fs/cgroup
Progress and Verbose mutually exclusive
usage:  /sbin/restorecon [-iFnprRv0] [-e excludedir] pathname...
usage:  /sbin/restorecon [-iFnprRv0] [-e excludedir] -f filename
Warning: Skipping the following R/O filesystems:
/sys/fs/cgroup
229k

after:

Warning: Skipping the following R/O filesystems:
/sys/fs/cgroup
/sbin/restorecon:  lstat(-v) failed:  No such file or directory
Warning: Skipping the following R/O filesystems:
/sys/fs/cgroup
229k

This matches the usage shown in the manual page.  While we're in there,
we should handle spaces as well e.g `fixfiles restore "a b"`.  Before:

Warning: Skipping the following R/O filesystems:
/sys/fs/cgroup
/sbin/restorecon:  lstat(b) failed:  No such file or directory

After:

Warning: Skipping the following R/O filesystems:
/sys/fs/cgroup
/sbin/restorecon:  lstat(a b) failed:  No such file or directory

Signed-off-by: Alan Jenkins <alan.christopher.jenk...@gmail.com>


Both of these have been applied.

Thanks,
Jim


---
 policycoreutils/scripts/fixfiles | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/policycoreutils/scripts/fixfiles b/policycoreutils/scripts/fixfiles
index 3896d19..d3a53ba 100755
--- a/policycoreutils/scripts/fixfiles
+++ b/policycoreutils/scripts/fixfiles
@@ -248,7 +248,7 @@ if [ ! -z "$RPMFILES" ]; then
 exit $?
 fi
 if [ ! -z "$FILEPATH" ]; then
-${RESTORECON} $exclude_dirs ${FORCEFLAG} ${VERBOSE} -R $* $FILEPATH 2>&1 | cat 
>> $LOGFILE
+${RESTORECON} $exclude_dirs ${FORCEFLAG} ${VERBOSE} -R $* -- "$FILEPATH" 2>&1 | 
cat >> $LOGFILE
 return
 fi
 if [  -n "${FILESYSTEMSRW}" ]; then
@@ -400,7 +400,7 @@ else
process $command
 else
while [ -n "$1" ]; do
-   FILEPATH=$1
+   FILEPATH="$1"
process $command
shift
done




--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: [PATCH 1/1] libsepol/cil: do not dereference a NULL pointer when calloc() fails

2017-03-28 Thread James Carter

On 03/25/2017 09:48 AM, Nicolas Iooss wrote:

When list_init() fails to allocate a list with calloc(), it calls
list_destroy() with l = NULL. This functions starts by dereferencing
its argument ("(*list)->head"), which does not work well when it is
NULL.

This bug can be fixed by returning directly in list_init() when calloc()
fails. Doing so allows making list_init() implementation shorter by
removing label "exit" and local variable "rc".

This issue has been found using clang's static analyzer.

Signed-off-by: Nicolas Iooss <nicolas.io...@m4x.org>


Applied.

Thanks,
Jim


---
 libsepol/src/module_to_cil.c | 8 +---
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c
index 6c33b94da9d9..308ada4f1381 100644
--- a/libsepol/src/module_to_cil.c
+++ b/libsepol/src/module_to_cil.c
@@ -250,19 +250,13 @@ static void attr_list_destroy(struct list **attr_list)

 static int list_init(struct list **list)
 {
-   int rc = -1;
struct list *l = calloc(1, sizeof(*l));
if (l == NULL) {
-   goto exit;
+   return -1;
}

*list = l;
-
return 0;
-
-exit:
-   list_destroy();
-   return rc;
 }

 static int list_prepend(struct list *list, void *data)




--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: [PATCH 1/3] policycoreutils/setfiles: stdout messages don't need program prefix

2017-03-28 Thread James Carter

On 03/26/2017 12:22 PM, Alan Jenkins wrote:

I suggested that if you run a command for its informational output (by
passing  `-v`), you don't expect it to be prefixed with the program name.
Prefixing is used for error messages, so you can tell where your shell
script blew up :).  If a script is running a command for its informational
output, it's usually the script's responsibility to make sure it's in
context, e.g. providing headers if there are multiple sections of output.

Removing the program name from setfiles/restorecon output is particularly
useful because it generates very long lines.  But also, it actually helps
highlight where there are error messages - the prefix will make them
stand out visually.

Signed-off-by: Alan Jenkins <alan.christopher.jenk...@gmail.com>


All three of these have been applied.

Thanks,
Jim


---
 policycoreutils/setfiles/setfiles.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/policycoreutils/setfiles/setfiles.c 
b/policycoreutils/setfiles/setfiles.c
index 6f69c90..83e0b2a 100644
--- a/policycoreutils/setfiles/setfiles.c
+++ b/policycoreutils/setfiles/setfiles.c
@@ -142,9 +142,15 @@ static int __attribute__ ((format(printf, 2, 3)))
 log_callback(int type, const char *fmt, ...)
 {
int rc;
-   FILE *out = (type == SELINUX_INFO) ? stdout : stderr;
+   FILE *out;
va_list ap;
-   fprintf(out, "%s: ", r_opts.progname);
+
+   if (type == SELINUX_INFO) {
+   out = stdout;
+   } else {
+   out = stderr;
+   fprintf(out, "%s: ", r_opts.progname);
+   }
va_start(ap, fmt);
rc = vfprintf(out, fmt, ap);
    va_end(ap);




--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


[PATCH] libsepol: In module_to_cil create one attribute for each unique set

2017-03-28 Thread James Carter
CIL does not allow type or role sets in certain rules (such as allow
rules). It does, however, allow sets in typeattributeset and
roleattributeset statements. Because of this, when module_to_cil
translates a policy into CIL, it creates a new attribute for each
set that it encounters. But often the same set is used multiple times
which means that more attributes are created then necessary. As the
number of attributes increases the time required for the kernel to
make each policy decision increases which can be a problem.

To help reduce the number of attributes in a kernel policy,
when module_to_cil encounters a role or type set search to see if the
set was encountered already and, if it was, use the previously
generated attribute instead of creating a new one.

Testing on Android and Refpolicy policies show that this reduces the
number of attributes generated by about 40%.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 libsepol/src/module_to_cil.c | 593 +--
 1 file changed, 283 insertions(+), 310 deletions(-)

diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c
index 6c33b94..4ea8a83 100644
--- a/libsepol/src/module_to_cil.c
+++ b/libsepol/src/module_to_cil.c
@@ -174,12 +174,9 @@ struct role_list_node {
 };
 
 struct attr_list_node {
-   char *attribute;
+   char *attr_name;
int is_type;
-   union {
-   struct type_set *ts;
-   struct role_set *rs;
-   } set;
+   void *set;
 };
 
 struct list_node {
@@ -237,7 +234,7 @@ static void attr_list_destroy(struct list **attr_list)
while (curr != NULL) {
attr = curr->data;
if (attr != NULL) {
-   free(attr->attribute);
+   free(attr->attr_name);
}
 
free(curr->data);
@@ -717,54 +714,85 @@ static int num_digits(int n)
return num;
 }
 
-static int set_to_cil_attr(struct policydb *pdb, int is_type, char ***names, 
uint32_t *num_names)
+static int ebitmap_to_cil(struct policydb *pdb, struct ebitmap *map, int type)
+{
+   struct ebitmap_node *node;
+   uint32_t i;
+   char **val_to_name = pdb->sym_val_to_name[type];
+
+   ebitmap_for_each_bit(map, node, i) {
+   if (!ebitmap_get_bit(map, i)) {
+   continue;
+   }
+   cil_printf("%s ", val_to_name[i]);
+   }
+
+   return 0;
+}
+
+static char *get_new_attr_name(struct policydb *pdb, int is_type)
 {
static unsigned int num_attrs = 0;
-   int rc = -1;
int len, rlen;
-   const char *attr_infix;
-   char *attr;
+   char *infix;
+   char *attr_name = NULL;
 
num_attrs++;
 
if (is_type) {
-   attr_infix = TYPEATTR_INFIX;
+   infix = TYPEATTR_INFIX;
} else {
-   attr_infix = ROLEATTR_INFIX;
+   infix = ROLEATTR_INFIX;
}
 
-   len = strlen(pdb->name) + strlen(attr_infix) + num_digits(num_attrs) + 
1;
-   attr = malloc(len);
-   if (attr == NULL) {
+   len = strlen(pdb->name) + strlen(infix) + num_digits(num_attrs) + 1;
+   attr_name = malloc(len);
+   if (!attr_name) {
log_err("Out of memory");
-   rc = -1;
goto exit;
}
-   rlen = snprintf(attr, len, "%s%s%i", pdb->name, attr_infix, num_attrs);
+
+   rlen = snprintf(attr_name, len, "%s%s%i", pdb->name, infix, num_attrs);
if (rlen < 0 || rlen >= len) {
log_err("Failed to generate attribute name");
-   rc = -1;
+   free(attr_name);
+   attr_name = NULL;
goto exit;
}
 
-   *names = malloc(sizeof(**names));
-   if (*names == NULL) {
+exit:
+   return attr_name;
+}
+
+static int cil_add_attr_to_list(struct list *attr_list, char *attr_name, int 
is_type, void *set)
+{
+   struct attr_list_node *attr_list_node = NULL;
+   int rc = 0;
+
+   attr_list_node = calloc(1, sizeof(*attr_list_node));
+   if (attr_list_node == NULL) {
log_err("Out of memory");
rc = -1;
goto exit;
}
 
+   rc = list_prepend(attr_list, attr_list_node);
+   if (rc != 0) {
+   goto exit;
+   }
 
-   *names[0] = attr;
-   *num_names = 1;
+   attr_list_node->attr_name = attr_name;
+   attr_list_node->is_type = is_type;
+   attr_list_node->set = set;
 
-   rc = 0;
+   return rc;
 
 exit:
+   free(attr_list_node);
return rc;
 }
 
-static int cil_print_attr_strs(int indent, struct policydb *pdb, int is_type, 
struct ebitmap *pos, struct ebitmap *neg, uint32_t flags, char *attr)
+static int cil_print_attr_strs(int indent, struct policydb *pdb, int is_type, 
void 

[PATCH 3/3 v3] checkpolicy: Add options to convert binary policy to CIL or a policy.conf

2017-03-23 Thread James Carter
Use the same option "-C" used to ouput CIL from a policy.conf, but now
generate CIL from a binary policy instead of giving an error.i

Use the option "-F" to generate a policy.conf file from a binary policy.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 checkpolicy/checkpolicy.8 |  5 -
 checkpolicy/checkpolicy.c | 55 +++
 2 files changed, 41 insertions(+), 19 deletions(-)

diff --git a/checkpolicy/checkpolicy.8 b/checkpolicy/checkpolicy.8
index 600d5cd..7b28696 100644
--- a/checkpolicy/checkpolicy.8
+++ b/checkpolicy/checkpolicy.8
@@ -3,7 +3,7 @@
 checkpolicy \- SELinux policy compiler
 .SH SYNOPSIS
 .B checkpolicy
-.I "[\-b] [\-C] [\-d] [\-M] [\-c policyvers] [\-o output_file] [input_file]"
+.I "[\-b[F]] [\-C] [\-d] [\-M] [\-c policyvers] [\-o output_file] [input_file]"
 .br
 .SH "DESCRIPTION"
 This manual page describes the
@@ -27,6 +27,9 @@ Write CIL policy file rather than binary policy file.
 .B \-d,\-\-debug
 Enter debug mode after loading the policy.
 .TP
+.B \-F,\-\-conf
+Write policy.conf file rather than binary policy file. Can only be used with 
binary policy file.
+.TP
 .B \-M,\-\-mls
 Enable the MLS policy when checking and compiling the policy.
 .TP
diff --git a/checkpolicy/checkpolicy.c b/checkpolicy/checkpolicy.c
index b744d6a..534fc22 100644
--- a/checkpolicy/checkpolicy.c
+++ b/checkpolicy/checkpolicy.c
@@ -75,6 +75,8 @@
 #include 
 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -105,7 +107,7 @@ unsigned int policyvers = POLICYDB_VERSION_MAX;
 static __attribute__((__noreturn__)) void usage(const char *progname)
 {
printf
-   ("usage:  %s [-b] [-C] [-d] [-U handle_unknown (allow,deny,reject)] 
[-M]"
+   ("usage:  %s [-b[F]] [-C] [-d] [-U handle_unknown 
(allow,deny,reject)] [-M]"
 "[-c policyvers (%d-%d)] [-o output_file] [-t target_platform 
(selinux,xen)]"
 "[input_file]\n",
 progname, POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX);
@@ -388,7 +390,7 @@ int main(int argc, char **argv)
size_t scontext_len, pathlen;
unsigned int i;
unsigned int protocol, port;
-   unsigned int binary = 0, debug = 0, cil = 0;
+   unsigned int binary = 0, debug = 0, cil = 0, conf = 0;
struct val_to_name v;
int ret, ch, fd, target = SEPOL_TARGET_SELINUX;
unsigned int nel, uret;
@@ -411,11 +413,12 @@ int main(int argc, char **argv)
{"handle-unknown", required_argument, NULL, 'U'},
{"mls", no_argument, NULL, 'M'},
{"cil", no_argument, NULL, 'C'},
+   {"conf",no_argument, NULL, 'F'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0}
};
 
-   while ((ch = getopt_long(argc, argv, "o:t:dbU:MCVc:h", long_options, 
NULL)) != -1) {
+   while ((ch = getopt_long(argc, argv, "o:t:dbU:MCFVc:h", long_options, 
NULL)) != -1) {
switch (ch) {
case 'o':
outfile = optarg;
@@ -461,6 +464,9 @@ int main(int argc, char **argv)
case 'C':
cil = 1;
break;
+   case 'F':
+   conf = 1;
+   break;
case 'c':{
long int n;
errno = 0;
@@ -510,12 +516,12 @@ int main(int argc, char **argv)
sepol_set_policydb();
sepol_set_sidtab();
 
+   if (cil && conf) {
+   fprintf(stderr, "Can't convert to CIL and policy.conf at the 
same time\n");
+   exit(1);
+   }
+
if (binary) {
-   if (cil) {
-   fprintf(stderr, "%s:  Converting kernel policy to CIL 
is not supported\n",
-   argv[0]);
-   exit(1);
-   }
fd = open(file, O_RDONLY);
if (fd < 0) {
fprintf(stderr, "Can't open '%s':  %s\n",
@@ -568,6 +574,10 @@ int main(int argc, char **argv)
}
}
} else {
+   if (conf) {
+   fprintf(stderr, "Can only generate policy.conf from 
binary policy\n");
+   exit(1);
+   }
if (policydb_init(_policy))
exit(1);
/* We build this as a base policy first since that is all the 
parser understands */
@@ -621,15 +631,20 @@ int main(int argc, char **argv)
policydb.policyvers = policyvers;
 
if (!cil) {
-   printf
-   ("%s:  writing binary representation (ve

[PATCH 0/3 v3] libsepol and checkpolicy: Output CIL or policy.conf from kernel policy

2017-03-23 Thread James Carter
It would sometimes be helpful for debugging or verification purposes to be able 
to convert
a binary policy to a human-readable form.

This patchset adds libsepol functions that take a kernel policydb in and 
outputs either
a CIL or policy.conf text.

Checkpolicy is modified to generate CIL text from a binary policy if using the 
"-C" option
and to add the "-F" option to generate policy.conf text from a binary policy.

Where possible rules are sorted in alphabetical or numerical order to aid in 
debugging.

Changes from v1:
- Moved __attribute__((format(printf...))) for printf-like functions to 
kernel_to_common.h
- Incorporated patch from Nicolas Iooss to make const char* variables where 
appropriate
- Fixed conditional block formatting problems when generating policy.conf
- Initialize mls_constraints and non_mls_constraints to NULL in 
kernel_to_conf.c and kernel_to_cil.c so they are not accessed without 
initializaton if an error occurs.
- Updated checkpolicy manpage to include the new option
- Removed commented-out block from checkpolicy.c

Changes from v2:
- Fixed conditional block formatting problems when generating CIL.
- Fixed improper range syntax for non-mls CIL policies.
- Write types in alphabetical order in roletype rules for CIL and role rules 
for policy.conf.
- Write roles in alphabetical order in userrole rules for CIL and user rules 
for policy.conf.
- Write policy capability rules in alphabetical order
- Separated writing of constrain and validatetrans constraint rules for both 
CIL and policy.conf.
- Write constraints in alphabetical order for both CIL and policy.conf
- Now continously creating a policy.conf and then a binary produces an 
identical binary (although for CIL, secilc will remove unused attributes during 
the first cycle.)

James Carter (3):
  libsepol: Add ability to convert binary policy to CIL
  libsepol: Add ability to convert binary policy to policy.conf file
  checkpolicy: Add options to convert binary policy to CIL or a
policy.conf

 checkpolicy/checkpolicy.8   |5 +-
 checkpolicy/checkpolicy.c   |   55 +-
 libsepol/include/sepol/kernel_to_cil.h  |5 +
 libsepol/include/sepol/kernel_to_conf.h |5 +
 libsepol/src/kernel_to_cil.c| 3226 +++
 libsepol/src/kernel_to_common.c |  677 +++
 libsepol/src/kernel_to_common.h |  114 ++
 libsepol/src/kernel_to_conf.c   | 3096 +
 libsepol/src/libsepol.map.in|2 +
 9 files changed, 7166 insertions(+), 19 deletions(-)
 create mode 100644 libsepol/include/sepol/kernel_to_cil.h
 create mode 100644 libsepol/include/sepol/kernel_to_conf.h
 create mode 100644 libsepol/src/kernel_to_cil.c
 create mode 100644 libsepol/src/kernel_to_common.c
 create mode 100644 libsepol/src/kernel_to_common.h
 create mode 100644 libsepol/src/kernel_to_conf.c

-- 
2.7.4

___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


[PATCH] libsepol/cil: Add hexadecimal support for Xen ioportcon statements

2017-03-22 Thread James Carter
Add hexadecimal support for Xen ioportcon statements which was
left out of commit c408c70.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 libsepol/cil/src/cil_build_ast.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
index 442f100..8a19df4 100644
--- a/libsepol/cil/src/cil_build_ast.c
+++ b/libsepol/cil/src/cil_build_ast.c
@@ -4689,12 +4689,12 @@ int cil_gen_ioportcon(struct cil_db *db, struct 
cil_tree_node *parse_current, st
if (parse_current->next->cl_head != NULL) {
if (parse_current->next->cl_head->next != NULL &&
parse_current->next->cl_head->next->next == NULL) {
-   rc = cil_fill_integer(parse_current->next->cl_head, 
>ioport_low, 10);
+   rc = cil_fill_integer(parse_current->next->cl_head, 
>ioport_low, 0);
if (rc != SEPOL_OK) {
cil_log(CIL_ERR, "Improper ioport specified\n");
goto exit;
}
-   rc = 
cil_fill_integer(parse_current->next->cl_head->next, >ioport_high, 
10);
+   rc = 
cil_fill_integer(parse_current->next->cl_head->next, >ioport_high, 
0);
if (rc != SEPOL_OK) {
cil_log(CIL_ERR, "Improper ioport specified\n");
goto exit;
@@ -4705,7 +4705,7 @@ int cil_gen_ioportcon(struct cil_db *db, struct 
cil_tree_node *parse_current, st
goto exit;
}
} else {
-   rc = cil_fill_integer(parse_current->next, 
>ioport_low, 10);
+   rc = cil_fill_integer(parse_current->next, 
>ioport_low, 0);
if (rc != SEPOL_OK) {
cil_log(CIL_ERR, "Improper ioport specified\n");
goto exit;
-- 
2.7.4

___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: [PATCH 0/3 v2] libsepol and checkpolicy: Output CIL or policy.conf from kernel policy

2017-03-22 Thread James Carter

On 03/21/2017 06:43 PM, Nicolas Iooss wrote:

On Mon, Mar 20, 2017 at 4:40 PM, James Carter <jwca...@tycho.nsa.gov> wrote:

It would sometimes be helpful for debugging or verification purposes to be able 
to convert
a binary policy to a human-readable form.

This patchset adds libsepol functions that take a kernel policydb in and 
outputs either
a CIL or policy.conf text.

Checkpolicy is modified to generate CIL text from a binary policy if using the 
"-C" option
and to add the "-F" option to generate policy.conf text from a binary policy.

Where possible rules are sorted in alphabetical or numerical order to aid in 
debugging.

Changes from v1:
- Moved __attribute__((format(printf...))) for printf-like functions to 
kernel_to_common.h
- Incorporated patch from Nicolas Iooss to make const char* variables where 
appropriate
- Fixed conditional block formatting problems when generating policy.conf
- Initialize mls_constraints and non_mls_constraints to NULL in 
kernel_to_conf.c and kernel_to_cil.c so they are not accessed without 
initializaton if an error occurs.
- Updated checkpolicy manpage to include the new option
- Removed commented-out block from checkpolicy.c

James Carter (3):
  libsepol: Add ability to convert binary policy to CIL
  libsepol: Add ability to convert binary policy to policy.conf file
  checkpolicy: Add options to convert binary policy to CIL or a
policy.conf


Hello,

I have tested this new version and it worked quite fine on my system.
It also builds without any trouble on Travis-CI
(https://travis-ci.org/fishilico/selinux/builds/213586224).

After performing some tests, I quickly read the CIL policy generated
with "checkpolicy -bC" and found:

(booleanif (and git_cgi_enable_homedirs use_nfs_home_dirs)
(true
(allow httpd_git_script_t nfs_t (dir (getattr search open)))
(allow httpd_git_script_t nfs_t (dir (ioctl read getattr lock
search open)))
(allow httpd_git_script_t nfs_t (dir (ioctl read getattr lock
search open)))
(allow httpd_git_script_t nfs_t (file (ioctl read getattr lock open)))
(allow httpd_git_script_t nfs_t (filesystem (getattr)))
)
(false(dontaudit httpd_git_script_t nfs_t (file (ioctl
read getattr lock open)))
)
)

There is a missing "\n" after "(false" on line 2059 of kernel_to_cil.c
(function write_cond_nodes_to_cil).



Not sure how I missed that.


Moreover when trying to compile with secilc the resulting file, I get
"Bad userrange declaration" on a line which contains "(userrange root
systemlow systemlow)" (this is a non-MLS policy). There are missing
parentheses around the levels when generating userrange statements in
write_user_decl_rules_to_cil().



I guess I have been too focused on testing MLS policies.


By iterating cycles of secilc and checkpolicy -bC, it appears that the
roletypes statements get generated with alphabetical order of roles,
but a random order for types (which is the order in the binary policy
file if I understand the code correctly). Would it be possible to sort
them in alphabetical order too? I guess a "struct strs"-based
construction similar to what write_cond_av_list_to_cil() does can be
used, even though I have not taken time to test this yet.



I do sort the types when generating a policy.conf. I should do them for CIL as 
well.


Thanks for the review and comments.

Jim


Cheers,
Nicolas




--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: [PATCH 0/3] libsepol: Allow hexadecimal numbers in Xen context rules

2017-03-21 Thread James Carter

On 03/20/2017 11:18 AM, James Carter wrote:

Allow the use of hexadecimal numbers in iomemcon, ioportcon, and
pcidevicecon statements. The use of hexadecimal numbers is often
the natural choice for these rules.

James Carter (3):
  libsepol/cil: Allow hexadecimal numbers in Xen context rules
  libsepol: Update module_to_cil to output hexadecimal for Xen rules
  libsepol/cil: Use hexadecimal numbers when writing Xen rules

 libsepol/cil/src/cil_build_ast.c | 30 +++---
 libsepol/cil/src/cil_build_ast.h |  4 ++--
 libsepol/cil/src/cil_policy.c| 10 +++---
 libsepol/src/module_to_cil.c | 11 ++-
 4 files changed, 30 insertions(+), 25 deletions(-)



This series has been applied.

--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: [PATCH 1/1] checkpolicy: dereference rangehead after checking it was not NULL

2017-03-21 Thread James Carter

On 03/17/2017 06:10 PM, Nicolas Iooss wrote:

Signed-off-by: Nicolas Iooss <nicolas.io...@m4x.org>


Applied.

Thanks,
Jim


---
 checkpolicy/policy_define.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c
index dbafadb01e21..949ca7117233 100644
--- a/checkpolicy/policy_define.c
+++ b/checkpolicy/policy_define.c
@@ -1924,11 +1924,11 @@ int avrule_ioctl_ranges(struct av_ioctl_range_list 
**rangelist)
/* read in ranges to include and omit */
if (avrule_read_ioctls())
return -1;
-   omit = rangehead->omit;
if (rangehead == NULL) {
yyerror("error processing ioctl commands");
return -1;
}
+   omit = rangehead->omit;
/* sort and merge the input ioctls */
if (avrule_sort_ioctls())
return -1;




--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: [PATCH] checkpolicy: Fix minor memory leak in checkpolicy

2017-03-21 Thread James Carter

On 03/20/2017 11:14 AM, James Carter wrote:

sepol_set_sidtab() is called without calling sepol_sidtab_destroy().
This is not a big deal, since checkpolicy does not run for long, but
it does add noise when checking for other, more important, leaks.

Call sepol_sidtab_destroy() before exiting if not in debug mode.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>


This has been applied.


---
 checkpolicy/checkpolicy.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/checkpolicy/checkpolicy.c b/checkpolicy/checkpolicy.c
index 442e7db..534fc22 100644
--- a/checkpolicy/checkpolicy.c
+++ b/checkpolicy/checkpolicy.c
@@ -673,6 +673,7 @@ int main(int argc, char **argv)

if (!debug) {
policydb_destroy();
+   sepol_sidtab_destroy();
exit(0);
}





--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: [PATCH 1/1] libsepol/cil: avoid freeing uninitialized values

2017-03-21 Thread James Carter

On 03/17/2017 05:30 PM, Nicolas Iooss wrote:

cil_resolve_ast() begins by checking whether one of its parameters is
NULL and "goto exit;" when it is the case. As extra_args has not been
initialized there, this leads to calling cil_destroy_tree_node_stack(),
__cil_ordered_lists_destroy()... on garbage values.

In practise this cannot happen because cil_resolve_ast() is only called
by cil_compile() after cil_build_ast() succeeded. As the if condition
exists nonetheless, fix the body of the if block in order to silence a
warning reported by clang Static Analyzer.

Signed-off-by: Nicolas Iooss <nicolas.io...@m4x.org>


Applied.

Thanks,
Jim


---
 libsepol/cil/src/cil_resolve_ast.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libsepol/cil/src/cil_resolve_ast.c 
b/libsepol/cil/src/cil_resolve_ast.c
index 87817ca29a5f..187050116379 100644
--- a/libsepol/cil/src/cil_resolve_ast.c
+++ b/libsepol/cil/src/cil_resolve_ast.c
@@ -3797,7 +3797,7 @@ int cil_resolve_ast(struct cil_db *db, struct 
cil_tree_node *current)
uint32_t changed = 0;

if (db == NULL || current == NULL) {
-   goto exit;
+   return rc;
}

extra_args.db = db;




--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: [PATCH 1/1] libsepol/cil: make reporting conflicting type transitions work

2017-03-21 Thread James Carter

On 03/17/2017 05:05 PM, Nicolas Iooss wrote:

When compiling a CIL policy which defines conflicting type transitions,
secilc crashes when trying to format an error message with uninitialized
values. This is caused by __cil_typetransition_to_avtab() not
initializing the ..._str fields of its local variable "struct
cil_type_rule trans" before calling __cil_type_rule_to_avtab().

While at it, make the error report clearer about what is wrong by
showing the types and classes which got expanded in
__cil_type_rule_to_avtab(). Here is an example of the result:

Conflicting type rules (scontext=testuser_emacs.subj
tcontext=fs.tmpfs.fs tclass=dir
result=users.generic_tmpfs.user_tmpfs_file),
existing=emacs.tmpfs.user_tmpfs_file

Expanded from type rule (scontext=ARG1 tcontext=fs tclass=ARG3
result=ARG2)

Reported-By: Dominick Grift <dac.overr...@gmail.com>
Signed-off-by: Nicolas Iooss <nicolas.io...@m4x.org>


Applied.

Thanks,
Jim


---
 libsepol/cil/src/cil_binary.c | 22 --
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c
index ac371aef7b2d..ac18c4e2ee5d 100644
--- a/libsepol/cil/src/cil_binary.c
+++ b/libsepol/cil/src/cil_binary.c
@@ -1018,7 +1018,14 @@ int __cil_insert_type_rule(policydb_t *pdb, uint32_t 
kind, uint32_t src, uint32_
 * non-duplicate rule using the same key.
 */
if (existing->datum.data != res) {
-   cil_log(CIL_ERR, "Conflicting type rules (scontext=%s tcontext=%s 
tclass=%s result=%s)\n", cil_rule->src_str, cil_rule->tgt_str, cil_rule->obj_str, 
cil_rule->result_str);
+   cil_log(CIL_ERR, "Conflicting type rules (scontext=%s 
tcontext=%s tclass=%s result=%s), existing=%s\n",
+   pdb->p_type_val_to_name[src - 1],
+   pdb->p_type_val_to_name[tgt - 1],
+   pdb->p_class_val_to_name[obj - 1],
+   pdb->p_type_val_to_name[res - 1],
+   pdb->p_type_val_to_name[existing->datum.data - 
1]);
+   cil_log(CIL_ERR, "Expanded from type rule (scontext=%s 
tcontext=%s tclass=%s result=%s)\n",
+   cil_rule->src_str, cil_rule->tgt_str, 
cil_rule->obj_str, cil_rule->result_str);
rc = SEPOL_ERR;
}
goto exit;
@@ -1044,7 +1051,14 @@ int __cil_insert_type_rule(policydb_t *pdb, uint32_t 
kind, uint32_t src, uint32_
search_datum = cil_cond_av_list_search(_key, 
other_list);
if (search_datum == NULL) {
if (existing->datum.data != res) {
-   cil_log(CIL_ERR, "Conflicting type rules (scontext=%s 
tcontext=%s tclass=%s result=%s)\n", cil_rule->src_str, cil_rule->tgt_str, 
cil_rule->obj_str, cil_rule->result_str);
+   cil_log(CIL_ERR, "Conflicting type rules 
(scontext=%s tcontext=%s tclass=%s result=%s), existing=%s\n",
+   pdb->p_type_val_to_name[src - 
1],
+   pdb->p_type_val_to_name[tgt - 
1],
+   pdb->p_class_val_to_name[obj - 
1],
+   pdb->p_type_val_to_name[res - 
1],
+   
pdb->p_type_val_to_name[existing->datum.data - 1]);
+   cil_log(CIL_ERR, "Expanded from type rule 
(scontext=%s tcontext=%s tclass=%s result=%s)\n",
+   cil_rule->src_str, cil_rule->tgt_str, 
cil_rule->obj_str, cil_rule->result_str);
rc = SEPOL_ERR;
goto exit;
}
@@ -1146,6 +1160,10 @@ int __cil_typetransition_to_avtab(policydb_t *pdb, const 
struct cil_db *db, stru
trans.tgt = typetrans->tgt;
trans.obj = typetrans->obj;
trans.result = typetrans->result;
+   trans.src_str = typetrans->src_str;
+   trans.tgt_str = typetrans->tgt_str;
+   trans.obj_str = typetrans->obj_str;
+   trans.result_str = typetrans->result_str;
return __cil_type_rule_to_avtab(pdb, db, , cond_node, 
cond_flavor);
}





--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


[PATCH 2/3 v2] libsepol: Add ability to convert binary policy to policy.conf file

2017-03-20 Thread James Carter
It would sometimes be helpful for debugging or verification purposes
to be able to convert a binary policy to a human-readable form.

Create new function, sepol_kernel_policydb_to_conf(), that takes a
policydb created from a binary policy and writes a policy.conf file
to the provided FILE pointer.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 libsepol/include/sepol/kernel_to_conf.h |5 +
 libsepol/src/kernel_to_conf.c   | 3043 +++
 libsepol/src/libsepol.map.in|1 +
 3 files changed, 3049 insertions(+)
 create mode 100644 libsepol/include/sepol/kernel_to_conf.h
 create mode 100644 libsepol/src/kernel_to_conf.c

diff --git a/libsepol/include/sepol/kernel_to_conf.h 
b/libsepol/include/sepol/kernel_to_conf.h
new file mode 100644
index 000..2313f38
--- /dev/null
+++ b/libsepol/include/sepol/kernel_to_conf.h
@@ -0,0 +1,5 @@
+#include 
+
+#include 
+
+int sepol_kernel_policydb_to_conf(FILE *fp, struct policydb *pdb);
diff --git a/libsepol/src/kernel_to_conf.c b/libsepol/src/kernel_to_conf.c
new file mode 100644
index 000..1ff68be
--- /dev/null
+++ b/libsepol/src/kernel_to_conf.c
@@ -0,0 +1,3043 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#ifndef IPPROTO_DCCP
+#define IPPROTO_DCCP 33
+#endif
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "kernel_to_common.h"
+
+
+static char *cond_expr_to_str(struct policydb *pdb, struct cond_expr *expr)
+{
+   struct cond_expr *curr;
+   struct strs *stack;
+   char *new_val;
+   char *str = NULL;
+   int rc;
+
+   rc = stack_init();
+   if (rc != 0) {
+   goto exit;
+   }
+
+   for (curr = expr; curr != NULL; curr = curr->next) {
+   if (curr->expr_type == COND_BOOL) {
+   char *val1 = pdb->p_bool_val_to_name[curr->bool - 1];
+   new_val = create_str("%s", 1, val1);
+   } else {
+   const char *op;
+   uint32_t num_params;
+   char *val1 = NULL;
+   char *val2 = NULL;
+
+   switch(curr->expr_type) {
+   case COND_NOT:  op = "!";  num_params = 1; break;
+   case COND_OR:   op = "||"; num_params = 2; break;
+   case COND_AND:  op = "&&"; num_params = 2; break;
+   case COND_XOR:  op = "^";  num_params = 2; break;
+   case COND_EQ:   op = "=="; num_params = 2; break;
+   case COND_NEQ:  op = "!="; num_params = 2; break;
+   default:
+   sepol_log_err("Unknown conditional operator: 
%i", curr->expr_type);
+   goto exit;
+   }
+
+   if (num_params == 2) {
+   val2 = stack_pop(stack);
+   if (!val2) {
+   sepol_log_err("Invalid conditional 
expression");
+   goto exit;
+   }
+   }
+   val1 = stack_pop(stack);
+   if (!val1) {
+   sepol_log_err("Invalid conditional expression");
+   free(val2);
+   goto exit;
+   }
+   if (num_params == 2) {
+   new_val = create_str("(%s %s %s)", 3, val1, op, 
val2);
+   free(val2);
+   } else {
+   new_val = create_str("%s %s", 2, op, val1);
+   }
+   free(val1);
+   }
+   if (!new_val) {
+   sepol_log_err("Invalid conditional expression");
+   goto exit;
+   }
+   rc = stack_push(stack, new_val);
+   if (rc != 0) {
+   sepol_log_err("Out of memory");
+   goto exit;
+   }
+   }
+
+   new_val = stack_pop(stack);
+   if (!new_val || !stack_empty(stack)) {
+   sepol_log_err("Invalid conditional expression");
+   goto exit;
+   }
+
+   str = new_val;
+
+   stack_destroy();
+   return str;
+
+exit:
+   while ((new_val = stack_pop(stack)) != NULL) {
+   free(new_val);
+   }
+   stack_destroy();
+
+   return NULL;
+}
+
+static char *constraint_expr_to_str(struct policydb *pdb, struct 
constraint_expr *expr, int *use_mls)
+{
+   struc

[PATCH 1/3 v2] libsepol: Add ability to convert binary policy to CIL

2017-03-20 Thread James Carter
It would sometimes be helpful for debugging or verification purposes
to be able to convert a binary policy to a human-readable form.

Create new function, sepol_kernel_policydb_to_cil(), that takes a
policydb created from a binary policy and writes CIL policy to the
provided FILE pointer.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 libsepol/include/sepol/kernel_to_cil.h |5 +
 libsepol/src/kernel_to_cil.c   | 3154 
 libsepol/src/kernel_to_common.c|  677 +++
 libsepol/src/kernel_to_common.h|  114 ++
 libsepol/src/libsepol.map.in   |1 +
 5 files changed, 3951 insertions(+)
 create mode 100644 libsepol/include/sepol/kernel_to_cil.h
 create mode 100644 libsepol/src/kernel_to_cil.c
 create mode 100644 libsepol/src/kernel_to_common.c
 create mode 100644 libsepol/src/kernel_to_common.h

diff --git a/libsepol/include/sepol/kernel_to_cil.h 
b/libsepol/include/sepol/kernel_to_cil.h
new file mode 100644
index 000..60346ad
--- /dev/null
+++ b/libsepol/include/sepol/kernel_to_cil.h
@@ -0,0 +1,5 @@
+#include 
+
+#include 
+
+int sepol_kernel_policydb_to_cil(FILE *fp, struct policydb *pdb);
diff --git a/libsepol/src/kernel_to_cil.c b/libsepol/src/kernel_to_cil.c
new file mode 100644
index 000..b0faa4e
--- /dev/null
+++ b/libsepol/src/kernel_to_cil.c
@@ -0,0 +1,3154 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#ifndef IPPROTO_DCCP
+#define IPPROTO_DCCP 33
+#endif
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "kernel_to_common.h"
+
+
+static char *cond_expr_to_str(struct policydb *pdb, struct cond_expr *expr)
+{
+   struct cond_expr *curr;
+   struct strs *stack;
+   char *new_val;
+   char *str = NULL;
+   int rc;
+
+   rc = stack_init();
+   if (rc != 0) {
+   goto exit;
+   }
+
+   for (curr = expr; curr != NULL; curr = curr->next) {
+   if (curr->expr_type == COND_BOOL) {
+   char *val1 = pdb->p_bool_val_to_name[curr->bool - 1];
+   new_val = create_str("%s", 1, val1);
+   } else {
+   const char *op;
+   uint32_t num_params;
+   char *val1 = NULL;
+   char *val2 = NULL;
+
+   switch(curr->expr_type) {
+   case COND_NOT:  op = "not"; num_params = 1; break;
+   case COND_OR:   op = "or";  num_params = 2; break;
+   case COND_AND:  op = "and"; num_params = 2; break;
+   case COND_XOR:  op = "xor"; num_params = 2; break;
+   case COND_EQ:   op = "eq";  num_params = 2; break;
+   case COND_NEQ:  op = "neq"; num_params = 2; break;
+   default:
+   sepol_log_err("Unknown conditional operator: 
%i",
+ curr->expr_type);
+   goto exit;
+   }
+
+   if (num_params == 2) {
+   val2 = stack_pop(stack);
+   if (!val2) {
+   sepol_log_err("Invalid conditional 
expression");
+   goto exit;
+   }
+   }
+   val1 = stack_pop(stack);
+   if (!val1) {
+   sepol_log_err("Invalid conditional expression");
+   free(val2);
+   goto exit;
+   }
+   if (num_params == 2) {
+   new_val = create_str("(%s %s %s)", 3, op, val1, 
val2);
+   free(val2);
+   } else {
+   new_val = create_str("(%s %s)", 2, op, val1);
+   }
+   free(val1);
+   }
+   if (!new_val) {
+   sepol_log_err("Invalid conditional expression");
+   goto exit;
+   }
+   rc = stack_push(stack, new_val);
+   if (rc != 0) {
+   sepol_log_err("Out of memory");
+   goto exit;
+   }
+   }
+
+   new_val = stack_pop(stack);
+   if (!new_val || !stack_empty(stack)) {
+   sepol_log_err("Invalid conditional expression");
+   goto exit;
+   }
+
+   str = new_val;
+
+   stack_destroy();
+   return str;
+
+exit:
+   while ((new_va

[PATCH 3/3 v2] checkpolicy: Add options to convert binary policy to CIL or a policy.conf

2017-03-20 Thread James Carter
Use the same option "-C" used to ouput CIL from a policy.conf, but now
generate CIL from a binary policy instead of giving an error.

Use the option "-F" to generate a policy.conf file from a binary policy.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 checkpolicy/checkpolicy.8 |  5 -
 checkpolicy/checkpolicy.c | 55 +++
 2 files changed, 41 insertions(+), 19 deletions(-)

diff --git a/checkpolicy/checkpolicy.8 b/checkpolicy/checkpolicy.8
index 600d5cd..7b28696 100644
--- a/checkpolicy/checkpolicy.8
+++ b/checkpolicy/checkpolicy.8
@@ -3,7 +3,7 @@
 checkpolicy \- SELinux policy compiler
 .SH SYNOPSIS
 .B checkpolicy
-.I "[\-b] [\-C] [\-d] [\-M] [\-c policyvers] [\-o output_file] [input_file]"
+.I "[\-b[F]] [\-C] [\-d] [\-M] [\-c policyvers] [\-o output_file] [input_file]"
 .br
 .SH "DESCRIPTION"
 This manual page describes the
@@ -27,6 +27,9 @@ Write CIL policy file rather than binary policy file.
 .B \-d,\-\-debug
 Enter debug mode after loading the policy.
 .TP
+.B \-F,\-\-conf
+Write policy.conf file rather than binary policy file. Can only be used with 
binary policy file.
+.TP
 .B \-M,\-\-mls
 Enable the MLS policy when checking and compiling the policy.
 .TP
diff --git a/checkpolicy/checkpolicy.c b/checkpolicy/checkpolicy.c
index b98bfcd..442e7db 100644
--- a/checkpolicy/checkpolicy.c
+++ b/checkpolicy/checkpolicy.c
@@ -75,6 +75,8 @@
 #include 
 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -105,7 +107,7 @@ unsigned int policyvers = POLICYDB_VERSION_MAX;
 static __attribute__((__noreturn__)) void usage(const char *progname)
 {
printf
-   ("usage:  %s [-b] [-C] [-d] [-U handle_unknown (allow,deny,reject)] 
[-M]"
+   ("usage:  %s [-b[F]] [-C] [-d] [-U handle_unknown 
(allow,deny,reject)] [-M]"
 "[-c policyvers (%d-%d)] [-o output_file] [-t target_platform 
(selinux,xen)]"
 "[input_file]\n",
 progname, POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX);
@@ -388,7 +390,7 @@ int main(int argc, char **argv)
size_t scontext_len, pathlen;
unsigned int i;
unsigned int protocol, port;
-   unsigned int binary = 0, debug = 0, cil = 0;
+   unsigned int binary = 0, debug = 0, cil = 0, conf = 0;
struct val_to_name v;
int ret, ch, fd, target = SEPOL_TARGET_SELINUX;
unsigned int nel, uret;
@@ -411,11 +413,12 @@ int main(int argc, char **argv)
{"handle-unknown", required_argument, NULL, 'U'},
{"mls", no_argument, NULL, 'M'},
{"cil", no_argument, NULL, 'C'},
+   {"conf",no_argument, NULL, 'F'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0}
};
 
-   while ((ch = getopt_long(argc, argv, "o:t:dbU:MCVc:h", long_options, 
NULL)) != -1) {
+   while ((ch = getopt_long(argc, argv, "o:t:dbU:MCFVc:h", long_options, 
NULL)) != -1) {
switch (ch) {
case 'o':
outfile = optarg;
@@ -461,6 +464,9 @@ int main(int argc, char **argv)
case 'C':
cil = 1;
break;
+   case 'F':
+   conf = 1;
+   break;
case 'c':{
long int n;
errno = 0;
@@ -510,12 +516,12 @@ int main(int argc, char **argv)
sepol_set_policydb();
sepol_set_sidtab();
 
+   if (cil && conf) {
+   fprintf(stderr, "Can't convert to CIL and policy.conf at the 
same time\n");
+   exit(1);
+   }
+
if (binary) {
-   if (cil) {
-   fprintf(stderr, "%s:  Converting kernel policy to CIL 
is not supported\n",
-   argv[0]);
-   exit(1);
-   }
fd = open(file, O_RDONLY);
if (fd < 0) {
fprintf(stderr, "Can't open '%s':  %s\n",
@@ -568,6 +574,10 @@ int main(int argc, char **argv)
}
}
} else {
+   if (conf) {
+   fprintf(stderr, "Can only generate policy.conf from 
binary policy\n");
+   exit(1);
+   }
if (policydb_init(_policy))
exit(1);
/* We build this as a base policy first since that is all the 
parser understands */
@@ -621,15 +631,20 @@ int main(int argc, char **argv)
policydb.policyvers = policyvers;
 
if (!cil) {
-   printf
-   ("%s:  writing binary representation (ve

[PATCH 0/3 v2] libsepol and checkpolicy: Output CIL or policy.conf from kernel policy

2017-03-20 Thread James Carter
It would sometimes be helpful for debugging or verification purposes to be able 
to convert
a binary policy to a human-readable form.

This patchset adds libsepol functions that take a kernel policydb in and 
outputs either
a CIL or policy.conf text.

Checkpolicy is modified to generate CIL text from a binary policy if using the 
"-C" option
and to add the "-F" option to generate policy.conf text from a binary policy.

Where possible rules are sorted in alphabetical or numerical order to aid in 
debugging.

Changes from v1:
- Moved __attribute__((format(printf...))) for printf-like functions to 
kernel_to_common.h
- Incorporated patch from Nicolas Iooss to make const char* variables where 
appropriate
- Fixed conditional block formatting problems when generating policy.conf
- Initialize mls_constraints and non_mls_constraints to NULL in 
kernel_to_conf.c and kernel_to_cil.c so they are not accessed without 
initializaton if an error occurs.
- Updated checkpolicy manpage to include the new option
- Removed commented-out block from checkpolicy.c

James Carter (3):
  libsepol: Add ability to convert binary policy to CIL
  libsepol: Add ability to convert binary policy to policy.conf file
  checkpolicy: Add options to convert binary policy to CIL or a
policy.conf

 checkpolicy/checkpolicy.8   |5 +-
 checkpolicy/checkpolicy.c   |   55 +-
 libsepol/include/sepol/kernel_to_cil.h  |5 +
 libsepol/include/sepol/kernel_to_conf.h |5 +
 libsepol/src/kernel_to_cil.c| 3154 +++
 libsepol/src/kernel_to_common.c |  677 +++
 libsepol/src/kernel_to_common.h |  114 ++
 libsepol/src/kernel_to_conf.c   | 3043 +
 libsepol/src/libsepol.map.in|2 +
 9 files changed, 7041 insertions(+), 19 deletions(-)
 create mode 100644 libsepol/include/sepol/kernel_to_cil.h
 create mode 100644 libsepol/include/sepol/kernel_to_conf.h
 create mode 100644 libsepol/src/kernel_to_cil.c
 create mode 100644 libsepol/src/kernel_to_common.c
 create mode 100644 libsepol/src/kernel_to_common.h
 create mode 100644 libsepol/src/kernel_to_conf.c

-- 
2.7.4

___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


[PATCH 2/3] libsepol: Update module_to_cil to output hexadecimal for Xen rules

2017-03-20 Thread James Carter
When generating CIL, use hexadecimal numbers in ioportcon,
iomemcon, and pcidevicecon statements.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 libsepol/src/module_to_cil.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c
index 8c4fff9..6c33b94 100644
--- a/libsepol/src/module_to_cil.c
+++ b/libsepol/src/module_to_cil.c
@@ -34,6 +34,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -2854,9 +2855,9 @@ static int ocontext_xen_ioport_to_cil(struct policydb 
*pdb, struct ocontext *iop
high = ioport->u.ioport.high_ioport;
 
if (low == high) {
-   cil_printf("(ioportcon %i ", low);
+   cil_printf("(ioportcon 0x%x ", low);
} else {
-   cil_printf("(ioportcon (%i %i) ", low, high);
+   cil_printf("(ioportcon (0x%x 0x%x) ", low, high);
}
 
context_to_cil(pdb, >context[0]);
@@ -2878,9 +2879,9 @@ static int ocontext_xen_iomem_to_cil(struct policydb 
*pdb, struct ocontext *iome
high = iomem->u.iomem.high_iomem;
 
if (low == high) {
-   cil_printf("(iomemcon %#lX ", (unsigned long)low);
+   cil_printf("(iomemcon 0x%"PRIx64" ", low);
} else {
-   cil_printf("(iomemcon (%#lX %#lX) ", (unsigned 
long)low, (unsigned long)high);
+   cil_printf("(iomemcon (0x%"PRIx64" 0x%"PRIx64") ", low, 
high);
}
 
context_to_cil(pdb, >context[0]);
@@ -2896,7 +2897,7 @@ static int ocontext_xen_pcidevice_to_cil(struct policydb 
*pdb, struct ocontext *
struct ocontext *pcid;
 
for (pcid = pcids; pcid != NULL; pcid = pcid->next) {
-   cil_printf("(pcidevicecon %#lx ", (unsigned 
long)pcid->u.device);
+   cil_printf("(pcidevicecon 0x%lx ", (unsigned 
long)pcid->u.device);
context_to_cil(pdb, >context[0]);
cil_printf(")\n");
}
-- 
2.7.4

___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


[PATCH 1/3] libsepol/cil: Allow hexadecimal numbers in Xen context rules

2017-03-20 Thread James Carter
Allow the use of hexadecimal numbers in iomemcon, ioportcon, and
pcidevicecon statements. The use of hexadecimal numbers is often
the natural choice for these rules.

A zero base is now passed to strtol() and strtoull() which will
assume base 16 if the string has a prefix of "0x", base 8 if the
string starts with "0", and base 10 otherwise.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 libsepol/cil/src/cil_build_ast.c | 30 +++---
 libsepol/cil/src/cil_build_ast.h |  4 ++--
 2 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
index d3d663b..442f100 100644
--- a/libsepol/cil/src/cil_build_ast.c
+++ b/libsepol/cil/src/cil_build_ast.c
@@ -4228,12 +4228,12 @@ int cil_gen_portcon(struct cil_db *db, struct 
cil_tree_node *parse_current, stru
if (parse_current->next->next->cl_head != NULL) {
if (parse_current->next->next->cl_head->next != NULL
&& parse_current->next->next->cl_head->next->next == NULL) {
-   rc = 
cil_fill_integer(parse_current->next->next->cl_head, >port_low);
+   rc = 
cil_fill_integer(parse_current->next->next->cl_head, >port_low, 10);
if (rc != SEPOL_OK) {
cil_log(CIL_ERR, "Improper port specified\n");
goto exit;
}
-   rc = 
cil_fill_integer(parse_current->next->next->cl_head->next, >port_high);
+   rc = 
cil_fill_integer(parse_current->next->next->cl_head->next, >port_high, 
10);
if (rc != SEPOL_OK) {
cil_log(CIL_ERR, "Improper port specified\n");
goto exit;
@@ -4244,7 +4244,7 @@ int cil_gen_portcon(struct cil_db *db, struct 
cil_tree_node *parse_current, stru
goto exit;
}
} else {
-   rc = cil_fill_integer(parse_current->next->next, 
>port_low);
+   rc = cil_fill_integer(parse_current->next->next, 
>port_low, 10);
if (rc != SEPOL_OK) {
cil_log(CIL_ERR, "Improper port specified\n");
goto exit;
@@ -4538,7 +4538,7 @@ int cil_gen_pirqcon(struct cil_db *db, struct 
cil_tree_node *parse_current, stru
 
cil_pirqcon_init();
 
-   rc = cil_fill_integer(parse_current->next, >pirq);
+   rc = cil_fill_integer(parse_current->next, >pirq, 10);
if (rc != SEPOL_OK) {
goto exit;
}
@@ -4604,12 +4604,12 @@ int cil_gen_iomemcon(struct cil_db *db, struct 
cil_tree_node *parse_current, str
if (parse_current->next->cl_head != NULL) {
if (parse_current->next->cl_head->next != NULL &&
parse_current->next->cl_head->next->next == NULL) {
-   rc = cil_fill_integer64(parse_current->next->cl_head, 
>iomem_low);
+   rc = cil_fill_integer64(parse_current->next->cl_head, 
>iomem_low, 0);
if (rc != SEPOL_OK) {
cil_log(CIL_ERR, "Improper iomem specified\n");
goto exit;
}
-   rc = 
cil_fill_integer64(parse_current->next->cl_head->next, >iomem_high);
+   rc = 
cil_fill_integer64(parse_current->next->cl_head->next, >iomem_high, 
0);
if (rc != SEPOL_OK) {
cil_log(CIL_ERR, "Improper iomem specified\n");
goto exit;
@@ -4620,7 +4620,7 @@ int cil_gen_iomemcon(struct cil_db *db, struct 
cil_tree_node *parse_current, str
goto exit;
}
} else {
-   rc = cil_fill_integer64(parse_current->next, 
>iomem_low);;
+   rc = cil_fill_integer64(parse_current->next, 
>iomem_low, 0);
if (rc != SEPOL_OK) {
cil_log(CIL_ERR, "Improper iomem specified\n");
goto exit;
@@ -4689,12 +4689,12 @@ int cil_gen_ioportcon(struct cil_db *db, struct 
cil_tree_node *parse_current, st
if (parse_current->next->cl_head != NULL) {
if (parse_current->next->cl_head->next != NULL &&
parse_current->next->cl_head->next->next == NULL) {
-   rc = cil_fill_integer(parse_current->next->cl_head, 
>ioport_low);
+   rc = cil_fill_integer(parse_current->next->cl_head, 
>ioport_low, 10);

[PATCH 3/3] libsepol/cil: Use hexadecimal numbers when writing Xen rules

2017-03-20 Thread James Carter
When writing a policy.conf file from CIL source, use hexadecimal
numbers in ioportcon, iomemcon, and pcidevicecon rules.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 libsepol/cil/src/cil_policy.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/libsepol/cil/src/cil_policy.c b/libsepol/cil/src/cil_policy.c
index 2e6814a..77179e6 100644
--- a/libsepol/cil/src/cil_policy.c
+++ b/libsepol/cil/src/cil_policy.c
@@ -1831,7 +1831,11 @@ static void cil_iomemcons_to_policy(FILE *out, struct 
cil_sort *iomemcons, int m
 
for (i = 0; icount; i++) {
iomemcon = iomemcons->array[i];
-   fprintf(out, "iomemcon %" PRIu64 "-%" PRIu64 " ", 
iomemcon->iomem_low, iomemcon->iomem_high);
+   if (iomemcon->iomem_low == iomemcon->iomem_high) {
+   fprintf(out, "iomemcon %"PRIx64" ", 
iomemcon->iomem_low);
+   } else {
+   fprintf(out, "iomemcon %"PRIx64"-%"PRIx64" ", 
iomemcon->iomem_low, iomemcon->iomem_high);
+   }
cil_context_to_policy(out, iomemcon->context, mls);
fprintf(out, ";\n");
}
@@ -1844,7 +1848,7 @@ static void cil_ioportcons_to_policy(FILE *out, struct 
cil_sort *ioportcons, int
 
for (i = 0; i < ioportcons->count; i++) {
ioportcon = ioportcons->array[i];
-   fprintf(out, "ioportcon %d-%d ", ioportcon->ioport_low, 
ioportcon->ioport_high);
+   fprintf(out, "ioportcon 0x%x-0x%x ", ioportcon->ioport_low, 
ioportcon->ioport_high);
cil_context_to_policy(out, ioportcon->context, mls);
fprintf(out, ";\n");
}
@@ -1857,7 +1861,7 @@ static void cil_pcidevicecons_to_policy(FILE *out, struct 
cil_sort *pcidevicecon
 
for (i = 0; i < pcidevicecons->count; i++) {
pcidevicecon = pcidevicecons->array[i];
-   fprintf(out, "pcidevicecon %d ", pcidevicecon->dev);
+   fprintf(out, "pcidevicecon 0x%x ", pcidevicecon->dev);
cil_context_to_policy(out, pcidevicecon->context, mls);
fprintf(out, ";\n");
}
-- 
2.7.4

___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


[PATCH] checkpolicy: Fix minor memory leak in checkpolicy

2017-03-20 Thread James Carter
sepol_set_sidtab() is called without calling sepol_sidtab_destroy().
This is not a big deal, since checkpolicy does not run for long, but
it does add noise when checking for other, more important, leaks.

Call sepol_sidtab_destroy() before exiting if not in debug mode.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 checkpolicy/checkpolicy.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/checkpolicy/checkpolicy.c b/checkpolicy/checkpolicy.c
index 442e7db..534fc22 100644
--- a/checkpolicy/checkpolicy.c
+++ b/checkpolicy/checkpolicy.c
@@ -673,6 +673,7 @@ int main(int argc, char **argv)
 
if (!debug) {
policydb_destroy();
+   sepol_sidtab_destroy();
exit(0);
}
 
-- 
2.7.4

___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: [PATCH 0/3] libsepol and checkpolicy: Output CIL or policy.conf from kernel policy

2017-03-13 Thread James Carter

On 03/11/2017 03:02 PM, Nicolas Iooss wrote:

On Fri, Mar 10, 2017 at 8:49 PM, James Carter <jwca...@tycho.nsa.gov> wrote:

It would sometimes be helpful for debugging or verification purposes to be able 
to convert
a binary policy to a human-readable form.

This patchset adds libsepol functions that take a kernel policydb in and 
outputs either
a CIL or policy.conf text.

Checkpolicy is modified to generate CIL text from a binary policy if using the 
"-C" option
and to add the "-F" option to generate policy.conf text from a binary policy.

Where possible rules are sorted in alphabetical or numerical order to aid in 
debugging.

James Carter (3):
  libsepol: Add ability to convert binary policy to CIL
  libsepol: Add ability to convert binary policy to policy.conf file
  checkpolicy: Add options to convert binary policy to CIL or a
policy.conf


Hello,
I agree such features are useful when analyzing policies. I have
tested the patches and compiled with some warnings flags (I have not
done a "real" code review). Here are some comments:

- First, the documentation (at least checkpolicy manpage) needs to be
updated with the new options. Also I spent some time trying to
understand what I was doing wrong with options -C and -F until I read
the third patch and understood that "-b" needs to be used as well.

- Then, when using "checkpolicy -bF" on my policy, I got blocks such as:

if ((git_cgi_enable_homedirs && use_samba_home_dirs)) {
allow httpd_git_script_t cifs_t:dir { getattr search open };
allow httpd_git_script_t cifs_t:dir { ioctl read getattr lock
search open };
allow httpd_git_script_t cifs_t:dir { ioctl read getattr lock
search open };
allow httpd_git_script_t cifs_t:file { ioctl read getattr lock open };
allow httpd_git_script_t cifs_t:filesystem { getattr };
} else {dontaudit httpd_git_script_t cifs_t:file { ioctl
read getattr lock open };
}

The blocks have indentation issues (the first line of the if statement
has too much spaces and a "\n" is missing at the beginning of the else
block. Moreover the permissions are not sorted in alphabetical order
but this may be included in the "Where possible" part of your message.

- Third, the first patch introduces functions with printf-like
arguments and defines them with __attribute__((format(printf...))) in
the .c file. This is fine for the static functions but the other ones
need to have attributes in kernel_to_common.h instead (this enables
the compiler to check the format strings at build time when compiling
other files).

- Finally when compiling with -Wwrite-strings, gcc reports some issues
with literal strings assigned to non-const char* variables. I have
quickly written a short patch to make some variables const char* and
checkpolicy seems to work fine with it. The patch is attached to this
email if you want to consider it.



Thanks for testing it out. I agree with all of your comments and suggestions 
above. Thanks for the patch as well.


Jim


Cheers,
Nicolas




--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: [PATCH 3/3] checkpolicy: Add options to convert binary policy to CIL or a policy.conf

2017-03-13 Thread James Carter

On 03/10/2017 04:04 PM, Stephen Smalley wrote:

On Fri, 2017-03-10 at 14:49 -0500, James Carter wrote:

Use the same option "-C" used to ouput CIL from a policy.conf, but
now
generate CIL from a binary policy instead of giving an error.

Use the option "-F" to generate a policy.conf file from a binary
policy.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 checkpolicy/checkpolicy.c | 60 +--

 1 file changed, 42 insertions(+), 18 deletions(-)

diff --git a/checkpolicy/checkpolicy.c b/checkpolicy/checkpolicy.c
index b98bfcd..9694f57 100644
--- a/checkpolicy/checkpolicy.c
+++ b/checkpolicy/checkpolicy.c
@@ -75,6 +75,8 @@
 #include 

 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -105,7 +107,7 @@ unsigned int policyvers = POLICYDB_VERSION_MAX;
 static __attribute__((__noreturn__)) void usage(const char
*progname)
 {
printf
-   ("usage:  %s [-b] [-C] [-d] [-U handle_unknown
(allow,deny,reject)] [-M]"
+   ("usage:  %s [-b] [-C] [-F] [-d] [-U handle_unknown
(allow,deny,reject)] [-M]"
 "[-c policyvers (%d-%d)] [-o output_file] [-t
target_platform (selinux,xen)]"
 "[input_file]\n",
 progname, POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX);
@@ -388,7 +390,7 @@ int main(int argc, char **argv)
size_t scontext_len, pathlen;
unsigned int i;
unsigned int protocol, port;
-   unsigned int binary = 0, debug = 0, cil = 0;
+   unsigned int binary = 0, debug = 0, cil = 0, conf = 0;
struct val_to_name v;
int ret, ch, fd, target = SEPOL_TARGET_SELINUX;
unsigned int nel, uret;
@@ -411,11 +413,12 @@ int main(int argc, char **argv)
{"handle-unknown", required_argument, NULL, 'U'},
{"mls", no_argument, NULL, 'M'},
{"cil", no_argument, NULL, 'C'},
+   {"conf",no_argument, NULL, 'F'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0}
};

-   while ((ch = getopt_long(argc, argv, "o:t:dbU:MCVc:h",
long_options, NULL)) != -1) {
+   while ((ch = getopt_long(argc, argv, "o:t:dbU:MCFVc:h",
long_options, NULL)) != -1) {
switch (ch) {
case 'o':
outfile = optarg;
@@ -461,6 +464,9 @@ int main(int argc, char **argv)
case 'C':
cil = 1;
break;
+   case 'F':
+   conf = 1;
+   break;
case 'c':{
long int n;
errno = 0;
@@ -510,12 +516,17 @@ int main(int argc, char **argv)
sepol_set_policydb();
sepol_set_sidtab();

+   if (cil && conf) {
+   fprintf(stderr, "Can't convert to CIL and
policy.conf at the same time\n");
+   exit(1);
+   }
+
if (binary) {
-   if (cil) {
-   fprintf(stderr, "%s:  Converting
kernel policy to CIL is not supported\n",
-   argv[0]);
-   exit(1);
-   }
+   /* if (cil) { */
+   /*  fprintf(stderr, "%s:  Converting
kernel policy to CIL is not supported\n", */
+   /*  argv[0]); */
+   /*  exit(1); */
+   /* } */


Just remove?


Yes, I forgot to remove that. Thanks.




fd = open(file, O_RDONLY);
if (fd < 0) {
fprintf(stderr, "Can't open '%s':  %s\n",
@@ -568,6 +579,10 @@ int main(int argc, char **argv)
}
}
} else {
+   if (conf) {
+   fprintf(stderr, "Can only generate
policy.conf from binary policy\n");
+   exit(1);
+   }
if (policydb_init(_policy))
exit(1);
/* We build this as a base policy first since that
is all the parser understands */
@@ -621,15 +636,20 @@ int main(int argc, char **argv)
policydb.policyvers = policyvers;

if (!cil) {
-   printf
-   ("%s:  writing binary representation
(version %d) to %s\n",
-argv[0], policyvers, outfile);
-   policydb.policy_type = POLICY_KERN;
-
-   policy_file_init();
-   pf.type = PF_USE_STDIO;
-   pf.fp = outfp;
-   ret = policydb_write(, );
+   if (!conf) {
+   printf("%s:  writing binary
representation (version %d) to %s\n

[PATCH 1/3] libsepol: Add ability to convert binary policy to CIL

2017-03-10 Thread James Carter
It would sometimes be helpful for debugging or verification purposes
to be able to convert a binary policy to a human-readable form.

Create new function, sepol_kernel_policydb_to_cil(), that takes a
policydb created from a binary policy and writes CIL policy to the
provided FILE pointer.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 libsepol/include/sepol/kernel_to_cil.h |5 +
 libsepol/src/kernel_to_cil.c   | 3149 
 libsepol/src/kernel_to_common.c|  681 +++
 libsepol/src/kernel_to_common.h|  110 ++
 libsepol/src/libsepol.map.in   |1 +
 5 files changed, 3946 insertions(+)
 create mode 100644 libsepol/include/sepol/kernel_to_cil.h
 create mode 100644 libsepol/src/kernel_to_cil.c
 create mode 100644 libsepol/src/kernel_to_common.c
 create mode 100644 libsepol/src/kernel_to_common.h

diff --git a/libsepol/include/sepol/kernel_to_cil.h 
b/libsepol/include/sepol/kernel_to_cil.h
new file mode 100644
index 000..60346ad
--- /dev/null
+++ b/libsepol/include/sepol/kernel_to_cil.h
@@ -0,0 +1,5 @@
+#include 
+
+#include 
+
+int sepol_kernel_policydb_to_cil(FILE *fp, struct policydb *pdb);
diff --git a/libsepol/src/kernel_to_cil.c b/libsepol/src/kernel_to_cil.c
new file mode 100644
index 000..143f7fa
--- /dev/null
+++ b/libsepol/src/kernel_to_cil.c
@@ -0,0 +1,3149 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#ifndef IPPROTO_DCCP
+#define IPPROTO_DCCP 33
+#endif
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "kernel_to_common.h"
+
+
+static char *cond_expr_to_str(struct policydb *pdb, struct cond_expr *expr)
+{
+   struct cond_expr *curr;
+   struct strs *stack;
+   char *new_val;
+   char *str = NULL;
+   int rc;
+
+   rc = stack_init();
+   if (rc != 0) {
+   goto exit;
+   }
+
+   for (curr = expr; curr != NULL; curr = curr->next) {
+   if (curr->expr_type == COND_BOOL) {
+   char *val1 = pdb->p_bool_val_to_name[curr->bool - 1];
+   new_val = create_str("%s", 1, val1);
+   } else {
+   const char *op;
+   uint32_t num_params;
+   char *val1 = NULL;
+   char *val2 = NULL;
+
+   switch(curr->expr_type) {
+   case COND_NOT:  op = "not"; num_params = 1; break;
+   case COND_OR:   op = "or";  num_params = 2; break;
+   case COND_AND:  op = "and"; num_params = 2; break;
+   case COND_XOR:  op = "xor"; num_params = 2; break;
+   case COND_EQ:   op = "eq";  num_params = 2; break;
+   case COND_NEQ:  op = "neq"; num_params = 2; break;
+   default:
+   sepol_log_err("Unknown conditional operator: 
%i",
+ curr->expr_type);
+   goto exit;
+   }
+
+   if (num_params == 2) {
+   val2 = stack_pop(stack);
+   if (!val2) {
+   sepol_log_err("Invalid conditional 
expression");
+   goto exit;
+   }
+   }
+   val1 = stack_pop(stack);
+   if (!val1) {
+   sepol_log_err("Invalid conditional expression");
+   free(val2);
+   goto exit;
+   }
+   if (num_params == 2) {
+   new_val = create_str("(%s %s %s)", 3, op, val1, 
val2);
+   free(val2);
+   } else {
+   new_val = create_str("(%s %s)", 2, op, val1);
+   }
+   free(val1);
+   }
+   if (!new_val) {
+   sepol_log_err("Invalid conditional expression");
+   goto exit;
+   }
+   rc = stack_push(stack, new_val);
+   if (rc != 0) {
+   sepol_log_err("Out of memory");
+   goto exit;
+   }
+   }
+
+   new_val = stack_pop(stack);
+   if (!new_val || !stack_empty(stack)) {
+   sepol_log_err("Invalid conditional expression");
+   goto exit;
+   }
+
+   str = new_val;
+
+   stack_destroy();
+   return str;
+
+exit:
+   while ((new_val = stac

[PATCH 2/3] libsepol: Add ability to convert binary policy to policy.conf file

2017-03-10 Thread James Carter
It would sometimes be helpful for debugging or verification purposes
to be able to convert a binary policy to a human-readable form.

Create new function, sepol_kernel_policydb_to_conf(), that takes a
policydb created from a binary policy and writes a policy.conf file
to the provided FILE pointer.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 libsepol/include/sepol/kernel_to_conf.h |5 +
 libsepol/src/kernel_to_conf.c   | 3014 +++
 libsepol/src/libsepol.map.in|1 +
 3 files changed, 3020 insertions(+)
 create mode 100644 libsepol/include/sepol/kernel_to_conf.h
 create mode 100644 libsepol/src/kernel_to_conf.c

diff --git a/libsepol/include/sepol/kernel_to_conf.h 
b/libsepol/include/sepol/kernel_to_conf.h
new file mode 100644
index 000..2313f38
--- /dev/null
+++ b/libsepol/include/sepol/kernel_to_conf.h
@@ -0,0 +1,5 @@
+#include 
+
+#include 
+
+int sepol_kernel_policydb_to_conf(FILE *fp, struct policydb *pdb);
diff --git a/libsepol/src/kernel_to_conf.c b/libsepol/src/kernel_to_conf.c
new file mode 100644
index 000..5e5a864
--- /dev/null
+++ b/libsepol/src/kernel_to_conf.c
@@ -0,0 +1,3014 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#ifndef IPPROTO_DCCP
+#define IPPROTO_DCCP 33
+#endif
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "kernel_to_common.h"
+
+
+static char *cond_expr_to_str(struct policydb *pdb, struct cond_expr *expr)
+{
+   struct cond_expr *curr;
+   struct strs *stack;
+   char *new_val;
+   char *str = NULL;
+   int rc;
+
+   rc = stack_init();
+   if (rc != 0) {
+   goto exit;
+   }
+
+   for (curr = expr; curr != NULL; curr = curr->next) {
+   if (curr->expr_type == COND_BOOL) {
+   char *val1 = pdb->p_bool_val_to_name[curr->bool - 1];
+   new_val = create_str("%s", 1, val1);
+   } else {
+   const char *op;
+   uint32_t num_params;
+   char *val1 = NULL;
+   char *val2 = NULL;
+
+   switch(curr->expr_type) {
+   case COND_NOT:  op = "!";  num_params = 1; break;
+   case COND_OR:   op = "||"; num_params = 2; break;
+   case COND_AND:  op = "&&"; num_params = 2; break;
+   case COND_XOR:  op = "^";  num_params = 2; break;
+   case COND_EQ:   op = "=="; num_params = 2; break;
+   case COND_NEQ:  op = "!="; num_params = 2; break;
+   default:
+   sepol_log_err("Unknown conditional operator: 
%i", curr->expr_type);
+   goto exit;
+   }
+
+   if (num_params == 2) {
+   val2 = stack_pop(stack);
+   if (!val2) {
+   sepol_log_err("Invalid conditional 
expression");
+   goto exit;
+   }
+   }
+   val1 = stack_pop(stack);
+   if (!val1) {
+   sepol_log_err("Invalid conditional expression");
+   free(val2);
+   goto exit;
+   }
+   if (num_params == 2) {
+   new_val = create_str("(%s %s %s)", 3, val1, op, 
val2);
+   free(val2);
+   } else {
+   new_val = create_str("%s %s", 2, op, val1);
+   }
+   free(val1);
+   }
+   if (!new_val) {
+   sepol_log_err("Invalid conditional expression");
+   goto exit;
+   }
+   rc = stack_push(stack, new_val);
+   if (rc != 0) {
+   sepol_log_err("Out of memory");
+   goto exit;
+   }
+   }
+
+   new_val = stack_pop(stack);
+   if (!new_val || !stack_empty(stack)) {
+   sepol_log_err("Invalid conditional expression");
+   goto exit;
+   }
+
+   str = new_val;
+
+   stack_destroy();
+   return str;
+
+exit:
+   while ((new_val = stack_pop(stack)) != NULL) {
+   free(new_val);
+   }
+   stack_destroy();
+
+   return NULL;
+}
+
+static char *constraint_expr_to_str(struct policydb *pdb, struct 
constraint_expr *expr, int *use_mls)
+{
+   struct constraint_

[PATCH 0/3] libsepol and checkpolicy: Output CIL or policy.conf from kernel policy

2017-03-10 Thread James Carter
It would sometimes be helpful for debugging or verification purposes to be able 
to convert
a binary policy to a human-readable form.

This patchset adds libsepol functions that take a kernel policydb in and 
outputs either
a CIL or policy.conf text.

Checkpolicy is modified to generate CIL text from a binary policy if using the 
"-C" option
and to add the "-F" option to generate policy.conf text from a binary policy.

Where possible rules are sorted in alphabetical or numerical order to aid in 
debugging.

James Carter (3):
  libsepol: Add ability to convert binary policy to CIL
  libsepol: Add ability to convert binary policy to policy.conf file
  checkpolicy: Add options to convert binary policy to CIL or a
policy.conf

 checkpolicy/checkpolicy.c   |   60 +-
 libsepol/include/sepol/kernel_to_cil.h  |5 +
 libsepol/include/sepol/kernel_to_conf.h |5 +
 libsepol/src/kernel_to_cil.c| 3149 +++
 libsepol/src/kernel_to_common.c |  681 +++
 libsepol/src/kernel_to_common.h |  110 ++
 libsepol/src/kernel_to_conf.c   | 3014 +
 libsepol/src/libsepol.map.in|2 +
 8 files changed, 7008 insertions(+), 18 deletions(-)
 create mode 100644 libsepol/include/sepol/kernel_to_cil.h
 create mode 100644 libsepol/include/sepol/kernel_to_conf.h
 create mode 100644 libsepol/src/kernel_to_cil.c
 create mode 100644 libsepol/src/kernel_to_common.c
 create mode 100644 libsepol/src/kernel_to_common.h
 create mode 100644 libsepol/src/kernel_to_conf.c

-- 
2.7.4

___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


[PATCH 3/3] checkpolicy: Add options to convert binary policy to CIL or a policy.conf

2017-03-10 Thread James Carter
Use the same option "-C" used to ouput CIL from a policy.conf, but now
generate CIL from a binary policy instead of giving an error.

Use the option "-F" to generate a policy.conf file from a binary policy.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 checkpolicy/checkpolicy.c | 60 +--
 1 file changed, 42 insertions(+), 18 deletions(-)

diff --git a/checkpolicy/checkpolicy.c b/checkpolicy/checkpolicy.c
index b98bfcd..9694f57 100644
--- a/checkpolicy/checkpolicy.c
+++ b/checkpolicy/checkpolicy.c
@@ -75,6 +75,8 @@
 #include 
 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -105,7 +107,7 @@ unsigned int policyvers = POLICYDB_VERSION_MAX;
 static __attribute__((__noreturn__)) void usage(const char *progname)
 {
printf
-   ("usage:  %s [-b] [-C] [-d] [-U handle_unknown (allow,deny,reject)] 
[-M]"
+   ("usage:  %s [-b] [-C] [-F] [-d] [-U handle_unknown 
(allow,deny,reject)] [-M]"
 "[-c policyvers (%d-%d)] [-o output_file] [-t target_platform 
(selinux,xen)]"
 "[input_file]\n",
 progname, POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX);
@@ -388,7 +390,7 @@ int main(int argc, char **argv)
size_t scontext_len, pathlen;
unsigned int i;
unsigned int protocol, port;
-   unsigned int binary = 0, debug = 0, cil = 0;
+   unsigned int binary = 0, debug = 0, cil = 0, conf = 0;
struct val_to_name v;
int ret, ch, fd, target = SEPOL_TARGET_SELINUX;
unsigned int nel, uret;
@@ -411,11 +413,12 @@ int main(int argc, char **argv)
{"handle-unknown", required_argument, NULL, 'U'},
{"mls", no_argument, NULL, 'M'},
{"cil", no_argument, NULL, 'C'},
+   {"conf",no_argument, NULL, 'F'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0}
};
 
-   while ((ch = getopt_long(argc, argv, "o:t:dbU:MCVc:h", long_options, 
NULL)) != -1) {
+   while ((ch = getopt_long(argc, argv, "o:t:dbU:MCFVc:h", long_options, 
NULL)) != -1) {
switch (ch) {
case 'o':
outfile = optarg;
@@ -461,6 +464,9 @@ int main(int argc, char **argv)
case 'C':
cil = 1;
break;
+   case 'F':
+   conf = 1;
+   break;
case 'c':{
long int n;
errno = 0;
@@ -510,12 +516,17 @@ int main(int argc, char **argv)
sepol_set_policydb();
sepol_set_sidtab();
 
+   if (cil && conf) {
+   fprintf(stderr, "Can't convert to CIL and policy.conf at the 
same time\n");
+   exit(1);
+   }
+
if (binary) {
-   if (cil) {
-   fprintf(stderr, "%s:  Converting kernel policy to CIL 
is not supported\n",
-   argv[0]);
-   exit(1);
-   }
+   /* if (cil) { */
+   /*  fprintf(stderr, "%s:  Converting kernel policy to CIL 
is not supported\n", */
+   /*  argv[0]); */
+   /*  exit(1); */
+   /* } */
fd = open(file, O_RDONLY);
if (fd < 0) {
fprintf(stderr, "Can't open '%s':  %s\n",
@@ -568,6 +579,10 @@ int main(int argc, char **argv)
}
}
} else {
+   if (conf) {
+   fprintf(stderr, "Can only generate policy.conf from 
binary policy\n");
+   exit(1);
+   }
if (policydb_init(_policy))
exit(1);
/* We build this as a base policy first since that is all the 
parser understands */
@@ -621,15 +636,20 @@ int main(int argc, char **argv)
policydb.policyvers = policyvers;
 
if (!cil) {
-   printf
-   ("%s:  writing binary representation (version 
%d) to %s\n",
-argv[0], policyvers, outfile);
-   policydb.policy_type = POLICY_KERN;
-
-   policy_file_init();
-   pf.type = PF_USE_STDIO;
-   pf.fp = outfp;
-   ret = policydb_write(, );
+   if (!conf) {
+   printf("%s:  writing binary representation 
(version %d) to %s\n", argv[0], policyvers, outfile);
+
+   policydb.policy_type = POLICY_KERN;
+
+ 

Re: [PATCH 1/6] restorecond: add noreturn attribute to exitApp()

2017-03-07 Thread James Carter

On 03/05/2017 12:13 PM, Nicolas Iooss wrote:

This makes it possible for static analyzers such as clang's one to
understand that strings_list_add() cannot dereference a NULL pointer in
the following code:

if (!newptr)
exitApp("Out of Memory");
newptr->string = strdup(string);

Signed-off-by: Nicolas Iooss <nicolas.io...@m4x.org>


I applied these six patches.

Thanks,
Jim


---
 restorecond/restorecond.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/restorecond/restorecond.h b/restorecond/restorecond.h
index a6be584c84a5..db7e50f72d2d 100644
--- a/restorecond/restorecond.h
+++ b/restorecond/restorecond.h
@@ -33,7 +33,7 @@ extern int run_as_user;
 extern int start(void);
 extern int server(int, const char *watch_file);

-extern void exitApp(const char *msg);
+extern void exitApp(const char *msg) __attribute__((__noreturn__));
 extern void read_config(int fd,const char *watch_file);

 extern int watch(int fd, const char *watch_file);




--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: [PATCH 1/6] semodule_package: do not leak memory when using -u or -s

2017-03-01 Thread James Carter

On 02/27/2017 03:39 PM, Nicolas Iooss wrote:

When using -u and -s options, semodule_package's main() allocates
user_extra and seusers to hold the argument values. These allocated
memory blocks are not freed when main() exits, which leads gcc's Address
Sanitizer to report a memory leak. This occurs for example when building
refpolicy base.pp module.

Signed-off-by: Nicolas Iooss <nicolas.io...@m4x.org>


I applied all six of these patches.

Thanks,
Jim


---
 semodule-utils/semodule_package/semodule_package.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/semodule-utils/semodule_package/semodule_package.c 
b/semodule-utils/semodule_package/semodule_package.c
index e472054826a3..a25daf59f9e7 100644
--- a/semodule-utils/semodule_package/semodule_package.c
+++ b/semodule-utils/semodule_package/semodule_package.c
@@ -257,5 +257,7 @@ int main(int argc, char **argv)
free(file_contexts);
free(outfile);
free(module);
+   free(seusers);
+   free(user_extra);
exit(0);
 }




--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: Support for multiple types in typeattribute

2017-02-24 Thread James Carter

On 02/24/2017 01:00 PM, Dominick Grift wrote:

On 02/24/2017 06:39 PM, Alex Klyubin wrote:

Hi,

typeattribute currently accepts only a single type as its first argument.
It associates the provided type with the attribute provided as the second
argument. Is there a reason why typeattribute doesn't support multiple
types specified as the first argument? The idea being that it would
associate each of those types with the attribute.

For example, the first argument to typeattribute could use the same syntax
as used for the first argument of allow and neverallow. typeattribute could
then expand this set of types, attributes, and exclusions into the set of
matching types and then associate each of the types with the provided
attribute.



There is no reason (that I know of) why it couldn't be changed to work the way 
you suggest other than someone having the time and desire to make the change. I 
honestly don't know if it would be difficult to make the change or not. It 
doesn't seem like it would, but ...



The reason I'm asking is because in Android SELinux policy we're bumping
against the need to associate attribute A with the set of types which are
grouped using attribute G. We could add a typeattribute for each type
associated with G, but that (1) duplicates the grouping which is already
expressed via G, and (2) makes it very cumbersome/brittle to keep both A
and G associated with exactly the same set of types. In particular, because
Android SELinux policy source tree is distributed between a large number of
Android devices and organizations, requiring that any time you associate a
type with G you must also associate it with A is suboptimal, not to mention
that making such a change in the existing policies requires to change each
policy.



This is why, as Dominck mentions below, that CIL allows you to use an expression 
that can include types and attributes to associate types to an attribute.


In November I added the ability to create a policy.conf from the CIL AST with 
the libsepol function cil_write_policy_conf() or from CIL policy using the 
program secil2conf. Those might be useful to you.


Jim


To make life more interesting, there's also a need to associate A with a
subset of G, for example, G minus some type or two.



CIL is a bit more flexible. You can associate type attributes with type
attributes and do things like:

(typeattributeset
not_dyntransition_subj_type_or_unconfined_subj_type_attribute
(not
(
dyntransition_subj_type_attribute
unconfined_subj_type_attribute
)
)
)

and:

(typeattributeset except_obj_type_attribute
(and
(
obj_type_attribute
)
(not
(
auth_obj_type_attribute
exception_obj_type_attribute
sec_obj_type_attribute
)
)
)
)




Kind Regards,
Alex



___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.






___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.




--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: [PATCH] sepolgen: strip non-printable characters when parsing audit messages

2017-02-21 Thread James Carter

On 02/21/2017 09:41 AM, Vit Mojzis wrote:

Strip the following characters
\x1cFile Separator
\x1dGroup Separator
\x1eRecord Separator
\x85Next Line (C1 Control Code)
from audit message fields to make sure they are not evaluated
as part of some identifier (eg. ausearch used insert \x1d into
--raw output resulting in "unrecognized class" error messages).

This is done as part of str.split() in python3.

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1406328


Applied.

Thanks,
Jim


---
 python/sepolgen/src/sepolgen/audit.py | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/python/sepolgen/src/sepolgen/audit.py 
b/python/sepolgen/src/sepolgen/audit.py
index 724d3ea..26ce6c9 100644
--- a/python/sepolgen/src/sepolgen/audit.py
+++ b/python/sepolgen/src/sepolgen/audit.py
@@ -376,7 +376,9 @@ class AuditParser:
 #   AuditMessage (or subclass) - object representing a parsed
 #  and valid audit message.
 def __parse_line(self, line):
-rec = line.split()
+# strip("\x1c\x1d\x1e\x85") is only needed for python2
+# since str.split() in python3 already does this
+rec = [x.strip("\x1c\x1d\x1e\x85") for x in line.split()]
 for i in rec:
 found = False
 if i == "avc:" or i == "message=avc:" or i == "msg='avc:":




--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: [PATCH 1/1] libselinux, libsemanage: make PYPREFIX computation more robust

2017-02-21 Thread James Carter

On 02/19/2017 04:53 PM, Nicolas Iooss wrote:

On systems where $PYTHON is python3.5 (instead of python2 or python3),
pkg-config fails to find the Python package because it is named with a
dash (e.g. python-3.5).

Moreover the build system may have been using the pkg-config
configuration files for the wrong Python version when several Python
with the same major version number are installed (e.g. using python-3.5
on a system with both python-3.4 and python-3.5 and where
/usr/lib/pkgconfig/python3.pc is a symlink to python-3.5.pc).

In order to fix these two issues, compute $PYPREFIX from $PYTHON by
using the full major.minor version.

Moreover update Travis-Ci configuration to grab the relevant
configuration files for pkg-config from /opt/python (for example
/opt/python/3.5.2/lib/pkgconfig/python-3.5.pc) instead of using
system-provided files (/usr/lib/x86_64-linux-gnu/pkgconfig/python3.pc
and /usr/lib/x86_64-linux-gnu/pkgconfig/python2.pc).

Signed-off-by: Nicolas Iooss <nicolas.io...@m4x.org>


Applied.

Thanks,
Jim


---
 .travis.yml  | 3 ++-
 libselinux/src/Makefile  | 2 +-
 libsemanage/src/Makefile | 2 +-
 3 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 6dce35165bd3..7d7424459344 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -76,7 +76,8 @@ before_script:
   # Configure the variables for Python parts
   - export VIRTUAL_ENV="$HOME/virtualenv/$PYVER"
   - export PYTHON="$VIRTUAL_ENV/bin/python"
-  - export PYPREFIX="$($PYTHON -c 'import sys;print("python%d" % 
sys.version_info[0])')"
+  # Use the header files in /opt/python/... for Python because the virtualenvs 
do not provide Python.h
+  - export PKG_CONFIG_PATH="/opt/python/$($PYTHON -c 'import sys;print("%d.%d.%d" % 
sys.version_info[:3])')/lib/pkgconfig"
   # PyPy does not provide a config file for pkg-config nor a pypy-c.so
   - if echo "$PYVER" | grep -q pypy ; then export PYINC=-I$($PYTHON -c 'import 
sys;print(sys.prefix)')/include PYLIBS= ; fi
   # Python virtualenvs do not support "import site; 
print(site.getsitepackages()[0]"
diff --git a/libselinux/src/Makefile b/libselinux/src/Makefile
index 5640a57d2768..a277b8715819 100644
--- a/libselinux/src/Makefile
+++ b/libselinux/src/Makefile
@@ -2,7 +2,7 @@
 # runtimes (e.g. Python 2 vs Python 3) by optionally prefixing the build
 # targets with "PYPREFIX":
 PYTHON ?= python
-PYPREFIX ?= $(notdir $(PYTHON))
+PYPREFIX ?= $(shell $(PYTHON) -c 'import sys;print("python-%d.%d" % 
sys.version_info[:2])')
 RUBY ?= ruby
 RUBYPREFIX ?= $(notdir $(RUBY))
 PKG_CONFIG ?= pkg-config
diff --git a/libsemanage/src/Makefile b/libsemanage/src/Makefile
index 92c829be234d..77f6efc86d2d 100644
--- a/libsemanage/src/Makefile
+++ b/libsemanage/src/Makefile
@@ -2,7 +2,7 @@
 # runtimes (e.g. Python 2 vs Python 3) by optionally prefixing the build
 # targets with "PYPREFIX":
 PYTHON ?= python
-PYPREFIX ?= $(notdir $(PYTHON))
+PYPREFIX ?= $(shell $(PYTHON) -c 'import sys;print("python-%d.%d" % 
sys.version_info[:2])')
 RUBY ?= ruby
 RUBYPREFIX ?= $(notdir $(RUBY))
 PKG_CONFIG ?= pkg-config




--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: [PATCH 2/5] libsepol/cil: destroy bitmap when __cil_permx_str_to_int() fails

2017-02-21 Thread James Carter

On 02/19/2017 05:30 AM, Nicolas Iooss wrote:

When __cil_permx_to_bitmap() calls __cil_permx_str_to_int() on an
invalid number, local variablt "bitmap" is left initialized when the
function returns and its memory is leaked.

This memory leak has been found by running clang's Address Sanitizer on
a set of policies generated by American Fuzzy Lop.

Signed-off-by: Nicolas Iooss <nicolas.io...@m4x.org>


For this one I decided to move the ebitmap_init() call to right before the 
ebitmap_set_bit() call. This seemed to fit the style of the other functions in 
cil_post.c a bit better.


I applied the other four patches.

Thanks,
Jim


---
 libsepol/cil/src/cil_post.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c
index 687962eae5ee..2de55b562b8f 100644
--- a/libsepol/cil/src/cil_post.c
+++ b/libsepol/cil/src/cil_post.c
@@ -806,13 +806,13 @@ static int __cil_permx_to_bitmap(struct cil_symtab_datum 
*datum, ebitmap_t *bitm

if (ebitmap_set_bit(bitmap, (unsigned int)val, 1)) {
cil_log(CIL_ERR, "Failed to set permissionx bit\n");
-   ebitmap_destroy(bitmap);
goto exit;
}

return SEPOL_OK;

 exit:
+   ebitmap_destroy(bitmap);
return rc;
 }





--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: [PATCH] libsepol/cil: Destroy cil_tree_node stacks when finished resolving AST

2017-02-17 Thread James Carter

On 02/08/2017 11:17 AM, James Carter wrote:

CIL uses separate cil_tree_node stacks for optionals and blocks to
check for statements not allowed in optionals or blocks and to know
which optional to disable when necessary. But these stacks were not
being destroyed when exiting cil_resolve_ast(). This is not a problem
normally because the stacks will be empty, but this is not the case
when exiting with an error.

Destroy both tree node stacks when exiting to ensure that they are
empty.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>


This has been applied.


---
 libsepol/cil/src/cil_resolve_ast.c | 24 
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/libsepol/cil/src/cil_resolve_ast.c 
b/libsepol/cil/src/cil_resolve_ast.c
index 7fe4a74..6628dc4 100644
--- a/libsepol/cil/src/cil_resolve_ast.c
+++ b/libsepol/cil/src/cil_resolve_ast.c
@@ -3778,6 +3778,16 @@ exit:
return rc;
 }

+static void cil_destroy_tree_node_stack(struct cil_tree_node *curr)
+{
+   struct cil_tree_node *next;
+   while (curr != NULL) {
+   next = curr->cl_head;
+   free(curr);
+   curr = next;
+   }
+}
+
 int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
 {
int rc = SEPOL_ERR;
@@ -3904,16 +3914,12 @@ int cil_resolve_ast(struct cil_db *db, struct 
cil_tree_node *current)
/* reset the arguments */
changed = 0;
while (extra_args.optstack != NULL) {
-   struct cil_tree_node *curr = extra_args.optstack;
-   struct cil_tree_node *next = curr->cl_head;
-   free(curr);
-   extra_args.optstack = next;
+   cil_destroy_tree_node_stack(extra_args.optstack);
+   extra_args.optstack = NULL;
}
while (extra_args.blockstack!= NULL) {
-   struct cil_tree_node *curr = extra_args.blockstack;
-   struct cil_tree_node *next = curr->cl_head;
-   free(curr);
-   extra_args.blockstack= next;
+   cil_destroy_tree_node_stack(extra_args.blockstack);
+   extra_args.blockstack = NULL;
}
}

@@ -3924,6 +3930,8 @@ int cil_resolve_ast(struct cil_db *db, struct 
cil_tree_node *current)

rc = SEPOL_OK;
 exit:
+   cil_destroy_tree_node_stack(extra_args.optstack);
+   cil_destroy_tree_node_stack(extra_args.blockstack);
__cil_ordered_lists_destroy(_args.sidorder_lists);
__cil_ordered_lists_destroy(_args.classorder_lists);
__cil_ordered_lists_destroy(_args.catorder_lists);




--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


[PATCH] libsepol/cil: Destroy cil_tree_node stacks when finished resolving AST

2017-02-08 Thread James Carter
CIL uses separate cil_tree_node stacks for optionals and blocks to
check for statements not allowed in optionals or blocks and to know
which optional to disable when necessary. But these stacks were not
being destroyed when exiting cil_resolve_ast(). This is not a problem
normally because the stacks will be empty, but this is not the case
when exiting with an error.

Destroy both tree node stacks when exiting to ensure that they are
empty.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 libsepol/cil/src/cil_resolve_ast.c | 24 
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/libsepol/cil/src/cil_resolve_ast.c 
b/libsepol/cil/src/cil_resolve_ast.c
index 7fe4a74..6628dc4 100644
--- a/libsepol/cil/src/cil_resolve_ast.c
+++ b/libsepol/cil/src/cil_resolve_ast.c
@@ -3778,6 +3778,16 @@ exit:
return rc;
 }
 
+static void cil_destroy_tree_node_stack(struct cil_tree_node *curr)
+{
+   struct cil_tree_node *next;
+   while (curr != NULL) {
+   next = curr->cl_head;
+   free(curr);
+   curr = next;
+   }
+}
+
 int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
 {
int rc = SEPOL_ERR;
@@ -3904,16 +3914,12 @@ int cil_resolve_ast(struct cil_db *db, struct 
cil_tree_node *current)
/* reset the arguments */
changed = 0;
while (extra_args.optstack != NULL) {
-   struct cil_tree_node *curr = extra_args.optstack;
-   struct cil_tree_node *next = curr->cl_head;
-   free(curr);
-   extra_args.optstack = next;
+   cil_destroy_tree_node_stack(extra_args.optstack);
+   extra_args.optstack = NULL;
}
while (extra_args.blockstack!= NULL) {
-   struct cil_tree_node *curr = extra_args.blockstack;
-   struct cil_tree_node *next = curr->cl_head;
-   free(curr);
-   extra_args.blockstack= next;
+   cil_destroy_tree_node_stack(extra_args.blockstack);
+   extra_args.blockstack = NULL;
}
}
 
@@ -3924,6 +3930,8 @@ int cil_resolve_ast(struct cil_db *db, struct 
cil_tree_node *current)
 
rc = SEPOL_OK;
 exit:
+   cil_destroy_tree_node_stack(extra_args.optstack);
+   cil_destroy_tree_node_stack(extra_args.blockstack);
__cil_ordered_lists_destroy(_args.sidorder_lists);
__cil_ordered_lists_destroy(_args.classorder_lists);
__cil_ordered_lists_destroy(_args.catorder_lists);
-- 
2.7.4

___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: [PATCH 1/1] libsepol/cil: fix type confusion in cil_copy_ast

2017-02-08 Thread James Carter

On 02/05/2017 09:14 AM, Nicolas Iooss wrote:

When running secilc on the following CIL file, the program tries to free
the data associated with type X using cil_destroy_typeattribute():

(macro sys_obj_type ((user ARG1)) (typeattribute X))

(block B
(type X)
(call sys_obj_type (Y))
)

By adding some printf statements to cil_typeattribute_init(),
cil_type_init() and cil_destroy_typeattribute(), the error message I get
when using gcc's address sanitizer is:

$ secilc -o /dev/null -f /dev/null test.cil -vv
creating TYPE 0x6040dfd0
Parsing 2017-02-02_crashing_nulptrderef_cil.cil
Building AST from Parse Tree
creating TYPEATTR 0x6060e420
creating TYPE 0x6040df50
Destroying Parse Tree
Resolving AST
Failed to resolve call statement at 2017-02-02_crashing_nulptrderef_cil.cil:5
Problem at 2017-02-02_crashing_nulptrderef_cil.cil:5
Pass 8 of resolution failed
Failed to resolve ast
Failed to compile cildb: -2
Destroying TYPEATTR 0x6060e420, types (nil) name X
Destroying TYPEATTR 0x6040df50, types 0xbebebebe name X
ASAN:DEADLYSIGNAL
=
==30684==ERROR: AddressSanitizer: SEGV on unknown address
0x (pc 0x7fc0539d114a bp 0x7ffc1fbcb300 sp
0x7ffc1fbcb2f0 T0)
#0 0x7fc0539d1149 in ebitmap_destroy 
/usr/src/selinux/libsepol/src/ebitmap.c:356
#1 0x7fc053b96201 in cil_destroy_typeattribute 
../cil/src/cil_build_ast.c:2370
#2 0x7fc053b42ea4 in cil_destroy_data ../cil/src/cil.c:616
#3 0x7fc053c595bf in cil_tree_node_destroy ../cil/src/cil_tree.c:235
#4 0x7fc053c59819 in cil_tree_children_destroy ../cil/src/cil_tree.c:201
#5 0x7fc053c59958 in cil_tree_subtree_destroy ../cil/src/cil_tree.c:172
#6 0x7fc053c59a27 in cil_tree_destroy ../cil/src/cil_tree.c:165
#7 0x7fc053b44fd7 in cil_db_destroy ../cil/src/cil.c:299
#8 0x4026a1 in main /usr/src/selinux/secilc/secilc.c:335
#9 0x7fc0535e5290 in __libc_start_main (/usr/lib/libc.so.6+0x20290)
#10 0x403af9 in _start (/usr/src/selinux/DESTDIR/usr/bin/secilc+0x403af9)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /usr/src/selinux/libsepol/src/ebitmap.c:356 in 
ebitmap_destroy
==30684==ABORTING

When copying the AST tree in cil_resolve_call1(),
__cil_copy_node_helper() calls cil_copy_typeattribute() to grab type X
in the symbol table of block B, and creates a node with the data of X
but with CIL_TYPEATTRIBUTE flavor.

This example is a "type confusion" bug between cil_type and
cil_typeattribute structures. It can be generalized to any couple of
structures sharing the same symbol table (an easy way of finding other
couples is by reading the code of cil_flavor_to_symtab_index()).

Fix this issue in a "generic" way in __cil_copy_node_helper(), by
verifying that the flavor of the found data is the same as expected and
triggering an error when it is not.

Signed-off-by: Nicolas Iooss <nicolas.io...@m4x.org>


Applied with one addition. I added the line "new->flavor = FLAVOR(data);" to 
make sure the data flavor matches. I don't think that that is needed because 
cil_destroy_data() will not be called on the new node (since a previous node 
exists), but I would rather be safe and have the flavor match.


Thanks,
Jim


---
 libsepol/cil/src/cil_copy_ast.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/libsepol/cil/src/cil_copy_ast.c b/libsepol/cil/src/cil_copy_ast.c
index 5debd0d5359c..17a8c991c66d 100644
--- a/libsepol/cil/src/cil_copy_ast.c
+++ b/libsepol/cil/src/cil_copy_ast.c
@@ -1987,6 +1987,13 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, 
__attribute__((unused)) u
new->data = data;

if (orig->flavor >= CIL_MIN_DECLARATIVE) {
+   /* Check the flavor of data if was found in the 
destination symtab */
+   if (DATUM(data)->nodes->head && FLAVOR(data) != 
orig->flavor) {
+   cil_tree_log(orig, CIL_ERR, "Incompatible flavor when 
trying to copy %s", DATUM(data)->name);
+   cil_tree_log(NODE(data), CIL_ERR, "Note: conflicting 
declaration");
+   rc = SEPOL_ERR;
+   goto exit;
+   }
rc = cil_symtab_insert(symtab, ((struct 
cil_symtab_datum*)orig->data)->name, ((struct cil_symtab_datum*)data), new);

namespace = new;




--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: [PATCH 1/1] Introduce Travis-CI tests

2017-02-08 Thread James Carter
-d -1 "$HOME/.rvm/rubies/ruby-$RUBYLIBVER"*/bin/ruby | head 
-n 1)"
+
+  # Set the linker in $CC so that it gets used everywhere
+  - if [ -n "$LINKER" ]; then CC="$CC -fuse-ld=$LINKER" ; fi
+
+  # Show variables and versions (to help debugging)
+  - echo "$CC" ; $CC --version
+  - echo "$PYTHON" ; $PYTHON --version
+  - echo "$RUBY" ; $RUBY --version
+
+script:
+  # Start by installing everything into $DESTDIR
+  - make install -k
+  - make install-pywrap -k
+  - make install-rubywrap -k
+
+  # Now that everything is installed, run "make all" to build everything which 
may have not been built
+  - make all -k
+
+  # Set up environment variables for the tests
+  - export CFLAGS="-I$DESTDIR/usr/include"
+  - export LD_LIBRARY_PATH="$DESTDIR/usr/lib:$DESTDIR/lib"
+  - export 
PATH="$DESTDIR/usr/sbin:$DESTDIR/usr/bin:$DESTDIR/sbin:$DESTDIR/bin:$PATH"
+  - export PYTHONPATH="$PYSITEDIR"
+  - export RUBYLIB="$DESTDIR/$($RUBY -e 'puts 
RbConfig::CONFIG["vendorlibdir"]'):$DESTDIR/$($RUBY -e 'puts 
RbConfig::CONFIG["vendorarchdir"]')"
+
+  # Show variables (to help debugging issues)
+  - echo "$CFLAGS"
+  - echo "$LD_LIBRARY_PATH"
+  - echo "$PATH"
+  - echo "$PYTHONPATH"
+  - echo "$RUBYLIB"
+
+  # Run tests
+  - make test
+
+  # Test Python and Ruby wrappers
+  - $PYTHON -c 'import selinux;import selinux.audit2why;import 
semanage;print(selinux.is_selinux_enabled())'
+  - $RUBY -e 'require "selinux";require "semanage";puts 
Selinux::is_selinux_enabled()'
+
+  # Remove every installed files
+  - rm -rf "$DESTDIR"
+
+  # Test that "git status" looks clean, or print a clear error message
+  - |-
+git status --short | sed -n 's/^??/error: missing .gitignore entry for/p' 
| (! grep '^')
+
+  # Clean up everything and show which file would be added to "make clean"
+  - make clean distclean
+  - |-
+git ls-files --ignored --others --exclude-standard | sed 's/^/error: "make 
clean distclean" did not remove /' | (! grep '^')
+
+# Do not spam by email so long as the build succeeds
+notifications:
+  email:
+on_success: never




--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: [PATCH 1/8] libsepol: fix -Wwrite-strings warnings

2017-02-06 Thread James Carter
rule)

 static void cil_type_rule_to_policy(FILE *out, struct cil_type_rule *rule)
 {
-   char *kind;
+   const char *kind;
struct cil_symtab_datum *src, *tgt, *res;
struct cil_list *class_list;
struct cil_list_item *i1;
diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c
index 2acb600dddae..8c4fff9c3d9f 100644
--- a/libsepol/src/module_to_cil.c
+++ b/libsepol/src/module_to_cil.c
@@ -775,7 +775,7 @@ static int cil_print_attr_strs(int indent, struct policydb 
*pdb, int is_type, st
int rc = 0;
struct ebitmap_node *node;
unsigned int i;
-   char *statement;
+   const char *statement;
int has_positive = pos && (ebitmap_cardinality(pos) > 0);
int has_negative = neg && (ebitmap_cardinality(neg) > 0);
char **val_to_name;




--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: [PATCH 3/8] policycoreutils/semodule: hide -Wwrite-strings warnings

2017-02-06 Thread James Carter

On 02/05/2017 10:58 AM, Nicolas Iooss wrote:

When building with "clang -Wwrite-strings", the compiler complains about
initializing a char* array (variable genhomedirconargv) with literal
strings (which are in read-only memory).

However the programs needs to use a non-const char* array in order to
fake arguments of getopt_long() (called by parse_command_line()). Silent
the compiler warnings by introducing casts to char*.

Signed-off-by: Nicolas Iooss <nicolas.io...@m4x.org>
---
 policycoreutils/semodule/semodule.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/policycoreutils/semodule/semodule.c 
b/policycoreutils/semodule/semodule.c
index ce048bc061b9..36686d0230a8 100644
--- a/policycoreutils/semodule/semodule.c
+++ b/policycoreutils/semodule/semodule.c
@@ -341,7 +341,7 @@ int main(int argc, char *argv[])
int i, commit = 0;
int result;
int status = EXIT_FAILURE;
-   char *genhomedirconargv[] = { "genhomedircon", "-B", "-n" };
+   char *genhomedirconargv[] = { (char *)"genhomedircon", (char *)"-B", (char 
*)"-n" };
create_signal_handlers();
if (strcmp(basename(argv[0]), "genhomedircon") == 0) {
argc = 3;



I think that I would prefer the following for this one:

diff --git a/policycoreutils/semodule/semodule.c 
b/policycoreutils/semodule/semodule.c

index ce048bc..c63a864 100644
--- a/policycoreutils/semodule/semodule.c
+++ b/policycoreutils/semodule/semodule.c
@@ -341,11 +341,11 @@ int main(int argc, char *argv[])
int i, commit = 0;
int result;
int status = EXIT_FAILURE;
-   char *genhomedirconargv[] = { "genhomedircon", "-B", "-n" };
+   const char *genhomedirconargv[] = { "genhomedircon", "-B", "-n" };
create_signal_handlers();
if (strcmp(basename(argv[0]), "genhomedircon") == 0) {
argc = 3;
-   argv=genhomedirconargv;
+   argv = (char **)genhomedirconargv;
}
parse_command_line(argc, argv);


--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: [PATCH 0/5] checkpolicy: Cleanup declare and require functions

2017-02-03 Thread James Carter

On 01/31/2017 02:41 PM, James Carter wrote:

Cleanup declare and require functions in module_compiler.c to improve
maintainability and clarity. Functionality is not changed.

James Carter (5):
  checkpolicy: Create common function for type declares and requires
  checkpolicy: Create common function for role declares and requires
  checkpolicy: Create common function for user declares and requires
  checkpolicy: Cleanup error messages
  checkpolicy: Move common require and declare code into new function

 checkpolicy/module_compiler.c | 892 +++---
 1 file changed, 395 insertions(+), 497 deletions(-)



Merged this series with the one change of making all the create_*() functions 
static.


--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: [PATCH 0/5] checkpolicy: Cleanup declare and require functions

2017-02-03 Thread James Carter

On 02/02/2017 06:19 PM, Nicolas Iooss wrote:

On Tue, Jan 31, 2017 at 8:41 PM, James Carter <jwca...@tycho.nsa.gov
<mailto:jwca...@tycho.nsa.gov>> wrote:

Cleanup declare and require functions in module_compiler.c to improve
maintainability and clarity. Functionality is not changed.

James Carter (5):
  checkpolicy: Create common function for type declares and requires
  checkpolicy: Create common function for role declares and requires
  checkpolicy: Create common function for user declares and requires
  checkpolicy: Cleanup error messages
  checkpolicy: Move common require and declare code into new function

 checkpolicy/module_compiler.c | 892 
+++---
 1 file changed, 395 insertions(+), 497 deletions(-)


Thanks for your patches. I have tested the 8 patches you sent and everything
seems fine: the issue I reported is fixed, there is no new memory leak, and the
code looks right when I read it. I am only wondering why the new functions
create_type(), create_role(), create_user() and print_error_msg() are not 
static.



They should be static; I will make them static when I commit the patches. Thanks 
for testing them.



By the way I have been working on integrating this project with Travis-CI for a
few months and now I have a stable working configuration file. I used it to
build-test this patchset with several compilers/linkers. The (successful)
results are available
on https://travis-ci.org/fishilico/selinux/builds/197478803 and the commit which
introduced .travis.yml file is the last one
on https://github.com/fishilico/selinux/commits/2017-01-31_James_Carter_patches
. Would there be an interest to have the Travis-CI configuration file in the
project?


I don't have much experience with Travis-CI and will have to look it over. 
Thanks for the suggestion.


Jim



Cheers,
Nicolas



--
James Carter <jwca...@tycho.nsa.gov>
National Security Agency
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


[PATCH 2/2] checkpolicy: Remove uneeded return check in require_symbol()

2017-01-31 Thread James Carter
Since symtab_insert() no longer returns -2 in the case of a
declaration of an identifier followed by a require of the same
symbol, remove the uneeded check.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 checkpolicy/module_compiler.c | 20 ++--
 1 file changed, 6 insertions(+), 14 deletions(-)

diff --git a/checkpolicy/module_compiler.c b/checkpolicy/module_compiler.c
index 95e29be..a5be276 100644
--- a/checkpolicy/module_compiler.c
+++ b/checkpolicy/module_compiler.c
@@ -719,23 +719,15 @@ int require_symbol(uint32_t symbol_type,
avrule_decl_t *decl = stack_top->decl;
int ret = create_symbol(symbol_type, key, datum, dest_value, SCOPE_REQ);
 
-   if (ret == 0 || ret == 1) {
-   if (ebitmap_set_bit(decl->required.scope + symbol_type,
-   *datum_value - 1, 1)) {
-   return -3;
-   }
-   } else if (ret == -2) {
-   /* ignore require statements if that symbol was
-* previously declared and is in current scope */
-   if (is_id_in_scope(symbol_type, key)) {
-   ret = 1;
-   } else {
-   return -2;
-   }
-   } else if (ret < 0) {
+   if (ret < 0) {
return ret;
}
 
+   if (ebitmap_set_bit(decl->required.scope + symbol_type,
+   *datum_value - 1, 1)) {
+   return -3;
+   }
+
stack_top->require_given = 1;
return ret;
 }
-- 
2.7.4

___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


[PATCH 1/2] libsepol: Return +1 when declaration is followed by a require

2017-01-31 Thread James Carter
A check is made in symtab_insert() for the case when an identifier
had already been declared and was now being required. This meant
that a declaration followed by a require was treated differently
from a require followed by a declaration.

Remove that check and treat both cases the same (which means
returning +1).

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 libsepol/src/policydb.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
index 5b9b9f0..3cff6d2 100644
--- a/libsepol/src/policydb.c
+++ b/libsepol/src/policydb.c
@@ -1666,9 +1666,6 @@ int symtab_insert(policydb_t * pol, uint32_t sym,
}
} else if (scope_datum->scope == SCOPE_REQ && scope == SCOPE_DECL) {
scope_datum->scope = SCOPE_DECL;
-   } else if (scope_datum->scope != scope) {
-   /* This only happens in DECL then REQUIRE case, which is 
handled by caller */
-   return -2;
}
 
/* search through the pre-existing list to avoid adding duplicates */
-- 
2.7.4

___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


[PATCH 3/5] checkpolicy: Create common function for user declares and requires

2017-01-31 Thread James Carter
Move common code out of declare_user() and require_user() into the
new function create_user().

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 checkpolicy/module_compiler.c | 224 +-
 1 file changed, 114 insertions(+), 110 deletions(-)

diff --git a/checkpolicy/module_compiler.c b/checkpolicy/module_compiler.c
index 891cadf..90e82c2 100644
--- a/checkpolicy/module_compiler.c
+++ b/checkpolicy/module_compiler.c
@@ -456,103 +456,132 @@ static int user_implicit_bounds(hashtab_t users_tab,
return 0;
 }
 
-user_datum_t *declare_user(void)
+int create_user(uint32_t scope, user_datum_t **user, char **key)
 {
-   char *id = queue_remove(id_queue), *dest_id = NULL;
-   user_datum_t *user = NULL, *dest_user = NULL;
-   int retval;
-   uint32_t value = 0;
+   char *id = queue_remove(id_queue);
+   user_datum_t *datum = NULL;
+   int ret;
+   uint32_t value;
+
+   *user = NULL;
+   *key = NULL;
 
if (id == NULL) {
yyerror("no user name");
-   return NULL;
+   return -1;
}
-   if ((user = (user_datum_t *) malloc(sizeof(*user))) == NULL) {
+
+   datum = malloc(sizeof(*datum));
+   if (datum == NULL) {
yyerror("Out of memory!");
free(id);
-   return NULL;
+   return -1;
}
-   user_datum_init(user);
 
-   retval =
-   declare_symbol(SYM_USERS, id, (hashtab_datum_t *) user, ,
-  );
+   user_datum_init(datum);
 
-   if (retval == 0) {
-   user->s.value = value;
-   if ((dest_id = strdup(id)) == NULL) {
+   if (scope == SCOPE_DECL) {
+   ret = declare_symbol(SYM_USERS, id, datum, , );
+   } else {
+   ret = require_symbol(SYM_USERS, id, datum, , );
+   }
+
+   datum->s.value = value;
+
+   if (ret == 0) {
+   *user = datum;
+   *key = strdup(id);
+   if (*key == NULL) {
yyerror("Out of memory!");
-   return NULL;
+   return -1;
}
+   } else if (ret == 1) {
+   *user = datum;
+   *key = id;
} else {
-   /* this user was already declared in this module, or error */
-   dest_id = id;
-   user_datum_destroy(user);
-   free(user);
-   }
-   if (retval == 0 || retval == 1) {
-   /* create a new user_datum_t for this decl, if necessary */
-   hashtab_t users_tab;
-   assert(stack_top->type == 1);
-   if (stack_top->parent == NULL) {
-   /* in parent, so use global symbol table */
-   users_tab = policydbp->p_users.table;
-   } else {
-   users_tab = stack_top->decl->p_users.table;
+   free(id);
+   user_datum_destroy(datum);
+   free(datum);
+
+   switch (ret) {
+   case -3:
+   yyerror("Out of memory!");
+   break;
+   case -2:
+   yyerror("duplicate declaration of user");
+   break;
+   case -1:
+   yyerror("could not declare user here");
+   break;
+   default:
+   abort();/* should never get here */
}
-   dest_user = (user_datum_t *) hashtab_search(users_tab, dest_id);
-   if (dest_user == NULL) {
-   if ((dest_user =
-(user_datum_t *) malloc(sizeof(*dest_user))) ==
-   NULL) {
+   }
+
+   return ret;
+}
+
+user_datum_t *declare_user(void)
+{
+   char *key = NULL;
+   user_datum_t *user = NULL;
+   user_datum_t *dest_user = NULL;
+   hashtab_t users_tab;
+   int ret, ret2;
+
+   ret = create_user(SCOPE_DECL, , );
+   if (ret < 0) {
+   return NULL;
+   }
+
+   /* create a new user_datum_t for this decl, if necessary */
+   assert(stack_top->type == 1);
+
+   if (stack_top->parent == NULL) {
+   /* in parent, so use global symbol table */
+   users_tab = policydbp->p_users.table;
+   } else {
+   users_tab = stack_top->decl->p_users.table;
+   }
+
+   dest_user = hashtab_search(users_tab, key);
+   if (dest_user == NULL) {
+   if (ret == 0) {
+   dest_user = malloc(sizeof(*dest_user));
+   if (dest_user == NULL) {
yyerror("Out of memory!");
- 

[PATCH] checkpolicy: Improve check for identifier flavor mismatch

2017-01-31 Thread James Carter
An identifier flavor mismatch occurs when an identifier is
declared or required as a regular role or type in one place but as
an attribute in another place.

Currently there is only a check for an identifier flavor mismatch
when a type has already been declared and there is a require of
the same type in the same scope. There are no checks if the require
comes first and there are no checks for roles.

Check for an identifier flavor mismatch for both roles and types
whenever a declaration or requirement tries to add an identifier
that is already in the symtab.

Signed-off-by: James Carter <jwca...@tycho.nsa.gov>
---
 checkpolicy/module_compiler.c | 46 +--
 1 file changed, 18 insertions(+), 28 deletions(-)

diff --git a/checkpolicy/module_compiler.c b/checkpolicy/module_compiler.c
index e128a1b..95e29be 100644
--- a/checkpolicy/module_compiler.c
+++ b/checkpolicy/module_compiler.c
@@ -291,6 +291,15 @@ int create_role(uint32_t scope, unsigned char isattr, 
role_datum_t **role, char
return -1;
}
} else if (ret == 1) {
+   *role = hashtab_search(policydbp->symtab[SYM_ROLES].table, id);
+   if (*role && (isattr != (*role)->flavor)) {
+   yyerror2("Identifier %s used as both an attribute and a 
role",
+id);
+   free(id);
+   role_datum_destroy(datum);
+   free(datum);
+   return -1;
+   }
*role = datum;
*key = id;
} else {
@@ -383,6 +392,7 @@ int create_type(uint32_t scope, unsigned char isattr, 
type_datum_t **type)
uint32_t value = 0;
 
*type = NULL;
+   isattr = isattr ? TYPE_ATTRIB : TYPE_TYPE;
 
id = (char *)queue_remove(id_queue);
if (!id) {
@@ -403,7 +413,7 @@ int create_type(uint32_t scope, unsigned char isattr, 
type_datum_t **type)
}
type_datum_init(datum);
datum->primary = 1;
-   datum->flavor = isattr ? TYPE_ATTRIB : TYPE_TYPE;
+   datum->flavor = isattr;
 
if (scope == SCOPE_DECL) {
ret = declare_symbol(SYM_TYPES, id, datum, , );
@@ -418,6 +428,12 @@ int create_type(uint32_t scope, unsigned char isattr, 
type_datum_t **type)
type_datum_destroy(datum);
free(datum);
*type = hashtab_search(policydbp->symtab[SYM_TYPES].table, id);
+   if (*type && (isattr != (*type)->flavor)) {
+   yyerror2("Identifier %s used as both an attribute and a 
type",
+id);
+   free(id);
+   return -1;
+   }
free(id);
} else {
print_error_msg(ret, SYM_TYPES);
@@ -711,35 +727,9 @@ int require_symbol(uint32_t symbol_type,
} else if (ret == -2) {
/* ignore require statements if that symbol was
 * previously declared and is in current scope */
-   int prev_declaration_ok = 0;
if (is_id_in_scope(symbol_type, key)) {
-   if (symbol_type == SYM_TYPES) {
-   /* check that previous symbol has same
-* type/attribute-ness */
-   unsigned char new_isattr =
-   ((type_datum_t *) datum)->flavor;
-   type_datum_t *old_datum =
-   (type_datum_t *) hashtab_search(policydbp->
-   symtab
-   [SYM_TYPES].
-   table, key);
-   assert(old_datum != NULL);
-   unsigned char old_isattr = old_datum->flavor;
-   prev_declaration_ok =
-   (old_isattr == new_isattr ? 1 : 0);
-   } else {
-   prev_declaration_ok = 1;
-   }
-   }
-   if (prev_declaration_ok) {
-   /* ignore this require statement because it
-* was already declared within my scope */
-   stack_top->require_given = 1;
-   return 1;
+   ret = 1;
} else {
-   /* previous declaration was not in scope or
-* had a mismatched type/attribute, so
-* generate an error */
return -2;
}
} else if (ret < 0) {
-- 
2.7.4

___

  1   2   3   >