From b6c964fb5a00c8b8ab26a4678cdde24c3e9b1d9c Mon Sep 17 00:00:00 2001 From: Alice Frosi Date: Tue, 28 Mar 2023 16:48:58 +0200 Subject: Rename cooker and eater with seitan prefix --- eater/eater.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 eater/eater.c (limited to 'eater/eater.c') diff --git a/eater/eater.c b/eater/eater.c new file mode 100644 index 0000000..96a7b61 --- /dev/null +++ b/eater/eater.c @@ -0,0 +1,143 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +/* SEITAN - Syscall Expressive Interpreter, Transformer and Notifier + * + * src/eater/eater.c - Load BPF program and execute binary + * + * Copyright (c) 2022 Red Hat GmbH + * Authors: Stefano Brivio , Alice Frosi + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "common.h" + +extern char **environ; + +static char doc[] = + "Usage: seitan-eater: setain-eater -i -- program args1 args2..."; + +/* Eater options */ +static struct argp_option options[] = { { "input", 'i', "FILE", 0, + "BPF filter input file", 0 }, + { 0 } }; + +struct arguments { + char *input_file; + unsigned int program_index; +}; + +static error_t parse_opt(int key, char *arg, struct argp_state *state) +{ + struct arguments *arguments = state->input; + + if (state->quoted == 0) + arguments->program_index = state->next + 1; + switch (key) { + case 'i': + if (state->quoted == 0) + arguments->input_file = arg; + break; + case ARGP_KEY_END: + if (arguments->input_file == NULL) + argp_error(state, "missing input file"); + if (state->argv[arguments->program_index] == NULL) + argp_error(state, "missing program"); + break; + } + + return 0; +} + +static struct argp argp = { .options = options, + .parser = parse_opt, + .args_doc = NULL, + .doc = doc, + .children = NULL, + .help_filter = NULL, + .argp_domain = NULL }; + +static int seccomp(unsigned int operation, unsigned int flags, void *args) +{ + return syscall(__NR_seccomp, operation, flags, args); +} + +static void signal_handler(__attribute__((unused)) int s) +{ +} + +/** + * main() - Entry point + * @argc: Argument count + * @argv: Seitan-eater and program arguments + * + * Return: 0 once interrupted, non-zero on failure + */ +int main(int argc, char **argv) +{ + struct sock_filter filter[1024]; + struct arguments arguments; + struct sock_fprog prog; + struct sigaction act; + size_t n; + int fd, flags; + + argp_parse(&argp, argc, argv, 0, 0, &arguments); + fd = open(arguments.input_file, O_CLOEXEC | O_RDONLY); + n = read(fd, filter, sizeof(filter)); + close(fd); + + prog.filter = filter; + prog.len = (unsigned short)(n / sizeof(filter[0])); + if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) != 0) { + perror("prctl"); + exit(EXIT_FAILURE); + } + if (seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_NEW_LISTENER, + &prog) < 0) { + perror("seccomp"); + exit(EXIT_FAILURE); + } + /* + * close-on-exec flag is set for the file descriptor by seccomp. + * We want to preserve the fd on the exec in this way we are able + * to easly find the notifier fd if seitan restarts. + */ + fd = find_fd_seccomp_notifier("/proc/self/fd"); + flags = fcntl(fd, F_GETFD); + if (fcntl(fd, F_SETFD, flags & !FD_CLOEXEC) < 0) { + perror("fcntl"); + exit(EXIT_FAILURE); + } + act.sa_handler = signal_handler; + sigaction(SIGCONT, &act, NULL); + pause(); + + execvpe(argv[arguments.program_index], &argv[arguments.program_index], + environ); + if (errno != ENOENT) { + perror("execvpe"); + exit(EXIT_FAILURE); + } + close(fd); + return EXIT_FAILURE; +} -- cgit v1.2.3