From nobody Sun Apr 5 16:33:19 2026 Received: from dggsgout11.his.huawei.com (dggsgout11.his.huawei.com [45.249.212.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0E0882853EE; Tue, 24 Mar 2026 11:54:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774353284; cv=none; b=VFE2BpzHMwZeXSYloPr9vAkgit5elhg+U0XBBaWXaTiM5f/jxFcfhtPRWAukw4MN1OwL0V8M5SPQDcunqoIZK+sEubKTtGn1vnVJTQPWy25ILKWRIKdrwsPzI0T7BEftJ5X/G9tD4ODyNTdSZPJJnhFvpSLXZIAkvvGDTX5Qaxk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774353284; c=relaxed/simple; bh=FjgMUY1XqHPv2g7QJYGJMMEYJVZcSe1PtNdo674ry/g=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Jrs7tocY3uATgjyTz8XXVCbbwcAAgaUr3Vn+cAeFZE1+UXzDI5hI0S0v9PCJTSpaZR8UJh8MJZ0BPwcF1kiwJXZsvf0gD0Si7eELpuGg3zmKe+s0W9Lyh7Q36R3anxTQlx7qUb3fdpH8S2w+Cs7lNdRONp0npfj398N8qm2sGkk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.198]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTPS id 4fg7kH0nSJzYQv3J; Tue, 24 Mar 2026 19:54:31 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id AE98E40579; Tue, 24 Mar 2026 19:54:39 +0800 (CST) Received: from k01.k01 (unknown [10.67.174.197]) by APP1 (Coremail) with SMTP id cCh0CgAXGdl7e8Jpv2M5CA--.508S5; Tue, 24 Mar 2026 19:54:39 +0800 (CST) From: Xu Kuohai To: bpf@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Martin KaFai Lau , Eduard Zingerman , Yonghong Song , Puranjay Mohan , Anton Protopopov , =?UTF-8?q?Alexis=20Lothor=C3=A9?= , Shahab Vahedi , Russell King , Tiezhu Yang , Hengqi Chen , Johan Almbladh , Paul Burton , Hari Bathini , Christophe Leroy , Naveen N Rao , Luke Nelson , Xi Wang , =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= , Pu Lehui , Ilya Leoshkevich , Heiko Carstens , Vasily Gorbik , "David S . Miller" , Wang YanQing Subject: [PATCH bpf-next v10 3/5] bpf: Add helper to detect indirect jump targets Date: Tue, 24 Mar 2026 20:20:50 +0800 Message-ID: <20260324122052.342751-4-xukuohai@huaweicloud.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260324122052.342751-1-xukuohai@huaweicloud.com> References: <20260324122052.342751-1-xukuohai@huaweicloud.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: cCh0CgAXGdl7e8Jpv2M5CA--.508S5 X-Coremail-Antispam: 1UD129KBjvJXoWxAFWDGF4UZF17XF47Gw4fuFg_yoW7JF17pF 4DW3s3Ar4kuFZrWr9rAa1jyry3Ja1rW345GFWxC348AayYqr1vqFWFgr1YvF95trZ5C3Wx ZF4jvr4UWFyUZFJanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUPab4IE77IF4wAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUWw A2048vs2IY020Ec7CjxVAFwI0_Xr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxS w2x7M28EF7xvwVC0I7IYx2IY67AKxVW7JVWDJwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxV W8Jr0_Cr1UM28EF7xvwVC2z280aVAFwI0_GcCE3s1l84ACjcxK6I8E87Iv6xkF7I0E14v2 6rxl6s0DM2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F40Ex7xfMc Ij6xIIjxv20xvE14v26r1j6r18McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC6x0Yz7v_ Jr0_Gr1lF7xvr2IYc2Ij64vIr41lFIxGxcIEc7CjxVA2Y2ka0xkIwI1lc7CjxVAaw2AFwI 0_GFv_Wryl42xK82IYc2Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG 67AKxVWUJVWUGwC20s026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r4a6rW5MI IYrxkI7VAKI48JMIIF0xvE2Ix0cI8IcVAFwI0_Jr0_JF4lIxAIcVC0I7IYx2IY6xkF7I0E 14v26r4UJVWxJr1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r 1j6r4UMIIF0xvEx4A2jsIEc7CjxVAFwI0_Gr1j6F4UJbIYCTnIWIevJa73UjIFyTuYvjxU IF4iUUUUU X-CM-SenderInfo: 50xn30hkdlqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" From: Xu Kuohai Introduce helper bpf_insn_is_indirect_target to check whether a BPF instruction is an indirect jump target. Since the verifier knows which instructions are indirect jump targets, add a new flag indirect_target to struct bpf_insn_aux_data to mark them. The verifier sets this flag when verifying an indirect jump target instruction, and the helper checks the flag to determine whether an instruction is an indirect jump target. Reviewed-by: Anton Protopopov Signed-off-by: Xu Kuohai --- include/linux/bpf.h | 2 ++ include/linux/bpf_verifier.h | 9 +++++---- kernel/bpf/core.c | 9 +++++++++ kernel/bpf/verifier.c | 18 ++++++++++++++++++ 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 05b34a6355b0..90760e250865 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -1541,6 +1541,8 @@ bool bpf_has_frame_pointer(unsigned long ip); int bpf_jit_charge_modmem(u32 size); void bpf_jit_uncharge_modmem(u32 size); bool bpf_prog_has_trampoline(const struct bpf_prog *prog); +bool bpf_insn_is_indirect_target(const struct bpf_verifier_env *env, const= struct bpf_prog *prog, + int insn_idx); #else static inline int bpf_trampoline_link_prog(struct bpf_tramp_link *link, struct bpf_trampoline *tr, diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h index 090aa26d1c98..6431b94746cf 100644 --- a/include/linux/bpf_verifier.h +++ b/include/linux/bpf_verifier.h @@ -578,16 +578,17 @@ struct bpf_insn_aux_data { =20 /* below fields are initialized once */ unsigned int orig_idx; /* original instruction index */ - bool jmp_point; - bool prune_point; + u32 jmp_point:1; + u32 prune_point:1; /* ensure we check state equivalence and save state checkpoint and * this instruction, regardless of any heuristics */ - bool force_checkpoint; + u32 force_checkpoint:1; /* true if instruction is a call to a helper function that * accepts callback function as a parameter. */ - bool calls_callback; + u32 calls_callback:1; + u32 indirect_target:1; /* if it is an indirect jump target */ /* * CFG strongly connected component this instruction belongs to, * zero if it is a singleton SCC. diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index fa3d6d8d76da..6e0c3f327144 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -1572,6 +1572,15 @@ struct bpf_prog *bpf_jit_blind_constants(struct bpf_= verifier_env *env, struct bp clone->blinded =3D 1; return clone; } + +bool bpf_insn_is_indirect_target(const struct bpf_verifier_env *env, const= struct bpf_prog *prog, + int insn_idx) +{ + if (!env) + return false; + insn_idx +=3D prog->aux->subprog_start; + return env->insn_aux_data[insn_idx].indirect_target; +} #endif /* CONFIG_BPF_JIT */ =20 /* Base function for offset calculation. Needs to go into .text section, diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 89fb700d818f..3b81747a1b61 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -4028,6 +4028,11 @@ static bool is_jmp_point(struct bpf_verifier_env *en= v, int insn_idx) return env->insn_aux_data[insn_idx].jmp_point; } =20 +static void mark_indirect_target(struct bpf_verifier_env *env, int idx) +{ + env->insn_aux_data[idx].indirect_target =3D true; +} + #define LR_FRAMENO_BITS 3 #define LR_SPI_BITS 6 #define LR_ENTRY_BITS (LR_SPI_BITS + LR_FRAMENO_BITS + 1) @@ -21117,12 +21122,14 @@ static int check_indirect_jump(struct bpf_verifie= r_env *env, struct bpf_insn *in } =20 for (i =3D 0; i < n - 1; i++) { + mark_indirect_target(env, env->gotox_tmp_buf->items[i]); other_branch =3D push_stack(env, env->gotox_tmp_buf->items[i], env->insn_idx, env->cur_state->speculative); if (IS_ERR(other_branch)) return PTR_ERR(other_branch); } env->insn_idx =3D env->gotox_tmp_buf->items[n-1]; + mark_indirect_target(env, env->insn_idx); return 0; } =20 @@ -22048,6 +22055,17 @@ static void adjust_insn_aux_data(struct bpf_verifi= er_env *env, data[i].seen =3D old_seen; data[i].zext_dst =3D insn_has_def32(insn + i); } + + /* The indirect_target flag of the original instruction was moved to the = last of the + * new instructions by the above memmove and memset, but the indirect jum= p target is + * actually the first instruction, so move it back. This also matches wit= h the behavior + * of bpf_insn_array_adjust(), which preserves xlated_off to point to the= first new + * instruction. + */ + if (data[off + cnt - 1].indirect_target) { + data[off].indirect_target =3D 1; + data[off + cnt - 1].indirect_target =3D 0; + } } =20 static void adjust_subprog_starts(struct bpf_verifier_env *env, u32 off, u= 32 len) --=20 2.47.3