On Mon, 2024-08-12 at 12:29 -0700, Alexei Starovoitov wrote: [...] > > It does not seem correct to swap the order for these two checks: > > > > if (exact != NOT_EXACT && i < cur->allocated_stack && > > old->stack[spi].slot_type[i % BPF_REG_SIZE] != > > cur->stack[spi].slot_type[i % BPF_REG_SIZE]) > > return false; > > > > if (!(old->stack[spi].spilled_ptr.live & REG_LIVE_READ) > > && exact == NOT_EXACT) { > > i += BPF_REG_SIZE - 1; > > /* explored state didn't use this */ > > continue; > > } > > > > if we do, 'slot_type' won't be checked for 'cur' when 'old' register is not marked live. > > I see. This is to compare states in open coded iter loops when liveness > is not propagated yet, right? Yes > > Then when comparing for exact states we should probably do: > if (exact != NOT_EXACT && > (i >= cur->allocated_stack || > old->stack[spi].slot_type[i % BPF_REG_SIZE] != > cur->stack[spi].slot_type[i % BPF_REG_SIZE])) > return false; > > ? Hm, right, otherwise the old slots in the interval [cur->allocated_stack..old->allocated_stack) won't be checked using exact rules.