From: Edward Cree <hidden> Date: 2017-09-14 17:53:31
Is BPF_END supposed to only be used with BPF_ALU, never with BPF_ALU64?
In kernel/bpf/core.c:___bpf_prog_run(), there are only jump table targets
for the BPF_ALU case, not for the BPF_ALU64 case (opcodes 0xd7 and 0xdf).
But the verifier doesn't enforce this; by crafting a program that uses
these opcodes I can get a WARN when they're run (without JIT; it looks
like the x86 JIT, at least, won't like it either).
Proposed patch below the cut; build-tested only.
-Ed
---
[PATCH net] bpf/verifier: reject BPF_ALU64|BPF_END
Neither ___bpf_prog_run nor the JITs accept it.
Fixes: 17a5267067f3 ("bpf: verifier (add verifier core)")
Signed-off-by: Edward Cree <redacted>
---
kernel/bpf/verifier.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
Is BPF_END supposed to only be used with BPF_ALU, never with BPF_ALU64?
In kernel/bpf/core.c:___bpf_prog_run(), there are only jump table targets
for the BPF_ALU case, not for the BPF_ALU64 case (opcodes 0xd7 and 0xdf).
But the verifier doesn't enforce this; by crafting a program that uses
these opcodes I can get a WARN when they're run (without JIT; it looks
like the x86 JIT, at least, won't like it either).
Proposed patch below the cut; build-tested only.
Good catch.
A really neat test would be a program that uploads random BPF programs
into the kernel, in a syzkaller'ish way. It might have triggered this
(eventually).
Is BPF_END supposed to only be used with BPF_ALU, never with BPF_ALU64?
Yes, only BPF_ALU. The below is LLVM bpf swap insn encoding:
...
// bswap16, bswap32, bswap64
class BSWAP ...
...
let op = 0xd; // BPF_END
let BPFSrc = 1; // BPF_TO_BE (TODO: use BPF_TO_LE for big-endian target)
let BPFClass = 4; // BPF_ALU
...
quoted
In kernel/bpf/core.c:___bpf_prog_run(), there are only jump table targets
for the BPF_ALU case, not for the BPF_ALU64 case (opcodes 0xd7 and 0xdf).
But the verifier doesn't enforce this; by crafting a program that uses
these opcodes I can get a WARN when they're run (without JIT; it looks
like the x86 JIT, at least, won't like it either).
Proposed patch below the cut; build-tested only.
Good catch.
A really neat test would be a program that uploads random BPF programs
into the kernel, in a syzkaller'ish way. It might have triggered this
(eventually).
From: Daniel Borkmann <daniel@iogearbox.net> Date: 2017-09-14 23:05:02
On 09/14/2017 07:53 PM, Edward Cree wrote:
Is BPF_END supposed to only be used with BPF_ALU, never with BPF_ALU64?
In kernel/bpf/core.c:___bpf_prog_run(), there are only jump table targets
for the BPF_ALU case, not for the BPF_ALU64 case (opcodes 0xd7 and 0xdf).
But the verifier doesn't enforce this; by crafting a program that uses
these opcodes I can get a WARN when they're run (without JIT; it looks
like the x86 JIT, at least, won't like it either).
Proposed patch below the cut; build-tested only.
-Ed
---
[PATCH net] bpf/verifier: reject BPF_ALU64|BPF_END
Neither ___bpf_prog_run nor the JITs accept it.
Fixes: 17a5267067f3 ("bpf: verifier (add verifier core)")
Signed-off-by: Edward Cree <redacted>
Good catch! Can you submit this as an official patch for -net together
with a test case for tools/testing/selftests/bpf/test_verifier.c?
Thanks!
Acked-by: Daniel Borkmann <daniel@iogearbox.net>