diff options
author | Yonghong Song <yhs@fb.com> | 2020-06-18 16:46:31 -0700 |
---|---|---|
committer | Daniel Borkmann <daniel@iogearbox.net> | 2020-06-19 23:34:42 +0200 |
commit | 6c6935419e2fd8ef1fcde71c4e50b9095e520900 (patch) | |
tree | 0e827993fe8351e8492d71f2a4d13fa680cd35f9 /tools/testing/selftests/bpf/verifier/value_ptr_arith.c | |
parent | 7c7982cbadbb63eb76401ddc4ef090cf7ae274b4 (diff) |
bpf: Avoid verifier failure for 32bit pointer arithmetic
When do experiments with llvm (disabling instcombine and
simplifyCFG), I hit the following error with test_seg6_loop.o.
; R1=pkt(id=0,off=0,r=48,imm=0), R7=pkt(id=0,off=40,r=48,imm=0)
w2 = w7
; R2_w=inv(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff))
w2 -= w1
R2 32-bit pointer arithmetic prohibited
The corresponding source code is:
uint32_t srh_off
// srh and skb->data are all packet pointers
srh_off = (char *)srh - (char *)(long)skb->data;
The verifier does not support 32-bit pointer/scalar arithmetic.
Without my llvm change, the code looks like
; R3=pkt(id=0,off=40,r=48,imm=0), R8=pkt(id=0,off=0,r=48,imm=0)
w3 -= w8
; R3_w=inv(id=0)
This is explicitly allowed in verifier if both registers are
pointers and the opcode is BPF_SUB.
To fix this problem, I changed the verifier to allow
32-bit pointer/scaler BPF_SUB operations.
At the source level, the issue could be workarounded with
inline asm or changing "uint32_t srh_off" to "uint64_t srh_off".
But I feel that verifier change might be the right thing to do.
Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: John Fastabend <john.fastabend@gmail.com>
Link: https://lore.kernel.org/bpf/20200618234631.3321118-1-yhs@fb.com
Diffstat (limited to 'tools/testing/selftests/bpf/verifier/value_ptr_arith.c')
0 files changed, 0 insertions, 0 deletions