On Tue, 2024-01-09 at 16:36 +0100, Hao Sun wrote: > For PTR_TO_FLOW_KEYS, check_flow_keys_access() only uses fixed off > for validation. However, variable offset ptr alu is not prohibited > for this ptr kind. So the variable offset is not checked. > [...] > > Fixes: d58e468b1112 ("flow_dissector: implements flow dissector BPF hook") > Signed-off-by: Hao Sun <sunhao.th@xxxxxxxxx> > --- > kernel/bpf/verifier.c | 4 ++++ > 1 file changed, 4 insertions(+) > > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c > index adbf330d364b..65f598694d55 100644 > --- a/kernel/bpf/verifier.c > +++ b/kernel/bpf/verifier.c > @@ -12826,6 +12826,10 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, > } > > switch (base_type(ptr_reg->type)) { > + case PTR_TO_FLOW_KEYS: > + if (known) > + break; > + fallthrough; > case CONST_PTR_TO_MAP: > /* smin_val represents the known value */ > if (known && smin_val == 0 && opcode == BPF_ADD) This change makes sense, could you please add a testcase? Also, this switch is written to explicitly disallow and implicitly allow pointer arithmetics, which might be a bit unsafe when new ptr types are added. Would it make more sense to instead rewrite it to explicitly allow? E.g. here is what it currently allows / disallows: | Pointer type | Arithmetics allowed | |---------------------+---------------------| | PTR_TO_CTX | yes | | CONST_PTR_TO_MAP | conditionally | | PTR_TO_MAP_VALUE | yes | | PTR_TO_MAP_KEY | yes | | PTR_TO_STACK | yes | | PTR_TO_PACKET_META | yes | | PTR_TO_PACKET | yes | | PTR_TO_PACKET_END | no | | PTR_TO_FLOW_KEYS | yes | | PTR_TO_SOCKET | no | | PTR_TO_SOCK_COMMON | no | | PTR_TO_TCP_SOCK | no | | PTR_TO_TP_BUFFER | yes | | PTR_TO_XDP_SOCK | no | | PTR_TO_BTF_ID | yes | | PTR_TO_MEM | yes | | PTR_TO_BUF | yes | | PTR_TO_FUNC | yes | | CONST_PTR_TO_DYNPTR | yes | Of these PTR_TO_FUNC and CONST_PTR_TO_DYNPTR (?) should not be allowed as well, probably (not sure if that could be exploited).