0001
0002
0003
0004 #define __EXPORTED_HEADERS__
0005
0006 #include <stdio.h>
0007 #include <stdlib.h>
0008 #include <unistd.h>
0009 #include <string.h>
0010 #include <errno.h>
0011 #include <ctype.h>
0012
0013 struct security_class_mapping {
0014 const char *name;
0015 const char *perms[sizeof(unsigned) * 8 + 1];
0016 };
0017
0018 #include "classmap.h"
0019 #include "initial_sid_to_string.h"
0020
0021 const char *progname;
0022
0023 static void usage(void)
0024 {
0025 printf("usage: %s flask.h av_permissions.h\n", progname);
0026 exit(1);
0027 }
0028
0029 static char *stoupperx(const char *s)
0030 {
0031 char *s2 = strdup(s);
0032 char *p;
0033
0034 if (!s2) {
0035 fprintf(stderr, "%s: out of memory\n", progname);
0036 exit(3);
0037 }
0038
0039 for (p = s2; *p; p++)
0040 *p = toupper(*p);
0041 return s2;
0042 }
0043
0044 int main(int argc, char *argv[])
0045 {
0046 int i, j;
0047 int isids_len;
0048 FILE *fout;
0049
0050 progname = argv[0];
0051
0052 if (argc < 3)
0053 usage();
0054
0055 fout = fopen(argv[1], "w");
0056 if (!fout) {
0057 fprintf(stderr, "Could not open %s for writing: %s\n",
0058 argv[1], strerror(errno));
0059 exit(2);
0060 }
0061
0062 fprintf(fout, "/* This file is automatically generated. Do not edit. */\n");
0063 fprintf(fout, "#ifndef _SELINUX_FLASK_H_\n#define _SELINUX_FLASK_H_\n\n");
0064
0065 for (i = 0; secclass_map[i].name; i++) {
0066 char *name = stoupperx(secclass_map[i].name);
0067
0068 fprintf(fout, "#define SECCLASS_%-39s %2d\n", name, i+1);
0069 free(name);
0070 }
0071
0072 fprintf(fout, "\n");
0073
0074 isids_len = sizeof(initial_sid_to_string) / sizeof(char *);
0075 for (i = 1; i < isids_len; i++) {
0076 const char *s = initial_sid_to_string[i];
0077 if (s) {
0078 char *sidname = stoupperx(s);
0079
0080 fprintf(fout, "#define SECINITSID_%-39s %2d\n", sidname, i);
0081 free(sidname);
0082 }
0083 }
0084 fprintf(fout, "\n#define SECINITSID_NUM %d\n", i-1);
0085 fprintf(fout, "\nstatic inline bool security_is_socket_class(u16 kern_tclass)\n");
0086 fprintf(fout, "{\n");
0087 fprintf(fout, "\tbool sock = false;\n\n");
0088 fprintf(fout, "\tswitch (kern_tclass) {\n");
0089 for (i = 0; secclass_map[i].name; i++) {
0090 static char s[] = "SOCKET";
0091 int len, l;
0092 char *name = stoupperx(secclass_map[i].name);
0093
0094 len = strlen(name);
0095 l = sizeof(s) - 1;
0096 if (len >= l && memcmp(name + len - l, s, l) == 0)
0097 fprintf(fout, "\tcase SECCLASS_%s:\n", name);
0098 free(name);
0099 }
0100 fprintf(fout, "\t\tsock = true;\n");
0101 fprintf(fout, "\t\tbreak;\n");
0102 fprintf(fout, "\tdefault:\n");
0103 fprintf(fout, "\t\tbreak;\n");
0104 fprintf(fout, "\t}\n\n");
0105 fprintf(fout, "\treturn sock;\n");
0106 fprintf(fout, "}\n");
0107
0108 fprintf(fout, "\n#endif\n");
0109
0110 if (fclose(fout) != 0) {
0111 fprintf(stderr, "Could not successfully close %s: %s\n",
0112 argv[1], strerror(errno));
0113 exit(4);
0114 }
0115
0116 fout = fopen(argv[2], "w");
0117 if (!fout) {
0118 fprintf(stderr, "Could not open %s for writing: %s\n",
0119 argv[2], strerror(errno));
0120 exit(5);
0121 }
0122
0123 fprintf(fout, "/* This file is automatically generated. Do not edit. */\n");
0124 fprintf(fout, "#ifndef _SELINUX_AV_PERMISSIONS_H_\n#define _SELINUX_AV_PERMISSIONS_H_\n\n");
0125
0126 for (i = 0; secclass_map[i].name; i++) {
0127 const struct security_class_mapping *map = &secclass_map[i];
0128 int len;
0129 char *name = stoupperx(map->name);
0130
0131 len = strlen(name);
0132 for (j = 0; map->perms[j]; j++) {
0133 char *permname;
0134
0135 if (j >= 32) {
0136 fprintf(stderr, "Too many permissions to fit into an access vector at (%s, %s).\n",
0137 map->name, map->perms[j]);
0138 exit(5);
0139 }
0140 permname = stoupperx(map->perms[j]);
0141 fprintf(fout, "#define %s__%-*s 0x%08xU\n", name,
0142 39-len, permname, 1U<<j);
0143 free(permname);
0144 }
0145 free(name);
0146 }
0147
0148 fprintf(fout, "\n#endif\n");
0149
0150 if (fclose(fout) != 0) {
0151 fprintf(stderr, "Could not successfully close %s: %s\n",
0152 argv[2], strerror(errno));
0153 exit(6);
0154 }
0155
0156 exit(0);
0157 }