All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
To: Hans Verkuil <hverkuil@xs4all.nl>
Cc: linux-media@vger.kernel.org, Hans Verkuil <hans.verkuil@cisco.com>
Subject: Re: [PATCHv13 06/28] v4l2-dev: lock req_queue_mutex
Date: Tue, 8 May 2018 07:45:28 -0300	[thread overview]
Message-ID: <20180508074528.10e5c8cd@vento.lan> (raw)
In-Reply-To: <f33821d6-3105-4ac0-ca86-36024463bec9@xs4all.nl>

Em Tue, 8 May 2018 09:45:27 +0200
Hans Verkuil <hverkuil@xs4all.nl> escreveu:

> On 05/07/2018 07:20 PM, Mauro Carvalho Chehab wrote:
> > Em Thu,  3 May 2018 16:52:56 +0200
> > Hans Verkuil <hverkuil@xs4all.nl> escreveu:
> >   
> >> From: Hans Verkuil <hans.verkuil@cisco.com>
> >>
> >> We need to serialize streamon/off with queueing new requests.
> >> These ioctls may trigger the cancellation of a streaming
> >> operation, and that should not be mixed with queuing a new
> >> request at the same time.
> >>
> >> Also TRY/S_EXT_CTRLS needs this lock to correctly serialize
> >> with MEDIA_REQUEST_IOC_QUEUE.
> >>
> >> Finally close() needs this lock since that too can trigger the
> >> cancellation of a streaming operation.
> >>
> >> We take the req_queue_mutex here before any other locks since
> >> it is a very high-level lock.
> >>
> >> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
> >> ---
> >>  drivers/media/v4l2-core/v4l2-dev.c | 37 +++++++++++++++++++++++++++++-
> >>  1 file changed, 36 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
> >> index 1d0b2208e8fb..b1c9efc0ecc4 100644
> >> --- a/drivers/media/v4l2-core/v4l2-dev.c
> >> +++ b/drivers/media/v4l2-core/v4l2-dev.c
> >> @@ -353,13 +353,36 @@ static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
> >>  
> >>  	if (vdev->fops->unlocked_ioctl) {
> >>  		struct mutex *lock = v4l2_ioctl_get_lock(vdev, cmd);
> >> +		struct mutex *queue_lock = NULL;
> >>  
> >> -		if (lock && mutex_lock_interruptible(lock))
> >> +		/*
> >> +		 * We need to serialize streamon/off with queueing new requests.
> >> +		 * These ioctls may trigger the cancellation of a streaming
> >> +		 * operation, and that should not be mixed with queueing a new
> >> +		 * request at the same time.
> >> +		 *
> >> +		 * Also TRY/S_EXT_CTRLS needs this lock to correctly serialize
> >> +		 * with MEDIA_REQUEST_IOC_QUEUE.
> >> +		 */
> >> +		if (vdev->v4l2_dev->mdev &&
> >> +		    (cmd == VIDIOC_STREAMON || cmd == VIDIOC_STREAMOFF ||
> >> +		     cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_TRY_EXT_CTRLS))
> >> +			queue_lock = &vdev->v4l2_dev->mdev->req_queue_mutex;
> >> +
> >> +		if (queue_lock && mutex_lock_interruptible(queue_lock))
> >> +			return -ERESTARTSYS;  
> > 
> > Taking both locks seems risky. Here you're taking first v4l2 lock, returned
> > by v4l2_ioctl_get_lock(vdev, cmd), and then you're taking the req_queue lock.  
> 
> No,  v4l2_ioctl_get_lock() only returns a pointer to a mutex, it doesn't lock
> anything. I think you got confused there. I'll reorganize the code a bit so
> the call to  v4l2_ioctl_get_lock() happens after the queue_lock has been taken.

Yeah, I didn't actually look at the implementation of v4l2_ioctl_get_lock().

As we're using "_get" along this patch series to increment krefs (with is
a sort of locking), the name here confused me. IMHO, we should rename it
to v4l2_ioctl_return_lock() (or similar) on some future, in order to avoid
confusion.

