]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
media: vb2: vb2_mmap: move lock up
authorHans Verkuil <hverkuil@xs4all.nl>
Tue, 13 Nov 2018 14:06:46 +0000 (09:06 -0500)
committerKleber Sacilotto de Souza <kleber.souza@canonical.com>
Wed, 14 Aug 2019 09:18:49 +0000 (11:18 +0200)
BugLink: https://bugs.launchpad.net/bugs/1837477
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>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
Signed-off-by: Khalid Elmously <khalid.elmously@canonical.com>
drivers/media/v4l2-core/videobuf2-core.c

index fe90f0f8ba06b3c03cfb22f4108c1ea0f4b2bc83..5a7c18c1cdd23551352a73db747184093b3364f9 100644 (file)
@@ -1926,9 +1926,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;
        }
 
        /*
@@ -1936,7 +1940,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];
 
@@ -1952,8 +1956,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;