From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (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 D7C673CB54A; Wed, 5 Aug 2026 06:08:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.156.1 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785910086; cv=none; b=qMN4UHTERNCPQ+mgRs8xqN5/uIkzTM9Bln8dENJBJKjqH8S+4xQO1LZUJYwTipSdPi/mQBZgz9xVXTlpWXPUmc5WTFH1HghEdFxYKaCRklxBgUlmXY92PzPda0wTgs5QrUPfS+HYG11ixkBzE9aHbl+40MR2TpLskKBRqL4L8ps= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785910086; c=relaxed/simple; bh=JobXSihsFa055QDolhBCncphvZ+rd+MhUEYk5+qneMI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=H0ToWAKxveWx1qa+Yr8Ia5gXWHNFuNRXMRUyt3UWzT3Ify+BddxOz23bYeyXomy5deQIf1oxXbWphLC0X6Bc5lT3JZLSMEWpGnLtUUgEr8B81+I9LWYQqb0zsMN3onsn7t4D39hYOn7Jso342DCeERBniCgDkO/knwYe5KIMiTM= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=kUwYOyxb; arc=none smtp.client-ip=148.163.156.1 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="kUwYOyxb" Received: from pps.filterd (m0356517.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 6755mHKB3005943; Wed, 5 Aug 2026 06:07:46 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=KBcDtZLPwVQ7VCYkQ J8d6HsLEpBHOjdVJIqNO1zyfWM=; b=kUwYOyxbxELu8ocBduwND8xAzlU7vhvKL 1+zqIdObQSvXnn35009E43Ru/MfGty3VTphnFtKhQqoikn6DyMv1MjJOu2GLen4k EJoopCeJv+RNnH8DS8eV8lJ3kjoOgTUB1SAoVeM5Ezyk9Rs8NnHyBzBgYt0e8u9R foTYAdH+yvdhb8gNQlrXxW4PPoBmwPD/YdGsB7WaZCyG8Zkfnc3bTfGpfIx6ucKW F/d7n4gU1Lp1rx+XXXQ9v/7YLruLIzbTw3N6FCvMCgegO/D8/oTJDeU3Og+8AV94 iucEHlYjOOG3m+fZO0wfUJqrtxw8MJ5veEB7/0VEeWoPdvqlDzoiA== Received: from ppma22.wdc07v.mail.ibm.com (5c.69.3da9.ip4.static.sl-reverse.com [169.61.105.92]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4fs8h51j4n-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 05 Aug 2026 06:07:45 +0000 (GMT) Received: from pps.filterd (ppma22.wdc07v.mail.ibm.com [127.0.0.1]) by ppma22.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 6755ucXU007362; Wed, 5 Aug 2026 06:07:44 GMT Received: from smtprelay04.fra02v.mail.ibm.com ([9.218.2.228]) by ppma22.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4fsugw5byh-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 05 Aug 2026 06:07:44 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (smtpav01.fra02v.mail.ibm.com [10.20.54.100]) by smtprelay04.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 67567euk30605996 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 5 Aug 2026 06:07:40 GMT Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 9D0E620043; Wed, 5 Aug 2026 06:07:40 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 458D820040; Wed, 5 Aug 2026 06:07:37 +0000 (GMT) Received: from li-1cb9f04c-2ae1-11b2-a85c-a8a0a83790a8.ibm.com.com (unknown [9.124.213.166]) by smtpav01.fra02v.mail.ibm.com (Postfix) with ESMTP; Wed, 5 Aug 2026 06:07:37 +0000 (GMT) From: Saket Kumar Bhaskar To: bpf@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Cc: hbathini@linux.ibm.com, maddy@linux.ibm.com, ast@kernel.org, andrii@kernel.org, daniel@iogearbox.net, shuah@kernel.org, linux-kselftest@vger.kernel.org, stable@vger.kernel.org, venkat88@linux.ibm.com, yeswanth@linux.ibm.com, skb99@linux.ibm.com Subject: [PATCH v10 7/8] powerpc/bpf: fix buffer overflow in JIT for large BPF programs Date: Wed, 5 Aug 2026 11:37:03 +0530 Message-ID: <45cfcf00a9ca1ec0a06c516fabc73e284d529dc1.1785906979.git.skb99@linux.ibm.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-TM-AS-GCONF: 00 X-Proofpoint-Spam-Info: AW1haW4tMjYwODA1MDA0MiBTYWx0ZWRfXzUlhcsMZC7rg /8RcWpAC5tdt8/qikti79UXVAembtz8orR5jgiKwTpbJ5isVXv1f3Lyz86+OjxLRpdbkKx/8+we K9BDvZPWxmevO3as/gT58UFr/9m1juA= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODA1MDA0MiBTYWx0ZWRfX6B0wPl3Nlg7Q tPo12aVefNLYVDe39Z9IUQPkOSeYNf74ivGNElVhodi1kK6aLU/VWWQg/vr7nlX2dpDis7SDBKF LNXSOcMhiPciPC/x6FnEnwebH793xhlzX7CJzhqNKRhQ0fA68VhQyMp298rWwYwAlRdHvIMpXSX kP/Q7PyIWUFlil0KWDkZsAh9wNehXD03TeQVFyIeItzAr6L2fVgqWPqppKkLE3DjPBCaOfGIzfH lI4hH30ZADcdC6RBI6ibmGHEW0d5xq5i57ptuNcTsb+LWxm99xIdzA6VxQ2gOt5s1kaKrVQZlct Thr8qvqnfjxL1aSzV+xNJxWodaUkyfw7vGA7LScFfXNgZlUGoPVhXfuU8GgVWxyIVYsFJa6cxIH pSicCSuA4LtWhwB0cz+rnrfQUdK0FzCaYkIsxaJziky0J2vQFFmeBY3AfVIDxCAdmWXlg7r636t 0M6mpE8O3oqi3d8iqfw== X-Authority-Analysis: v=2.4 cv=SI1ykuvH c=1 sm=1 tr=0 ts=6a72d331 cx=c_pps a=5BHTudwdYE3Te8bg5FgnPg==:117 a=5BHTudwdYE3Te8bg5FgnPg==:17 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=U7nrCbtTmkRpXpFmAIza:22 a=VwQbUJbxAAAA:8 a=VnNF1IyMAAAA:8 a=BWs5Yjlbf5yakj1inp4A:9 X-Proofpoint-ORIG-GUID: i_VI0PL2sg43iPhlmSbqErn8yp-tBwS5 X-Proofpoint-GUID: i_VI0PL2sg43iPhlmSbqErn8yp-tBwS5 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-05_02,2026-08-04_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1011 bulkscore=0 suspectscore=0 impostorscore=0 spamscore=0 phishscore=0 priorityscore=1501 lowpriorityscore=0 adultscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608050042 From: Abhishek Dubey During size calculation in pass-0, exit_addr is 0 since addrs[fp->len] is not yet populated. bpf_jit_emit_exit_insn() treats a zero exit_addr as in-range and skips bpf_jit_build_epilogue(), so the alternate inline epilogue instructions are not counted in alloclen. In later passes, if the real exit_addr falls outside the 32MB branch range, the full inline epilogue is emitted into the already-allocated buffer, writing past its end and corrupting adjacent memory. Fix by ensuring exit_addr is non-zero before treating it as in-range, so pass-0 always falls through to bpf_jit_build_epilogue() and conservatively accounts for all epilogue instructions in alloclen. Also range check alt_exit_addr directly in the else-if condition. Since exit_addr handling now falls through to the epilogue, two related issues in bpf_int_jit_compile() must also be addressed: 1. Reset cgctx.alt_exit_addr before the second size-calculation pass. Without this, a stale alt_exit_addr from the first pass causes the second pass to emit a single jump instead of the full epilogue, undercounting alloclen and reintroducing the overflow. 2. Recompute addrs[fp->len] at the end of each code-generation pass. The larger pass-0 body can shrink in later passes as out-of-range exits settle into in-range jumps; a stale addrs[fp->len] would leave exit branches targeting past the real (shrunken) epilogue. Because shrinkage in a later pass can move the epilogue offset, the fixed two-pass loop is no longer sufficient: an exit that was out of range in an earlier pass may fall in range once the epilogue offset shrinks, shrinking the body further and overwriting the start of the epilogue. Convert the code-generation loop to iterate until the program size converges, bounded by CODEGEN_MAX_PASSES, and fail the JIT if it does not converge. Reported-by: sashiko-bot@kernel.org Closes: https://lore.kernel.org/bpf/20260529015855.364704-2-adubey@linux.ibm.com/T/#mfcb23909d977b949727cca4f59ee56a13fd69b92 Fixes: d243b62b7bd3 ("powerpc64/bpf: Add support for bpf trampolines") Cc: stable@vger.kernel.org Signed-off-by: Hari Bathini Signed-off-by: Abhishek Dubey Signed-off-by: Saket Kumar Bhaskar Link: https://lore.kernel.org/bpf/20260529015855.364704-2-adubey@linux.ibm.com/T/#mfcb23909d977b949727cca4f59ee56a13fd69b92 Tested-by: Yeswanth Krishna Tellakula --- arch/powerpc/net/bpf_jit.h | 7 +++++++ arch/powerpc/net/bpf_jit_comp.c | 34 +++++++++++++++++++++++++-------- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h index af510da12d8e..4da8bde92e1e 100644 --- a/arch/powerpc/net/bpf_jit.h +++ b/arch/powerpc/net/bpf_jit.h @@ -14,6 +14,13 @@ #include #include +/* + * We need at least 2 passes for proper code generation, and may need + * additional passes if code size changes between passes. + */ +#define CODEGEN_MIN_PASSES 2 +#define CODEGEN_MAX_PASSES 3 + #ifdef CONFIG_PPC64_ELF_ABI_V1 #define FUNCTION_DESCR_SIZE 24 #else diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c index 8be5ded13a4a..3c20bb13cfd7 100644 --- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c @@ -128,11 +128,10 @@ void bpf_jit_build_fentry_stubs(u32 *image, u32 *fimage, struct codegen_context int bpf_jit_emit_exit_insn(u32 *image, u32 *fimage, struct codegen_context *ctx, int tmp_reg, long exit_addr) { - if (!exit_addr || is_offset_in_branch_range(exit_addr - (ctx->idx * 4))) { + if (exit_addr && is_offset_in_branch_range(exit_addr - (long)(ctx->idx * 4))) { PPC_JMP(exit_addr); - } else if (ctx->alt_exit_addr) { - if (WARN_ON(!is_offset_in_branch_range((long)ctx->alt_exit_addr - (ctx->idx * 4)))) - return -1; + } else if (ctx->alt_exit_addr && is_offset_in_branch_range( + (long)(ctx->alt_exit_addr) - (long)(ctx->idx * 4))) { PPC_JMP(ctx->alt_exit_addr); } else { ctx->alt_exit_addr = ctx->idx * 4; @@ -303,6 +302,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr */ if (cgctx.seen & SEEN_TAILCALL || !is_offset_in_branch_range((long)cgctx.idx * 4)) { cgctx.idx = 0; + cgctx.alt_exit_addr = 0; if (bpf_jit_build_body(fp, NULL, NULL, &cgctx, addrs, 0, false)) goto out_err; } @@ -335,10 +335,13 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr code_base = (u32 *)(image + FUNCTION_DESCR_SIZE); fcode_base = (u32 *)(fimage + FUNCTION_DESCR_SIZE); - /* Code generation passes 1-2 */ - for (pass = 1; pass < 3; pass++) { + /* Code generation passes 1-2+, loop until program size converges. */ + for (pass = 1; pass <= CODEGEN_MAX_PASSES; pass++) { + u32 prev_proglen = proglen; + /* Now build the prologue, body code & epilogue for real. */ cgctx.idx = 0; + cgctx.exentry_idx = 0; cgctx.alt_exit_addr = 0; bpf_jit_build_prologue(code_base, &cgctx); if (bpf_jit_build_body(fp, code_base, fcode_base, &cgctx, addrs, pass, @@ -347,11 +350,26 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr bpf_jit_binary_pack_free(fhdr, hdr); goto out_err; } + addrs[fp->len] = cgctx.idx * 4; bpf_jit_build_epilogue(code_base, fcode_base, &cgctx); + proglen = cgctx.idx * 4; + if (bpf_jit_enable > 1) pr_info("Pass %d: shrink = %d, seen = 0x%x\n", pass, - proglen - (cgctx.idx * 4), cgctx.seen); + prev_proglen - proglen, cgctx.seen); + + /* Check if program size has converged, but ensure minimum passes */ + if (pass >= CODEGEN_MIN_PASSES && proglen == prev_proglen) + break; + + if (pass == CODEGEN_MAX_PASSES && proglen != prev_proglen) { + pr_err("BPF JIT: Program did not converge after %d passes\n", + CODEGEN_MAX_PASSES); + bpf_arch_text_copy(&fhdr->size, &hdr->size, sizeof(hdr->size)); + bpf_jit_binary_pack_free(fhdr, hdr); + goto out_err; + } } if (bpf_jit_enable > 1) @@ -428,7 +446,7 @@ int bpf_add_extable_entry(struct bpf_prog *fp, u32 *image, u32 *fimage, int pass u32 *fixup; /* Populate extable entries only in the last pass */ - if (pass != 2) + if (pass >= CODEGEN_MIN_PASSES) return 0; if (!fp->aux->extable || -- 2.54.0