Previous commit changed BPF verifier to track pointer offsets entirely in bpf_reg_state->var_off. This commit removes references to bpf_reg_state->off in netronome code. - In most of the places `.off` field is used as a part of a sum: `reg->off + reg->var_off.value`. In such code the `reg->off` addend is removed. - Function jit.c:cross_mem_access() uses `.off` but ignores `.var_off` to compute memory access offset. Here access to `.off` is replaced with access to `.var_off.value`. verifier.c:nfp_bpf_check_ptr() rejects programs for which !tnum_is_const(reg->var_off), so the above change will read a valid constant. Not sure why `.var_off` was ignored in this function previously. Signed-off-by: Eduard Zingerman --- drivers/net/ethernet/netronome/nfp/bpf/jit.c | 18 ++++++++---------- drivers/net/ethernet/netronome/nfp/bpf/verifier.c | 12 ++++++------ 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/drivers/net/ethernet/netronome/nfp/bpf/jit.c b/drivers/net/ethernet/netronome/nfp/bpf/jit.c index 3a02eef58cc6d977fcd130e0b69947deff468d3f..c9ab55abfd4c5d72e63f3f5b089915298a06c121 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/jit.c +++ b/drivers/net/ethernet/netronome/nfp/bpf/jit.c @@ -1731,7 +1731,7 @@ map_call_stack_common(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta) /* We only have to reload LM0 if the key is not at start of stack */ lm_off = nfp_prog->stack_frame_depth; - lm_off += meta->arg2.reg.var_off.value + meta->arg2.reg.off; + lm_off += meta->arg2.reg.var_off.value; load_lm_ptr = meta->arg2.var_off || lm_off; /* Set LM0 to start of key */ @@ -2874,8 +2874,7 @@ mem_ldx(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta, } if (meta->ptr.type == PTR_TO_STACK) - return mem_ldx_stack(nfp_prog, meta, size, - meta->ptr.off + meta->ptr.var_off.value); + return mem_ldx_stack(nfp_prog, meta, size, meta->ptr.var_off.value); if (meta->ptr.type == PTR_TO_MAP_VALUE) return mem_ldx_emem(nfp_prog, meta, size); @@ -2985,8 +2984,7 @@ mem_stx(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta, return mem_stx_data(nfp_prog, meta, size); if (meta->ptr.type == PTR_TO_STACK) - return mem_stx_stack(nfp_prog, meta, size, - meta->ptr.off + meta->ptr.var_off.value); + return mem_stx_stack(nfp_prog, meta, size, meta->ptr.var_off.value); return -EOPNOTSUPP; } @@ -4153,9 +4151,9 @@ cross_mem_access(struct bpf_insn *ld, struct nfp_insn_meta *head_ld_meta, /* Canonicalize the offsets. Turn all of them against the original * base register. */ - head_ld_off = head_ld_meta->insn.off + head_ld_meta->ptr.off; - head_st_off = head_st_meta->insn.off + head_st_meta->ptr.off; - ld_off = ld->off + head_ld_meta->ptr.off; + head_ld_off = head_ld_meta->insn.off + head_ld_meta->ptr.var_off.value; + head_st_off = head_st_meta->insn.off + head_st_meta->ptr.var_off.value; + ld_off = ld->off + head_ld_meta->ptr.var_off.value; /* Ascending order cross. */ if (ld_off > head_ld_off && @@ -4326,7 +4324,7 @@ static void nfp_bpf_opt_pkt_cache(struct nfp_prog *nfp_prog) * support this. */ if (meta->ptr.id == range_ptr_id && - meta->ptr.off == range_ptr_off) { + meta->ptr.var_off.value == range_ptr_off) { s16 new_start = range_start; s16 end, off = insn->off; s16 new_end = range_end; @@ -4361,7 +4359,7 @@ static void nfp_bpf_opt_pkt_cache(struct nfp_prog *nfp_prog) range_node = meta; range_node->pkt_cache.do_init = true; range_ptr_id = range_node->ptr.id; - range_ptr_off = range_node->ptr.off; + range_ptr_off = range_node->ptr.var_off.value; range_start = insn->off; range_end = insn->off + BPF_LDST_BYTES(insn); } diff --git a/drivers/net/ethernet/netronome/nfp/bpf/verifier.c b/drivers/net/ethernet/netronome/nfp/bpf/verifier.c index 9d235c0ce46a8149370131d4e7b403ad3224b955..2893be0f9f18c7084fd75c1c09a8dff298689f0c 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/verifier.c +++ b/drivers/net/ethernet/netronome/nfp/bpf/verifier.c @@ -98,7 +98,7 @@ static bool nfp_bpf_map_update_value_ok(struct bpf_verifier_env *env) offmap = map_to_offmap(reg1->map_ptr); nfp_map = offmap->dev_priv; - off = reg3->off + reg3->var_off.value; + off = reg3->var_off.value; for (i = 0; i < offmap->map.value_size; i++) { struct bpf_stack_state *stack_entry; @@ -137,7 +137,7 @@ nfp_bpf_stack_arg_ok(const char *fname, struct bpf_verifier_env *env, return false; } - off = reg->var_off.value + reg->off; + off = reg->var_off.value; if (-off % 4) { pr_vlog(env, "%s: unaligned stack pointer %lld\n", fname, -off); return false; @@ -147,7 +147,7 @@ nfp_bpf_stack_arg_ok(const char *fname, struct bpf_verifier_env *env, if (!old_arg) return true; - old_off = old_arg->reg.var_off.value + old_arg->reg.off; + old_off = old_arg->reg.var_off.value; old_arg->var_off |= off != old_off; return true; @@ -358,8 +358,8 @@ nfp_bpf_check_stack_access(struct nfp_prog *nfp_prog, if (meta->ptr.type == NOT_INIT) return 0; - old_off = meta->ptr.off + meta->ptr.var_off.value; - new_off = reg->off + reg->var_off.value; + old_off = meta->ptr.var_off.value; + new_off = reg->var_off.value; meta->ptr_not_const |= old_off != new_off; @@ -428,7 +428,7 @@ nfp_bpf_map_mark_used(struct bpf_verifier_env *env, struct nfp_insn_meta *meta, return -EOPNOTSUPP; } - off = reg->var_off.value + meta->insn.off + reg->off; + off = reg->var_off.value + meta->insn.off; size = BPF_LDST_BYTES(&meta->insn); offmap = map_to_offmap(reg->map_ptr); nfp_map = offmap->dev_priv; -- 2.51.1