aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/bpf/syscall.c
diff options
context:
space:
mode:
authorDaniel Borkmann <daniel@iogearbox.net>2016-12-04 17:19:41 -0500
committerDavid S. Miller <davem@davemloft.net>2016-12-05 15:33:11 -0500
commit7bd509e311f408f7a5132fcdde2069af65fa05ae (patch)
tree045d83766d5a303f3ae8eaa0ff4cde5a66526e55 /kernel/bpf/syscall.c
parent8d829bdb97dc3a0c9c8090b9b168ca46ea99c8d8 (diff)
bpf: add prog_digest and expose it via fdinfo/netlink
When loading a BPF program via bpf(2), calculate the digest over the program's instruction stream and store it in struct bpf_prog's digest member. This is done at a point in time before any instructions are rewritten by the verifier. Any unstable map file descriptor number part of the imm field will be zeroed for the hash. fdinfo example output for progs: # cat /proc/1590/fdinfo/5 pos: 0 flags: 02000002 mnt_id: 11 prog_type: 1 prog_jited: 1 prog_digest: b27e8b06da22707513aa97363dfb11c7c3675d28 memlock: 4096 When programs are pinned and retrieved by an ELF loader, the loader can check the program's digest through fdinfo and compare it against one that was generated over the ELF file's program section to see if the program needs to be reloaded. Furthermore, this can also be exposed through other means such as netlink in case of a tc cls/act dump (or xdp in future), but also through tracepoints or other facilities to identify the program. Other than that, the digest can also serve as a base name for the work in progress kallsyms support of programs. The digest doesn't depend/select the crypto layer, since we need to keep dependencies to a minimum. iproute2 will get support for this facility. Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'kernel/bpf/syscall.c')
-rw-r--r--kernel/bpf/syscall.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 85af86c496cd..c0d2b423ce93 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -662,8 +662,30 @@ static int bpf_prog_release(struct inode *inode, struct file *filp)
662 return 0; 662 return 0;
663} 663}
664 664
665#ifdef CONFIG_PROC_FS
666static void bpf_prog_show_fdinfo(struct seq_file *m, struct file *filp)
667{
668 const struct bpf_prog *prog = filp->private_data;
669 char prog_digest[sizeof(prog->digest) * 2 + 1] = { };
670
671 bin2hex(prog_digest, prog->digest, sizeof(prog->digest));
672 seq_printf(m,
673 "prog_type:\t%u\n"
674 "prog_jited:\t%u\n"
675 "prog_digest:\t%s\n"
676 "memlock:\t%llu\n",
677 prog->type,
678 prog->jited,
679 prog_digest,
680 prog->pages * 1ULL << PAGE_SHIFT);
681}
682#endif
683
665static const struct file_operations bpf_prog_fops = { 684static const struct file_operations bpf_prog_fops = {
666 .release = bpf_prog_release, 685#ifdef CONFIG_PROC_FS
686 .show_fdinfo = bpf_prog_show_fdinfo,
687#endif
688 .release = bpf_prog_release,
667}; 689};
668 690
669int bpf_prog_new_fd(struct bpf_prog *prog) 691int bpf_prog_new_fd(struct bpf_prog *prog)