lkml.org 
[lkml]   [2020]   [Jun]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 1/2] spi: spidev: fix a race between spidev_release and spidev_remove
    Date
    Imagine below scene, spidev is referenced after it's freed.

    spidev_release() spidev_remove()
    ...
    spin_lock_irq(&spidev->spi_lock);
    spidev->spi = NULL;
    spin_unlock_irq(&spidev->spi_lock);
    mutex_lock(&device_list_lock);
    dofree = (spidev->spi == NULL);
    if (dofree)
    kfree(spidev);
    mutex_unlock(&device_list_lock);
    mutex_lock(&device_list_lock);
    list_del(&spidev->device_entry);
    device_destroy(spidev_class, spidev->devt);
    clear_bit(MINOR(spidev->devt), minors);
    if (spidev->users == 0)
    kfree(spidev);
    mutex_unlock(&device_list_lock);

    Fix it by resetting spidev->spi in device_list_lock's protection.

    Signed-off-by: Zhenzhong Duan <zhenzhong.duan@gmail.com>
    ---
    drivers/spi/spidev.c | 4 ++--
    1 file changed, 2 insertions(+), 2 deletions(-)

    diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
    index d753df7..f74ea26 100644
    --- a/drivers/spi/spidev.c
    +++ b/drivers/spi/spidev.c
    @@ -787,13 +787,13 @@ static int spidev_remove(struct spi_device *spi)
    {
    struct spidev_data *spidev = spi_get_drvdata(spi);

    + /* prevent new opens */
    + mutex_lock(&device_list_lock);
    /* make sure ops on existing fds can abort cleanly */
    spin_lock_irq(&spidev->spi_lock);
    spidev->spi = NULL;
    spin_unlock_irq(&spidev->spi_lock);

    - /* prevent new opens */
    - mutex_lock(&device_list_lock);
    list_del(&spidev->device_entry);
    device_destroy(spidev_class, spidev->devt);
    clear_bit(MINOR(spidev->devt), minors);
    --
    1.8.3.1
    \
     
     \ /
      Last update: 2020-06-18 05:22    [W:2.856 / U:0.132 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site