diff --git a/libbpf b/libbpf index 39635dd04328cf581ed629f0ad0d19a313386bcc..2e3baf61a6178304ceb1e670910da67c8c239eda 160000 --- a/libbpf +++ b/libbpf @@ -1 +1 @@ -Subproject commit 39635dd04328cf581ed629f0ad0d19a313386bcc +Subproject commit 2e3baf61a6178304ceb1e670910da67c8c239eda diff --git a/src/task_filter_magic.bpf.c b/src/task_filter_magic.bpf.c index 18807f2874cda4ac79643ad49c4dcb22b50c77d3..f11fcd889279fb700d18bcc326f6b167586e4f03 100644 --- a/src/task_filter_magic.bpf.c +++ b/src/task_filter_magic.bpf.c @@ -4,27 +4,107 @@ #include <bpf/bpf_helpers.h> #include "task_lib.bpf.h" -#include "task_ag.h" + +#define NAME task_filter_magic + +/* https://stackoverflow.com/questions/5873722/c-macro-dynamic-include */ +#define __header(x) #x +#define _name_h(x) __header(x.h) +#define name_h(x) _name_h(x) +#include name_h(NAME) 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; +uintptr_t u_bpfmem; +uintptr_t u_buf; +uintptr_t u_magic; +uintptr_t u_statbuf; + SEC("task") int entry(void *ctx) { int err = 0; - bpf_printk("ctx = %llx", ctx); + /* struct stat *statbuf = bpf_task_map(sizeof(struct stat), u_statbuf); */ + /* if (statbuf == NULL) { */ + /* bpf_printk("Error: buf is NULL"); */ + /* return -1; */ + /* } */ - /* BUG: why does this reutrn -1? */ - char *buf = bpf_task_map(SIZE, ctx); - if (buf == NULL) { - bpf_printk("Error: buf is NULL"); - return -1; + struct bpfmem *bpfmem; + bpfmem = bpf_task_map(sizeof(struct bpfmem), u_bpfmem); + if (bpfmem == NULL) { + bpf_printk("Error: bpfmem is NULL"); + err = -1; + goto end; } - err = *buf; + 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++) { + uintptr_t u_pathbuf = u_pathbufs + i * MAX_PATHLEN; + + int fd = open((char *) u_pathbuf, O_RDONLY); + if (fd == -1) { + err = -3; + goto unmap; + } + + /* err = fstat(fd, u_statbuf); */ + /* if (err != 0) { */ + /* goto unmap; */ + /* } */ + /* if (statbuf.st_size < offset + magic_size-1) { */ + /* err = -1; */ + /* goto unmap; */ + /* } */ + + /* if (offset) { */ + /* off_t o = lseek(fd, offset, SEEK_SET); */ + /* if (o == -1) { */ + /* err = -1; */ + /* goto unmap; */ + /* } */ + /* } */ + + ssize_t nread = read(fd, u_buf, magic_size-1); + if (nread == -1) { + err = -1; + goto unmap; + } + if (nread < magic_size-1) { + err = -2; + goto unmap; + } + + /* if (strcmp(magic, buf) == 0) { */ + /* printf("%s\n", u_pathbuf); */ + /* } */ + + close: + err = close(fd); + if (err) { + goto unmap; + } + } unmap: - bpf_task_unmap(buf, SIZE); + bpf_task_unmap(bpfmem, sizeof(struct bpfmem)); +end: return err; } diff --git a/src/task_filter_magic.c b/src/task_filter_magic.c index 8a32d5b5b9dab855dcbc6320fa12970b643aab52..9572636437bd33bfe4452cc3230f99d4dc33203d 100644 --- a/src/task_filter_magic.c +++ b/src/task_filter_magic.c @@ -144,8 +144,6 @@ static void plog(const unsigned int level, const char *fmt, ...) { va_end(args); } -#define MAX_PATHLEN 512 - static int filter_magic_user_fp(size_t offset, const char *magic) { int err; size_t magic_size = strlen(magic) + 1; @@ -404,7 +402,7 @@ static int filter_magic_user_burst(size_t offset, const char *magic, size_t max_ } } -static int filter_magic_bpf(size_t offset, const char *magic, size_t max_burst_size) { +static int filter_magic_bpf(size_t offset, const char *magic_argv, size_t max_burst_size) { int err; int ret = EXIT_SUCCESS; @@ -423,12 +421,26 @@ static int filter_magic_bpf(size_t offset, const char *magic, size_t max_burst_s return EXIT_FAILURE; } - - size_t magic_size = strlen(magic) + 1; - char buf[magic_size]; - buf[magic_size-1] = '\0'; char pathbufs[max_burst_size][MAX_PATHLEN]; - /* TODO: Write pathbufs, buf, offset and magic into program. */ + + /* 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.buf[magic_size-1] = '\0'; + strcpy(&bpfmem.magic[0], magic_argv); + + /* Write pathbufs, buf, offset and magic into program. */ + skel->bss->offset = offset; + skel->bss->magic_size = magic_size; + skel->bss->u_pathbufs = pathbufs; + 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; /* Load & verify BPF programs */ err = BPF_LOAD(skel); @@ -542,6 +554,12 @@ int main(int argc, char **argv) } else if (strcmp(variant, "user_burst_skip") == 0) { return filter_magic_user_burst(offset, magic, max_burst_size, true); } else if (strcmp(variant, "bpf") == 0) { + if (max_burst_size != MAX_BURST_SIZE) { + log_err("bpf only supports max_burst_size = %u", MAX_BURST_SIZE); + return EXIT_FAILURE; + } return filter_magic_bpf(offset, magic, max_burst_size); + } else { + return EXIT_FAILURE; } } diff --git a/src/task_filter_magic.h b/src/task_filter_magic.h index ce6021e6a9bc16b42c59f5564d10519cab8a3843..fd4490407c08c0f5dc420fe34577f246fc12b6ab 100644 --- a/src/task_filter_magic.h +++ b/src/task_filter_magic.h @@ -1,6 +1,14 @@ #ifndef __TASK_BULK_H_ #define __TASK_BULK_H_ -#define SIZE 4096 +#define MAX_MAGIC_SIZE 32 +#define MAX_PATHLEN 512 +#define MAX_BURST_SIZE 1024 + +struct bpfmem { + char buf[MAX_MAGIC_SIZE]; + char magic[MAX_MAGIC_SIZE]; + struct stat statbuf; +}; #endif // __TASK_BULK_H_ diff --git a/src/task_lib.bpf.h b/src/task_lib.bpf.h index 59d1e960978f3821c77542e6fac15c480b325415..28d53ae9c97499526bf0fcc9a2b78d16853ffd38 100644 --- a/src/task_lib.bpf.h +++ b/src/task_lib.bpf.h @@ -14,10 +14,14 @@ #define false ((bool) 0) #define true ((bool) 1) +typedef __u32 uint32_t; typedef __u64 uint64_t; /* BUG: This asserts a 64-bit system. */ typedef __u64 uintptr_t; +typedef long intptr_t; + typedef uintptr_t size_t; +typedef intptr_t ssize_t; typedef __u64 ino64_t; typedef __u64 off64_t; typedef off64_t off_t; @@ -40,6 +44,36 @@ struct timespec { long tv_nsec; /* nanoseconds */ }; +/* fstat(2) */ +typedef int dev_t; +typedef int ino_t; +typedef int mode_t; +typedef int nlink_t; +typedef int uid_t; +typedef int gid_t; +typedef int blksize_t; +typedef int blkcnt_t; +struct stat { + dev_t st_dev; /* ID of device containing file */ + ino_t st_ino; /* Inode number */ + mode_t st_mode; /* File type and mode */ + nlink_t st_nlink; /* Number of hard links */ + uid_t st_uid; /* User ID of owner */ + gid_t st_gid; /* Group ID of owner */ + dev_t st_rdev; /* Device ID (if special file) */ + off_t st_size; /* Total size, in bytes */ + blksize_t st_blksize; /* Block size for filesystem I/O */ + blkcnt_t st_blocks; /* Number of 512B blocks allocated */ + + /* Since Linux 2.6, the kernel supports nanosecond + precision for the following timestamp fields. + For the details before Linux 2.6, see NOTES. */ + + struct timespec st_atim; /* Time of last access */ + struct timespec st_mtim; /* Time of last modification */ + struct timespec st_ctim; /* Time of last status change */ +}; + static char *strncpy(char *dest, const char *src, size_t n) { for (size_t i = 0; i < n; i++) { dest[i] = src[i]; @@ -56,7 +90,19 @@ static void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t } static int nanosleep(const struct timespec *req, struct timespec *rem) { - return (int) bpf_task_sys_nanosleep_2(req, 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 ssize_t read(int fd, void *buf, size_t count) { + return (ssize_t) bpf_task_sys_read_3(fd, (uint64_t) buf, count); +} + +static int close(int fd) { + return (int) bpf_task_sys_close_1(fd); } #endif // __TASK_LIBC_BPF_H_