diff options
author | Sandipan Das <sandipan@linux.vnet.ibm.com> | 2018-05-24 02:56:51 -0400 |
---|---|---|
committer | Daniel Borkmann <daniel@iogearbox.net> | 2018-05-24 03:20:49 -0400 |
commit | 4d56a76ead2fcd856e677cdc9445ad331a409b8c (patch) | |
tree | 9b8b3e6d662723418d65bb23012bfdba33e3d7c7 /kernel/bpf/syscall.c | |
parent | f84192ee00b7d8b3c38545d3a61d4191f80cc81a (diff) |
bpf: fix multi-function JITed dump obtained via syscall
Currently, for multi-function programs, we cannot get the JITed
instructions using the bpf system call's BPF_OBJ_GET_INFO_BY_FD
command. Because of this, userspace tools such as bpftool fail
to identify a multi-function program as being JITed or not.
With the JIT enabled and the test program running, this can be
verified as follows:
# cat /proc/sys/net/core/bpf_jit_enable
1
Before applying this patch:
# bpftool prog list
1: kprobe name foo tag b811aab41a39ad3d gpl
loaded_at 2018-05-16T11:43:38+0530 uid 0
xlated 216B not jited memlock 65536B
...
# bpftool prog dump jited id 1
no instructions returned
After applying this patch:
# bpftool prog list
1: kprobe name foo tag b811aab41a39ad3d gpl
loaded_at 2018-05-16T12:13:01+0530 uid 0
xlated 216B jited 308B memlock 65536B
...
# bpftool prog dump jited id 1
0: nop
4: nop
8: mflr r0
c: std r0,16(r1)
10: stdu r1,-112(r1)
14: std r31,104(r1)
18: addi r31,r1,48
1c: li r3,10
...
Signed-off-by: Sandipan Das <sandipan@linux.vnet.ibm.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'kernel/bpf/syscall.c')
-rw-r--r-- | kernel/bpf/syscall.c | 37 |
1 files changed, 34 insertions, 3 deletions
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 068a4fc79ddb..c8e987a612b5 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c | |||
@@ -1970,13 +1970,44 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog, | |||
1970 | * for offload. | 1970 | * for offload. |
1971 | */ | 1971 | */ |
1972 | ulen = info.jited_prog_len; | 1972 | ulen = info.jited_prog_len; |
1973 | info.jited_prog_len = prog->jited_len; | 1973 | if (prog->aux->func_cnt) { |
1974 | u32 i; | ||
1975 | |||
1976 | info.jited_prog_len = 0; | ||
1977 | for (i = 0; i < prog->aux->func_cnt; i++) | ||
1978 | info.jited_prog_len += prog->aux->func[i]->jited_len; | ||
1979 | } else { | ||
1980 | info.jited_prog_len = prog->jited_len; | ||
1981 | } | ||
1982 | |||
1974 | if (info.jited_prog_len && ulen) { | 1983 | if (info.jited_prog_len && ulen) { |
1975 | if (bpf_dump_raw_ok()) { | 1984 | if (bpf_dump_raw_ok()) { |
1976 | uinsns = u64_to_user_ptr(info.jited_prog_insns); | 1985 | uinsns = u64_to_user_ptr(info.jited_prog_insns); |
1977 | ulen = min_t(u32, info.jited_prog_len, ulen); | 1986 | ulen = min_t(u32, info.jited_prog_len, ulen); |
1978 | if (copy_to_user(uinsns, prog->bpf_func, ulen)) | 1987 | |
1979 | return -EFAULT; | 1988 | /* for multi-function programs, copy the JITed |
1989 | * instructions for all the functions | ||
1990 | */ | ||
1991 | if (prog->aux->func_cnt) { | ||
1992 | u32 len, free, i; | ||
1993 | u8 *img; | ||
1994 | |||
1995 | free = ulen; | ||
1996 | for (i = 0; i < prog->aux->func_cnt; i++) { | ||
1997 | len = prog->aux->func[i]->jited_len; | ||
1998 | len = min_t(u32, len, free); | ||
1999 | img = (u8 *) prog->aux->func[i]->bpf_func; | ||
2000 | if (copy_to_user(uinsns, img, len)) | ||
2001 | return -EFAULT; | ||
2002 | uinsns += len; | ||
2003 | free -= len; | ||
2004 | if (!free) | ||
2005 | break; | ||
2006 | } | ||
2007 | } else { | ||
2008 | if (copy_to_user(uinsns, prog->bpf_func, ulen)) | ||
2009 | return -EFAULT; | ||
2010 | } | ||
1980 | } else { | 2011 | } else { |
1981 | info.jited_prog_insns = 0; | 2012 | info.jited_prog_insns = 0; |
1982 | } | 2013 | } |