diff options
-rw-r--r-- | bpf.c | 19 | ||||
-rw-r--r-- | bpf.h | 4 | ||||
-rw-r--r-- | parse_seccomp_policy.cc | 112 |
3 files changed, 88 insertions, 47 deletions
@@ -182,25 +182,6 @@ size_t bpf_arg_comp(struct sock_filter **pfilter, int op, int argidx, return curr_block - filter; } -void dump_bpf_filter(struct sock_filter *filter, unsigned short len) -{ - int i = 0; - - printf("len == %d\n", len); - printf("filter:\n"); - for (i = 0; i < len; i++) { - printf("%d: \t{ code=%#x, jt=%u, jf=%u, k=%#x \t}\n", i, - filter[i].code, filter[i].jt, filter[i].jf, filter[i].k); - } -} - -void dump_bpf_prog(struct sock_fprog *fprog) -{ - struct sock_filter *filter = fprog->filter; - unsigned short len = fprog->len; - dump_bpf_filter(filter, len); -} - int bpf_resolve_jumps(struct bpf_labels *labels, struct sock_filter *filter, size_t len) { @@ -192,10 +192,6 @@ size_t bpf_allow_syscall(struct sock_filter *filter, int nr); size_t bpf_allow_syscall_args(struct sock_filter *filter, int nr, unsigned int id); -/* Debug functions. */ -void dump_bpf_prog(struct sock_fprog *fprog); -void dump_bpf_filter(struct sock_filter *filter, unsigned short len); - #ifdef __cplusplus }; /* extern "C" */ #endif diff --git a/parse_seccomp_policy.cc b/parse_seccomp_policy.cc index 76e8ab8..18cff96 100644 --- a/parse_seccomp_policy.cc +++ b/parse_seccomp_policy.cc @@ -3,34 +3,98 @@ * found in the LICENSE file. */ +#include <getopt.h> #include <stdio.h> +#include <string> + #include "bpf.h" #include "syscall_filter.h" #include "util.h" -/* TODO(jorgelo): Use libseccomp disassembler here. */ -int main(int argc, char **argv) { - init_logging(LOG_TO_FD, STDERR_FILENO, LOG_INFO); - - if (argc < 2) { - fprintf(stderr, "Usage: %s <policy file>\n", argv[0]); - return 1; - } - - FILE *f = fopen(argv[1], "re"); - if (!f) { - pdie("fopen(%s) failed", argv[1]); - } - - struct sock_fprog fp; - int res = compile_filter(argv[1], f, &fp, 0, 0); - if (res != 0) { - die("compile_filter failed"); - } - dump_bpf_prog(&fp); - - free(fp.filter); - fclose(f); - return 0; +namespace { + +void DumpBpfProg(struct sock_fprog* fprog) { + struct sock_filter* filter = fprog->filter; + unsigned short len = fprog->len; + + printf("len == %d\n", len); + printf("filter:\n"); + for (size_t i = 0; i < len; i++) { + printf("%zu: \t{ code=%#x, jt=%u, jf=%u, k=%#x \t}\n", i, filter[i].code, + filter[i].jt, filter[i].jf, filter[i].k); + } +} + +void Usage(const char* progn, int status) { + // clang-format off + fprintf(status ? stderr : stdout, + "Usage: %s [--dump[=<output.bpf>]] <policy file>\n" + " --dump[=<output>]: Dump the BPF program into stdout (or <output>,\n" + " -d[<output>]: if provided). Useful if you want to inspect it\n" + " with libseccomp's scmp_bpf_disasm.\n", + progn); + // clang-format on + exit(status); +} + +} // namespace + +int main(int argc, char** argv) { + init_logging(LOG_TO_FD, STDERR_FILENO, LOG_INFO); + + const char* optstring = "d:h"; + const struct option long_options[] = { + {"help", no_argument, 0, 'h'}, + {"dump", optional_argument, 0, 'd'}, + {0, 0, 0, 0}, + }; + + bool dump = false; + std::string dump_path; + int opt; + while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) { + switch (opt) { + case 'h': + Usage(argv[0], 0); + return 0; + case 'd': + dump = true; + if (optarg) + dump_path = optarg; + break; + } + } + + // There should be at least one additional unparsed argument: the + // policy script. + if (argc == optind) + Usage(argv[0], 1); + + FILE* f = fopen(argv[optind], "re"); + if (!f) + pdie("fopen(%s) failed", argv[1]); + + struct sock_fprog fp; + int res = compile_filter(argv[1], f, &fp, 0, 0); + fclose(f); + if (res != 0) + die("compile_filter failed"); + + if (dump) { + FILE* out = stdout; + if (!dump_path.empty()) { + out = fopen(dump_path.c_str(), "we"); + if (!out) + pdie("fopen(%s) failed", dump_path.c_str()); + } + if (fwrite(fp.filter, sizeof(struct sock_filter), fp.len, out) != fp.len) + pdie("fwrite(%s) failed", dump_path.c_str()); + fclose(out); + } else { + DumpBpfProg(&fp); + } + + free(fp.filter); + return 0; } |