From patchwork Wed Sep 2 12:40:19 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aohan Mei X-Patchwork-Id: 2296632 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=2bN1bPSq; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=rtqz/g/u; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=patchwork.ozlabs.org) Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4hZj5P4tThz1xy9 for ; Wed, 02 Sep 2026 22:41:13 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-ID:Date:Subject:Cc :To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=51yLFymGzv/hY82Cz3i29ga7vNHH3GREMC75l6OKdc8=; b=2bN1bPSqycEq0z HL3tz//W5lQDAJ1RfX7suUvzrZunSlYtq70PJh0JiGzAJFEEb2RmrsjE3iLO91rz0ZNA9RUMhYsDw QnVTh89YAvwkasxd44+afFWWEMdMzAukcPR0zlaOLFE5xBE4ULrKsUrY3Z1acS5dVzGNJvvBN8zNa 8bJsRPOtfXcGk8zl4gxbxaDvugVXd5qjfkOQ7g6tZhwDm04POMHtWWHJYHerN2C5ZTo4ug/TEItSE WjL9BJsu5KS2O98BbPOyDyW5W2JuSc23sNYCQ9HV3umA2mxJuxFSehXh2nxz+zE36eGz4XB94fTl3 +byfGqCXzizwowe0d7Tw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1x1kH2-0000000EhYS-2LSj; Wed, 02 Sep 2026 12:41:04 +0000 Received: from mail-pj1-x1033.google.com ([2607:f8b0:4864:20::1033]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1x1kGy-0000000EhWr-1qh9 for linux-mtd@lists.infradead.org; Wed, 02 Sep 2026 12:41:01 +0000 Received: by mail-pj1-x1033.google.com with SMTP id 98e67ed59e1d1-3966791a6eeso1231415a91.3 for ; Wed, 02 Sep 2026 05:40:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788352859; x=1788957659; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=Z+i1+hLinUt3Q2bK2ZT3Wc0emmUMZr61lAfSOzdane8=; b=rtqz/g/uK+n/k5BNGVb/HJ18y4vW78NNOZS2klC2mYuqPCDJ3uUGPTBhSnzJVgeSiQ H6oWk4a7W4OCt1yJnHAiROgGqTEUE7JDN2PViTOA14p2R41BE5oXYdHOoWeVGcRG6dQb PIMjKOkzWSwiOhJxpv16S22qJlSzJSvY8zf90iIYy+EUi/VqSiwjQLYZBjDDF3lY98QW v14VL4Jle5rv7tGXHNk7K2U30zFu6Wlc0N87iuBr5KgqNasjAiBm4tBO5DAJFupdbuii M2eWPmAxI7eVcOAVBpfuw22zhzBmuJpzBHcL2/fcxjqkOMZYZqrscH0BK9eil1FBjvjQ ynMg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788352859; x=1788957659; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Z+i1+hLinUt3Q2bK2ZT3Wc0emmUMZr61lAfSOzdane8=; b=Nx0XfHogr7Fh74sLZifuzc0GP9gJlHNCPoeRXO6SOCW14SezqAbeIyagbGv2UxFvtj uGT7sNPVK2R2aEeVv3dzywOR0RaaxxL4sO+4LdQQVqbZ6oxK8V07UkJStztsFiUn0Xh4 oRPr6YmaHNx4c43rgkjoPr/gH6IhRs9JArno4M5NcDXj4IeIt04VyN5h50VwsS/sPGzc Hphbk7xH6rQh+3lXmBXEJDorC3jf0Sxy+pEI3pEeqG7GzPdin/OMeecy9vi+gi7n1wXl gwkOIhrC+xNNd0Jvg3xk+BlDqPyfzCQ7kVd24QI0r+Ko7UQwcm9jTkcnQW00m+BputS7 Pf4w== X-Gm-Message-State: AFuF++nHD892+lMk9cSIBEaOaax8bbtKX6Qhflzycrg+YzjS+BIKPzCf GH94qCJA04gSB6J9KpPx34tdTGovJdFQ2fvz/lYl8NhsyA7UcuRVqeIyb2OL2w== X-Gm-Gg: AYBFou3TuBrmHtvDZNDTe9Zgji3Bvx/JwUd68G8yg91OFPPWYIUDWOs+CMUDoCH7EFX mqzhQ5jDQqCNwyi8CNm1zJfksAS+sYuj8AyG3ZgqBQ0PMjWq203L+H/ooieSZAtMES3FQaqQrcA R9PFy+21VOFPVIbnQ8ob+2NEN9GUtWqIIX2MEF67XQpaMJjbg1G/PYt2SINq89wHzlr4JU/ueA3 B5obLecd9KGPVh3vlPiLg+gXd0botrDHugKqKdfJ/dRWhnwZOR52XYQsOdrujzTPtQOoY/dG1hh hOjZEmCEOjo4flFPi3CKkD7ji+Lf1HoWBtf+3Lxl/t98PMQF2uxSt8An5kP5HDZbqKTSNGWF1HC +pFVleZEkRAw4fF/cAedAiXK9ItYyI13EHDuGuq2hEE0SJ3JxaSzAQQkHVSRlvbzwRlFE6ljBVw HtBDX2kiUy7oz0pCKi2VzsFeNr+kxwKoTnXbVBRS0jSVqBz61tu5BliNAHfUTPhG6KS9FIodrUh qMYMCoq+BMPupkIjys8aTclPxnqAKZwjQ== X-Received: by 2002:a17:90b:4407:b0:398:9bd4:d13 with SMTP id 98e67ed59e1d1-39aee219427mr6732990a91.18.1788352858942; Wed, 02 Sep 2026 05:40:58 -0700 (PDT) Received: from localhost.localdomain ([180.101.244.71]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-3990bd21e9dsm11879576a91.4.2026.09.02.05.40.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Sep 2026 05:40:58 -0700 (PDT) From: henrymei X-Google-Original-From: henrymei To: linux-mtd@lists.infradead.org Cc: miquel.raynal@bootlin.com, richard@nod.at, vigneshr@ti.com, linux-kernel@vger.kernel.org, Aohan Mei , TencentOS Corvus AI , stable@vger.kernel.org Subject: [PATCH] mtd: inftl: validate MediaHeader partition geometry before allocating tables Date: Wed, 2 Sep 2026 20:40:19 +0800 Message-ID: <20260902124044.3942821-1-henrymei@tencent.com> X-Mailer: git-send-email 2.43.7 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.9.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260902_054100_582025_BC79A37B X-CRM114-Status: GOOD ( 16.56 ) X-Spam-Score: -1.9 (-) X-Spam-Report: Spam detection software, running on the system "bombadil.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: From: Aohan Mei find_boot_record() trusts the on-flash INFTL MediaHeader partition fields without validating their relationship to each other or to the device geometry. The sanity check Content analysis details: (-1.9 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2607:f8b0:4864:20:0:0:0:1033 listed in] [list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] 0.2 FREEMAIL_ENVFROM_END_DIGIT Envelope-from freemail username ends in digit [ljp1205831794(at)gmail.com] 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider [ljp1205831794(at)gmail.com] -0.0 DMARC_PASS DMARC pass policy X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Aohan Mei find_boot_record() trusts the on-flash INFTL MediaHeader partition fields without validating their relationship to each other or to the device geometry. The sanity check if ((ip->lastUnit - ip->firstUnit + 1) < ip->virtualUnits) is evaluated in unsigned 32-bit arithmetic. With lastUnit < firstUnit the subtraction wraps to a huge value and the check passes. Control then reaches: inftl->nb_boot_blocks = ip->firstUnit; /* loop bound */ inftl->nb_blocks = ip->lastUnit + 1; /* table size */ so PUtable/VUtable are allocated with lastUnit + 1 entries while the boot-block marking loop writes firstUnit u16 entries: for (i = 0; i < inftl->nb_boot_blocks; i++) inftl->PUtable[i] = BLOCK_RESERVED; A crafted MediaHeader (e.g. firstUnit=7000, lastUnit=3) turns a kmalloc_array(4, 2) 8-byte allocation into a ~14 KB out-of-bounds write: BUG: KASAN: slab-out-of-bounds in find_boot_record Write of size 2 ... 0 bytes to the right of allocated 8-byte region The MediaHeader unit itself is also marked through PUtable[block] without verifying that block lies within the described extent. Reject inconsistent partition geometry (lastUnit < firstUnit, or lastUnit beyond the device) as each partition entry is scanned, and reject a boot record that lies outside the extent of the selected partition. The existing virtualUnits check then subtracts values that can no longer underflow. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reported-by: TencentOS Corvus AI Cc: stable@vger.kernel.org Assisted-by: CodeBuddy:Kimi-K3 Signed-off-by: Aohan Mei --- drivers/mtd/inftlmount.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/drivers/mtd/inftlmount.c b/drivers/mtd/inftlmount.c index 87e246a6f488..b0f01db95280 100644 --- a/drivers/mtd/inftlmount.c +++ b/drivers/mtd/inftlmount.c @@ -192,6 +192,23 @@ static int find_boot_record(struct INFTLrecord *inftl) ip->lastUnit, ip->flags, ip->spareUnits); + /* + * Reject inconsistent partition geometry before it is + * used: lastUnit < firstUnit would make the + * (lastUnit - firstUnit + 1) check below underflow, + * and lastUnit must stay within the device as it later + * bounds the PUtable/VUtable allocations. + */ + if (ip->lastUnit < ip->firstUnit || + ip->lastUnit >= inftl->nb_blocks) { + pr_warn("INFTL: Media Header " + "Partition %d sanity check failed:\n" + " firstUnit %d lastUnit %d " + "(nb_blocks %d)\n", + i, ip->firstUnit, ip->lastUnit, + inftl->nb_blocks); + return -1; + } if (ip->Reserved0 != ip->firstUnit) { struct erase_info *instr = &inftl->instr; @@ -233,6 +250,18 @@ static int find_boot_record(struct INFTLrecord *inftl) return -1; } + /* + * The boot record unit must lie within the described + * extent; it is later marked through PUtable[block]. + */ + if (block > ip->lastUnit) { + pr_warn("INFTL: Media Header " + "Partition %d sanity check failed:\n" + " boot record unit %d beyond " + "lastUnit %d\n", + i, block, ip->lastUnit); + return -1; + } inftl->nb_boot_blocks = ip->firstUnit; inftl->numvunits = ip->virtualUnits; if (inftl->numvunits > (inftl->nb_blocks -