On Wed, Sep 25, 2024 at 10:24:01AM GMT, Alexei Starovoitov wrote: > On Tue, Sep 24, 2024 at 12:40 PM Daniel Xu <dxu@xxxxxxxxx> wrote: > > > > + > > +/* Returns constant key value if possible, else -1 */ > > +static long get_constant_map_key(struct bpf_verifier_env *env, > > + struct bpf_reg_state *key) > > +{ > > + struct bpf_func_state *state = func(env, key); > > + struct bpf_reg_state *reg; > > + int stack_off; > > + int slot; > > + int spi; > > + > > + if (key->type != PTR_TO_STACK) > > + return -1; > > + if (!tnum_is_const(key->var_off)) > > + return -1; > > + > > + stack_off = key->off + key->var_off.value; > > + slot = -stack_off - 1; > > + if (slot < 0) > > + /* Stack grew upwards */ > > The comment is misleading. > The verifier is supposed to catch this. > It's just this helper was called before the stack bounds > were checked? Yeah. Stack bounds checked in check_stack_access_within_bounds() as part of helper call argument checks. > Maybe the call can be done later? Maybe? The argument checking starts clobbering state so it'll probably be not very simple to pull information out after args are checked. I think the logic will probably be much easier to follow with current approach. But maybe I'm missing a simpler idea. > > > + return -1; > > + else if (slot >= state->allocated_stack) > > + /* Stack uninitialized */ > > + return -1; > > + > > + spi = slot / BPF_REG_SIZE; > > + reg = &state->stack[spi].spilled_ptr; > > + if (!tnum_is_const(reg->var_off)) > > + /* Stack value not statically known */ > > + return -1; > > + > > + return reg->var_off.value; > > +} > > Looks like the code is more subtle than it looks. > > I think it's better to guard it all with CAP_BPF. Ack.