| From 28989d06e55c1be6e2dc2f87f018ec238bf6c228 Mon Sep 17 00:00:00 2001 |
| From: Eric Dumazet <edumazet@google.com> |
| Date: Thu, 31 Oct 2019 20:34:44 -0700 |
| Subject: [PATCH] powerpc/bpf: Fix tail call implementation |
| |
| commit 7de086909365cd60a5619a45af3f4152516fd75c upstream. |
| |
| We have seen many crashes on powerpc hosts while loading bpf programs. |
| |
| The problem here is that bpf_int_jit_compile() does a first pass |
| to compute the program length. |
| |
| Then it allocates memory to store the generated program and |
| calls bpf_jit_build_body() a second time (and a third time |
| later) |
| |
| What I have observed is that the second bpf_jit_build_body() |
| could end up using few more words than expected. |
| |
| If bpf_jit_binary_alloc() put the space for the program |
| at the end of the allocated page, we then write on |
| a non mapped memory. |
| |
| It appears that bpf_jit_emit_tail_call() calls |
| bpf_jit_emit_common_epilogue() while ctx->seen might not |
| be stable. |
| |
| Only after the second pass we can be sure ctx->seen wont be changed. |
| |
| Trying to avoid a second pass seems quite complex and probably |
| not worth it. |
| |
| Fixes: ce0761419faef ("powerpc/bpf: Implement support for tail calls") |
| Signed-off-by: Eric Dumazet <edumazet@google.com> |
| Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> |
| Cc: Naveen N. Rao <naveen.n.rao@linux.ibm.com> |
| Cc: Sandipan Das <sandipan@linux.ibm.com> |
| Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> |
| Cc: Paul Mackerras <paulus@samba.org> |
| Cc: Michael Ellerman <mpe@ellerman.id.au> |
| Cc: Martin KaFai Lau <kafai@fb.com> |
| Cc: Song Liu <songliubraving@fb.com> |
| Cc: Yonghong Song <yhs@fb.com> |
| Link: https://lore.kernel.org/bpf/20191101033444.143741-1-edumazet@google.com |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c |
| index c2ee6041f02c..4d09d0a6e899 100644 |
| --- a/arch/powerpc/net/bpf_jit_comp64.c |
| +++ b/arch/powerpc/net/bpf_jit_comp64.c |
| @@ -1112,6 +1112,19 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp) |
| } |
| |
| /* |
| + * If we have seen a tail call, we need a second pass. |
| + * This is because bpf_jit_emit_common_epilogue() is called |
| + * from bpf_jit_emit_tail_call() with a not yet stable ctx->seen. |
| + */ |
| + if (cgctx.seen & SEEN_TAILCALL) { |
| + cgctx.idx = 0; |
| + if (bpf_jit_build_body(fp, 0, &cgctx, addrs, false)) { |
| + fp = org_fp; |
| + goto out_addrs; |
| + } |
| + } |
| + |
| + /* |
| * Pretend to build prologue, given the features we've seen. This will |
| * update ctgtx.idx as it pretends to output instructions, then we can |
| * calculate total size from idx. |
| -- |
| 2.7.4 |
| |