Skip to content

Commit

Permalink
spi: spi-zynqmp-gqspi: fix use-after-free in zynqmp_qspi_exec_op
Browse files Browse the repository at this point in the history
When handling op->addr, it is using the buffer "tmpbuf" which has been
freed. This will trigger a use-after-free KASAN warning. Let's use
temporary variables to store op->addr.val and op->cmd.opcode to fix
this issue.

Fixes: 1c26372 ("spi: spi-zynqmp-gqspi: Update driver to use spi-mem framework")
Signed-off-by: Quanyang Wang <quanyang.wang@windriver.com>
Link: https://lore.kernel.org/r/20210416004652.2975446-5-quanyang.wang@windriver.com
Signed-off-by: Mark Brown <broonie@kernel.org>
  • Loading branch information
Quanyang Wang authored and Mark Brown committed Apr 16, 2021
1 parent 2530b3d commit a2c5bed
Showing 1 changed file with 4 additions and 10 deletions.
14 changes: 4 additions & 10 deletions drivers/spi/spi-zynqmp-gqspi.c
Original file line number Diff line number Diff line change
Expand Up @@ -928,8 +928,9 @@ static int zynqmp_qspi_exec_op(struct spi_mem *mem,
struct zynqmp_qspi *xqspi = spi_controller_get_devdata
(mem->spi->master);
int err = 0, i;
u8 *tmpbuf;
u32 genfifoentry = 0;
u16 opcode = op->cmd.opcode;
u64 opaddr;

dev_dbg(xqspi->dev, "cmd:%#x mode:%d.%d.%d.%d\n",
op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth,
Expand All @@ -942,14 +943,8 @@ static int zynqmp_qspi_exec_op(struct spi_mem *mem,
genfifoentry |= xqspi->genfifobus;

if (op->cmd.opcode) {
tmpbuf = kzalloc(op->cmd.nbytes, GFP_KERNEL | GFP_DMA);
if (!tmpbuf) {
mutex_unlock(&xqspi->op_lock);
return -ENOMEM;
}
tmpbuf[0] = op->cmd.opcode;
reinit_completion(&xqspi->data_completion);
xqspi->txbuf = tmpbuf;
xqspi->txbuf = &opcode;
xqspi->rxbuf = NULL;
xqspi->bytes_to_transfer = op->cmd.nbytes;
xqspi->bytes_to_receive = 0;
Expand All @@ -963,13 +958,12 @@ static int zynqmp_qspi_exec_op(struct spi_mem *mem,
if (!wait_for_completion_timeout
(&xqspi->data_completion, msecs_to_jiffies(1000))) {
err = -ETIMEDOUT;
kfree(tmpbuf);
goto return_err;
}
kfree(tmpbuf);
}

if (op->addr.nbytes) {
xqspi->txbuf = &opaddr;
for (i = 0; i < op->addr.nbytes; i++) {
*(((u8 *)xqspi->txbuf) + i) = op->addr.val >>
(8 * (op->addr.nbytes - i - 1));
Expand Down

0 comments on commit a2c5bed

Please sign in to comment.