From 36b8eb3ce55602bcf36199330e98f2e154225cf7 Mon Sep 17 00:00:00 2001 From: Stefano Brivio Date: Tue, 25 Oct 2022 15:19:55 +0200 Subject: seitan: Initial import Signed-off-by: Stefano Brivio --- loader.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 loader.c (limited to 'loader.c') diff --git a/loader.c b/loader.c new file mode 100644 index 0000000..bd2530e --- /dev/null +++ b/loader.c @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +/* SEITAN - Syscall Expressive Interpreter, Transformer and Notifier + * + * loader.c - Load BPF program and execute binary + * + * Copyright (c) 2022 Red Hat GmbH + * Author: Stefano Brivio + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +extern char **environ; + +static char *qemu_names[] = { + "kvm", + "qemu-kvm", +#ifdef ARCH + ( "qemu-system-" ARCH ), +#endif + "/usr/libexec/qemu-kvm", + NULL, +}; + +/** + * usage() - Print usage and exit + */ +void usage(void) +{ + fprintf(stderr, "Usage: seitan-loader [QEMU_ARG]...\n"); + fprintf(stderr, "\n"); + + exit(EXIT_FAILURE); +} + +static int seccomp(unsigned int operation, unsigned int flags, void *args) +{ + return syscall(__NR_seccomp, operation, flags, args); +} + +/** + * main() - Entry point + * @argc: Argument count + * @argv: qemu arguments + * + * Return: 0 once interrupted, non-zero on failure + */ +int main(int argc, char **argv) +{ + int fd = open("bpf.out", O_CLOEXEC | O_RDONLY); + struct sock_filter filter[1024]; + struct sock_fprog prog; + char **name; + size_t n; + + (void)argc; + + n = read(fd, filter, sizeof(filter)); + close(fd); + + prog.filter = filter; + prog.len = (unsigned short)(n / sizeof(filter[0])); + prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); + fd = seccomp(SECCOMP_SET_MODE_FILTER, + SECCOMP_FILTER_FLAG_NEW_LISTENER, &prog); + + connect(0, NULL, 0); /* Wait for seitan to unblock this */ + + for (name = qemu_names; *name; name++) { + argv[0] = *name; + execvpe(*name, argv, environ); + if (errno != ENOENT) { + perror("execvpe"); + usage(); + } + } + + perror("execvpe"); + return EXIT_FAILURE; +} -- cgit v1.2.3