1 #include <getopt.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <sepol/sepol.h>
5 #include <selinux/selinux.h>
6 #include <selinux/label.h>
7
8 static int nerr;
9
validate(char ** contextp)10 static int validate(char **contextp)
11 {
12 char *context = *contextp;
13 if (sepol_check_context(context) < 0) {
14 nerr++;
15 return -1;
16 }
17 return 0;
18 }
19
usage(char * name)20 static void usage(char *name) {
21 fprintf(stderr, "usage: %s [OPTIONS] sepolicy context_file\n\n", name);
22 fprintf(stderr, "Parses a context file and checks for syntax errors.\n");
23 fprintf(stderr, "The context_file is assumed to be a file_contexts file\n");
24 fprintf(stderr, "unless explicitly switched by an option.\n\n");
25 fprintf(stderr, " OPTIONS:\n");
26 fprintf(stderr, " -p : context file represents a property_context file.\n");
27 fprintf(stderr, "\n");
28 exit(1);
29 }
30
main(int argc,char ** argv)31 int main(int argc, char **argv)
32 {
33 struct selinux_opt opts[] = {
34 { SELABEL_OPT_VALIDATE, (void*)1 },
35 { SELABEL_OPT_PATH, NULL }
36 };
37
38 // Default backend unless changed by input argument.
39 unsigned int backend = SELABEL_CTX_FILE;
40
41 FILE *fp;
42 struct selabel_handle *sehnd;
43 char c;
44
45 while ((c = getopt(argc, argv, "ph")) != -1) {
46 switch (c) {
47 case 'p':
48 backend = SELABEL_CTX_ANDROID_PROP;
49 break;
50 case 'h':
51 default:
52 usage(argv[0]);
53 break;
54 }
55 }
56
57 int index = optind;
58 if (argc - optind != 2) {
59 fprintf(stderr, "Expected sepolicy file and context file as arguments.\n");
60 usage(argv[0]);
61 }
62
63 // remaining args are sepolicy file and context file
64 char *sepolicyFile = argv[index];
65 char *contextFile = argv[index + 1];
66
67 fp = fopen(sepolicyFile, "r");
68 if (!fp) {
69 perror(sepolicyFile);
70 exit(2);
71 }
72 if (sepol_set_policydb_from_file(fp) < 0) {
73 fprintf(stderr, "Error loading policy from %s\n", sepolicyFile);
74 exit(3);
75 }
76
77 selinux_set_callback(SELINUX_CB_VALIDATE,
78 (union selinux_callback)&validate);
79
80 opts[1].value = contextFile;
81
82 sehnd = selabel_open(backend, opts, 2);
83 if (!sehnd) {
84 fprintf(stderr, "Error loading context file from %s\n", contextFile);
85 exit(4);
86 }
87 if (nerr) {
88 fprintf(stderr, "Invalid context file found in %s\n", contextFile);
89 exit(5);
90 }
91
92 exit(0);
93 }
94