From baf15e8f960f4c5edde74d87d9dcc5b2b97deaac Mon Sep 17 00:00:00 2001
From: Luis Gerhorst <privat@luisgerhorst.de>
Date: Sat, 15 May 2021 17:01:20 +0200
Subject: [PATCH] filter_magic += write, iter, open, read

---
 libbpf                      |  2 +-
 src/task_filter_magic.bpf.c | 51 +++++++++++++------------------------
 src/task_filter_magic.c     | 36 ++++++++++++++++----------
 src/task_filter_magic.h     |  9 +++++--
 src/task_lib.bpf.h          | 28 ++++++++++++++++++--
 5 files changed, 74 insertions(+), 52 deletions(-)

diff --git a/libbpf b/libbpf
index 2e3baf6..3341a4e 160000
--- a/libbpf
+++ b/libbpf
@@ -1 +1 @@
-Subproject commit 2e3baf61a6178304ceb1e670910da67c8c239eda
+Subproject commit 3341a4e49443c98dc5c058d2793ab8897cabe52d
diff --git a/src/task_filter_magic.bpf.c b/src/task_filter_magic.bpf.c
index f11fcd8..f1c3b12 100644
--- a/src/task_filter_magic.bpf.c
+++ b/src/task_filter_magic.bpf.c
@@ -15,13 +15,6 @@
 
 char LICENSE[] SEC("license") = "Dual BSD/GPL";
 
-struct bpf_map_def SEC("maps") args = {
-    .type = BPF_MAP_TYPE_HASH,
-    .key_size = sizeof(uint32_t),
-    .value_size = sizeof(size_t),
-    .max_entries = 1,
-};
-
 size_t offset;
 size_t magic_size;
 uintptr_t u_pathbufs;
@@ -29,39 +22,33 @@ uintptr_t u_bpfmem;
 uintptr_t u_buf;
 uintptr_t u_magic;
 uintptr_t u_statbuf;
+uintptr_t u_newline;
 
 SEC("task")
 int entry(void *ctx)
 {
 	int err = 0;
 
-	/* struct stat *statbuf = bpf_task_map(sizeof(struct stat), u_statbuf); */
-	/* if (statbuf == NULL) { */
-	/* 	bpf_printk("Error: buf is NULL"); */
-	/* 	return -1; */
-	/* } */
-
-	struct bpfmem *bpfmem;
+	volatile struct bpfmem *bpfmem;
 	bpfmem = bpf_task_map(sizeof(struct bpfmem), u_bpfmem);
 	if (bpfmem == NULL) {
-		bpf_printk("Error: bpfmem is NULL");
-		err = -1;
+		err = -6;
 		goto end;
 	}
+	if (bpfmem->bpfmem_magic != sizeof(struct bpfmem)) {
+		err = -7;
+		goto unmap;
+	}
 
 	char *magic = &bpfmem->magic[0];
 	char *buf = &bpfmem->buf[0];
-	struct stat *statbuf = &bpfmem->statbuf;
-
-	goto unmap;
-	/* size_t burst_size = bpf_map_lookup_elem(args, 0); */
 
-	for (size_t i = 0; i < MAX_BURST_SIZE; i++) {
+	for (size_t i = 0; i < MAX_BURST_SIZE && i < bpfmem->burst_size; i++) {
 		uintptr_t u_pathbuf = u_pathbufs + i * MAX_PATHLEN;
 
-		int fd = open((char *) u_pathbuf, O_RDONLY);
+		int fd = open(u_pathbuf, O_RDONLY, 0777);
 		if (fd == -1) {
-			err = -3;
+			err = -2;
 			goto unmap;
 		}
 
@@ -84,27 +71,25 @@ int entry(void *ctx)
 
 		ssize_t nread = read(fd, u_buf, magic_size-1);
 		if (nread == -1) {
-			err = -1;
+			err = -3;
 			goto unmap;
 		}
 		if (nread < magic_size-1) {
-			err = -2;
-			goto unmap;
+			goto close;
 		}
 
-		/* if (strcmp(magic, buf) == 0) { */
-		/* 	printf("%s\n", u_pathbuf); */
-		/* } */
+		if (magic[0] == buf[0]) {
+			write(STDOUT_FILENO, u_pathbuf, bpfmem->pathbuf_strlen[i]);
+			write(STDOUT_FILENO, u_newline, 1);
+		}
 
 	close:
-		err = close(fd);
-		if (err) {
-			goto unmap;
-		}
+		close(fd);
 	}
 
 unmap:
 	bpf_task_unmap(bpfmem, sizeof(struct bpfmem));
 end:
+	bpf_printk("Info: err = %d", err);
 	return err;
 }
diff --git a/src/task_filter_magic.c b/src/task_filter_magic.c
index 9572636..9e183b9 100644
--- a/src/task_filter_magic.c
+++ b/src/task_filter_magic.c
@@ -402,10 +402,18 @@ static int filter_magic_user_burst(size_t offset, const char *magic, size_t max_
 	}
 }
 
