xref: /openbmc/linux/scripts/selinux/genheaders/genheaders.c (revision 4ed91d48259d9ddd378424d008f2e6559f7e78f8)
1 
2 /* NOTE: we really do want to use the kernel headers here */
3 #define __EXPORTED_HEADERS__
4 
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <unistd.h>
8 #include <string.h>
9 #include <errno.h>
10 #include <ctype.h>
11 
12 struct security_class_mapping {
13 	const char *name;
14 	const char *perms[sizeof(unsigned) * 8 + 1];
15 };
16 
17 #include "classmap.h"
18 #include "initial_sid_to_string.h"
19 
20 #define max(x, y) (((int)(x) > (int)(y)) ? x : y)
21 
22 const char *progname;
23 
24 static void usage(void)
25 {
26 	printf("usage: %s flask.h av_permissions.h\n", progname);
27 	exit(1);
28 }
29 
30 static char *stoupperx(const char *s)
31 {
32 	char *s2 = strdup(s);
33 	char *p;
34 
35 	if (!s2) {
36 		fprintf(stderr, "%s:  out of memory\n", progname);
37 		exit(3);
38 	}
39 
40 	for (p = s2; *p; p++)
41 		*p = toupper(*p);
42 	return s2;
43 }
44 
45 int main(int argc, char *argv[])
46 {
47 	int i, j, k;
48 	int isids_len;
49 	FILE *fout;
50 	const char *needle = "SOCKET";
51 	char *substr;
52 
53 	progname = argv[0];
54 
55 	if (argc < 3)
56 		usage();
57 
58 	fout = fopen(argv[1], "w");
59 	if (!fout) {
60 		fprintf(stderr, "Could not open %s for writing:  %s\n",
61 			argv[1], strerror(errno));
62 		exit(2);
63 	}
64 
65 	for (i = 0; secclass_map[i].name; i++) {
66 		struct security_class_mapping *map = &secclass_map[i];
67 		map->name = stoupperx(map->name);
68 		for (j = 0; map->perms[j]; j++)
69 			map->perms[j] = stoupperx(map->perms[j]);
70 	}
71 
72 	isids_len = sizeof(initial_sid_to_string) / sizeof (char *);
73 	for (i = 1; i < isids_len; i++)
74 		initial_sid_to_string[i] = stoupperx(initial_sid_to_string[i]);
75 
76 	fprintf(fout, "/* This file is automatically generated.  Do not edit. */\n");
77 	fprintf(fout, "#ifndef _SELINUX_FLASK_H_\n#define _SELINUX_FLASK_H_\n\n");
78 
79 	for (i = 0; secclass_map[i].name; i++) {
80 		struct security_class_mapping *map = &secclass_map[i];
81 		fprintf(fout, "#define SECCLASS_%s", map->name);
82 		for (j = 0; j < max(1, 40 - strlen(map->name)); j++)
83 			fprintf(fout, " ");
84 		fprintf(fout, "%2d\n", i+1);
85 	}
86 
87 	fprintf(fout, "\n");
88 
89 	for (i = 1; i < isids_len; i++) {
90 		const char *s = initial_sid_to_string[i];
91 		fprintf(fout, "#define SECINITSID_%s", s);
92 		for (j = 0; j < max(1, 40 - strlen(s)); j++)
93 			fprintf(fout, " ");
94 		fprintf(fout, "%2d\n", i);
95 	}
96 	fprintf(fout, "\n#define SECINITSID_NUM %d\n", i-1);
97 	fprintf(fout, "\nstatic inline bool security_is_socket_class(u16 kern_tclass)\n");
98 	fprintf(fout, "{\n");
99 	fprintf(fout, "\tbool sock = false;\n\n");
100 	fprintf(fout, "\tswitch (kern_tclass) {\n");
101 	for (i = 0; secclass_map[i].name; i++) {
102 		struct security_class_mapping *map = &secclass_map[i];
103 		substr = strstr(map->name, needle);
104 		if (substr && strcmp(substr, needle) == 0)
105 			fprintf(fout, "\tcase SECCLASS_%s:\n", map->name);
106 	}
107 	fprintf(fout, "\t\tsock = true;\n");
108 	fprintf(fout, "\t\tbreak;\n");
109 	fprintf(fout, "\tdefault:\n");
110 	fprintf(fout, "\t\tbreak;\n");
111 	fprintf(fout, "\t}\n\n");
112 	fprintf(fout, "\treturn sock;\n");
113 	fprintf(fout, "}\n");
114 
115 	fprintf(fout, "\n#endif\n");
116 	fclose(fout);
117 
118 	fout = fopen(argv[2], "w");
119 	if (!fout) {
120 		fprintf(stderr, "Could not open %s for writing:  %s\n",
121 			argv[2], strerror(errno));
122 		exit(4);
123 	}
124 
125 	fprintf(fout, "/* This file is automatically generated.  Do not edit. */\n");
126 	fprintf(fout, "#ifndef _SELINUX_AV_PERMISSIONS_H_\n#define _SELINUX_AV_PERMISSIONS_H_\n\n");
127 
128 	for (i = 0; secclass_map[i].name; i++) {
129 		struct security_class_mapping *map = &secclass_map[i];
130 		for (j = 0; map->perms[j]; j++) {
131 			fprintf(fout, "#define %s__%s", map->name,
132 				map->perms[j]);
133 			for (k = 0; k < max(1, 40 - strlen(map->name) - strlen(map->perms[j])); k++)
134 				fprintf(fout, " ");
135 			fprintf(fout, "0x%08xUL\n", (1<<j));
136 		}
137 	}
138 
139 	fprintf(fout, "\n#endif\n");
140 	fclose(fout);
141 	exit(0);
142 }
143