lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250415180434.513405-1-csokas.bence@prolan.hu>
Date: Tue, 15 Apr 2025 20:04:32 +0200
From: Bence Csókás <csokas.bence@...lan.hu>
To: <linux-mtd@...ts.infradead.org>, <linux-kernel@...r.kernel.org>
CC: Csókás, Bence <csokas.bence@...lan.hu>,
	Szentendrei, Tamás <szentendrei.tamas@...lan.hu>, "Tudor
 Ambarus" <tudor.ambarus@...aro.org>, Pratyush Yadav <pratyush@...nel.org>,
	Michael Walle <mwalle@...nel.org>, Miquel Raynal <miquel.raynal@...tlin.com>,
	Richard Weinberger <richard@....at>, Vignesh Raghavendra <vigneshr@...com>
Subject: [PATCH] spi-nor: Verify written data in paranoid mode

From: Csókás, Bence <csokas.bence@...lan.hu>

Add MTD_SPI_NOR_PARANOID config option for verifying all written data to
prevent silent bit errors to be undetected, at the cost of halving SPI
bandwidth.

Co-developed-by: Szentendrei, Tamás <szentendrei.tamas@...lan.hu>
Signed-off-by: Szentendrei, Tamás <szentendrei.tamas@...lan.hu>
Signed-off-by: Csókás, Bence <csokas.bence@...lan.hu>
---
 drivers/mtd/spi-nor/Kconfig | 10 ++++++++++
 drivers/mtd/spi-nor/core.c  | 33 +++++++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+)

diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig
index 24cd25de2b8b..425ea9a22424 100644
--- a/drivers/mtd/spi-nor/Kconfig
+++ b/drivers/mtd/spi-nor/Kconfig
@@ -68,6 +68,16 @@ config MTD_SPI_NOR_SWP_KEEP
 
 endchoice
 
+config MTD_SPI_NOR_PARANOID
+	bool "Read back written data (paranoid mode)"
+	help
+	  This option makes the SPI NOR core read back all data on a write
+	  and report an error if it doesn't match the written data. This can
+	  safeguard against silent bit errors resulting from a faulty Flash,
+	  controller oddities, bus noise etc.
+
+	  If you are unsure, select 'n'.
+
 source "drivers/mtd/spi-nor/controllers/Kconfig"
 
 endif # MTD_SPI_NOR
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index ac4b960101cc..ca05a6ec8afe 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -2063,6 +2063,7 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
 	size_t *retlen, const u_char *buf)
 {
 	struct spi_nor *nor = mtd_to_spi_nor(mtd);
+	u_char *verify_buf = NULL;
 	size_t i;
 	ssize_t ret;
 	u32 page_size = nor->params->page_size;
@@ -2073,6 +2074,14 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
 	if (ret)
 		return ret;
 
+#if IS_ENABLED(CONFIG_MTD_SPI_NOR_PARANOID)
+	verify_buf = devm_kmalloc(nor->dev, page_size, GFP_KERNEL);
+	if (!verify_buf) {
+		ret = -ENOMEM;
+		goto write_err;
+	}
+#endif
+
 	for (i = 0; i < len; ) {
 		ssize_t written;
 		loff_t addr = to + i;
@@ -2099,11 +2108,35 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
 		ret = spi_nor_wait_till_ready(nor);
 		if (ret)
 			goto write_err;
+
+#if IS_ENABLED(CONFIG_MTD_SPI_NOR_PARANOID)
+		/* read back to make sure it's correct */
+		ret = spi_nor_read_data(nor, addr, written, verify_buf);
+		if (ret < 0)
+			goto write_err;
+		if (ret != written) {
+			/* We shouldn't see short reads */
+			dev_err(nor->dev, "Verify failed, written %zd but only read %zd",
+				written, ret);
+			ret = -EIO;
+			goto write_err;
+		}
+
+		if (memcmp(verify_buf, buf + i, written)) {
+			dev_err(nor->dev, "Verify failed, compare mismatch!");
+			ret = -EIO;
+			goto write_err;
+		}
+#endif
+
+		ret = 0;
+
 		*retlen += written;
 		i += written;
 	}
 
 write_err:
+	devm_kfree(nor->dev, verify_buf);
 	spi_nor_unlock_and_unprep_pe(nor, to, len);
 
 	return ret;

base-commit: 834a4a689699090a406d1662b03affa8b155d025
-- 
2.49.0



Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