+static volatile struct bpfmem bpfmem = {};
+
 static int filter_magic_bpf(size_t offset, const char *magic_argv, size_t max_burst_size) {
 	int err;
 	int ret = EXIT_SUCCESS;
 
+	size_t magic_size = strlen(magic_argv) + 1;
+	if (magic_size > MAX_MAGIC_SIZE) {
+		log_err("magic too long");
+		return EXIT_FAILURE;
+	}
+
 	struct NAME_BPF *skel;
 
 	/* Set up libbpf errors and debug info callback */
@@ -423,13 +431,7 @@ static int filter_magic_bpf(size_t offset, const char *magic_argv, size_t max_bu
 
 	char pathbufs[max_burst_size][MAX_PATHLEN];
 
-	/* TODO: use struct mem */
-	struct bpfmem bpfmem;
-	size_t magic_size = strlen(magic_argv) + 1;
-	if (magic_size > MAX_MAGIC_SIZE) {
-		log_err("magic too long");
-		return EXIT_FAILURE;
-	}
+	bpfmem.bpfmem_magic = sizeof(struct bpfmem);
 	bpfmem.buf[magic_size-1] = '\0';
 	strcpy(&bpfmem.magic[0], magic_argv);
 
@@ -440,12 +442,13 @@ static int filter_magic_bpf(size_t offset, const char *magic_argv, size_t max_bu
 	skel->bss->u_bpfmem = &bpfmem;
 	skel->bss->u_buf = &bpfmem.buf[0];
 	skel->bss->u_magic = &bpfmem.magic[0];
-	skel->bss->u_statbuf = &bpfmem.statbuf;
+	skel->bss->u_newline = "\n";
 
 	/* Load & verify BPF programs */
 	err = BPF_LOAD(skel);
 	if (err) {
 		fprintf(stderr, "Failed to load and verify BPF skeleton\n");
+		ret = EXIT_FAILURE;
 		goto destroy;
 	}
 
@@ -460,7 +463,8 @@ static int filter_magic_bpf(size_t offset, const char *magic_argv, size_t max_bu
 			if (ptr == NULL) {
 				if (ferror(stdin)) {
 					log_err("fgets(stdin) failed");
-					return EXIT_FAILURE;
+					ret = EXIT_FAILURE;
+					goto destroy;
 				} else {
 					log_debug("EOF reached");
 					eof = true;
@@ -469,16 +473,20 @@ static int filter_magic_bpf(size_t offset, const char *magic_argv, size_t max_bu
 			}
 
 			/* Line must end with a newline. */
-			if (pathbuf[strlen(pathbuf)-1] == '\n') {
-				pathbuf[strlen(pathbuf)-1] = '\0';
+			size_t len = strlen(pathbuf);
+			if (pathbuf[len-1] == '\n') {
+				pathbuf[len-1] = '\0';
 			} else {
 				log_err("line too long / no newline");
 				ret = EXIT_FAILURE;
 				goto destroy;
 			}
+
+			bpfmem.pathbuf_strlen[burst_size] = len-1;
+			log_debug("i=%llu, len=%llu", burst_size, len);
 		}
+		bpfmem.burst_size = burst_size;
 
-		/* TODO: pass burst_size to bpf */
 		err = syscall(SYS_bpftask, prog_fd, NULL);
 		if (err) {
 			log_err("sys_bpftaks = %d", err);
@@ -495,10 +503,10 @@ destroy:
 int main(int argc, char **argv)
 {
 	bool debug = false;
-	char *variant;
+	char *variant = "bpf";
 	size_t max_burst_size = 1024; /* 32k l1d, 256k l2, 4096k l3 */
 	size_t offset = 0;
-	char *magic;
+	char *magic = "";
 
 	int c;
 	opterr = 0;
diff --git a/src/task_filter_magic.h b/src/task_filter_magic.h
index fd44904..18cd28a 100644
--- a/src/task_filter_magic.h
+++ b/src/task_filter_magic.h
@@ -5,10 +5,15 @@
 #define MAX_PATHLEN 512
 #define MAX_BURST_SIZE 1024
 
-struct bpfmem {
+#define __packed __attribute__((__packed__))
+
+struct __packed __attribute__((__aligned__(4096))) bpfmem {
+	size_t bpfmem_magic;
 	char buf[MAX_MAGIC_SIZE];
 	char magic[MAX_MAGIC_SIZE];
-	struct stat statbuf;
+	size_t burst_size;
+	size_t pathbuf_strlen[MAX_BURST_SIZE];
+	/* struct stat statbuf; */
 };
 
 #endif // __TASK_BULK_H_
diff --git a/src/task_lib.bpf.h b/src/task_lib.bpf.h
index 28d53ae..bd17b01 100644
--- a/src/task_lib.bpf.h
+++ b/src/task_lib.bpf.h
@@ -26,6 +26,10 @@ typedef __u64 ino64_t;
 typedef __u64 off64_t;
 typedef off64_t off_t;
 
+#define STDIN_FILENO 0
+#define STDOUT_FILENO 1
+#define STDERR_FILENO 2
+
 /* Copied from man getdents64(2). */
 struct linux_dirent64 {
 	ino64_t        d_ino;    /* 64-bit inode number */
@@ -45,6 +49,7 @@ struct timespec {
 };
 
 /* fstat(2) */
+/* TODO: fix */
 typedef int dev_t;
 typedef int ino_t;
 typedef int mode_t;
@@ -84,6 +89,21 @@ static char *strncpy(char *dest, const char *src, size_t n) {
 	return dest;
 }
 
+static int strncmp(const char *s1, const char *s2, size_t n) {
+	size_t i;
+	for (i = 0; i < n; i++) {
+		if (!s1[i] || s1[i] != s2[i]) {
+			break;
+		}
+	}
+
+	if (n == i) {
+		return 0;
+	} else {
+		return (unsigned char) s1[i] - (unsigned char) s2[i];
+	}
+}
+
 static void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset) {
 	uint64_t arg_tail[3] = {flags, fd, offset};
 	return (void *) bpf_task_sys_mmap_6((uint64_t) addr, length, prot, arg_tail, sizeof(arg_tail));
@@ -93,14 +113,18 @@ static int nanosleep(const struct timespec *req, struct timespec *rem) {
 	return (int) bpf_task_sys_nanosleep_2((uint64_t) req, (uint64_t) rem);
 }
 
-static int open(const char *pathname, int flags) {
-	return (int) bpf_task_sys_open_2((uint64_t) pathname, flags);
+static int open(uintptr_t pathname, int flags, mode_t mode) {
+	return (int) bpf_task_sys_open_3((uint64_t) pathname, flags, mode);
 }
 
 static ssize_t read(int fd, void *buf, size_t count) {
 	return (ssize_t) bpf_task_sys_read_3(fd, (uint64_t) buf, count);
 }
 
+static ssize_t write(int fd, void *buf, size_t count) {
+	return (ssize_t) bpf_task_sys_write_3(fd, (uint64_t) buf, count);
+}
+
 static int close(int fd) {
 	return (int) bpf_task_sys_close_1(fd);
 }
-- 
GitLab