aboutgitcodelistschat:MatrixIRC
path: root/loader.c
diff options
context:
space:
mode:
authorStefano Brivio <sbrivio@redhat.com>2022-10-25 15:19:55 +0200
committerStefano Brivio <sbrivio@redhat.com>2022-10-25 15:19:55 +0200
commit36b8eb3ce55602bcf36199330e98f2e154225cf7 (patch)
tree53935e784940eb07401aea7d85fbede6f5f3bafa /loader.c
downloadseitan-36b8eb3ce55602bcf36199330e98f2e154225cf7.tar
seitan-36b8eb3ce55602bcf36199330e98f2e154225cf7.tar.gz
seitan-36b8eb3ce55602bcf36199330e98f2e154225cf7.tar.bz2
seitan-36b8eb3ce55602bcf36199330e98f2e154225cf7.tar.lz
seitan-36b8eb3ce55602bcf36199330e98f2e154225cf7.tar.xz
seitan-36b8eb3ce55602bcf36199330e98f2e154225cf7.tar.zst
seitan-36b8eb3ce55602bcf36199330e98f2e154225cf7.zip
seitan: Initial import
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'loader.c')
-rw-r--r--loader.c94
1 files changed, 94 insertions, 0 deletions
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 <sbrivio@redhat.com>
+ */
+
+#define _GNU_SOURCE
+#include <errno.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/prctl.h>
+#include <sys/syscall.h>
+#include <sys/socket.h>
+
+#include <linux/audit.h>
+#include <linux/filter.h>
+#include <linux/seccomp.h>
+
+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;
+}