Skip to content

Commit

Permalink
spi: spidev: fix a potential use-after-free in spidev_release()
Browse files Browse the repository at this point in the history
If an spi device is unbounded from the driver before the release
process, there will be an NULL pointer reference when it's
referenced in spi_slave_abort().

Fix it by checking it's already freed before reference.

Signed-off-by: Zhenzhong Duan <zhenzhong.duan@gmail.com>
Link: https://lore.kernel.org/r/20200618032125.4650-2-zhenzhong.duan@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
  • Loading branch information
Zhenzhong Duan authored and broonie committed Jun 18, 2020
1 parent abd4278 commit 06096cc
Showing 1 changed file with 10 additions and 10 deletions.
20 changes: 10 additions & 10 deletions drivers/spi/spidev.c
Original file line number Diff line number Diff line change
Expand Up @@ -609,35 +609,35 @@ static int spidev_open(struct inode *inode, struct file *filp)
static int spidev_release(struct inode *inode, struct file *filp)
{
struct spidev_data *spidev;
int dofree;

mutex_lock(&device_list_lock);
spidev = filp->private_data;
filp->private_data = NULL;

spin_lock_irq(&spidev->spi_lock);
/* ... after we unbound from the underlying device? */
dofree = (spidev->spi == NULL);
spin_unlock_irq(&spidev->spi_lock);

/* last close? */
spidev->users--;
if (!spidev->users) {
int dofree;

kfree(spidev->tx_buffer);
spidev->tx_buffer = NULL;

kfree(spidev->rx_buffer);
spidev->rx_buffer = NULL;

spin_lock_irq(&spidev->spi_lock);
if (spidev->spi)
spidev->speed_hz = spidev->spi->max_speed_hz;

/* ... after we unbound from the underlying device? */
dofree = (spidev->spi == NULL);
spin_unlock_irq(&spidev->spi_lock);

if (dofree)
kfree(spidev);
else
spidev->speed_hz = spidev->spi->max_speed_hz;
}
#ifdef CONFIG_SPI_SLAVE
spi_slave_abort(spidev->spi);
if (!dofree)
spi_slave_abort(spidev->spi);
#endif
mutex_unlock(&device_list_lock);

Expand Down

0 comments on commit 06096cc

Please sign in to comment.