Alexei Starovoitov wrote: > From: Alexei Starovoitov <ast@xxxxxxxxxx> > > The llvm register allocator may use two different registers representing the > same virtual register. In such case the following pattern can be observed: > 1047: (bf) r9 = r6 > 1048: (a5) if r6 < 0x1000 goto pc+1 > 1050: ... > 1051: (a5) if r9 < 0x2 goto pc+66 > 1052: ... > 1053: (bf) r2 = r9 /* r2 needs to have upper and lower bounds */ > > In order to track this information without backtracking allocate ID > for scalars in a similar way as it's done for find_good_pkt_pointers(). > > When the verifier encounters r9 = r6 assignment it will assign the same ID > to both registers. Later if either register range is narrowed via conditional > jump propagate the register state into the other register. > > Clear register ID in adjust_reg_min_max_vals() for any alu instruction. Do we also need to clear the register ID on reg0 for CALL ops into a helper? Looks like check_helper_call might mark reg0 as a scalar, but I don't see where it would clear the reg->id? Did I miss it. Either way maybe a comment here would help make it obvious how CALLs are handled? Thanks, John > > Newly allocated register ID is ignored for scalars in regsafe() and doesn't > affect state pruning. mark_reg_unknown() also clears the ID. > > Signed-off-by: Alexei Starovoitov <ast@xxxxxxxxxx> > --- > kernel/bpf/verifier.c | 38 +++++++++++++++++++ > .../testing/selftests/bpf/prog_tests/align.c | 16 ++++---- > .../bpf/verifier/direct_packet_access.c | 2 +- > 3 files changed, 47 insertions(+), 9 deletions(-) > > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c > index 01120acab09a..09e17b483b0b 100644 > --- a/kernel/bpf/verifier.c > +++ b/kernel/bpf/verifier.c > @@ -6432,6 +6432,8 @@ static int adjust_reg_min_max_vals(struct bpf_verifier_env *env, > src_reg = NULL; > if (dst_reg->type != SCALAR_VALUE) > ptr_reg = dst_reg; > + else > + dst_reg->id = 0; > if (BPF_SRC(insn->code) == BPF_X) { > src_reg = ®s[insn->src_reg]; > if (src_reg->type != SCALAR_VALUE) { > @@ -6565,6 +6567,8 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn) > /* case: R1 = R2 > * copy register state to dest reg > */ > + if (src_reg->type == SCALAR_VALUE) > + src_reg->id = ++env->id_gen; > *dst_reg = *src_reg; > dst_reg->live |= REG_LIVE_WRITTEN; > dst_reg->subreg_def = DEF_NOT_SUBREG; > @@ -7365,6 +7369,30 @@ static bool try_match_pkt_pointers(const struct bpf_insn *insn, > return true; > }