> I'll also rename queue_lock to req_queue_lock (it's a bit more descriptive).

Agreed.

> 
> So we first take the high-level media_device req_queue_mutex if needed, and
> then the ioctl serialization lock. Doing it the other way around will indeed
> promptly deadlock (as I very quickly discovered after my initial implementation!).
> 
> So the order is:
> 
> 	req_queue_mutex (serialize request state changes from/to IDLE)
> 	ioctl lock (serialize ioctls)
> 	request->lock (spinlock)
> 
> The last is only held for short periods when updating the media_request struct.
> 
> > 
> > It is possible to call parts of the code that only handles req_queue
> > or v4l2 lock (for example, by mixing request API calls with non-requests
> > one). Worse than that, there are parts of the code where the request API
> > patches get both a mutex and a spin lock.
> > 
> > I didn't look too closely (nor ran any test), but I'm almost sure that
> > there are paths where it will end by leading into dead locks.  
> 
> I've done extensive testing with this and actually been very careful about
> the lock handling. It's also been tested with the cedrus driver.

I don't doubt it works using your apps, but real life can be messier:
people could be issuing ioctls at different orders, programs can abort
any time, closing file descriptors at random times, threads can be
used to paralelize ioctls, etc.

That not discarding the possibility of someone coming with some
ingenious code meant to cause machine hangups or to exposure some
other security flaws.



Thanks,
Mauro

  reply	other threads:[~2018-05-08 10:45 UTC|newest]

