Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp702376imm; Sat, 26 May 2018 09:01:47 -0700 (PDT) X-Google-Smtp-Source: ADUXVKJEWZSplHqDLRCsTJubi8gPb6uSMPwP8mLlBHqnWXsP+iJj70r3ne21ih7tWidJo29Alj7x X-Received: by 2002:a62:bd0:: with SMTP id 77-v6mr2529907pfl.235.1527350506950; Sat, 26 May 2018 09:01:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527350506; cv=none; d=google.com; s=arc-20160816; b=aZ21jJyu504caGjR6zLQ4csYCPep6ioyXu/zDcdu6jdAzB5W83YhgHBzMbQNlJ5G1A CWNUsc2kxtZkKb7BezsadEIFy5w3vMcjpBeOj8DVoRWlVtyBqEwd8tBg86Om5scGZELi Tan6oT624zjvgRsxp9G71gietxx64766Fm5wobGnlJOZojxM1925DAi+oRNahMIYR6Ay 8EFYdMIJTkaVwUbqhc72GrnzljkYsUS/7bF23UtABIegNBSIixsba4cxepl35lAHbaZz vfApDJxPUVVA00nVKy8a+k7Yub1WRqtGN3NEilBShsOzAxR2OxQjwLIGSrCo7plHtymu Giqg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:content-disposition :mime-version:message-id:subject:cc:to:from:date :arc-authentication-results; bh=otQIm6+8VYMzqCv9noIDOQo6TErdKuB5LQhF4oNDySs=; b=UQv5GUSZTBrnuQ9F3291ciLFdx74czlU27fCGm3BtDwfTQcLDK4KGW4/Xsn6hJI0Ro wMj3kkvzSmfWrxu4dCm/laKw1q8SMYgUlvD94U8SaYi8+SXdp2YMaEnx/OB4HkVgJv+I KjqDnSn1FtHgcGCKx+ruzAuVMxQuzFFj7xr4qlLYgfsQyHC0Y8ZJZsJFi4kCS5+gJdOi xlzczXDpVn1N5ud2QeKXdAOqjeVS0fFWdk0/HS1RqMGEuD6pndXcIi0n8xsnhtWHoixx R01OloANPS2rCt7pmgCO6z4ghq9U27YzCgoWrQHq8I8bMfkSWcnTraohAHUBqLGEnIcg VDWw== ARC-Authentication-Results: i=1; mx.google.com; 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 j33-v6si26339130pld.151.2018.05.26.09.01.32; Sat, 26 May 2018 09:01:46 -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; 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 S1032166AbeEZQBT (ORCPT + 99 others); Sat, 26 May 2018 12:01:19 -0400 Received: from spacedout.fries.net ([47.47.3.166]:56388 "EHLO SpacedOut.fries.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1032084AbeEZQBQ (ORCPT ); Sat, 26 May 2018 12:01:16 -0400 X-Greylist: delayed 617 seconds by postgrey-1.27 at vger.kernel.org; Sat, 26 May 2018 12:01:14 EDT Received: from SpacedOut.fries.net (ip6-localhost [IPv6:::1]) by SpacedOut.fries.net (8.14.4/8.14.4/Debian-8+deb8u2) with ESMTP id w4QFok3M004452 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Sat, 26 May 2018 10:50:46 -0500 Received: (from david@localhost) by SpacedOut.fries.net (8.14.4/8.14.4/Submit) id w4QFokkp004451; Sat, 26 May 2018 10:50:46 -0500 Date: Sat, 26 May 2018 10:50:46 -0500 From: David Fries To: linux-kernel@vger.kernel.org Cc: Guennadi Liakhovetski , Laurent Pinchart , Mauro Carvalho Chehab , stable@vger.kernel.org Subject: [PATCH 1/1] media: uvc_driver: fix USB Camera ref leak denial of service Message-ID: <20180526155046.GA3327@spacedout.fries.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit 9d15cd958c17 ("media: uvcvideo: Convert from using an atomic variable to a reference count") didn't take into account that while the old counter was initialized to 0 (no stream open), kref_init starts with a reference of 1. The reference count on unplug no longer reaches 0, uvc_delete isn't called, and evdev doesn't release /dev/input/event*. Plug and unplug enough times and it runs out of device minors preventing any new input device and the use of newly plugged in USB video cameras until the system is rebooted. Signed-off-by: David Fries Cc: Guennadi Liakhovetski Cc: Laurent Pinchart Cc: Mauro Carvalho Chehab Cc: stable@vger.kernel.org --- drivers/media/usb/uvc/uvc_driver.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 2469b49..3cbdc87 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -1871,13 +1871,6 @@ static void uvc_unregister_video(struct uvc_device *dev) { struct uvc_streaming *stream; - /* Unregistering all video devices might result in uvc_delete() being - * called from inside the loop if there's no open file handle. To avoid - * that, increment the refcount before iterating over the streams and - * decrement it when done. - */ - kref_get(&dev->ref); - list_for_each_entry(stream, &dev->streams, list) { if (!video_is_registered(&stream->vdev)) continue; @@ -1888,6 +1881,10 @@ static void uvc_unregister_video(struct uvc_device *dev) uvc_debugfs_cleanup_stream(stream); } + /* Release the reference implicit in kref_init from uvc_probe, + * the UVC device won't be deleted until the last file descriptor + * is also closed. + */ kref_put(&dev->ref, uvc_delete); } -- 2.1.4 From 32a612bc06a2a1b9215f3b7166342c98043bd925 Mon Sep 17 00:00:00 2001 From: David Fries Date: Thu, 24 May 2018 23:43:15 -0500 Subject: [PATCH] uvc_driver: UVC kref never reaches zero leading to denial of service Commit 9d15cd958c17 ("media: uvcvideo: Convert from using an atomic variable to a reference count") didn't take into account that while the counter was initialized to 0 (no stream open), kref_init starts with a reference of 1, leading to the device never reaching 0 and uvc_delete never getting called. This leads to evdev never getting released and /dev/input/event* eventually running out of minors preventing any new event devices and new USB cameras from being usable until the system is rebooted. In my case "disabled by hub (EMI?), re-enabling..." kept removing/inserting the device until days later it ran out of minors and I lost the video security feed. Now that the device is actually being removed other problems are showing up. Specifically the following if the camera is removed or `rmmod ehci_pci` while an application is getting video from it. It doesn't happen if the camera is not in use. How do I track that down? sysfs group 'power' not found for kobject 'event10' sysfs group 'power' not found for kobject 'input32' sysfs group 'id' not found for kobject 'input32' sysfs group 'capabilities' not found for kobject 'input32' sysfs group 'power' not found for kobject 'media0' Signed-off-by: David Fries --- drivers/media/usb/uvc/uvc_driver.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 2469b49..3cbdc87 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -1871,13 +1871,6 @@ static void uvc_unregister_video(struct uvc_device *dev) { struct uvc_streaming *stream; - /* Unregistering all video devices might result in uvc_delete() being - * called from inside the loop if there's no open file handle. To avoid - * that, increment the refcount before iterating over the streams and - * decrement it when done. - */ - kref_get(&dev->ref); - list_for_each_entry(stream, &dev->streams, list) { if (!video_is_registered(&stream->vdev)) continue; @@ -1888,6 +1881,10 @@ static void uvc_unregister_video(struct uvc_device *dev) uvc_debugfs_cleanup_stream(stream); } + /* Release the reference implicit in kref_init from uvc_probe, + * the UVC device won't be deleted until the last file descriptor + * is also closed. + */ kref_put(&dev->ref, uvc_delete); } -- 2.1.4