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 <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>
This commit is contained in:
parent
abd42781c3
commit
06096cc6c5
|
@ -609,15 +609,20 @@ 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;
|
||||
|
@ -625,19 +630,14 @@ static int spidev_release(struct inode *inode, struct file *filp)
|
|||
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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user