[PATCH] bpf, powerpc: fix jit for seccomp_data access
Daniel Borkmann
daniel at iogearbox.net
Wed Feb 21 11:47:35 AEDT 2018
On 02/21/2018 01:33 AM, Michael Ellerman wrote:
> Mark Lord <mlord at pobox.com> writes:
>
>> I am using SECCOMP to filter syscalls on a ppc32 platform,
>> and noticed that the JIT compiler was failing on the BPF
>> even though the interpreter was working fine.
>>
>> The issue was that the compiler was missing one of the instructions
>> used by SECCOMP, so here is a patch to enable JIT for that instruction.
>>
>> Signed-Off-By: Mark Lord <mlord at pobox.com>
>
> Thanks.
>
> What is the failure mode without this patch? I assume when you have the
> JIT enabled the seccomp filter fails to load entirely? Or do we have
> logic to fall back to the interpreter?
The logic for all JITs is that once a BPF insn cannot be JITed then it falls
back to BPF interpreter. Here, since ppc32 is cBPF the path is: cBPF insn ->
cBPF JIT -> fail -> migrate cBPF to eBPF -> run in eBPF interpreter. In the
case where interpreter is compiled out (CONFIG_BPF_JIT_ALWAYS_ON), then the
filter is rejected.
> Either way we should probably back port to stable. I assume this has
> been broken since we originally added 32-bit support, so:
Note that arm32 before it was converted to be an eBPF JIT (eBPF JITs do handle
seccomp BPF in any case) was the only cBPF JIT that had it 'JIT-able', so
currently, other cBPF ones like sparc32 or mips32 don't translate it either.
Meaning, it would be nice to have as feature; I wouldn't necessarily frame
it as a bug though (or at least a stable-urgent one, imho, but I leave that
to you, of course).
> Fixes: eb84bab0fb38 ("ppc: Kconfig: Enable BPF JIT on ppc32")
> Cc: stable at vger.kernel.org # v4.1+
>
> cheers
>
>
>> --- old/arch/powerpc/net/bpf_jit_comp.c 2018-02-16 14:07:01.000000000 -0500
>> +++ linux/arch/powerpc/net/bpf_jit_comp.c 2018-02-20 14:41:20.805227494 -0500
>> @@ -329,6 +329,9 @@ static int bpf_jit_build_body(struct bpf
>> BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4);
>> PPC_LWZ_OFFS(r_A, r_skb, offsetof(struct sk_buff, len));
>> break;
>> + case BPF_LDX | BPF_W | BPF_ABS: /* A = *((u32 *)(seccomp_data + K)); */
>> + PPC_LWZ_OFFS(r_A, r_skb, K);
>> + break;
>> case BPF_LDX | BPF_W | BPF_LEN: /* X = skb->len; */
>> PPC_LWZ_OFFS(r_X, r_skb, offsetof(struct sk_buff, len));
>> break;
>> --
>> Mark Lord
>> Real-Time Remedies Inc.
>> mlord at pobox.com
More information about the Linuxppc-dev
mailing list