checkpolicy: Add support for generating CIL

Add support to checkpolicy and checkmodule for generating CIL as their
output.

Add new options "-C" and "--cil" to specify CIL as the output format.

Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
This commit is contained in:
James Carter 2015-04-01 10:05:04 -04:00
parent 4514332550
commit b1d9456295
4 changed files with 105 additions and 56 deletions

View File

@ -3,7 +3,7 @@
checkmodule \- SELinux policy module compiler checkmodule \- SELinux policy module compiler
.SH SYNOPSIS .SH SYNOPSIS
.B checkmodule .B checkmodule
.I "[\-h] [\-b] [\-m] [\-M] [\-U handle_unknown ] [\-V] [\-o output_file] [input_file]" .I "[\-h] [\-b] [\-C] [\-m] [\-M] [\-U handle_unknown ] [\-V] [\-o output_file] [input_file]"
.SH "DESCRIPTION" .SH "DESCRIPTION"
This manual page describes the This manual page describes the
.BR checkmodule .BR checkmodule
@ -25,6 +25,9 @@ the module package into the module store and load the resulting policy.
Read an existing binary policy module file rather than a source policy Read an existing binary policy module file rather than a source policy
module file. This option is a development/debugging aid. module file. This option is a development/debugging aid.
.TP .TP
.B \-C,\-\-cil
Write CIL policy file rather than binary policy file.
.TP
.B \-h,\-\-help .B \-h,\-\-help
Print usage. Print usage.
.TP .TP

View File

