diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2018-11-19 12:09:00 +0100 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | 2019-04-22 17:50:07 +0200 |
commit | d65842f7126aa1a87fb44b7c9980c12630ed4f33 (patch) | |
tree | b5cdc1b59f56649c5c95322ef91cf898f2d2afc9 /include/media | |
parent | media: pvrusb2: Prevent a buffer overflow (diff) | |
download | linux-d65842f7126aa1a87fb44b7c9980c12630ed4f33.tar.xz linux-d65842f7126aa1a87fb44b7c9980c12630ed4f33.zip |
media: vb2: add waiting_in_dqbuf flag
Calling VIDIOC_DQBUF can release the core serialization lock pointed to
by vb2_queue->lock if it has to wait for a new buffer to arrive.
However, if userspace dup()ped the video device filehandle, then it is
possible to read or call DQBUF from two filehandles at the same time.
It is also possible to call REQBUFS from one filehandle while the other
is waiting for a buffer. This will remove all the buffers and reallocate
new ones. Removing all the buffers isn't the problem here (that's already
handled correctly by DQBUF), but the reallocating part is: DQBUF isn't
aware that the buffers have changed.
This is fixed by setting a flag whenever the lock is released while waiting
for a buffer to arrive. And checking the flag where needed so we can return
-EBUSY.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Reported-by: Syzbot <syzbot+4180ff9ca6810b06c1e9@syzkaller.appspotmail.com>
Reviewed-by: Tomasz Figa <tfiga@chromium.org>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Diffstat (limited to 'include/media')
-rw-r--r-- | include/media/videobuf2-core.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index fe010ad62b90..22f3ff76a8b5 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -596,6 +596,7 @@ struct vb2_queue { unsigned int start_streaming_called:1; unsigned int error:1; unsigned int waiting_for_buffers:1; + unsigned int waiting_in_dqbuf:1; unsigned int is_multiplanar:1; unsigned int is_output:1; unsigned int copy_timestamp:1; |