Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] vb2: check if vb2_fop_write/read is allowed

Return -EINVAL if read() or write() is not supported by the queue. This
makes it possible to provide both vb2_fop_read and vb2_fop_write in a
struct v4l2_file_operations since the vb2_fop_* function will check if
the file operation is allowed.

A similar check exists in __vb2_init_fileio() which is called from
__vb2_perform_fileio(), but that check is only done if no file I/O is
active. So the sequence of read() followed by write() would be allowed,
which is obviously a bug.

In addition, vb2_fop_write/read should always return -EINVAL if the
operation is not allowed, and by putting the check in the lower levels
of the code it is possible that other error codes are returned (EBUSY
or ERESTARTSYS).

All these issues are avoided by just doing a quick explicit check.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>

authored by

Hans Verkuil and committed by
Mauro Carvalho Chehab
ff05cb4b ee662d44

+4
+4
drivers/media/v4l2-core/videobuf2-core.c
··· 3416 3416 struct mutex *lock = vdev->queue->lock ? vdev->queue->lock : vdev->lock; 3417 3417 int err = -EBUSY; 3418 3418 3419 + if (!(vdev->queue->io_modes & VB2_WRITE)) 3420 + return -EINVAL; 3419 3421 if (lock && mutex_lock_interruptible(lock)) 3420 3422 return -ERESTARTSYS; 3421 3423 if (vb2_queue_is_busy(vdev, file)) ··· 3440 3438 struct mutex *lock = vdev->queue->lock ? vdev->queue->lock : vdev->lock; 3441 3439 int err = -EBUSY; 3442 3440 3441 + if (!(vdev->queue->io_modes & VB2_READ)) 3442 + return -EINVAL; 3443 3443 if (lock && mutex_lock_interruptible(lock)) 3444 3444 return -ERESTARTSYS; 3445 3445 if (vb2_queue_is_busy(vdev, file))