Skip to content

Commit 06096cc

Browse files
Zhenzhong Duanbroonie
authored andcommitted
spi: spidev: fix a potential use-after-free in spidev_release()
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 <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent abd4278 commit 06096cc

File tree

1 file changed

+10
-10
lines changed

1 file changed

+10
-10
lines changed

drivers/spi/spidev.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -609,35 +609,35 @@ static int spidev_open(struct inode *inode, struct file *filp)
609609
static int spidev_release(struct inode *inode, struct file *filp)
610610
{
611611
struct spidev_data *spidev;
612+
int dofree;
612613

613614
mutex_lock(&device_list_lock);
614615
spidev = filp->private_data;
615616
filp->private_data = NULL;
616617

618+
spin_lock_irq(&spidev->spi_lock);
619+
/* ... after we unbound from the underlying device? */
620+
dofree = (spidev->spi == NULL);
621+
spin_unlock_irq(&spidev->spi_lock);
622+
617623
/* last close? */
618624
spidev->users--;
619625
if (!spidev->users) {
620-
int dofree;
621626

622627
kfree(spidev->tx_buffer);
623628
spidev->tx_buffer = NULL;
624629

625630
kfree(spidev->rx_buffer);
626631
spidev->rx_buffer = NULL;
627632

628-
spin_lock_irq(&spidev->spi_lock);
629-
if (spidev->spi)
630-
spidev->speed_hz = spidev->spi->max_speed_hz;
631-
632-
/* ... after we unbound from the underlying device? */
633-
dofree = (spidev->spi == NULL);
634-
spin_unlock_irq(&spidev->spi_lock);
635-
636633
if (dofree)
637634
kfree(spidev);
635+
else
636+
spidev->speed_hz = spidev->spi->max_speed_hz;
638637
}
639638
#ifdef CONFIG_SPI_SLAVE
640-
spi_slave_abort(spidev->spi);
639+
if (!dofree)
640+
spi_slave_abort(spidev->spi);
641641
#endif
642642
mutex_unlock(&device_list_lock);
643643

0 commit comments

Comments
 (0)