@ -20,6 +20,7 @@
#include <errno.h> #include <errno.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sepol/module_to_cil.h>
#include <sepol/policydb/policydb.h> #include <sepol/policydb/policydb.h>
#include <sepol/policydb/services.h> #include <sepol/policydb/services.h>
#include <sepol/policydb/conditional.h> #include <sepol/policydb/conditional.h>
@ -108,20 +109,9 @@ static int read_binary_policy(policydb_t * p, const char *file, const char *prog
return 0; return 0;
} }
static int write_binary_policy(policydb_t * p, const char *file, char *progname) static int write_binary_policy(policydb_t * p, FILE *outfp)
{ {
FILE *outfp = NULL;
struct policy_file pf; struct policy_file pf;
int ret;
printf("%s: writing binary representation (version %d) to %s\n",
progname, policyvers, file);
outfp = fopen(file, "w");
if (!outfp) {
perror(file);
exit(1);
}
p->policy_type = policy_type; p->policy_type = policy_type;
p->policyvers = policyvers; p->policyvers = policyvers;
@ -130,24 +120,19 @@ static int write_binary_policy(policydb_t * p, const char *file, char *progname)
policy_file_init(&pf); policy_file_init(&pf);
pf.type = PF_USE_STDIO; pf.type = PF_USE_STDIO;
pf.fp = outfp; pf.fp = outfp;
ret = policydb_write(p, &pf); return policydb_write(p, &pf);
if (ret) {
fprintf(stderr, "%s: error writing %s\n", progname, file);
return -1;
}
fclose(outfp);
return 0;
} }
static void usage(char *progname) static void usage(char *progname)
{ {
printf("usage: %s [-h] [-V] [-b] [-U handle_unknown] [-m] [-M] [-o FILE] [INPUT]\n", progname); printf("usage: %s [-h] [-V] [-b] [-C] [-U handle_unknown] [-m] [-M] [-o FILE] [INPUT]\n", progname);
printf("Build base and policy modules.\n"); printf("Build base and policy modules.\n");
printf("Options:\n"); printf("Options:\n");
printf(" INPUT build module from INPUT (else read from \"%s\")\n", printf(" INPUT build module from INPUT (else read from \"%s\")\n",
txtfile); txtfile);
printf(" -V show policy versions created by this program\n"); printf(" -V show policy versions created by this program\n");
printf(" -b treat input as a binary policy file\n"); printf(" -b treat input as a binary policy file\n");
printf(" -C output CIL policy instead of binary policy\n");
printf(" -h print usage\n"); printf(" -h print usage\n");
printf(" -U OPTION How to handle unknown classes and permissions\n"); printf(" -U OPTION How to handle unknown classes and permissions\n");
printf(" deny: Deny unknown kernel checks\n"); printf(" deny: Deny unknown kernel checks\n");
@ -162,7 +147,7 @@ static void usage(char *progname)
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
const char *file = txtfile, *outfile = NULL; const char *file = txtfile, *outfile = NULL;
unsigned int binary = 0; unsigned int binary = 0, cil = 0;
int ch; int ch;
int show_version = 0; int show_version = 0;
policydb_t modpolicydb; policydb_t modpolicydb;
@ -173,10 +158,11 @@ int main(int argc, char **argv)
{"version", no_argument, NULL, 'V'}, {"version", no_argument, NULL, 'V'},
{"handle-unknown", required_argument, NULL, 'U'}, {"handle-unknown", required_argument, NULL, 'U'},
{"mls", no_argument, NULL, 'M'}, {"mls", no_argument, NULL, 'M'},
{"cil", no_argument, NULL, 'C'},
{NULL, 0, NULL, 0} {NULL, 0, NULL, 0}
}; };
while ((ch = getopt_long(argc, argv, "ho:bVU:mM", long_options, NULL)) != -1) { while ((ch = getopt_long(argc, argv, "ho:bVU:mMC", long_options, NULL)) != -1) {
switch (ch) { switch (ch) {
case 'h': case 'h':
usage(argv[0]); usage(argv[0]);
@ -212,6 +198,9 @@ int main(int argc, char **argv)
case 'M': case 'M':
mlspol = 1; mlspol = 1;
break; break;
case 'C':
cil = 1;
break;
default: default:
usage(argv[0]); usage(argv[0]);
} }
@ -269,7 +258,7 @@ int main(int argc, char **argv)
} }
} }
if (modpolicydb.policy_type == POLICY_BASE) { if (modpolicydb.policy_type == POLICY_BASE && !cil) {
/* Verify that we can successfully expand the base module. */ /* Verify that we can successfully expand the base module. */
policydb_t kernpolicydb; policydb_t kernpolicydb;
@ -295,10 +284,37 @@ int main(int argc, char **argv)
printf("%s: policy configuration loaded\n", argv[0]); printf("%s: policy configuration loaded\n", argv[0]);
if (outfile && if (outfile) {
write_binary_policy(&modpolicydb, outfile, argv[0]) == -1) { FILE *outfp = fopen(outfile, "w");
if (!outfp) {
perror(outfile);
exit(1);
}
if (!cil) {
printf("%s: writing binary representation (version %d) to %s\n",
argv[0], policyvers, file);
if (write_binary_policy(&modpolicydb, outfp) != 0) {
fprintf(stderr, "%s: error writing %s\n", argv[0], outfile);
exit(1);
}
} else {
printf("%s: writing CIL to %s\n",argv[0], outfile);
if (sepol_module_policydb_to_cil(outfp, &modpolicydb, 0) != 0) {
fprintf(stderr, "%s: error writing %s\n", argv[0], outfile);
exit(1);
}
}
fclose(outfp);
} else if (cil) {
fprintf(stderr, "%s: No file to write CIL was specified\n", argv[0]);
exit(1); exit(1);
} }
policydb_destroy(&modpolicydb); policydb_destroy(&modpolicydb);
return 0; return 0;

View File

@ -3,7 +3,7 @@
checkpolicy \- SELinux policy compiler checkpolicy \- SELinux policy compiler
.SH SYNOPSIS .SH SYNOPSIS
.B checkpolicy .B checkpolicy
.I "[\-b] [\-d] [\-M] [\-c policyvers] [\-o output_file] [input_file]" .I "[\-b] [\-C] [\-d] [\-M] [\-c policyvers] [\-o output_file] [input_file]"
.br .br
.SH "DESCRIPTION" .SH "DESCRIPTION"
This manual page describes the This manual page describes the
@ -21,6 +21,9 @@ policy.conf or policy, depending on whether the \-b flag is specified.
.B \-b,\-\-binary .B \-b,\-\-binary
Read an existing binary policy file rather than a source policy.conf file. Read an existing binary policy file rather than a source policy.conf file.
.TP .TP
.B \-C,\-\-cil
Write CIL policy file rather than binary policy file.
.TP
.B \-d,\-\-debug .B \-d,\-\-debug
Enter debug mode after loading the policy. Enter debug mode after loading the policy.
.TP .TP

View File

@ -74,6 +74,7 @@
#include <ctype.h> #include <ctype.h>
#endif #endif
#include <sepol/module_to_cil.h>
#include <sepol/policydb/policydb.h> #include <sepol/policydb/policydb.h>
#include <sepol/policydb/services.h> #include <sepol/policydb/services.h>
#include <sepol/policydb/conditional.h> #include <sepol/policydb/conditional.h>
@ -104,7 +105,7 @@ unsigned int policyvers = POLICYDB_VERSION_MAX;
void usage(char *progname) void usage(char *progname)
{ {
printf printf
("usage: %s [-b] [-d] [-U handle_unknown (allow,deny,reject)] [-M]" ("usage: %s [-b] [-C] [-d] [-U handle_unknown (allow,deny,reject)] [-M]"
"[-c policyvers (%d-%d)] [-o output_file] [-t target_platform (selinux,xen)]" "[-c policyvers (%d-%d)] [-o output_file] [-t target_platform (selinux,xen)]"
"[input_file]\n", "[input_file]\n",
progname, POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX); progname, POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX);
@ -376,6 +377,7 @@ static int check_level(hashtab_key_t key, hashtab_datum_t datum, void *arg __att
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
policydb_t parse_policy;
sepol_security_class_t tclass; sepol_security_class_t tclass;
sepol_security_id_t ssid, tsid, *sids, oldsid, newsid, tasksid; sepol_security_id_t ssid, tsid, *sids, oldsid, newsid, tasksid;
sepol_security_context_t scontext; sepol_security_context_t scontext;
@ -386,7 +388,7 @@ int main(int argc, char **argv)
size_t scontext_len, pathlen; size_t scontext_len, pathlen;
unsigned int i; unsigned int i;
unsigned int protocol, port; unsigned int protocol, port;
unsigned int binary = 0, debug = 0; unsigned int binary = 0, debug = 0, cil = 0;
struct val_to_name v; struct val_to_name v;
int ret, ch, fd, target = SEPOL_TARGET_SELINUX; int ret, ch, fd, target = SEPOL_TARGET_SELINUX;
unsigned int nel, uret; unsigned int nel, uret;
@ -408,11 +410,12 @@ int main(int argc, char **argv)
{"version", no_argument, NULL, 'V'}, {"version", no_argument, NULL, 'V'},
{"handle-unknown", required_argument, NULL, 'U'}, {"handle-unknown", required_argument, NULL, 'U'},
{"mls", no_argument, NULL, 'M'}, {"mls", no_argument, NULL, 'M'},
{"cil", no_argument, NULL, 'C'},
{"help", no_argument, NULL, 'h'}, {"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0} {NULL, 0, NULL, 0}
}; };
while ((ch = getopt_long(argc, argv, "o:t:dbU:MVc:h", long_options, NULL)) != -1) { while ((ch = getopt_long(argc, argv, "o:t:dbU:MCVc:h", long_options, NULL)) != -1) {
switch (ch) { switch (ch) {
case 'o': case 'o':
outfile = optarg; outfile = optarg;
@ -455,6 +458,9 @@ int main(int argc, char **argv)
case 'M': case 'M':
mlspol = 1; mlspol = 1;
break; break;
case 'C':
cil = 1;
break;
case 'c':{ case 'c':{
long int n; long int n;
errno = 0; errno = 0;
@ -505,6 +511,11 @@ int main(int argc, char **argv)
sepol_set_sidtab(&sidtab); sepol_set_sidtab(&sidtab);
if (binary) { 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); fd = open(file, O_RDONLY);
if (fd < 0) { if (fd < 0) {
fprintf(stderr, "Can't open '%s': %s\n", fprintf(stderr, "Can't open '%s': %s\n",
@ -557,8 +568,6 @@ int main(int argc, char **argv)
} }
} }
} else { } else {
policydb_t parse_policy;
if (policydb_init(&parse_policy)) if (policydb_init(&parse_policy))
exit(1); exit(1);
/* We build this as a base policy first since that is all the parser understands */ /* We build this as a base policy first since that is all the parser understands */
@ -577,23 +586,24 @@ int main(int argc, char **argv)
if (hashtab_map(policydbp->p_levels.table, check_level, NULL)) if (hashtab_map(policydbp->p_levels.table, check_level, NULL))
exit(1); exit(1);
if (policydb_init(&policydb)) {
fprintf(stderr, "%s: policydb_init failed\n", argv[0]);
exit(1);
}
/* Linking takes care of optional avrule blocks */ /* Linking takes care of optional avrule blocks */
if (link_modules(NULL, &parse_policy, NULL, 0, 0)) { if (link_modules(NULL, policydbp, NULL, 0, 0)) {
fprintf(stderr, "Error while resolving optionals\n"); fprintf(stderr, "Error while resolving optionals\n");
exit(1); exit(1);
} }
if (expand_module(NULL, &parse_policy, &policydb, 0, 1)) { if (!cil) {
fprintf(stderr, "Error while expanding policy\n"); if (policydb_init(&policydb)) {
exit(1); fprintf(stderr, "%s: policydb_init failed\n", argv[0]);
exit(1);
}
if (expand_module(NULL, policydbp, &policydb, 0, 1)) {
fprintf(stderr, "Error while expanding policy\n");
exit(1);
}
policydb_destroy(policydbp);
policydbp = &policydb;
} }
policydb_destroy(&parse_policy);
policydbp = &policydb;
} }
if (policydb_load_isids(&policydb, &sidtab)) if (policydb_load_isids(&policydb, &sidtab))
@ -602,29 +612,46 @@ int main(int argc, char **argv)
printf("%s: policy configuration loaded\n", argv[0]); printf("%s: policy configuration loaded\n", argv[0]);
if (outfile) { if (outfile) {
printf
("%s: writing binary representation (version %d) to %s\n",
argv[0], policyvers, outfile);
outfp = fopen(outfile, "w"); outfp = fopen(outfile, "w");
if (!outfp) { if (!outfp) {
perror(outfile); perror(outfile);
exit(1); exit(1);
} }
policydb.policy_type = POLICY_KERN;
policydb.policyvers = policyvers; policydb.policyvers = policyvers;
policy_file_init(&pf); if (!cil) {
pf.type = PF_USE_STDIO; printf
pf.fp = outfp; ("%s: writing binary representation (version %d) to %s\n",
ret = policydb_write(&policydb, &pf); argv[0], policyvers, outfile);
if (ret) { policydb.policy_type = POLICY_KERN;
fprintf(stderr, "%s: error writing %s\n",
argv[0], outfile); policy_file_init(&pf);
exit(1); pf.type = PF_USE_STDIO;
pf.fp = outfp;
ret = policydb_write(&policydb, &pf);
if (ret) {
fprintf(stderr, "%s: error writing %s\n",
argv[0], outfile);
exit(1);
}
} else {
printf("%s: writing CIL to %s\n",argv[0], outfile);
ret = sepol_module_policydb_to_cil(outfp, policydbp, 1);
if (ret) {
fprintf(stderr, "%s: error writing %s\n", argv[0], outfile);
exit(1);
}
} }
fclose(outfp);
if (outfile) {
fclose(outfp);
}
} else if (cil) {
fprintf(stderr, "%s: No file to write CIL was specified\n", argv[0]);
exit(1);
} }
if (!debug) { if (!debug) {
policydb_destroy(&policydb); policydb_destroy(&policydb);
exit(0); exit(0);