From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 311F933372A; Tue, 13 Oct 2026 12:25:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791894307; cv=none; b=rSxurnGJRkOus9OMNQG4YgZk1VGvXWGCjnFO21bGwXkWw2dbKWlhSiOls/qFRRAu3I5zODKQcWhzmXm6XsMrCpf+dCfzSS7Vh0W0RBlYJKK3mTAxEO5XhzLmVhrSG2yWxTVj42rcd93bHQSDncNtzZyUdIBnkw9NBLnBuebtox4= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791894307; c=relaxed/simple; bh=EiMiYblAFOfPnoym7Rp2cXKc9m/yslrizN6kOi4L9oA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hspPkSLORyFNOB4tzaMMDKbVIos7CBXPVKu7XJM7jRXaBceibZ5c2LkCcTEoHlc9Vdft15IxXK7YddJEgdnSOHZPCeNk6hVY3lFTXhXrDwkkWACml2RDofwv7f/jGczGlqSHsLpiPyRfRA3TcN7FuDwGGYkwY8gd5SEovfSKfzE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=j3avtiX0; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="j3avtiX0" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3FCAF1F000FF; Tue, 13 Oct 2026 12:25:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1791894305; bh=MJre9XkeEDQc9sJtZ2be7I8IpUievbW+QMRhH8OkEf8=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=j3avtiX0DFlnnMCV+kq1SLoH4wdW1DofsFCvbMwzTtiaNAFC9IOBOZfQIUWrg/9oN BHSRwblCQsqir8Uo6sQvIcAWxWAwKPguOruTDIy4FXjbB+AURcY2pb33UDFZ36FSXf ID4CEoFEMMPmSiMbvw7/ZkFHT+MYNFmQLEDbVYLE= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Nicholas Carlini , Eduard Zingerman , Alexei Starovoitov , Sasha Levin Subject: [PATCH 6.18 515/621] bpf: dont rewrite bpf_fastcall patterns entered by a jump Date: Tue, 13 Oct 2026 13:38:30 +0200 Message-ID: <20261013112933.047053077@linuxfoundation.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261013112920.855194808@linuxfoundation.org> References: <20261013112920.855194808@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Eduard Zingerman [ Upstream commit 0b1c83dc3c4401cd7e846548f62e3caf3d06742e ] mark_fastcall_pattern_for_call() must ensure that matched "spill; call; fill" instruction series is not interrupted by a jump. Otherwise the rewrite applied by bpf_remove_fastcall_spills_fills() is not sound. Record the instructions targeted by jumps in insn_aux_data[*].jump_target when the CFG is built and use this flag to stop growing a pattern at such an instruction. Jumps to the first spill are fine. Note that existing insn_aux_data[*].jmp_point field can't be reused, as it marks subprogram return instructions. Fixes: 5b5f51bff1b6 ("bpf: no_caller_saved_registers attribute for helper calls") Reported-by: Nicholas Carlini Suggested-by: Nicholas Carlini Signed-off-by: Eduard Zingerman Link: https://lore.kernel.org/r/20260903205820.1743087-1-eddyz87@gmail.com Signed-off-by: Alexei Starovoitov Signed-off-by: Sasha Levin --- include/linux/bpf_verifier.h | 2 ++ kernel/bpf/verifier.c | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h index d305d30ebe95c..56a6c5b8625d8 100644 --- a/include/linux/bpf_verifier.h +++ b/include/linux/bpf_verifier.h @@ -580,6 +580,8 @@ struct bpf_insn_aux_data { * accepts callback function as a parameter. */ bool calls_callback; + /* true if some jump or call instruction targets this instruction */ + bool jump_target; /* * CFG strongly connected component this instruction belongs to, * zero if it is a singleton SCC. diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 0e9218f74cf3c..971446e05187c 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -3889,6 +3889,16 @@ static bool is_jmp_point(struct bpf_verifier_env *env, int insn_idx) return env->insn_aux_data[insn_idx].jmp_point; } +static void mark_jump_target(struct bpf_verifier_env *env, int idx) +{ + env->insn_aux_data[idx].jump_target = true; +} + +static bool bpf_is_jump_target(struct bpf_verifier_env *env, int insn_idx) +{ + return env->insn_aux_data[insn_idx].jump_target; +} + #define LR_FRAMENO_BITS 3 #define LR_SPI_BITS 6 #define LR_ENTRY_BITS (LR_SPI_BITS + LR_FRAMENO_BITS + 1) @@ -18012,6 +18022,7 @@ static int push_insn(int t, int w, int e, struct bpf_verifier_env *env) /* mark branch target for state pruning */ mark_prune_point(env, w); mark_jmp_point(env, w); + mark_jump_target(env, w); } if (insn_state[w] == 0) { @@ -18206,6 +18217,10 @@ static bool get_call_summary(struct bpf_verifier_env *env, struct bpf_insn *call * r0 = *(u64 *)(r10 - 8); r0 += r1; * r0 += r1; exit; * exit; + * + * Both uses of the marks assume that a pattern is entered at its first + * spill and thus executes as a unit, hence a pattern is not grown past + * an instruction targeted by a jump. */ static void mark_fastcall_pattern_for_call(struct bpf_verifier_env *env, struct bpf_subprog_info *subprog, @@ -18244,6 +18259,10 @@ static void mark_fastcall_pattern_for_call(struct bpf_verifier_env *env, for (i = 1, off = lowest_off; i <= ARRAY_SIZE(caller_saved); ++i, off += BPF_REG_SIZE) { if (insn_idx - i < 0 || insn_idx + i >= env->prog->len) break; + /* stx/ldx/call must not be a jump targets, a jump to the first stx is fine */ + if (bpf_is_jump_target(env, insn_idx - i + 1) || + bpf_is_jump_target(env, insn_idx + i)) + break; stx = &insns[insn_idx - i]; ldx = &insns[insn_idx + i]; /* must be a stack spill/fill pair */ @@ -18429,6 +18448,7 @@ static int visit_insn(int t, struct bpf_verifier_env *env) mark_prune_point(env, t + off + 1); mark_jmp_point(env, t + off + 1); + mark_jump_target(env, t + off + 1); return ret; -- 2.53.0