Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc/bpf: Fix write protecting JIT code

Running program with bpf-to-bpf function calls results in data access
exception (0x300) with the below call trace:

bpf_int_jit_compile+0x238/0x750 (unreliable)
bpf_check+0x2008/0x2710
bpf_prog_load+0xb00/0x13a0
__sys_bpf+0x6f4/0x27c0
sys_bpf+0x2c/0x40
system_call_exception+0x164/0x330
system_call_vectored_common+0xe8/0x278

as bpf_int_jit_compile() tries writing to write protected JIT code
location during the extra pass.

Fix it by holding off write protection of JIT code until the extra
pass, where branch target addresses fixup happens.

Fixes: 62e3d4210ac9 ("powerpc/bpf: Write protect JIT code")
Cc: stable@vger.kernel.org # v5.14+
Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
Reviewed-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20211025055649.114728-1-hbathini@linux.ibm.com

authored by

Hari Bathini and committed by
Michael Ellerman
44a8214d cb662608

+1 -1
+1 -1
arch/powerpc/net/bpf_jit_comp.c
··· 237 237 fp->jited_len = alloclen; 238 238 239 239 bpf_flush_icache(bpf_hdr, (u8 *)bpf_hdr + (bpf_hdr->pages * PAGE_SIZE)); 240 - bpf_jit_binary_lock_ro(bpf_hdr); 241 240 if (!fp->is_func || extra_pass) { 241 + bpf_jit_binary_lock_ro(bpf_hdr); 242 242 bpf_prog_fill_jited_linfo(fp, addrs); 243 243 out_addrs: 244 244 kfree(addrs);