Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp278346ybi; Wed, 29 May 2019 21:14:34 -0700 (PDT) X-Google-Smtp-Source: APXvYqwaVP3dS/N8x+aDcPcNtjfbY/QQ2NREs/Gh8dBdc7eJMDrmeLQDB5FVKAB5ewZRf+idKBed X-Received: by 2002:a62:1dca:: with SMTP id d193mr1679027pfd.93.1559189674401; Wed, 29 May 2019 21:14:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1559189674; cv=none; d=google.com; s=arc-20160816; b=dlrXwIwzeDuIzHQ/0EAL7q+HsVR6iIjbFtlyqDF+55ArKR15SYUrX3Ylyxz0HOq57x ZL9zBPjfs5MyvG/EVQv0lU3q97qHoNx1oGOqadDj2SRnDIWhuGf3q9eDG8j1/H4+VTJm 5GybPiehAlLQXiyXM8BSMi/QJ2QByYJfJRiGE44kN6vnB0+OhE1fJHplx3eaO4FRljig YhAhG+HICiqnArS2Yw+Qfdtz634MCiB8446648c7Dvt09UQAlK/WmLjsrjGAduC84tRf G6xaVqOcH2cuUS/XXwoVh5Pv6PWvRZk0bIIYagO09d2cXx4hi+64rJymQxcWGdNTHak1 K9mw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=Ly7anscqCObod9n/q5s7LpH1UDTpW6V5FgqKUxtoGz0=; b=lKgWxPLQPeYBvHPScdCHyFDSQv56hQxmhGHcvFh5b75C1u5D60OBaxVYBiKfoJ0gvF nAsPeeIb9CDvEgdLzg4DvSrG+nAIRQEbBMuCQkvKTWaL/4lcms7WSej/7pk1O6VElD4w 6tVECptASdeWe5AVZCAshW7W0cKl/DUnrW1//kJrwU7t15yVp5urcC39Hpwz5XbZcMR7 4QEtT+HdO9FAJcbA1mAu6GUgIm3Zfn3egixEd+FmZyJidHWo1D5lpvvS+GC2xhUi9IXx shKwDX8Bm2Xyq2jcsJX23f8TVojZIhHUwjt40Pm3Yk/PtzT7qix199ArMmCayUcfFehK 2BIw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=nrTDqrGa; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f38si2099964plb.339.2019.05.29.21.14.19; Wed, 29 May 2019 21:14:34 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=nrTDqrGa; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730981AbfE3ENV (ORCPT + 99 others); Thu, 30 May 2019 00:13:21 -0400 Received: from mail.kernel.org ([198.145.29.99]:43312 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730762AbfE3DQl (ORCPT ); Wed, 29 May 2019 23:16:41 -0400 Received: from localhost (ip67-88-213-2.z213-88-67.customer.algx.net [67.88.213.2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id EC3C0245F8; Thu, 30 May 2019 03:16:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1559186201; bh=uIbglvcgcCD288qkSn4ygSDW/GSXl/64XOYxAqgcNZM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nrTDqrGaKmIld68UrRx2K7JQsxVFjxwKYFAkf4gcR7Ao0Ro2P84eCtaF+R1Bkdmac 5yu1xxoxvqTLJke62yr6Av1EdG3Ybjs0OI49WFmJ1KF0Q2CMnTPKCQfBO6u69QGy+t PDs+vidcky6rPr3xleMuLjOo+KpYBjrz7GTdPBQQ= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Hans Verkuil , Syzbot , Tomasz Figa , Hans Verkuil , Mauro Carvalho Chehab Subject: [PATCH 4.19 036/276] media: vb2: add waiting_in_dqbuf flag Date: Wed, 29 May 2019 20:03:14 -0700 Message-Id: <20190530030526.499360569@linuxfoundation.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190530030523.133519668@linuxfoundation.org> References: <20190530030523.133519668@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Hans Verkuil commit d65842f7126aa1a87fb44b7c9980c12630ed4f33 upstream. Calling VIDIOC_DQBUF can release the core serialization lock pointed to by vb2_queue->lock if it has to wait for a new buffer to arrive. However, if userspace dup()ped the video device filehandle, then it is possible to read or call DQBUF from two filehandles at the same time. It is also possible to call REQBUFS from one filehandle while the other is waiting for a buffer. This will remove all the buffers and reallocate new ones. Removing all the buffers isn't the problem here (that's already handled correctly by DQBUF), but the reallocating part is: DQBUF isn't aware that the buffers have changed. This is fixed by setting a flag whenever the lock is released while waiting for a buffer to arrive. And checking the flag where needed so we can return -EBUSY. Signed-off-by: Hans Verkuil Reported-by: Syzbot Reviewed-by: Tomasz Figa Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- drivers/media/common/videobuf2/videobuf2-core.c | 22 ++++++++++++++++++++++ include/media/videobuf2-core.h | 1 + 2 files changed, 23 insertions(+) --- a/drivers/media/common/videobuf2/videobuf2-core.c +++ b/drivers/media/common/videobuf2/videobuf2-core.c @@ -668,6 +668,11 @@ int vb2_core_reqbufs(struct vb2_queue *q return -EBUSY; } + if (q->waiting_in_dqbuf && *count) { + dprintk(1, "another dup()ped fd is waiting for a buffer\n"); + return -EBUSY; + } + if (*count == 0 || q->num_buffers != 0 || (q->memory != VB2_MEMORY_UNKNOWN && q->memory != memory)) { /* @@ -797,6 +802,10 @@ int vb2_core_create_bufs(struct vb2_queu } if (!q->num_buffers) { + if (q->waiting_in_dqbuf && *count) { + dprintk(1, "another dup()ped fd is waiting for a buffer\n"); + return -EBUSY; + } memset(q->alloc_devs, 0, sizeof(q->alloc_devs)); q->memory = memory; q->waiting_for_buffers = !q->is_output; @@ -1466,6 +1475,11 @@ static int __vb2_wait_for_done_vb(struct for (;;) { int ret; + if (q->waiting_in_dqbuf) { + dprintk(1, "another dup()ped fd is waiting for a buffer\n"); + return -EBUSY; + } + if (!q->streaming) { dprintk(1, "streaming off, will not wait for buffers\n"); return -EINVAL; @@ -1493,6 +1507,7 @@ static int __vb2_wait_for_done_vb(struct return -EAGAIN; } + q->waiting_in_dqbuf = 1; /* * We are streaming and blocking, wait for another buffer to * become ready or for streamoff. Driver's lock is released to @@ -1513,6 +1528,7 @@ static int __vb2_wait_for_done_vb(struct * the locks or return an error if one occurred. */ call_void_qop(q, wait_finish, q); + q->waiting_in_dqbuf = 0; if (ret) { dprintk(1, "sleep was interrupted\n"); return ret; @@ -2361,6 +2377,12 @@ static size_t __vb2_perform_fileio(struc if (!data) return -EINVAL; + if (q->waiting_in_dqbuf) { + dprintk(3, "another dup()ped fd is %s\n", + read ? "reading" : "writing"); + return -EBUSY; + } + /* * Initialize emulator on first call. */ --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -551,6 +551,7 @@ struct vb2_queue { unsigned int start_streaming_called:1; unsigned int error:1; unsigned int waiting_for_buffers:1; + unsigned int waiting_in_dqbuf:1; unsigned int is_multiplanar:1; unsigned int is_output:1; unsigned int copy_timestamp:1;