aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/bpf/syscall.c
diff options
context:
space:
mode:
authorSandipan Das <sandipan@linux.vnet.ibm.com>2018-05-24 02:56:51 -0400
committerDaniel Borkmann <daniel@iogearbox.net>2018-05-24 03:20:49 -0400
commit4d56a76ead2fcd856e677cdc9445ad331a409b8c (patch)
tree9b8b3e6d662723418d65bb23012bfdba33e3d7c7 /kernel/bpf/syscall.c
parentf84192ee00b7d8b3c38545d3a61d4191f80cc81a (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.c37
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 }