summaryrefslogtreecommitdiff
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-26 09:44:26 +0100
commitbabd8d8ca362ce44a2c9aaa9143a4b23e135be91 (patch)
tree3ad8ee053e89ba576a328d2aa43100b742f1f028
parent3c2350d7ef6b0e5e237701dee4038b7ca933d82a (diff)
downloadlinux-babd8d8ca362ce44a2c9aaa9143a4b23e135be91.tar.gz
linux-babd8d8ca362ce44a2c9aaa9143a4b23e135be91.tar.bz2
linux-babd8d8ca362ce44a2c9aaa9143a4b23e135be91.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/v4l2-core/videobuf2-core.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index f0811b7e900d..ac7c0ecb3626 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -2474,9 +2474,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;
}
/*
@@ -2484,7 +2488,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];
@@ -2500,8 +2504,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;