Message ID | 20231020-mtd-otp-byteswap-v4-1-0d132c06aa9d@linaro.org |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:2010:b0:403:3b70:6f57 with SMTP id fe16csp1309594vqb; Fri, 20 Oct 2023 13:31:20 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEJhVhu1pbg5bofn/Uje9ingRNxe+9snQkn+szGvZXBqPmPjkkHalm80IOG07nu3d7hFGy3 X-Received: by 2002:a05:6a00:a0b:b0:6bb:def8:b09c with SMTP id p11-20020a056a000a0b00b006bbdef8b09cmr3140344pfh.1.1697833880349; Fri, 20 Oct 2023 13:31:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1697833880; cv=none; d=google.com; s=arc-20160816; b=KuG+6EqEk19jT5Z4zufnIQCP+PObIp8BjrgYSDzCjZClKZImWngBvOY71sNDuxZuAr BUufVaewUJ/YJH87Q7Q5t3maD+m60AzqlMXo8BkL3OOo936l0Em4rzdoIPINiaTWPvvK WVi11EEI8L4kZhqYHHflQv24h0OvrEqKxsHEuy0fTwMw+xqHQJuHuLjmQ3ySTfnHgVgh MhlZ3B8DAUYeWa+cFCEe/n9m/XIZqtaaQIB8ZGXmlDjPl4/3jhDkrbIq0/4/xyxnPUvM BTaVbTe2MCRtBmf3RBlkjJG8zKy6o1y0iQ61qgYdhIV0cZmOpVeEm8XMsbRusr88B1F3 ESYA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:message-id:content-transfer-encoding :mime-version:subject:date:from:dkim-signature; bh=6GPuaggtGD10El9ZGrri8KfDDHuU0PlPpw0GJi5kP2w=; fh=rpg1CrYJvLh4bfVovdMRfKVw+2vfrlkwABxHjha9jig=; b=hsBL2CKpBI1vGGyLHVeG/Mzp/phrMxMOwcCNQBpKd1N0eaRRUZv7hLJIzPd5Z1EUig IvZF/rUMRtdSBz80goA5sRcmR9pgGL41Arb8hKyItMbRB44MfyQSo+D41tt5TIJC/Zfw t090DUST/sEHOI+1Byitafq6+HCcXWDSZNXABPpCEcSQnHGeGWMY2R7t16sOhw/R2Ssf 3vUJujSnzeBZqxZRhIVMhm/tCycoWviPAO+9yLzsOEANHZpLbBzcxdDtdzUAZbcVd55U 0AcOxQ0Bv6A2QkmtC5m9Z3P6rJE9LjSC8eH2GFQP/bat0EbPGsVnGWulvD5Vrr6umOCP Zrlg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Yv5OsElF; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:8 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from fry.vger.email (fry.vger.email. [2620:137:e000::3:8]) by mx.google.com with ESMTPS id f21-20020a056a00239500b0068c7033a5f5si2658290pfc.74.2023.10.20.13.31.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Oct 2023 13:31:20 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:8 as permitted sender) client-ip=2620:137:e000::3:8; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Yv5OsElF; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:8 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by fry.vger.email (Postfix) with ESMTP id 24930807648C; Fri, 20 Oct 2023 13:31:04 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at fry.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230162AbjJTUaf (ORCPT <rfc822;a1648639935@gmail.com> + 26 others); Fri, 20 Oct 2023 16:30:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50694 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230117AbjJTUae (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Fri, 20 Oct 2023 16:30:34 -0400 Received: from mail-lf1-x12e.google.com (mail-lf1-x12e.google.com [IPv6:2a00:1450:4864:20::12e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 34AB0D68 for <linux-kernel@vger.kernel.org>; Fri, 20 Oct 2023 13:30:32 -0700 (PDT) Received: by mail-lf1-x12e.google.com with SMTP id 2adb3069b0e04-507bd64814fso1775298e87.1 for <linux-kernel@vger.kernel.org>; Fri, 20 Oct 2023 13:30:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1697833830; x=1698438630; darn=vger.kernel.org; h=cc:to:message-id:content-transfer-encoding:mime-version:subject :date:from:from:to:cc:subject:date:message-id:reply-to; bh=6GPuaggtGD10El9ZGrri8KfDDHuU0PlPpw0GJi5kP2w=; b=Yv5OsElFPBRKgqrDkpz55T/JUR2eZnGKwCLLi17imW7tqP/BnLcxYzmnfCDFCex9qt vR2kMnjgvRM3vA2qpJ/LYhPPXQEBxxN061s3HUS1nXWj/h1ZNSQBoVGYzcHWhat+0uez M7ve2HYZsXAScjN6nmEf7BgyRV4BfEJLwY9T5iNpBoyQMEPg9KXgBLALfDCsZ0qgSMsW v16IoRw6LyX0YldY6VJpS9rNDCgc2WXkXz0RDCRAO2w+nsTPMbbShY22MKNJA9m6vU5t trByV6Dpch47pRjzWuEh5vo89PC5V+4h5CnZMu91pO4z0ZpVwIC6A6EwpeLix+iwYwA7 pnew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697833830; x=1698438630; h=cc:to:message-id:content-transfer-encoding:mime-version:subject :date:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=6GPuaggtGD10El9ZGrri8KfDDHuU0PlPpw0GJi5kP2w=; b=q1JSdF6Jg3wSIXW7s3jDEX/qhdH2vDZesQU2G6CJdtXxbmlmE4uL9CAN1Sb3wyQ+3J xtpGR9+mvyU30gEFgHAWl4xb327VzRbv1zVli6tTF2OrhmkXpEqQMb8qXUQ8X4iWZiI+ Nx8VzfXlqYIzXxvt+OFQuYn4HUdAiIYbuhSyshCsmj+D2gVO1bMbAUfM/rZYltB8vcKC OT4+DuVSW8OjzIfOFWRcDQWNCLNWK/yGtFljEM8any0Nvp0OnJZU2SqMYEEGA0GW5ycy YRQjftLuIzHRhDDvIbcban2+euov9vXXSP3wAM8PxNa20idI5thIHB8V50OCtiJx9YIl SgBQ== X-Gm-Message-State: AOJu0YyKTUrt4YQY0fj2srMaa1hgMhUPmd73B1xEWhqA6JOmqBHpPYi0 IPEOebCBafo9QGdgIE6/pfTOziRMP8ZcMQ70BQg= X-Received: by 2002:a19:711c:0:b0:500:aa41:9d67 with SMTP id m28-20020a19711c000000b00500aa419d67mr1843149lfc.8.1697833830125; Fri, 20 Oct 2023 13:30:30 -0700 (PDT) Received: from [192.168.1.2] (c-21d3225c.014-348-6c756e10.bbcust.telenor.se. [92.34.211.33]) by smtp.gmail.com with ESMTPSA id a24-20020a056512201800b004ff6fa3f038sm509345lfb.144.2023.10.20.13.30.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Oct 2023 13:30:29 -0700 (PDT) From: Linus Walleij <linus.walleij@linaro.org> Date: Fri, 20 Oct 2023 22:30:29 +0200 Subject: [PATCH v4] mtd: cfi_cmdset_0001: Byte swap OTP info MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20231020-mtd-otp-byteswap-v4-1-0d132c06aa9d@linaro.org> X-B4-Tracking: v=1; b=H4sIAGTjMmUC/x3MTQqAIBBA4avErBswjYSuEi00p5pFJSr9EN49a fkt3nshUmCK0FcvBDo58rEXtHUF02r2hZBdMUghVSOkwC05PJJH+ySKl/GorWm1ajpyWkHJfKC Z7385jDl/ifdQzWIAAAA= To: Miquel Raynal <miquel.raynal@bootlin.com>, Richard Weinberger <richard@nod.at>, Vignesh Raghavendra <vigneshr@ti.com> Cc: linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org, Nicolas Pitre <nico@fluxnic.net>, Linus Walleij <linus.walleij@linaro.org> X-Mailer: b4 0.12.3 X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on fry.vger.email Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (fry.vger.email [0.0.0.0]); Fri, 20 Oct 2023 13:31:04 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1780307859037003416 X-GMAIL-MSGID: 1780307859037003416 |
Series |
[v4] mtd: cfi_cmdset_0001: Byte swap OTP info
|
|
Commit Message
Linus Walleij
Oct. 20, 2023, 8:30 p.m. UTC
Currently the offset into the device when looking for OTP bits can go outside of the address of the MTD NOR devices, and if that memory isn't readable, bad things happen on the IXP4xx (added prints that illustrate the problem before the crash): cfi_intelext_otp_walk walk OTP on chip 0 start at reg_prot_offset 0x00000100 ixp4xx_copy_from copy from 0x00000100 to 0xc880dd78 cfi_intelext_otp_walk walk OTP on chip 0 start at reg_prot_offset 0x12000000 ixp4xx_copy_from copy from 0x12000000 to 0xc880dd78 8<--- cut here --- Unable to handle kernel paging request at virtual address db000000 [db000000] *pgd=00000000 (...) This happens in this case because the IXP4xx is big endian and the 32- and 16-bit fields in the struct cfi_intelext_otpinfo are not properly byteswapped. Compare to how the code in read_pri_intelext() byteswaps the fields in struct cfi_pri_intelext. Adding a small byte swapping loop for the OTP in read_pri_intelext() and the crash goes away. The problem went unnoticed for many years until I enabled CONFIG_MTD_OTP on the IXP4xx as well, triggering the bug. Cc: stable@vger.kernel.org Reviewed-by: Nicolas Pitre <nico@fluxnic.net> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> --- ChangeLog v3->v4: - Collected Nico's ACK. - Stalled since june! Has this been missed? ChangeLog v2->v3: - Link to v3: https://lore.kernel.org/linux-mtd/20230602204359.3493320-1-linus.walleij@linaro.org/ - Move the byte swapping to a small loop in read_pri_intelext() so all bytes are swapped as we reach cfi_intelext_otp_walk(). ChangeLog v1->v2: - Drill deeper and discover a big endian compatibility issue. --- drivers/mtd/chips/cfi_cmdset_0001.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) --- base-commit: 0bb80ecc33a8fb5a682236443c1e740d5c917d1d change-id: 20231020-mtd-otp-byteswap-7ba47316ed73 Best regards,
Comments
Hi Linus, linus.walleij@linaro.org wrote on Fri, 20 Oct 2023 22:30:29 +0200: > Currently the offset into the device when looking for OTP > bits can go outside of the address of the MTD NOR devices, > and if that memory isn't readable, bad things happen > on the IXP4xx (added prints that illustrate the problem before > the crash): > > cfi_intelext_otp_walk walk OTP on chip 0 start at reg_prot_offset 0x00000100 > ixp4xx_copy_from copy from 0x00000100 to 0xc880dd78 > cfi_intelext_otp_walk walk OTP on chip 0 start at reg_prot_offset 0x12000000 > ixp4xx_copy_from copy from 0x12000000 to 0xc880dd78 > 8<--- cut here --- > Unable to handle kernel paging request at virtual address db000000 > [db000000] *pgd=00000000 > (...) > > This happens in this case because the IXP4xx is big endian and > the 32- and 16-bit fields in the struct cfi_intelext_otpinfo are not > properly byteswapped. Compare to how the code in read_pri_intelext() > byteswaps the fields in struct cfi_pri_intelext. > > Adding a small byte swapping loop for the OTP in read_pri_intelext() > and the crash goes away. > > The problem went unnoticed for many years until I enabled > CONFIG_MTD_OTP on the IXP4xx as well, triggering the bug. > > Cc: stable@vger.kernel.org Would you like to add a Fixes tag as well? Or is this skipped on purpose? > Reviewed-by: Nicolas Pitre <nico@fluxnic.net> > Signed-off-by: Linus Walleij <linus.walleij@linaro.org> > --- > ChangeLog v3->v4: > - Collected Nico's ACK. > - Stalled since june! Has this been missed? Our current organization relies on Vignesh to pick-up (or tell me to pick-up) cfi patches. But he is slightly less active these days, so if I don't get any feedback from him soon I will take it for the next merge window. Sorry for the delay anyway. Cheers, Miquèl
On Mon, Oct 23, 2023 at 10:25 AM Miquel Raynal <miquel.raynal@bootlin.com> wrote: > linus.walleij@linaro.org wrote on Fri, 20 Oct 2023 22:30:29 +0200: > > > Currently the offset into the device when looking for OTP > > bits can go outside of the address of the MTD NOR devices, > > and if that memory isn't readable, bad things happen > > on the IXP4xx (added prints that illustrate the problem before > > the crash): > > > > cfi_intelext_otp_walk walk OTP on chip 0 start at reg_prot_offset 0x00000100 > > ixp4xx_copy_from copy from 0x00000100 to 0xc880dd78 > > cfi_intelext_otp_walk walk OTP on chip 0 start at reg_prot_offset 0x12000000 > > ixp4xx_copy_from copy from 0x12000000 to 0xc880dd78 > > 8<--- cut here --- > > Unable to handle kernel paging request at virtual address db000000 > > [db000000] *pgd=00000000 > > (...) > > > > This happens in this case because the IXP4xx is big endian and > > the 32- and 16-bit fields in the struct cfi_intelext_otpinfo are not > > properly byteswapped. Compare to how the code in read_pri_intelext() > > byteswaps the fields in struct cfi_pri_intelext. > > > > Adding a small byte swapping loop for the OTP in read_pri_intelext() > > and the crash goes away. > > > > The problem went unnoticed for many years until I enabled > > CONFIG_MTD_OTP on the IXP4xx as well, triggering the bug. > > > > Cc: stable@vger.kernel.org > > Would you like to add a Fixes tag as well? Or is this skipped on > purpose? Yes the actual commit predates existing git history... :/ Git blame looks like that: ^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 423) ^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 424) /* Protection Register info */ b359ed5184aeb (Jean-Philippe Brucker 2020-04-17 16:23:26 +0200 425) if (extp->NumProtectionFields) b359ed5184aeb (Jean-Philippe Brucker 2020-04-17 16:23:26 +0200 426) extra_size += (extp->NumProtectionFields - 1) * b359ed5184aeb (Jean-Philippe Brucker 2020-04-17 16:23:26 +0200 427) sizeof(struct cfi_intelext_otpinfo); Jean-Philippe's patch is not the root cause AFAICT, but something predating it, and predating git history. The fix easily applies to all maintained stable kernels. > > Reviewed-by: Nicolas Pitre <nico@fluxnic.net> > > Signed-off-by: Linus Walleij <linus.walleij@linaro.org> > > --- > > ChangeLog v3->v4: > > - Collected Nico's ACK. > > - Stalled since june! Has this been missed? > > Our current organization relies on Vignesh to pick-up (or tell me to > pick-up) cfi patches. But he is slightly less active these days, so if I > don't get any feedback from him soon I will take it for the next merge > window. > > Sorry for the delay anyway. No worries it's not like the patch is urgent. Yours, Linus Walleij
Hi Linus, linus.walleij@linaro.org wrote on Mon, 23 Oct 2023 10:35:24 +0200: > On Mon, Oct 23, 2023 at 10:25 AM Miquel Raynal > <miquel.raynal@bootlin.com> wrote: > > > linus.walleij@linaro.org wrote on Fri, 20 Oct 2023 22:30:29 +0200: > > > > > Currently the offset into the device when looking for OTP > > > bits can go outside of the address of the MTD NOR devices, > > > and if that memory isn't readable, bad things happen > > > on the IXP4xx (added prints that illustrate the problem before > > > the crash): > > > > > > cfi_intelext_otp_walk walk OTP on chip 0 start at reg_prot_offset 0x00000100 > > > ixp4xx_copy_from copy from 0x00000100 to 0xc880dd78 > > > cfi_intelext_otp_walk walk OTP on chip 0 start at reg_prot_offset 0x12000000 > > > ixp4xx_copy_from copy from 0x12000000 to 0xc880dd78 > > > 8<--- cut here --- > > > Unable to handle kernel paging request at virtual address db000000 > > > [db000000] *pgd=00000000 > > > (...) > > > > > > This happens in this case because the IXP4xx is big endian and > > > the 32- and 16-bit fields in the struct cfi_intelext_otpinfo are not > > > properly byteswapped. Compare to how the code in read_pri_intelext() > > > byteswaps the fields in struct cfi_pri_intelext. > > > > > > Adding a small byte swapping loop for the OTP in read_pri_intelext() > > > and the crash goes away. > > > > > > The problem went unnoticed for many years until I enabled > > > CONFIG_MTD_OTP on the IXP4xx as well, triggering the bug. > > > > > > Cc: stable@vger.kernel.org > > > > Would you like to add a Fixes tag as well? Or is this skipped on > > purpose? > > Yes the actual commit predates existing git history... :/ > > Git blame looks like that: > > ^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 423) > ^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 424) > /* Protection Register info */ > b359ed5184aeb (Jean-Philippe Brucker 2020-04-17 16:23:26 +0200 425) > if (extp->NumProtectionFields) > b359ed5184aeb (Jean-Philippe Brucker 2020-04-17 16:23:26 +0200 426) > extra_size += (extp->NumProtectionFields - 1) * > b359ed5184aeb (Jean-Philippe Brucker 2020-04-17 16:23:26 +0200 427) > sizeof(struct cfi_intelext_otpinfo); > > Jean-Philippe's patch is not the root cause AFAICT, but something > predating it, and predating git history. > > The fix easily applies to all maintained stable kernels. Ack. > > > Reviewed-by: Nicolas Pitre <nico@fluxnic.net> > > > Signed-off-by: Linus Walleij <linus.walleij@linaro.org> > > > --- > > > ChangeLog v3->v4: > > > - Collected Nico's ACK. > > > - Stalled since june! Has this been missed? > > > > Our current organization relies on Vignesh to pick-up (or tell me to > > pick-up) cfi patches. But he is slightly less active these days, so if I > > don't get any feedback from him soon I will take it for the next merge > > window. > > > > Sorry for the delay anyway. > > No worries it's not like the patch is urgent. Haha, well, yes :) Thanks, Miquèl
On Fri, 2023-10-20 at 20:30:29 UTC, Linus Walleij wrote: > Currently the offset into the device when looking for OTP > bits can go outside of the address of the MTD NOR devices, > and if that memory isn't readable, bad things happen > on the IXP4xx (added prints that illustrate the problem before > the crash): > > cfi_intelext_otp_walk walk OTP on chip 0 start at reg_prot_offset 0x00000100 > ixp4xx_copy_from copy from 0x00000100 to 0xc880dd78 > cfi_intelext_otp_walk walk OTP on chip 0 start at reg_prot_offset 0x12000000 > ixp4xx_copy_from copy from 0x12000000 to 0xc880dd78 > 8<--- cut here --- > Unable to handle kernel paging request at virtual address db000000 > [db000000] *pgd=00000000 > (...) > > This happens in this case because the IXP4xx is big endian and > the 32- and 16-bit fields in the struct cfi_intelext_otpinfo are not > properly byteswapped. Compare to how the code in read_pri_intelext() > byteswaps the fields in struct cfi_pri_intelext. > > Adding a small byte swapping loop for the OTP in read_pri_intelext() > and the crash goes away. > > The problem went unnoticed for many years until I enabled > CONFIG_MTD_OTP on the IXP4xx as well, triggering the bug. > > Cc: stable@vger.kernel.org > Reviewed-by: Nicolas Pitre <nico@fluxnic.net> > Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git mtd/next, thanks. Miquel
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index 11b06fefaa0e..c10693ba265b 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -422,9 +422,25 @@ read_pri_intelext(struct map_info *map, __u16 adr) extra_size = 0; /* Protection Register info */ - if (extp->NumProtectionFields) + if (extp->NumProtectionFields) { + struct cfi_intelext_otpinfo *otp = + (struct cfi_intelext_otpinfo *)&extp->extra[0]; + extra_size += (extp->NumProtectionFields - 1) * - sizeof(struct cfi_intelext_otpinfo); + sizeof(struct cfi_intelext_otpinfo); + + if (extp_size >= sizeof(*extp) + extra_size) { + int i; + + /* Do some byteswapping if necessary */ + for (i = 0; i < extp->NumProtectionFields - 1; i++) { + otp->ProtRegAddr = le32_to_cpu(otp->ProtRegAddr); + otp->FactGroups = le16_to_cpu(otp->FactGroups); + otp->UserGroups = le16_to_cpu(otp->UserGroups); + otp++; + } + } + } } if (extp->MinorVersion >= '1') {