Received: by 2002:a05:7412:40d:b0:e2:908c:2ebd with SMTP id 13csp1079946rdf; Wed, 22 Nov 2023 05:16:02 -0800 (PST) X-Google-Smtp-Source: AGHT+IGfAy/DoO8uQqxD2ytY+QzH32ew2rTVIQkFVmcNKYJshTlDQXU4t1fL6B/tV0sK86luynhA X-Received: by 2002:a17:902:f687:b0:1c3:e2eb:f79d with SMTP id l7-20020a170902f68700b001c3e2ebf79dmr8907297plg.8.1700658962121; Wed, 22 Nov 2023 05:16:02 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1700658962; cv=none; d=google.com; s=arc-20160816; b=WrwvK3ofXOsyF+iNboHPtMWD6uNR2noRYTgBvgqyPtqUAcMX5/6fFEHhFZ2+jwSPQh FzdXdZrXcDK8i2f2rDWIISRJg24UhD1wy0PfSDqC2334KS/gZGaj7mAx7OjIdL48VnmW aIOstlm0PkYQvFmCWqtJxN+zIqMgO5ArBtfdAuF6b/SbNFRvVzo+cYxsU2L2cpP6nJRn inffsG6cNYhKNevUxXYyFaJijgCgas1Hq8lvJ9zPXlLSmhFqC1lY+ZrqANA5pYTQFDyI RKKLXjuzBinu84L9fbSBuOfnZnfFCFSbiFlPDiBmeDcE3lid76NTYA8nws5b21HjsDYA sZiw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-disposition:mime-version :references:message-id:subject:cc:to:from:date:dkim-signature; bh=7eiGk9Zr2S5Ns7nkc+8Lkpsr7hr0okBVvs94OzZQ+rE=; fh=2fKaIjCK/Du9fXByU+Q5huZBQmxb4MH3pHgBgD6sFf0=; b=i9/fblhjLu79tUe4qTDrDx2cXvriSfh2L05twqQip7Q7f0ei03uWIYhoRv6ORczBUy 1nvznNMGU6JSaROqzuis9H5MZyvt6z7r/KgL+LeoRG8lvv9KiaEtEYK7/j5fypLnZS1T Pb7KSydyo6zeI7eeAdNF8dg5kKeC9cb/DsndU/jKqWH/u7VFaSbHHc4QcADqPtnJgKvo g6xJo21niIpYX/ESFdV0jK/ZjXlB0auu2U69Xwh2EE4UPQbqR3pjMzzCD5X5wHXljvWw 0WBAjRfaHGrmo6o2UxWqXGxDTlHGLGZbK3JvXyPfj5F0XFUoVAqctgav8p2cv1Q5uEN8 yo7g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass (test mode) header.i=@ideasonboard.com header.s=mail header.b="swIZNt/s"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.32 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from agentk.vger.email (agentk.vger.email. [23.128.96.32]) by mx.google.com with ESMTPS id m2-20020a654382000000b005c22024966asi9931609pgp.0.2023.11.22.05.15.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Nov 2023 05:16:02 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.32 as permitted sender) client-ip=23.128.96.32; Authentication-Results: mx.google.com; dkim=pass (test mode) header.i=@ideasonboard.com header.s=mail header.b="swIZNt/s"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.32 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by agentk.vger.email (Postfix) with ESMTP id A915E8077A7B; Wed, 22 Nov 2023 05:15:10 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at agentk.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343957AbjKVNOy (ORCPT + 99 others); Wed, 22 Nov 2023 08:14:54 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38086 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343619AbjKVNOx (ORCPT ); Wed, 22 Nov 2023 08:14:53 -0500 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B358219E; Wed, 22 Nov 2023 05:14:49 -0800 (PST) Received: from pendragon.ideasonboard.com (213-243-189-158.bb.dnainternet.fi [213.243.189.158]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 89721276; Wed, 22 Nov 2023 14:14:17 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1700658857; bh=I9y4sun9NeXdT7AZljuwRol7VPibB34QiqgjRQUZFpo=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=swIZNt/sv5KAV2KlMVIqUpuJ0ECH71R84iDO/VHU3YXKGBo8la459hrmNMnogg4GR bozwtL/zl6Qj4mBnM56gTPQN2VyVNl+BUuiCALRMniJLAcs1Rg1ws659YmjEryR2T8 CIVoV+uo6kmBRm/+nsJ9ANBw7U06KqNasYIy+nB8= Date: Wed, 22 Nov 2023 15:14:55 +0200 From: Laurent Pinchart To: Sakari Ailus Cc: Ricardo Ribalda , Mauro Carvalho Chehab , Guenter Roeck , Tomasz Figa , Alan Stern , Hans Verkuil , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Sean Paul , Sakari Ailus , Dan Williams Subject: Re: [PATCH v3 3/3] media: uvcvideo: Lock video streams and queues while unregistering Message-ID: <20231122131455.GC3909@pendragon.ideasonboard.com> References: <20231121-guenter-mini-v3-0-d8a5eae2312b@chromium.org> <20231121-guenter-mini-v3-3-d8a5eae2312b@chromium.org> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on agentk.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (agentk.vger.email [0.0.0.0]); Wed, 22 Nov 2023 05:15:11 -0800 (PST) CC'ing Dan Williams. On Wed, Nov 22, 2023 at 10:21:04AM +0000, Sakari Ailus wrote: > Hi Ricardo, > > On Tue, Nov 21, 2023 at 07:53:50PM +0000, Ricardo Ribalda wrote: > > From: Guenter Roeck > > > > The call to uvc_disconnect() is not protected by any mutex. > > This means it can and will be called while other accesses to the video > > device are in progress. This can cause all kinds of race conditions, > > including crashes such as the following. > > > > usb 1-4: USB disconnect, device number 3 > > BUG: unable to handle kernel NULL pointer dereference at 0000000000000000 > > PGD 0 P4D 0 > > Oops: 0000 [#1] PREEMPT SMP PTI > > CPU: 0 PID: 5633 Comm: V4L2CaptureThre Not tainted 4.19.113-08536-g5d29ca36db06 #1 > > Hardware name: GOOGLE Edgar, BIOS Google_Edgar.7287.167.156 03/25/2019 > > RIP: 0010:usb_ifnum_to_if+0x29/0x40 > > Code: <...> > > RSP: 0018:ffffa46f42a47a80 EFLAGS: 00010246 > > RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffff904a396c9000 > > RDX: ffff904a39641320 RSI: 0000000000000001 RDI: 0000000000000000 > > RBP: ffffa46f42a47a80 R08: 0000000000000002 R09: 0000000000000000 > > R10: 0000000000009975 R11: 0000000000000009 R12: 0000000000000000 > > R13: ffff904a396b3800 R14: ffff904a39e88000 R15: 0000000000000000 > > FS: 00007f396448e700(0000) GS:ffff904a3ba00000(0000) knlGS:0000000000000000 > > CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 > > CR2: 0000000000000000 CR3: 000000016cb46000 CR4: 00000000001006f0 > > Call Trace: > > usb_hcd_alloc_bandwidth+0x1ee/0x30f > > usb_set_interface+0x1a3/0x2b7 > > uvc_video_start_transfer+0x29b/0x4b8 [uvcvideo] > > uvc_video_start_streaming+0x91/0xdd [uvcvideo] > > uvc_start_streaming+0x28/0x5d [uvcvideo] > > vb2_start_streaming+0x61/0x143 [videobuf2_common] > > vb2_core_streamon+0xf7/0x10f [videobuf2_common] > > uvc_queue_streamon+0x2e/0x41 [uvcvideo] > > uvc_ioctl_streamon+0x42/0x5c [uvcvideo] > > __video_do_ioctl+0x33d/0x42a > > video_usercopy+0x34e/0x5ff > > ? video_ioctl2+0x16/0x16 > > v4l2_ioctl+0x46/0x53 > > do_vfs_ioctl+0x50a/0x76f > > ksys_ioctl+0x58/0x83 > > __x64_sys_ioctl+0x1a/0x1e > > do_syscall_64+0x54/0xde > > > > usb_set_interface() should not be called after the USB device has been > > unregistered. However, in the above case the disconnect happened after > > v4l2_ioctl() was called, but before the call to usb_ifnum_to_if(). > > > > Acquire various mutexes in uvc_unregister_video() to fix the majority > > (maybe all) of the observed race conditions. > > > > The uvc_device lock prevents races against suspend and resume calls > > and the poll function. > > > > The uvc_streaming lock prevents races against stream related functions; > > for the most part, those are ioctls. This lock also requires other > > functions using this lock to check if a video device is still registered > > after acquiring it. For example, it was observed that the video device > > was already unregistered by the time the stream lock was acquired in > > uvc_ioctl_streamon(). > > > > The uvc_queue lock prevents races against queue functions, Most of > > those are already protected by the uvc_streaming lock, but some > > are called directly. This is done as added protection; an actual race > > was not (yet) observed. > > > > Cc: Laurent Pinchart > > Cc: Alan Stern > > Cc: Hans Verkuil > > Reviewed-by: Tomasz Figa > > Reviewed-by: Sean Paul > > Signed-off-by: Guenter Roeck > > Signed-off-by: Ricardo Ribalda > > --- > > drivers/media/usb/uvc/uvc_driver.c | 9 +++++++++ > > 1 file changed, 9 insertions(+) > > > > diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c > > index 413c32867617..3408b865d346 100644 > > --- a/drivers/media/usb/uvc/uvc_driver.c > > +++ b/drivers/media/usb/uvc/uvc_driver.c > > @@ -1907,14 +1907,22 @@ static void uvc_unregister_video(struct uvc_device *dev) > > { > > struct uvc_streaming *stream; > > > > + mutex_lock(&dev->lock); > > + > > list_for_each_entry(stream, &dev->streams, list) { > > if (!video_is_registered(&stream->vdev)) > > continue; > > > > + mutex_lock(&stream->mutex); > > + mutex_lock(&stream->queue.mutex); > > + > > video_unregister_device(&stream->vdev); > > video_unregister_device(&stream->meta.vdev); > > > > uvc_debugfs_cleanup_stream(stream); > > + > > + mutex_unlock(&stream->queue.mutex); > > + mutex_unlock(&stream->mutex); > > } > > > > uvc_status_unregister(dev); > > @@ -1925,6 +1933,7 @@ static void uvc_unregister_video(struct uvc_device *dev) > > if (media_devnode_is_registered(dev->mdev.devnode)) > > media_device_unregister(&dev->mdev); > > #endif > > + mutex_unlock(&dev->lock); > > } > > > > int uvc_register_video_device(struct uvc_device *dev, > > > > Instead of acquiring all the possible locks, could you instead take the > same approach as you do with ISP? It should use refcount_t btw. >