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