From: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx> Commit 8cc3bad9d9d6 ("spi: Remove unneded check for orig_nents") introduced a regression: unmapped data could now be passed to the DMA APIs, resulting in null pointer dereferences. Commit 9f788ba457b4 ("spi: Don't mark message DMA mapped when no transfer in it is") and commit da560097c056 ("spi: Check if transfer is mapped before calling DMA sync APIs") addressed the problem, but only partially. Unidirectional transactions will still result in null pointer dereference. To prevent that from happening, assign a dummy scatterlist when no data is mapped, so that the DMA API can be called and not result in a null pointer dereference. Signed-off-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx> Reported-by: Neil Armstrong <neil.armstrong@xxxxxxxxxx> Closes: https://lore.kernel.org/r/8ae675b5-fcf9-4c9b-b06a-4462f70e1322@xxxxxxxxxx Reported-by: Nícolas F. R. A. Prado <nfraprado@xxxxxxxxxxxxx> Closes: https://lore.kernel.org/all/d3679496-2e4e-4a7c-97ed-f193bd53af1d@notapiano Closes: https://lore.kernel.org/all/4748499f-789c-45a8-b50a-2dd09f4bac8c@notapiano Fixes: 8cc3bad9d9d6 ("spi: Remove unneded check for orig_nents") Tested-by: Nícolas F. R. A. Prado <nfraprado@xxxxxxxxxxxxx> [nfraprado: wrote the commit message] Signed-off-by: Nícolas F. R. A. Prado <nfraprado@xxxxxxxxxxxxx> --- drivers/spi/spi.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index f94420858c22..9bc9fd10d538 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1220,6 +1220,11 @@ void spi_unmap_buf(struct spi_controller *ctlr, struct device *dev, spi_unmap_buf_attrs(ctlr, dev, sgt, dir, 0); } +/* Dummy SG for unidirect transfers */ +static struct scatterlist dummy_sg = { + .page_link = SG_END, +}; + static int __spi_map_msg(struct spi_controller *ctlr, struct spi_message *msg) { struct device *tx_dev, *rx_dev; @@ -1258,6 +1263,8 @@ static int __spi_map_msg(struct spi_controller *ctlr, struct spi_message *msg) attrs); if (ret != 0) return ret; + } else { + xfer->tx_sg.sgl = &dummy_sg; } if (xfer->rx_buf != NULL) { @@ -1271,6 +1278,8 @@ static int __spi_map_msg(struct spi_controller *ctlr, struct spi_message *msg) return ret; } + } else { + xfer->rx_sg.sgl = &dummy_sg; } } /* No transfer has been mapped, bail out with success */ --- base-commit: 9d99040b1bc8dbf385a8aa535e9efcdf94466e19 change-id: 20240529-dma-oops-dummy-2cbf8cbaec54 Best regards, -- Nícolas F. R. A. Prado <nfraprado@xxxxxxxxxxxxx>