aboutgitcodelistschat:MatrixIRC
diff options
context:
space:
mode:
-rw-r--r--eater.c86
1 files changed, 52 insertions, 34 deletions
diff --git a/eater.c b/eater.c
index a7a6b5f..e60a993 100644
--- a/eater.c
+++ b/eater.c
@@ -16,6 +16,7 @@
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
+#include <argp.h>
#include <sys/prctl.h>
#include <sys/syscall.h>
#include <sys/socket.h>
@@ -26,27 +27,49 @@
extern char **environ;
-static char *qemu_names[] = {
- "kvm",
- "qemu-kvm",
-#ifdef ARCH
- ( "qemu-system-" ARCH ),
-#endif
- "/usr/libexec/qemu-kvm",
- NULL,
+static char doc[] =
+ "Usage: seitan-eater: setain-eater -i <input file> -- 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;
};
-/**
- * usage() - Print usage and exit
- */
-void usage(void)
+static error_t parse_opt(int key, char *arg, struct argp_state *state)
{
- fprintf(stderr, "Usage: seitan-eater [QEMU_ARG]...\n");
- fprintf(stderr, "\n");
+ 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;
+ }
- exit(EXIT_FAILURE);
+ 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);
@@ -55,40 +78,35 @@ static int seccomp(unsigned int operation, unsigned int flags, void *args)
/**
* main() - Entry point
* @argc: Argument count
- * @argv: qemu arguments
+ * @argv: Seitan-eater and program 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 arguments arguments;
struct sock_fprog prog;
- char **name;
size_t n;
+ int fd;
- (void)argc;
-
+ 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]));
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();
- }
- }
+ fd = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_NEW_LISTENER,
+ &prog);
- perror("execvpe");
+ connect(0, NULL, 0); /* Wait for seitan to unblock this */
+ execvpe(argv[arguments.program_index], &argv[arguments.program_index],
+ environ);
+ if (errno != ENOENT) {
+ perror("execvpe");
+ exit(EXIT_FAILURE);
+ }
return EXIT_FAILURE;
}