Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eb376a62 authored by Hans Verkuil's avatar Hans Verkuil Committed by Greg Kroah-Hartman
Browse files

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: default avatarHans Verkuil <hverkuil@xs4all.nl>
Reported-by: default avatar <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>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent b9f93793
Loading
Loading
Loading
Loading
+8 −3
Original line number Original line Diff line number Diff line
@@ -1925,9 +1925,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;
	}
	}


	/*
	/*
@@ -1935,7 +1939,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];


@@ -1951,8 +1955,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;