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