* [PATCH v3 0/2] spi: spi-qpic-snand: avoid memory corruption
@ 2025-06-18 20:22 Gabor Juhos
2025-06-18 20:22 ` [PATCH v3 1/2] spi: spi-qpic-snand: reallocate BAM transactions Gabor Juhos
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Gabor Juhos @ 2025-06-18 20:22 UTC (permalink / raw)
To: Mark Brown, Md Sadre Alam, Varadarajan Narayanan,
Sricharan Ramabadhran, Miquel Raynal, Richard Weinberger,
Vignesh Raghavendra
Cc: linux-spi, linux-mtd, linux-arm-msm, linux-kernel, Gabor Juhos,
Lakshmi Sowjanya D
The 'spi-qpic-nand' driver may cause memory corruption under some
circumstances. The first patch in the series changes the driver to
avoid that, whereas the second adds some sanity checks to the common
QPIC code in order to make detecting such errors easier in the future.
Preferably, the two patches should go along in via the SPI tree.
It is not a strict requirement though, in the case the second patch
gets included separately through the MTD tree it reveals the bug
which is fixed in the first patch.
Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
---
Changes in v3:
- rebase on top of current spi/for-6.16
- add 'Acked-by' tag from Miquel to patch 2
- Link to v2: https://lore.kernel.org/r/20250529-qpic-snand-avoid-mem-corruption-v2-0-2f0d13afc7d2@gmail.com
Changes in v2:
- collect offered tags
- reduce kernel log spam in commit description of patch 1
- remove inline error printing function from patch 2, and adjust the
commit message of the patch
- Link to v1: https://lore.kernel.org/r/20250525-qpic-snand-avoid-mem-corruption-v1-0-5fe528def7fb@gmail.com
---
Gabor Juhos (2):
spi: spi-qpic-snand: reallocate BAM transactions
mtd: nand: qpic_common: prevent out of bounds access of BAM arrays
drivers/mtd/nand/qpic_common.c | 30 ++++++++++++++++++++++++++----
drivers/spi/spi-qpic-snand.c | 16 ++++++++++++++++
include/linux/mtd/nand-qpic-common.h | 8 ++++++++
3 files changed, 50 insertions(+), 4 deletions(-)
---
base-commit: d57e92dd660014ccac884eda616cafc7b04601e0
change-id: 20250523-qpic-snand-avoid-mem-corruption-301afabeb0eb
Best regards,
--
Gabor Juhos <j4g8y7@gmail.com>
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v3 1/2] spi: spi-qpic-snand: reallocate BAM transactions
2025-06-18 20:22 [PATCH v3 0/2] spi: spi-qpic-snand: avoid memory corruption Gabor Juhos
@ 2025-06-18 20:22 ` Gabor Juhos
2025-06-18 20:22 ` [PATCH v3 2/2] mtd: nand: qpic_common: prevent out of bounds access of BAM arrays Gabor Juhos
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Gabor Juhos @ 2025-06-18 20:22 UTC (permalink / raw)
To: Mark Brown, Md Sadre Alam, Varadarajan Narayanan,
Sricharan Ramabadhran, Miquel Raynal, Richard Weinberger,
Vignesh Raghavendra
Cc: linux-spi, linux-mtd, linux-arm-msm, linux-kernel, Gabor Juhos
Using the mtd_nandbiterrs module for testing the driver occasionally
results in weird things like below.
1. swiotlb mapping fails with the following message:
[ 85.926216] qcom_snand 79b0000.spi: swiotlb buffer is full (sz: 4294967294 bytes), total 512 (slots), used 0 (slots)
[ 85.932937] qcom_snand 79b0000.spi: failure in mapping desc
[ 87.999314] qcom_snand 79b0000.spi: failure to write raw page
[ 87.999352] mtd_nandbiterrs: error: write_oob failed (-110)
Rebooting the board after this causes a panic due to a NULL pointer
dereference.
2. If the swiotlb mapping does not fail, rebooting the board may result
in a different panic due to a bad spinlock magic:
[ 256.104459] BUG: spinlock bad magic on CPU#3, procd/2241
[ 256.104488] Unable to handle kernel paging request at virtual address ffffffff0000049b
...
Investigating the issue revealed that these symptoms are results of
memory corruption which is caused by out of bounds access within the
driver.
The driver uses a dynamically allocated structure for BAM transactions,
which structure must have enough space for all possible variations of
different flash operations initiated by the driver. The required space
heavily depends on the actual number of 'codewords' which is calculated
from the pagesize of the actual NAND chip.
Although the qcom_nandc_alloc() function allocates memory for the BAM
transactions during probe, but since the actual number of 'codewords'
is not yet know the allocation is done for one 'codeword' only.
Because of this, whenever the driver does a flash operation, and the
number of the required transactions exceeds the size of the allocated
arrays the driver accesses memory out of the allocated range.
To avoid this, change the code to free the initially allocated BAM
transactions memory, and allocate a new one once the actual number of
'codewords' required for a given NAND chip is known.
Fixes: 7304d1909080 ("spi: spi-qpic: add driver for QCOM SPI NAND flash Interface")
Reviewed-by: Md Sadre Alam <quic_mdalam@quicinc.com>
Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
---
Changes in v3:
- rebase on top of current spi/for-6.16
Changes in v2:
- add 'Reviewed-by' tag from Alam
- reduce kernel log spam in the commit message
---
drivers/spi/spi-qpic-snand.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/drivers/spi/spi-qpic-snand.c b/drivers/spi/spi-qpic-snand.c
index 77d9cc65477ad35a3da795d8f6d34d533b65bcc4..f2e1a27b410ddb98d1dfca52898cd5fe38308a2c 100644
--- a/drivers/spi/spi-qpic-snand.c
+++ b/drivers/spi/spi-qpic-snand.c
@@ -315,6 +315,22 @@ static int qcom_spi_ecc_init_ctx_pipelined(struct nand_device *nand)
mtd_set_ooblayout(mtd, &qcom_spi_ooblayout);
+ /*
+ * Free the temporary BAM transaction allocated initially by
+ * qcom_nandc_alloc(), and allocate a new one based on the
+ * updated max_cwperpage value.
+ */
+ qcom_free_bam_transaction(snandc);
+
+ snandc->max_cwperpage = cwperpage;
+
+ snandc->bam_txn = qcom_alloc_bam_transaction(snandc);
+ if (!snandc->bam_txn) {
+ dev_err(snandc->dev, "failed to allocate BAM transaction\n");
+ ret = -ENOMEM;
+ goto err_free_ecc_cfg;
+ }
+
ecc_cfg->cfg0 = FIELD_PREP(CW_PER_PAGE_MASK, (cwperpage - 1)) |
FIELD_PREP(UD_SIZE_BYTES_MASK, ecc_cfg->cw_data) |
FIELD_PREP(DISABLE_STATUS_AFTER_WRITE, 1) |
--
2.49.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v3 2/2] mtd: nand: qpic_common: prevent out of bounds access of BAM arrays
2025-06-18 20:22 [PATCH v3 0/2] spi: spi-qpic-snand: avoid memory corruption Gabor Juhos
2025-06-18 20:22 ` [PATCH v3 1/2] spi: spi-qpic-snand: reallocate BAM transactions Gabor Juhos
@ 2025-06-18 20:22 ` Gabor Juhos
2025-06-25 22:43 ` [PATCH v3 0/2] spi: spi-qpic-snand: avoid memory corruption Mark Brown
2025-06-30 12:37 ` Mark Brown
3 siblings, 0 replies; 6+ messages in thread
From: Gabor Juhos @ 2025-06-18 20:22 UTC (permalink / raw)
To: Mark Brown, Md Sadre Alam, Varadarajan Narayanan,
Sricharan Ramabadhran, Miquel Raynal, Richard Weinberger,
Vignesh Raghavendra
Cc: linux-spi, linux-mtd, linux-arm-msm, linux-kernel, Gabor Juhos,
Lakshmi Sowjanya D
The common QPIC code does not do any boundary checking when it handles
the command elements and scatter gater list arrays of a BAM transaction,
thus it allows to access out of bounds elements in those.
Although it is the responsibility of the given driver to allocate enough
space for all possible BAM transaction variations, however there can be
mistakes in the driver code which can lead to hidden memory corruption
issues which are hard to debug.
This kind of problem has been observed during testing the 'spi-qpic-snand'
driver. Although the driver has been fixed with a preceding patch, but it
still makes sense to reduce the chance of having such errors again later.
In order to prevent such errors, change the qcom_alloc_bam_transaction()
function to store the number of elements of the arrays in the
'bam_transaction' strucutre during allocation. Also, add sanity checks to
the qcom_prep_bam_dma_desc_{cmd,data}() functions to avoid using out of
bounds indices for the arrays.
Tested-by: Lakshmi Sowjanya D <quic_laksd@quicinc.com> # on SDX75
Acked-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
---
Changes in v3:
- rebase on top of current spi/for-6.16
- add 'Acked-by' tag from Miquel
Changes in v2:
- remove the inline qcom_err_bam_array_full() function and print the error
messages directly from the respective functions instead
- add 'Tested-by' tag from Lakshmi Sowjanya D, and remove the
"Tested with the 'spi-qpic-snand' driver only." line from the
commit message as SDX75 uses the qcom_nandc driver
- move the note about of the preferred merging order into the cover letter
---
drivers/mtd/nand/qpic_common.c | 30 ++++++++++++++++++++++++++----
include/linux/mtd/nand-qpic-common.h | 8 ++++++++
2 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/drivers/mtd/nand/qpic_common.c b/drivers/mtd/nand/qpic_common.c
index 4dc4d65e7d323e2843edecca8e3849a5090b775d..8e604cc22ca310159edf4d8dbc2f6a82d5119eb4 100644
--- a/drivers/mtd/nand/qpic_common.c
+++ b/drivers/mtd/nand/qpic_common.c
@@ -57,14 +57,15 @@ qcom_alloc_bam_transaction(struct qcom_nand_controller *nandc)
bam_txn_buf += sizeof(*bam_txn);
bam_txn->bam_ce = bam_txn_buf;
- bam_txn_buf +=
- sizeof(*bam_txn->bam_ce) * QPIC_PER_CW_CMD_ELEMENTS * num_cw;
+ bam_txn->bam_ce_nitems = QPIC_PER_CW_CMD_ELEMENTS * num_cw;
+ bam_txn_buf += sizeof(*bam_txn->bam_ce) * bam_txn->bam_ce_nitems;
bam_txn->cmd_sgl = bam_txn_buf;
- bam_txn_buf +=
- sizeof(*bam_txn->cmd_sgl) * QPIC_PER_CW_CMD_SGL * num_cw;
+ bam_txn->cmd_sgl_nitems = QPIC_PER_CW_CMD_SGL * num_cw;
+ bam_txn_buf += sizeof(*bam_txn->cmd_sgl) * bam_txn->cmd_sgl_nitems;
bam_txn->data_sgl = bam_txn_buf;
+ bam_txn->data_sgl_nitems = QPIC_PER_CW_DATA_SGL * num_cw;
init_completion(&bam_txn->txn_done);
@@ -238,6 +239,11 @@ int qcom_prep_bam_dma_desc_cmd(struct qcom_nand_controller *nandc, bool read,
struct bam_transaction *bam_txn = nandc->bam_txn;
u32 offset;
+ if (bam_txn->bam_ce_pos + size > bam_txn->bam_ce_nitems) {
+ dev_err(nandc->dev, "BAM %s array is full\n", "CE");
+ return -EINVAL;
+ }
+
bam_ce_buffer = &bam_txn->bam_ce[bam_txn->bam_ce_pos];
/* fill the command desc */
@@ -258,6 +264,12 @@ int qcom_prep_bam_dma_desc_cmd(struct qcom_nand_controller *nandc, bool read,
/* use the separate sgl after this command */
if (flags & NAND_BAM_NEXT_SGL) {
+ if (bam_txn->cmd_sgl_pos >= bam_txn->cmd_sgl_nitems) {
+ dev_err(nandc->dev, "BAM %s array is full\n",
+ "CMD sgl");
+ return -EINVAL;
+ }
+
bam_ce_buffer = &bam_txn->bam_ce[bam_txn->bam_ce_start];
bam_ce_size = (bam_txn->bam_ce_pos -
bam_txn->bam_ce_start) *
@@ -297,10 +309,20 @@ int qcom_prep_bam_dma_desc_data(struct qcom_nand_controller *nandc, bool read,
struct bam_transaction *bam_txn = nandc->bam_txn;
if (read) {
+ if (bam_txn->rx_sgl_pos >= bam_txn->data_sgl_nitems) {
+ dev_err(nandc->dev, "BAM %s array is full\n", "RX sgl");
+ return -EINVAL;
+ }
+
sg_set_buf(&bam_txn->data_sgl[bam_txn->rx_sgl_pos],
vaddr, size);
bam_txn->rx_sgl_pos++;
} else {
+ if (bam_txn->tx_sgl_pos >= bam_txn->data_sgl_nitems) {
+ dev_err(nandc->dev, "BAM %s array is full\n", "TX sgl");
+ return -EINVAL;
+ }
+
sg_set_buf(&bam_txn->data_sgl[bam_txn->tx_sgl_pos],
vaddr, size);
bam_txn->tx_sgl_pos++;
diff --git a/include/linux/mtd/nand-qpic-common.h b/include/linux/mtd/nand-qpic-common.h
index e8462deda6dbf61f99bbcb39e7cb12cdf66898fd..f0aa098a395f7140c3c4ad5640f973293f73a1cc 100644
--- a/include/linux/mtd/nand-qpic-common.h
+++ b/include/linux/mtd/nand-qpic-common.h
@@ -237,6 +237,9 @@
* @last_data_desc - last DMA desc in data channel (tx/rx).
* @last_cmd_desc - last DMA desc in command channel.
* @txn_done - completion for NAND transfer.
+ * @bam_ce_nitems - the number of elements in the @bam_ce array
+ * @cmd_sgl_nitems - the number of elements in the @cmd_sgl array
+ * @data_sgl_nitems - the number of elements in the @data_sgl array
* @bam_ce_pos - the index in bam_ce which is available for next sgl
* @bam_ce_start - the index in bam_ce which marks the start position ce
* for current sgl. It will be used for size calculation
@@ -255,6 +258,11 @@ struct bam_transaction {
struct dma_async_tx_descriptor *last_data_desc;
struct dma_async_tx_descriptor *last_cmd_desc;
struct completion txn_done;
+
+ unsigned int bam_ce_nitems;
+ unsigned int cmd_sgl_nitems;
+ unsigned int data_sgl_nitems;
+
struct_group(bam_positions,
u32 bam_ce_pos;
u32 bam_ce_start;
--
2.49.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v3 0/2] spi: spi-qpic-snand: avoid memory corruption
2025-06-18 20:22 [PATCH v3 0/2] spi: spi-qpic-snand: avoid memory corruption Gabor Juhos
2025-06-18 20:22 ` [PATCH v3 1/2] spi: spi-qpic-snand: reallocate BAM transactions Gabor Juhos
2025-06-18 20:22 ` [PATCH v3 2/2] mtd: nand: qpic_common: prevent out of bounds access of BAM arrays Gabor Juhos
@ 2025-06-25 22:43 ` Mark Brown
2025-06-26 7:25 ` Miquel Raynal
2025-06-30 12:37 ` Mark Brown
3 siblings, 1 reply; 6+ messages in thread
From: Mark Brown @ 2025-06-25 22:43 UTC (permalink / raw)
To: Gabor Juhos
Cc: Md Sadre Alam, Varadarajan Narayanan, Sricharan Ramabadhran,
Miquel Raynal, Richard Weinberger, Vignesh Raghavendra, linux-spi,
linux-mtd, linux-arm-msm, linux-kernel, Lakshmi Sowjanya D
[-- Attachment #1: Type: text/plain, Size: 663 bytes --]
On Wed, Jun 18, 2025 at 10:22:48PM +0200, Gabor Juhos wrote:
> The 'spi-qpic-nand' driver may cause memory corruption under some
> circumstances. The first patch in the series changes the driver to
> avoid that, whereas the second adds some sanity checks to the common
> QPIC code in order to make detecting such errors easier in the future.
>
> Preferably, the two patches should go along in via the SPI tree.
> It is not a strict requirement though, in the case the second patch
> gets included separately through the MTD tree it reveals the bug
> which is fixed in the first patch.
Miquel, are you OK with this plan for merging via the SPI tree?
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3 0/2] spi: spi-qpic-snand: avoid memory corruption
2025-06-25 22:43 ` [PATCH v3 0/2] spi: spi-qpic-snand: avoid memory corruption Mark Brown
@ 2025-06-26 7:25 ` Miquel Raynal
0 siblings, 0 replies; 6+ messages in thread
From: Miquel Raynal @ 2025-06-26 7:25 UTC (permalink / raw)
To: Mark Brown
Cc: Gabor Juhos, Md Sadre Alam, Varadarajan Narayanan,
Sricharan Ramabadhran, Richard Weinberger, Vignesh Raghavendra,
linux-spi, linux-mtd, linux-arm-msm, linux-kernel,
Lakshmi Sowjanya D
Hi Mark,
On 25/06/2025 at 23:43:23 +01, Mark Brown <broonie@kernel.org> wrote:
> On Wed, Jun 18, 2025 at 10:22:48PM +0200, Gabor Juhos wrote:
>> The 'spi-qpic-nand' driver may cause memory corruption under some
>> circumstances. The first patch in the series changes the driver to
>> avoid that, whereas the second adds some sanity checks to the common
>> QPIC code in order to make detecting such errors easier in the future.
>>
>> Preferably, the two patches should go along in via the SPI tree.
>> It is not a strict requirement though, in the case the second patch
>> gets included separately through the MTD tree it reveals the bug
>> which is fixed in the first patch.
>
> Miquel, are you OK with this plan for merging via the SPI tree?
Absolutely, my Ack is already there, thanks for asking.
Miquèl
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3 0/2] spi: spi-qpic-snand: avoid memory corruption
2025-06-18 20:22 [PATCH v3 0/2] spi: spi-qpic-snand: avoid memory corruption Gabor Juhos
` (2 preceding siblings ...)
2025-06-25 22:43 ` [PATCH v3 0/2] spi: spi-qpic-snand: avoid memory corruption Mark Brown
@ 2025-06-30 12:37 ` Mark Brown
3 siblings, 0 replies; 6+ messages in thread
From: Mark Brown @ 2025-06-30 12:37 UTC (permalink / raw)
To: Md Sadre Alam, Varadarajan Narayanan, Sricharan Ramabadhran,
Miquel Raynal, Richard Weinberger, Vignesh Raghavendra,
Gabor Juhos
Cc: linux-spi, linux-mtd, linux-arm-msm, linux-kernel,
Lakshmi Sowjanya D
On Wed, 18 Jun 2025 22:22:48 +0200, Gabor Juhos wrote:
> The 'spi-qpic-nand' driver may cause memory corruption under some
> circumstances. The first patch in the series changes the driver to
> avoid that, whereas the second adds some sanity checks to the common
> QPIC code in order to make detecting such errors easier in the future.
>
> Preferably, the two patches should go along in via the SPI tree.
> It is not a strict requirement though, in the case the second patch
> gets included separately through the MTD tree it reveals the bug
> which is fixed in the first patch.
>
> [...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next
Thanks!
[1/2] spi: spi-qpic-snand: reallocate BAM transactions
commit: d85d0380292a7e618915069c3579ae23c7c80339
[2/2] mtd: nand: qpic_common: prevent out of bounds access of BAM arrays
commit: ddaad4ad774d4ae02047ef873a8e38f62a4b7b01
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-06-30 12:37 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-18 20:22 [PATCH v3 0/2] spi: spi-qpic-snand: avoid memory corruption Gabor Juhos
2025-06-18 20:22 ` [PATCH v3 1/2] spi: spi-qpic-snand: reallocate BAM transactions Gabor Juhos
2025-06-18 20:22 ` [PATCH v3 2/2] mtd: nand: qpic_common: prevent out of bounds access of BAM arrays Gabor Juhos
2025-06-25 22:43 ` [PATCH v3 0/2] spi: spi-qpic-snand: avoid memory corruption Mark Brown
2025-06-26 7:25 ` Miquel Raynal
2025-06-30 12:37 ` Mark Brown
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).