blob: 38fcbee10154ac26d0b7928eb91be3733a5aba11 [file] [log] [blame]
Mike Frysinger50e31fa2018-01-19 18:59:49 -05001/* 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 */
Jorge Lucangeli Obesf16d6d12016-09-29 20:25:27 -04005
Luis Hector Chavezcb4ae322018-07-13 06:28:10 -07006#include <getopt.h>
Jorge Lucangeli Obesf16d6d12016-09-29 20:25:27 -04007#include <stdio.h>
Luis Hector Chavezdacb7052018-07-21 22:45:38 -07008#include <string.h>
Jorge Lucangeli Obesf16d6d12016-09-29 20:25:27 -04009
Luis Hector Chavezcb4ae322018-07-13 06:28:10 -070010#include <string>
11
Jorge Lucangeli Obesf16d6d12016-09-29 20:25:27 -040012#include "bpf.h"
13#include "syscall_filter.h"
14#include "util.h"
15
Luis Hector Chavezcb4ae322018-07-13 06:28:10 -070016namespace {
Luis Hector Chavez114a9302017-09-05 20:36:58 -070017
Luis Hector Chavezcb4ae322018-07-13 06:28:10 -070018void DumpBpfProg(struct sock_fprog* fprog) {
19 struct sock_filter* filter = fprog->filter;
20 unsigned short len = fprog->len;
Jorge Lucangeli Obesf16d6d12016-09-29 20:25:27 -040021
Luis Hector Chavezcb4ae322018-07-13 06:28:10 -070022 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}
Jorge Lucangeli Obesf16d6d12016-09-29 20:25:27 -040029
Luis Hector Chavezcb4ae322018-07-13 06:28:10 -070030void Usage(const char* progn, int status) {
31 // clang-format off
32 fprintf(status ? stderr : stdout,
Luis Hector Chavezdacb7052018-07-21 22:45:38 -070033 "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"
Luis Hector Chavezcb4ae322018-07-13 06:28:10 -070037 " --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}
Jorge Lucangeli Obesf16d6d12016-09-29 20:25:27 -040044
Luis Hector Chavezcb4ae322018-07-13 06:28:10 -070045} // namespace
46
47int 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
Luis Hector Chavezdacb7052018-07-21 22:45:38 -070073 FILE* f = stdin;
74 // If there is at least one additional unparsed argument, treat it as the
Luis Hector Chavezcb4ae322018-07-13 06:28:10 -070075 // policy script.
Luis Hector Chavezdacb7052018-07-21 22:45:38 -070076 if (argc > optind && strcmp(argv[optind], "-") != 0)
77 f = fopen(argv[optind], "re");
Luis Hector Chavezcb4ae322018-07-13 06:28:10 -070078 if (!f)
79 pdie("fopen(%s) failed", argv[1]);
80
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -040081 struct filter_options fopts {
82 .action = ACTION_RET_KILL,
83 .allow_logging = 0,
84 .allow_syscalls_for_logging = 0,
85 };
86
Luis Hector Chavezcb4ae322018-07-13 06:28:10 -070087 struct sock_fprog fp;
Jorge Lucangeli Obes32201f82019-06-12 14:45:06 -040088 int res = compile_filter(argv[1], f, &fp, &fopts);
Luis Hector Chavezcb4ae322018-07-13 06:28:10 -070089 fclose(f);
90 if (res != 0)
91 die("compile_filter failed");
92
93 if (dump) {
94 FILE* out = stdout;
95 if (!dump_path.empty()) {
96 out = fopen(dump_path.c_str(), "we");
97 if (!out)
98 pdie("fopen(%s) failed", dump_path.c_str());
99 }
100 if (fwrite(fp.filter, sizeof(struct sock_filter), fp.len, out) != fp.len)
101 pdie("fwrite(%s) failed", dump_path.c_str());
102 fclose(out);
103 } else {
104 DumpBpfProg(&fp);
105 }
106
107 free(fp.filter);
108 return 0;
Jorge Lucangeli Obesf16d6d12016-09-29 20:25:27 -0400109}