At the moment any BPF_ADD or BPF_NEG with a pointer type will create a new pointer and destroy the register range. Then any memory access after this will fail because it looks like no bounds checking has been done, even if it was previously done on the other pointer. So patterns like this fail,
ptrA = pkt_data; if (ptrA + expected_payload > data_end) return 0; ptrA += 1 accum += *ptrA ptrA += 1 accum += *ptrA I did a quick look over the code and it seems like if the ALU op has a uma_val and it is less than the previous range, we can simply reduce the range by that amount and pull it into the new ptr. This patch does the above. --- kernel/bpf/verifier.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 610559a..c41f587 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -2830,8 +2830,10 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, dst_reg->off = ptr_reg->off; if (reg_is_pkt_pointer(ptr_reg)) { dst_reg->id = ++env->id_gen; - /* something was added to pkt_ptr, set range to zero */ - dst_reg->range = 0; + if (umax_val > dst_reg->range) + dst_reg->range = 0; + else + dst_reg->range -= umax_val; } break; case BPF_SUB: