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