]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
bpf: Clear packet pointers after changing packet data in kfuncs
authorAmery Hung <ameryhung@gmail.com>
Mon, 22 Sep 2025 23:33:52 +0000 (16:33 -0700)
committerMartin KaFai Lau <martin.lau@kernel.org>
Tue, 23 Sep 2025 20:35:12 +0000 (13:35 -0700)
bpf_xdp_pull_data() may change packet data and therefore packet pointers
need to be invalidated. Add bpf_xdp_pull_data() to the special kfunc
list instead of introducing a new KF_ flag until there are more kfuncs
changing packet data.

Signed-off-by: Amery Hung <ameryhung@gmail.com>
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
Link: https://patch.msgid.link/20250922233356.3356453-5-ameryhung@gmail.com
kernel/bpf/verifier.c

index 5964bed40ffbf0083b385d931a1550453c0c8636..a1dd3c31a09e63d289d6dc39d9a304bf00ed2eba 100644 (file)
@@ -12235,6 +12235,7 @@ enum special_kfunc_type {
        KF_bpf_dynptr_from_skb,
        KF_bpf_dynptr_from_xdp,
        KF_bpf_dynptr_from_skb_meta,
+       KF_bpf_xdp_pull_data,
        KF_bpf_dynptr_slice,
        KF_bpf_dynptr_slice_rdwr,
        KF_bpf_dynptr_clone,
@@ -12285,10 +12286,12 @@ BTF_ID(func, bpf_rbtree_right)
 BTF_ID(func, bpf_dynptr_from_skb)
 BTF_ID(func, bpf_dynptr_from_xdp)
 BTF_ID(func, bpf_dynptr_from_skb_meta)
+BTF_ID(func, bpf_xdp_pull_data)
 #else
 BTF_ID_UNUSED
 BTF_ID_UNUSED
 BTF_ID_UNUSED
+BTF_ID_UNUSED
 #endif
 BTF_ID(func, bpf_dynptr_slice)
 BTF_ID(func, bpf_dynptr_slice_rdwr)
@@ -12358,6 +12361,11 @@ static bool is_kfunc_bpf_preempt_enable(struct bpf_kfunc_call_arg_meta *meta)
        return meta->func_id == special_kfunc_list[KF_bpf_preempt_enable];
 }
 
+static bool is_kfunc_pkt_changing(struct bpf_kfunc_call_arg_meta *meta)
+{
+       return meta->func_id == special_kfunc_list[KF_bpf_xdp_pull_data];
+}
+
 static enum kfunc_ptr_arg_type
 get_kfunc_ptr_arg_type(struct bpf_verifier_env *env,
                       struct bpf_kfunc_call_arg_meta *meta,
@@ -14077,6 +14085,9 @@ static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
                }
        }
 
+       if (is_kfunc_pkt_changing(&meta))
+               clear_all_pkt_pointers(env);
+
        nargs = btf_type_vlen(meta.func_proto);
        args = (const struct btf_param *)(meta.func_proto + 1);
        for (i = 0; i < nargs; i++) {
@@ -17794,6 +17805,8 @@ static int visit_insn(int t, struct bpf_verifier_env *env)
                         */
                        if (ret == 0 && is_kfunc_sleepable(&meta))
                                mark_subprog_might_sleep(env, t);
+                       if (ret == 0 && is_kfunc_pkt_changing(&meta))
+                               mark_subprog_changes_pkt_data(env, t);
                }
                return visit_func_call_insn(t, insns, env, insn->src_reg == BPF_PSEUDO_CALL);