Thread overview: 73+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-03 14:52 [PATCHv13 00/28] Request API Hans Verkuil
2018-05-03 14:52 ` [PATCHv13 01/28] v4l2-device.h: always expose mdev Hans Verkuil
2018-05-04 10:51   ` Sakari Ailus
2018-05-07 15:46     ` Mauro Carvalho Chehab
2018-05-08  8:34       ` Hans Verkuil
2018-05-16  3:40   ` Laurent Pinchart
2018-05-03 14:52 ` [PATCHv13 02/28] uapi/linux/media.h: add request API Hans Verkuil
2018-05-04 10:51   ` Sakari Ailus
2018-05-18 14:49   ` Laurent Pinchart
2018-05-03 14:52 ` [PATCHv13 03/28] media-request: implement media requests Hans Verkuil
2018-05-04 12:27   ` Sakari Ailus
2018-05-08 10:21     ` Mauro Carvalho Chehab
2018-05-08 10:52       ` Sakari Ailus
2018-05-08 12:41         ` Mauro Carvalho Chehab
2018-05-08 13:21           ` Sakari Ailus
2018-05-24 11:19       ` Hans Verkuil
2018-05-24  9:26     ` Hans Verkuil
2018-05-03 14:52 ` [PATCHv13 04/28] media-request: add media_request_get_by_fd Hans Verkuil
2018-05-04 12:26   ` Sakari Ailus
2018-05-07 17:01   ` Mauro Carvalho Chehab
2018-05-08  7:34     ` Hans Verkuil
2018-05-08 10:38       ` Mauro Carvalho Chehab
2018-05-03 14:52 ` [PATCHv13 05/28] media-request: add media_request_object_find Hans Verkuil
2018-05-04 12:43   ` Sakari Ailus
2018-05-07 17:05     ` Mauro Carvalho Chehab
2018-05-24  9:36       ` Hans Verkuil
2018-05-08 10:54     ` Sakari Ailus
2018-05-24  9:28     ` Hans Verkuil
2018-05-03 14:52 ` [PATCHv13 06/28] v4l2-dev: lock req_queue_mutex Hans Verkuil
2018-05-07 17:20   ` Mauro Carvalho Chehab
2018-05-08  7:45     ` Hans Verkuil
2018-05-08 10:45       ` Mauro Carvalho Chehab [this message]
2018-05-24  9:51         ` Hans Verkuil
2018-05-03 14:52 ` [PATCHv13 07/28] videodev2.h: add request_fd field to v4l2_ext_controls Hans Verkuil
2018-05-03 14:52 ` [PATCHv13 08/28] v4l2-ctrls: v4l2_ctrl_add_handler: add from_other_dev Hans Verkuil
2018-05-03 14:52 ` [PATCHv13 09/28] v4l2-ctrls: prepare internal structs for request API Hans Verkuil
2018-05-07 17:35   ` Mauro Carvalho Chehab
2018-05-08  7:49     ` Hans Verkuil
2018-05-03 14:53 ` [PATCHv13 10/28] v4l2-ctrls: alloc memory for p_req Hans Verkuil
2018-05-03 14:53 ` [PATCHv13 11/28] v4l2-ctrls: use ref in helper instead of ctrl Hans Verkuil
2018-05-03 14:53 ` [PATCHv13 12/28] v4l2-ctrls: add core request support Hans Verkuil
2018-05-07 18:06   ` Mauro Carvalho Chehab
2018-05-08  8:07     ` Hans Verkuil
2018-05-08 10:49       ` Mauro Carvalho Chehab
2018-05-24 10:27         ` Hans Verkuil
2018-05-16 10:19   ` Sakari Ailus
2018-05-16 10:46     ` Sakari Ailus
2018-05-16 10:55     ` Hans Verkuil
2018-05-16 11:18   ` Sakari Ailus
2018-05-03 14:53 ` [PATCHv13 13/28] v4l2-ctrls: support g/s_ext_ctrls for requests Hans Verkuil
2018-05-03 14:53 ` [PATCHv13 14/28] videodev2.h: Add request_fd field to v4l2_buffer Hans Verkuil
2018-05-03 14:53 ` [PATCHv13 15/28] vb2: store userspace data in vb2_v4l2_buffer Hans Verkuil
2018-05-03 14:53 ` [PATCHv13 16/28] videobuf2-core: embed media_request_object Hans Verkuil
2018-05-08  9:54   ` Mauro Carvalho Chehab
2018-05-03 14:53 ` [PATCHv13 17/28] videobuf2-core: integrate with media requests Hans Verkuil
2018-05-03 14:53 ` [PATCHv13 18/28] videobuf2-v4l2: " Hans Verkuil
2018-05-03 14:53 ` [PATCHv13 19/28] videobuf2-core: add request helper functions Hans Verkuil
2018-05-03 14:53 ` [PATCHv13 20/28] videobuf2-v4l2: add vb2_request_queue/validate helpers Hans Verkuil
2018-05-03 14:53 ` [PATCHv13 21/28] v4l2-mem2mem: add vb2_m2m_request_queue Hans Verkuil
2018-05-03 14:53 ` [PATCHv13 22/28] Documentation: v4l: document request API Hans Verkuil
2018-05-18 14:46   ` Laurent Pinchart
2018-05-24  4:32     ` Tomasz Figa
2018-05-24  7:55       ` Hans Verkuil
2018-05-24 14:46     ` Hans Verkuil
2018-05-03 14:53 ` [PATCHv13 23/28] media: vim2m: add media device Hans Verkuil
2018-05-03 14:53 ` [PATCHv13 24/28] vim2m: use workqueue Hans Verkuil
2018-05-04 11:34   ` Sakari Ailus
2018-05-03 14:53 ` [PATCHv13 25/28] vim2m: support requests Hans Verkuil
2018-05-17 20:41   ` Sakari Ailus
2018-05-03 14:53 ` [PATCHv13 26/28] vivid: add mc Hans Verkuil
2018-05-03 14:53 ` [PATCHv13 27/28] vivid: add request support Hans Verkuil
2018-05-03 14:53 ` [PATCHv13 28/28] RFC: media-requests: add debugfs node Hans Verkuil
2018-05-08 10:26 ` [PATCHv13 00/28] Request API Mauro Carvalho Chehab

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180508074528.10e5c8cd@vento.lan \
    --to=mchehab+samsung@kernel.org \
    --cc=hans.verkuil@cisco.com \
    --cc=hverkuil@xs4all.nl \
    --cc=linux-media@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.