aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2018-11-13 09:06:46 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-01-22 21:40:35 +0100
commitc4f39cba6fd08def0a4491f57566582823751568 (patch)
tree463f43a5f3b14b360ba17cb44d60ee5c91b71706
parenta19aedf1a77c2e426c9810aece80646283cc2808 (diff)
downloadlinux-yocto-c4f39cba6fd08def0a4491f57566582823751568.tar.gz
linux-yocto-c4f39cba6fd08def0a4491f57566582823751568.tar.bz2
linux-yocto-c4f39cba6fd08def0a4491f57566582823751568.zip
media: vb2: vb2_mmap: move lock up
commit cd26d1c4d1bc947b56ae404998ae2276df7b39b7 upstream. If a filehandle is dup()ped, then it is possible to close it from one fd and call mmap from the other. This creates a race condition in vb2_mmap where it is using queue data that __vb2_queue_free (called from close()) is in the process of releasing. By moving up the mutex_lock(mmap_lock) in vb2_mmap this race is avoided since __vb2_queue_free is called with the same mutex locked. So vb2_mmap now reads consistent buffer data. Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Reported-by: syzbot+be93025dd45dccd8923c@syzkaller.appspotmail.com Signed-off-by: Hans Verkuil <hansverk@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/media/common/videobuf2/videobuf2-core.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c
index 1faa64abc74f..07629e7c15be 100644
--- a/drivers/media/common/videobuf2/videobuf2-core.c
+++ b/drivers/media/common/videobuf2/videobuf2-core.c
@@ -1933,9 +1933,13 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma)
return -EINVAL;
}
}
+
+ mutex_lock(&q->mmap_lock);
+
if (vb2_fileio_is_active(q)) {
dprintk(1, "mmap: file io in progress\n");
- return -EBUSY;
+ ret = -EBUSY;
+ goto unlock;
}
/*
@@ -1943,7 +1947,7 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma)
*/
ret = __find_plane_by_offset(q, off, &buffer, &plane);
if (ret)
- return ret;
+ goto unlock;
vb = q->bufs[buffer];
@@ -1959,8 +1963,9 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma)
return -EINVAL;
}
- mutex_lock(&q->mmap_lock);
ret = call_memop(vb, mmap, vb->planes[plane].mem_priv, vma);
+
+unlock:
mutex_unlock(&q->mmap_lock);
if (ret)
return ret;