diff --git a/include/linux/bpf_types.h b/include/linux/bpf_types.h index a52a5688418e5db69f713e6e12e8a64a577f3b22..6319d0e4f15f40161fb5a2692ef1ed435fbca037 100644 --- a/include/linux/bpf_types.h +++ b/include/linux/bpf_types.h @@ -77,6 +77,9 @@ BPF_PROG_TYPE(BPF_PROG_TYPE_LSM, lsm, void *, void *) #endif /* CONFIG_BPF_LSM */ #endif +#ifdef CONFIG_BPFTASK_SYSCALL +BPF_PROG_TYPE(BPF_PROG_TYPE_TASK, task, void *, void *) /* TODO: What are arg2..arg4? */ +#endif BPF_MAP_TYPE(BPF_MAP_TYPE_ARRAY, array_map_ops) BPF_MAP_TYPE(BPF_MAP_TYPE_PERCPU_ARRAY, percpu_array_map_ops) diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 14aa88fe7078e675d63a232edfc4e5064878aaee..55a84700d6f7dde920da6a12c0b17adc2567a488 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -970,7 +970,7 @@ asmlinkage long sys_getrandom(char __user *buf, size_t count, unsigned int flags); asmlinkage long sys_memfd_create(const char __user *uname_ptr, unsigned int flags); asmlinkage long sys_bpf(int cmd, union bpf_attr *attr, unsigned int size); -asmlinkage long sys_bpftask(const char __user *pathname, const char __user *filename, int ofd, char __user *buf); +asmlinkage long sys_bpftask(int prog_fd, void __user *arg); asmlinkage long sys_execveat(int dfd, const char __user *filename, const char __user *const __user *argv, const char __user *const __user *envp, int flags); diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index b6238b2209b71a3d9094b7eec1eb67130175ed62..aa4a630b9a995b41c8d3d16b7c6e28782c731774 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -197,6 +197,7 @@ enum bpf_prog_type { BPF_PROG_TYPE_EXT, BPF_PROG_TYPE_LSM, BPF_PROG_TYPE_SK_LOOKUP, + BPF_PROG_TYPE_TASK, }; enum bpf_attach_type { diff --git a/kernel/bpf/task.c b/kernel/bpf/task.c index 8d4180a462f30263ebf5e056e6e2982cdbb13b8d..75677bdc811f430e938dff8e302f50540f909b94 100644 --- a/kernel/bpf/task.c +++ b/kernel/bpf/task.c @@ -6,6 +6,7 @@ #include <linux/errname.h> #include <linux/dirent.h> #include <linux/vmalloc.h> +#include <linux/filter.h> #define BUF_SIZE 1024 @@ -199,15 +200,28 @@ static long find(const char __user *pathname_user, const char __user *filename_u return err; } -SYSCALL_DEFINE4(bpftask, const char __user *, pathname, const char __user *, filename, int, ofd, char __user *, buf_user) +/* dummy _ops. The verifier will operate on target program's ops. */ +const struct bpf_verifier_ops task_verifier_ops = { +}; +const struct bpf_prog_ops task_prog_ops = { +}; + +SYSCALL_DEFINE2(bpftask, int, prog_fd, void *, arg) { - void *vm = vmalloc(1); - void *vmuser = vmalloc_user(1); - printk("bpftask, %p ?= %p, buf_user = %p, vmalloc = %p, vmalloc_user = %p\n", compat_alloc_user_space(16), compat_alloc_user_space(16), buf_user, vm, vmuser); + int ret = 0; /* The same check as in bpf/syscall.c */ if (sysctl_unprivileged_bpf_disabled && !bpf_capable()) return -EPERM; - return find(pathname, filename, ofd, buf_user); + struct bpf_prog *prog = bpf_prog_get(prog_fd); + if (IS_ERR(prog)) { + ret = PTR_ERR(prog); + goto out; + } + ret = BPF_PROG_RUN(prog, NULL); + + bpf_prog_put(prog); +out: + return ret; } diff --git a/scripts/bpf_helpers_doc.py b/scripts/bpf_helpers_doc.py index 5bfa448b4704bfd69683035f22d08180598119cf..535f81e93be642495a4e675d9ffc69f35de1b000 100755 --- a/scripts/bpf_helpers_doc.py +++ b/scripts/bpf_helpers_doc.py @@ -472,6 +472,8 @@ class PrinterHelpers(Printer): 'struct tcp_request_sock', 'struct udp6_sock', 'struct task_struct', + # Added for bpftask: + 'struct bpf_redir_neigh', 'struct linux_binprm', 'struct path', 'struct btf_ptr', 'struct inode', 'struct socket', 'struct file' } mapped_types = { 'u8': '__u8', diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index b6238b2209b71a3d9094b7eec1eb67130175ed62..aa4a630b9a995b41c8d3d16b7c6e28782c731774 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -197,6 +197,7 @@ enum bpf_prog_type { BPF_PROG_TYPE_EXT, BPF_PROG_TYPE_LSM, BPF_PROG_TYPE_SK_LOOKUP, + BPF_PROG_TYPE_TASK, }; enum bpf_attach_type { diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index e493d6048143f0cc1ed3b7bef32ee6606b556974..51da2f64c67d3cf9aa4ad406a185f8159061c1e9 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -6995,6 +6995,7 @@ static const struct bpf_sec_def section_defs[] = { BPF_PROG_SEC("struct_ops", BPF_PROG_TYPE_STRUCT_OPS), BPF_EAPROG_SEC("sk_lookup/", BPF_PROG_TYPE_SK_LOOKUP, BPF_SK_LOOKUP), + BPF_PROG_SEC("task", BPF_PROG_TYPE_TASK), }; #undef BPF_PROG_SEC_IMPL diff --git a/tools/lib/bpf/libbpf_probes.c b/tools/lib/bpf/libbpf_probes.c index 5a3d3f07840816597c4c8c35a767e77e79fa4609..2972055ecde80a3e2874382cc75330f685aa907f 100644 --- a/tools/lib/bpf/libbpf_probes.c +++ b/tools/lib/bpf/libbpf_probes.c @@ -112,6 +112,7 @@ probe_load(enum bpf_prog_type prog_type, const struct bpf_insn *insns, case BPF_PROG_TYPE_STRUCT_OPS: case BPF_PROG_TYPE_EXT: case BPF_PROG_TYPE_LSM: + case BPF_PROG_TYPE_TASK: default: break; }