mirror of
https://github.com/SELinuxProject/selinux
synced 2024-12-24 15:02:44 +00:00
libselinux: Add policy context validation to sefcontext_compile
Add -p option that will take a binary policy file to validate context entries in the text file_contexts file. Should validation fail the binary file will not be written. Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
This commit is contained in:
parent
b6c0a35dc4
commit
50640d313d
@ -1,4 +1,4 @@
|
||||
.TH "sefcontext_compile" "8" "12 Jun 2015" "dwalsh@redhat.com" "SELinux Command Line documentation"
|
||||
.TH "sefcontext_compile" "8" "12 Aug 2015" "dwalsh@redhat.com" "SELinux Command Line documentation"
|
||||
.SH "NAME"
|
||||
sefcontext_compile \- compile file context regular expression files
|
||||
.
|
||||
@ -6,6 +6,8 @@ sefcontext_compile \- compile file context regular expression files
|
||||
.B sefcontext_compile
|
||||
.RB [ \-o
|
||||
.IR outputfile ]
|
||||
.RB [ \-p
|
||||
.IR policyfile ]
|
||||
.I inputfile
|
||||
.
|
||||
.SH "DESCRIPTION"
|
||||
@ -29,7 +31,16 @@ Specify an
|
||||
that must be a fully qualified file name as the
|
||||
.B .bin
|
||||
suffix is not automatically added.
|
||||
.
|
||||
.TP
|
||||
.B \-p
|
||||
Specify a binary
|
||||
.I policyfile
|
||||
that will be used to validate the context entries in the
|
||||
.I inputfile
|
||||
.br
|
||||
If an invalid context is found the pcre formatted file will not be written and
|
||||
an error will be returned.
|
||||
|
||||
.SH "RETURN VALUE"
|
||||
On error -1 is returned. On success 0 is returned.
|
||||
|
||||
|
@ -28,7 +28,7 @@ LDLIBS += -L../src -lselinux -L$(LIBDIR)
|
||||
|
||||
TARGETS=$(patsubst %.c,%,$(wildcard *.c))
|
||||
|
||||
sefcontext_compile: LDLIBS += -lpcre ../src/libselinux.a
|
||||
sefcontext_compile: LDLIBS += -lpcre ../src/libselinux.a -lsepol
|
||||
|
||||
ifeq ($(DISABLE_AVC),y)
|
||||
UNUSED_TARGETS+=compute_av compute_create compute_member compute_relabel
|
||||
|
@ -10,11 +10,22 @@
|
||||
#include <getopt.h>
|
||||
#include <limits.h>
|
||||
#include <selinux/selinux.h>
|
||||
#include <sepol/sepol.h>
|
||||
|
||||
#include "../src/label_file.h"
|
||||
|
||||
static int validate_context(char __attribute__ ((unused)) **ctx)
|
||||
const char *policy_file;
|
||||
static int ctx_err;
|
||||
|
||||
static int validate_context(char **ctxp)
|
||||
{
|
||||
char *ctx = *ctxp;
|
||||
|
||||
if (policy_file && sepol_check_context(ctx) < 0) {
|
||||
ctx_err = -1;
|
||||
return ctx_err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -38,8 +49,15 @@ static int process_file(struct selabel_handle *rec, const char *filename)
|
||||
rc = 0;
|
||||
while (getline(&line_buf, &line_len, context_file) > 0) {
|
||||
rc = process_line(rec, filename, prefix, line_buf, ++line_num);
|
||||
if (rc)
|
||||
if (rc || ctx_err) {
|
||||
/* With -p option need to check and fail if ctx err as
|
||||
* process_line() context validation on Linux does not
|
||||
* return an error, but does print the error line to
|
||||
* stderr. Android will set both to error and print
|
||||
* the error line. */
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
out:
|
||||
free(line_buf);
|
||||
@ -263,13 +281,15 @@ static void free_specs(struct saved_data *data)
|
||||
static void usage(const char *progname)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: %s [-o out_file] fc_file\n"
|
||||
"Where:\n\t"
|
||||
"-o Optional file name of the PCRE formatted binary\n\t"
|
||||
" file to be output. If not specified the default\n\t"
|
||||
" will be fc_file with the .bin suffix appended.\n\t"
|
||||
"fc_file The text based file contexts file to be processed.\n",
|
||||
progname);
|
||||
"usage: %s [-o out_file] [-p policy_file] fc_file\n"
|
||||
"Where:\n\t"
|
||||
"-o Optional file name of the PCRE formatted binary\n\t"
|
||||
" file to be output. If not specified the default\n\t"
|
||||
" will be fc_file with the .bin suffix appended.\n\t"
|
||||
"-p Optional binary policy file that will be used to\n\t"
|
||||
" validate contexts defined in the fc_file.\n\t"
|
||||
"fc_file The text based file contexts file to be processed.\n",
|
||||
progname);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@ -280,6 +300,7 @@ int main(int argc, char *argv[])
|
||||
char stack_path[PATH_MAX + 1];
|
||||
char *tmp = NULL;
|
||||
int fd, rc, opt;
|
||||
FILE *policy_fp = NULL;
|
||||
struct stat buf;
|
||||
struct selabel_handle *rec = NULL;
|
||||
struct saved_data *data = NULL;
|
||||
@ -287,11 +308,14 @@ int main(int argc, char *argv[])
|
||||
if (argc < 2)
|
||||
usage(argv[0]);
|
||||
|
||||
while ((opt = getopt(argc, argv, "o:")) > 0) {
|
||||
while ((opt = getopt(argc, argv, "o:p:")) > 0) {
|
||||
switch (opt) {
|
||||
case 'o':
|
||||
out_file = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
policy_file = optarg;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
}
|
||||
@ -306,10 +330,30 @@ int main(int argc, char *argv[])
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Open binary policy if supplied. */
|
||||
if (policy_file) {
|
||||
policy_fp = fopen(policy_file, "r");
|
||||
|
||||
if (!policy_fp) {
|
||||
fprintf(stderr, "Failed to open policy: %s\n",
|
||||
policy_file);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (sepol_set_policydb_from_file(policy_fp) < 0) {
|
||||
fprintf(stderr, "Failed to load policy: %s\n",
|
||||
policy_file);
|
||||
fclose(policy_fp);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Generate dummy handle for process_line() function */
|
||||
rec = (struct selabel_handle *)calloc(1, sizeof(*rec));
|
||||
if (!rec) {
|
||||
fprintf(stderr, "Failed to calloc handle\n");
|
||||
if (policy_fp)
|
||||
fclose(policy_fp);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
rec->backend = SELABEL_CTX_FILE;
|
||||
@ -318,7 +362,8 @@ int main(int argc, char *argv[])
|
||||
* process_line function, however as the bin file being generated
|
||||
* may not be related to the currently loaded policy (that it
|
||||
* would be validated against), then set callback to ignore any
|
||||
* validation. */
|
||||
* validation - unless the -p option is used in which case if an
|
||||
* error is detected, the process will be aborted. */
|
||||
rec->validating = 1;
|
||||
selinux_set_callback(SELINUX_CB_VALIDATE,
|
||||
(union selinux_callback)&validate_context);
|
||||
@ -327,6 +372,8 @@ int main(int argc, char *argv[])
|
||||
if (!data) {
|
||||
fprintf(stderr, "Failed to calloc saved_data\n");
|
||||
free(rec);
|
||||
if (policy_fp)
|
||||
fclose(policy_fp);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@ -376,6 +423,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
rc = 0;
|
||||
out:
|
||||
if (policy_fp)
|
||||
fclose(policy_fp);
|
||||
|
||||
free_specs(data);
|
||||
free(rec);
|
||||
free(data);
|
||||
|
Loading…
Reference in New Issue
Block a user