media: vivid: fix the racy dev->radio_tx_rds_owner
authorSishuai Gong <sishuai.system@gmail.com>
Thu, 10 Aug 2023 00:53:48 +0000 (20:53 -0400)
committerMauro Carvalho Chehab <mchehab@kernel.org>
Mon, 14 Aug 2023 18:27:58 +0000 (20:27 +0200)
There is a race over dev->radio_tx_rds_owner between the two functions
mentioned below:

Thread-1                Thread-2
vivid_fop_release()     vivid_radio_rx_read()
mutex_unlock(&dev->mutex)
                        mutex_lock_interruptible(&dev->mutex)
                        ...
                        dev->radio_rx_rds_owner = file->private_data;
...
if (file->private_data == dev->radio_rx_rds_owner) {
        dev->radio_tx_rds_last_block = 0;
        dev->radio_tx_rds_owner = NULL;
}

This race can be fixed by only releasing the lock after vivid_fop_release()
finishes the checks.

Signed-off-by: Sishuai Gong <sishuai.system@gmail.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
drivers/media/test-drivers/vivid/vivid-core.c

index c2167cc..e95bdcc 100644 (file)
@@ -628,7 +628,6 @@ static int vivid_fop_release(struct file *file)
                v4l2_info(&dev->v4l2_dev, "reconnect\n");
                vivid_reconnect(dev);
        }
-       mutex_unlock(&dev->mutex);
        if (file->private_data == dev->radio_rx_rds_owner) {
                dev->radio_rx_rds_last_block = 0;
                dev->radio_rx_rds_owner = NULL;
@@ -637,6 +636,7 @@ static int vivid_fop_release(struct file *file)
                dev->radio_tx_rds_last_block = 0;
                dev->radio_tx_rds_owner = NULL;
        }
+       mutex_unlock(&dev->mutex);
        if (vdev->queue)
                return vb2_fop_release(file);
        return v4l2_fh_release(file);