Home | History | Annotate | Download | only in minijail
      1 /* Copyright 2016 The Chromium OS Authors. All rights reserved.
      2  * Use of this source code is governed by a BSD-style license that can be
      3  * found in the LICENSE file.
      4  */
      5 
      6 #include <getopt.h>
      7 #include <stdio.h>
      8 #include <string.h>
      9 
     10 #include <string>
     11 
     12 #include "bpf.h"
     13 #include "syscall_filter.h"
     14 #include "util.h"
     15 
     16 namespace {
     17 
     18 void DumpBpfProg(struct sock_fprog* fprog) {
     19   struct sock_filter* filter = fprog->filter;
     20   unsigned short len = fprog->len;
     21 
     22   printf("len == %d\n", len);
     23   printf("filter:\n");
     24   for (size_t i = 0; i < len; i++) {
     25     printf("%zu: \t{ code=%#x, jt=%u, jf=%u, k=%#x \t}\n", i, filter[i].code,
     26            filter[i].jt, filter[i].jf, filter[i].k);
     27   }
     28 }
     29 
     30 void Usage(const char* progn, int status) {
     31   // clang-format off
     32   fprintf(status ? stderr : stdout,
     33           "Usage: %s [--dump[=<output.bpf>]] [<policy file>]\n"
     34           "\n"
     35           "With no <policy file>, or when <policy file> is -, reads from standard input.\n"
     36           "\n"
     37           " --dump[=<output>]:  Dump the BPF program into stdout (or <output>,\n"
     38           "      -d[<output>]:  if provided). Useful if you want to inspect it\n"
     39           "                     with libseccomp's scmp_bpf_disasm.\n",
     40           progn);
     41   // clang-format on
     42   exit(status);
     43 }
     44 
     45 }  // namespace
     46 
     47 int main(int argc, char** argv) {
     48   init_logging(LOG_TO_FD, STDERR_FILENO, LOG_INFO);
     49 
     50   const char* optstring = "d:h";
     51   const struct option long_options[] = {
     52       {"help", no_argument, 0, 'h'},
     53       {"dump", optional_argument, 0, 'd'},
     54       {0, 0, 0, 0},
     55   };
     56 
     57   bool dump = false;
     58   std::string dump_path;
     59   int opt;
     60   while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
     61     switch (opt) {
     62       case 'h':
     63         Usage(argv[0], 0);
     64         return 0;
     65       case 'd':
     66         dump = true;
     67         if (optarg)
     68           dump_path = optarg;
     69         break;
     70     }
     71   }
     72 
     73   FILE* f = stdin;
     74   // If there is at least one additional unparsed argument, treat it as the
     75   // policy script.
     76   if (argc > optind && strcmp(argv[optind], "-") != 0)
     77     f = fopen(argv[optind], "re");
     78   if (!f)
     79     pdie("fopen(%s) failed", argv[1]);
     80 
     81   struct sock_fprog fp;
     82   int res = compile_filter(argv[1], f, &fp, 0, 0);
     83   fclose(f);
     84   if (res != 0)
     85     die("compile_filter failed");
     86 
     87   if (dump) {
     88     FILE* out = stdout;
     89     if (!dump_path.empty()) {
     90       out = fopen(dump_path.c_str(), "we");
     91       if (!out)
     92         pdie("fopen(%s) failed", dump_path.c_str());
     93     }
     94     if (fwrite(fp.filter, sizeof(struct sock_filter), fp.len, out) != fp.len)
     95       pdie("fwrite(%s) failed", dump_path.c_str());
     96     fclose(out);
     97   } else {
     98     DumpBpfProg(&fp);
     99   }
    100 
    101   free(fp.filter);
    102   return 0;
    103 }
    104