Mike Frysinger | 4c33189 | 2022-09-13 05:17:08 -0400 | [diff] [blame] | 1 | /* Copyright 2016 The ChromiumOS Authors |
Mike Frysinger | 50e31fa | 2018-01-19 18:59:49 -0500 | [diff] [blame] | 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 Obes | f16d6d1 | 2016-09-29 20:25:27 -0400 | [diff] [blame] | 5 | |
Luis Hector Chavez | cb4ae32 | 2018-07-13 06:28:10 -0700 | [diff] [blame] | 6 | #include <getopt.h> |
Jorge Lucangeli Obes | f16d6d1 | 2016-09-29 20:25:27 -0400 | [diff] [blame] | 7 | #include <stdio.h> |
Luis Hector Chavez | dacb705 | 2018-07-21 22:45:38 -0700 | [diff] [blame] | 8 | #include <string.h> |
Jorge Lucangeli Obes | f16d6d1 | 2016-09-29 20:25:27 -0400 | [diff] [blame] | 9 | |
Luis Hector Chavez | cb4ae32 | 2018-07-13 06:28:10 -0700 | [diff] [blame] | 10 | #include <string> |
| 11 | |
Jorge Lucangeli Obes | f16d6d1 | 2016-09-29 20:25:27 -0400 | [diff] [blame] | 12 | #include "bpf.h" |
| 13 | #include "syscall_filter.h" |
| 14 | #include "util.h" |
| 15 | |
Luis Hector Chavez | cb4ae32 | 2018-07-13 06:28:10 -0700 | [diff] [blame] | 16 | namespace { |
Luis Hector Chavez | 114a930 | 2017-09-05 20:36:58 -0700 | [diff] [blame] | 17 | |
Luis Hector Chavez | cb4ae32 | 2018-07-13 06:28:10 -0700 | [diff] [blame] | 18 | void DumpBpfProg(struct sock_fprog* fprog) { |
| 19 | struct sock_filter* filter = fprog->filter; |
| 20 | unsigned short len = fprog->len; |
Jorge Lucangeli Obes | f16d6d1 | 2016-09-29 20:25:27 -0400 | [diff] [blame] | 21 | |
Luis Hector Chavez | cb4ae32 | 2018-07-13 06:28:10 -0700 | [diff] [blame] | 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 | } |
Jorge Lucangeli Obes | f16d6d1 | 2016-09-29 20:25:27 -0400 | [diff] [blame] | 29 | |
Luis Hector Chavez | cb4ae32 | 2018-07-13 06:28:10 -0700 | [diff] [blame] | 30 | void Usage(const char* progn, int status) { |
| 31 | // clang-format off |
| 32 | fprintf(status ? stderr : stdout, |
Luis Hector Chavez | dacb705 | 2018-07-21 22:45:38 -0700 | [diff] [blame] | 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" |
Luis Hector Chavez | cb4ae32 | 2018-07-13 06:28:10 -0700 | [diff] [blame] | 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 | } |
Jorge Lucangeli Obes | f16d6d1 | 2016-09-29 20:25:27 -0400 | [diff] [blame] | 44 | |
Luis Hector Chavez | cb4ae32 | 2018-07-13 06:28:10 -0700 | [diff] [blame] | 45 | } // namespace |
| 46 | |
| 47 | int main(int argc, char** argv) { |
| 48 | init_logging(LOG_TO_FD, STDERR_FILENO, LOG_INFO); |
| 49 | |
Mike Frysinger | 0bfcbff | 2021-11-23 00:00:52 -0500 | [diff] [blame] | 50 | static const char optstring[] = "d:h"; |
| 51 | static const struct option long_options[] = { |
Luis Hector Chavez | cb4ae32 | 2018-07-13 06:28:10 -0700 | [diff] [blame] | 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 Chavez | dacb705 | 2018-07-21 22:45:38 -0700 | [diff] [blame] | 73 | FILE* f = stdin; |
| 74 | // If there is at least one additional unparsed argument, treat it as the |
Luis Hector Chavez | cb4ae32 | 2018-07-13 06:28:10 -0700 | [diff] [blame] | 75 | // policy script. |
Mike Frysinger | 22dc352 | 2022-07-07 19:24:13 -0400 | [diff] [blame] | 76 | if (argc > optind && !streq(argv[optind], "-")) |
Luis Hector Chavez | dacb705 | 2018-07-21 22:45:38 -0700 | [diff] [blame] | 77 | f = fopen(argv[optind], "re"); |
Luis Hector Chavez | cb4ae32 | 2018-07-13 06:28:10 -0700 | [diff] [blame] | 78 | if (!f) |
| 79 | pdie("fopen(%s) failed", argv[1]); |
| 80 | |
Jorge Lucangeli Obes | 32201f8 | 2019-06-12 14:45:06 -0400 | [diff] [blame] | 81 | struct filter_options fopts { |
| 82 | .action = ACTION_RET_KILL, |
| 83 | .allow_logging = 0, |
| 84 | .allow_syscalls_for_logging = 0, |
Nicole Anderson-Au | bcc8cfd | 2020-11-10 20:33:27 +0000 | [diff] [blame] | 85 | .allow_duplicate_syscalls = allow_duplicate_syscalls(), |
Jorge Lucangeli Obes | 32201f8 | 2019-06-12 14:45:06 -0400 | [diff] [blame] | 86 | }; |
| 87 | |
Luis Hector Chavez | cb4ae32 | 2018-07-13 06:28:10 -0700 | [diff] [blame] | 88 | struct sock_fprog fp; |
Jorge Lucangeli Obes | 32201f8 | 2019-06-12 14:45:06 -0400 | [diff] [blame] | 89 | int res = compile_filter(argv[1], f, &fp, &fopts); |
Luis Hector Chavez | cb4ae32 | 2018-07-13 06:28:10 -0700 | [diff] [blame] | 90 | fclose(f); |
| 91 | if (res != 0) |
| 92 | die("compile_filter failed"); |
| 93 | |
| 94 | if (dump) { |
| 95 | FILE* out = stdout; |
| 96 | if (!dump_path.empty()) { |
| 97 | out = fopen(dump_path.c_str(), "we"); |
| 98 | if (!out) |
| 99 | pdie("fopen(%s) failed", dump_path.c_str()); |
| 100 | } |
| 101 | if (fwrite(fp.filter, sizeof(struct sock_filter), fp.len, out) != fp.len) |
| 102 | pdie("fwrite(%s) failed", dump_path.c_str()); |
| 103 | fclose(out); |
| 104 | } else { |
| 105 | DumpBpfProg(&fp); |
| 106 | } |
| 107 | |
| 108 | free(fp.filter); |
| 109 | return 0; |
Jorge Lucangeli Obes | f16d6d1 | 2016-09-29 20:25:27 -0400 | [diff] [blame] | 110 | } |