Commit cd26d1c4 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

media: vb2: vb2_mmap: move lock up

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: default avatarHans Verkuil <hverkuil@xs4all.nl>
Reported-by: syzbot+be93025dd45dccd8923c@syzkaller.appspotmail.com
Signed-off-by: default avatarHans Verkuil <hansverk@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent 2e84eb9a
...@@ -2117,9 +2117,13 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma) ...@@ -2117,9 +2117,13 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma)
return -EINVAL; return -EINVAL;
} }
} }
mutex_lock(&q->mmap_lock);
if (vb2_fileio_is_active(q)) { if (vb2_fileio_is_active(q)) {
dprintk(1, "mmap: file io in progress\n"); dprintk(1, "mmap: file io in progress\n");
return -EBUSY; ret = -EBUSY;
goto unlock;
} }
/* /*
...@@ -2127,7 +2131,7 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma) ...@@ -2127,7 +2131,7 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma)
*/ */
ret = __find_plane_by_offset(q, off, &buffer, &plane); ret = __find_plane_by_offset(q, off, &buffer, &plane);
if (ret) if (ret)
return ret; goto unlock;
vb = q->bufs[buffer]; vb = q->bufs[buffer];
...@@ -2143,8 +2147,9 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma) ...@@ -2143,8 +2147,9 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma)
return -EINVAL; return -EINVAL;
} }
mutex_lock(&q->mmap_lock);
ret = call_memop(vb, mmap, vb->planes[plane].mem_priv, vma); ret = call_memop(vb, mmap, vb->planes[plane].mem_priv, vma);
unlock:
mutex_unlock(&q->mmap_lock); mutex_unlock(&q->mmap_lock);
if (ret) if (ret)
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment