Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp2313419imu; Sun, 16 Dec 2018 22:50:57 -0800 (PST) X-Google-Smtp-Source: AFSGD/VxHjjSO/8qTU3FD1Z9nDsB8w9UuePluqAAaqLHmDsFXJOTUaW0ublQMxm7mKQCMNfIF2Xd X-Received: by 2002:a63:da14:: with SMTP id c20mr10644137pgh.233.1545029457361; Sun, 16 Dec 2018 22:50:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1545029457; cv=none; d=google.com; s=arc-20160816; b=rtr9/Q9HlfjuZBPktweTFvx3y3Rg2wX032bI44L9k5J4nxRtlG4qElJW2xvSbmhw5X 5yQLaDqtlSysDyU8uTgMlRO2k5If2KEbnvYrgqXtVq3UqT6jmLqcFVK3gNEhaKpU+0se Jaj0yVJT+pjJcnRNuc4/IbpaW50xxTGNyrdRgm7k3V1GCxzLDf7JI5hVHMNt7r8D8s3K OeYjOucLLxVrOcn5Cg5BTA+cbvXM3/rNZocJeGr6J8EF6JLeSKVBhZMl7L8SHlSSDrhh 4qME+XJ6FhZWDv+CfJAQ27EC5iiutDruYro10Bj1m8hS1L3JPz4ktxdQ8u+f5myEfFI9 z74g== 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 :message-id:date:subject:cc:to:from:dkim-signature; bh=rrPidn3rCN1gHde9WS6H9hYiiDsvp4RLivG2flEdvlk=; b=YcVyApyfvG4vvET0wA1zNM6x7hfQwD/pRAevRteMz35o+KSReNe4ApiAGg68QO51mU ICuX0ax47c06E7u9/J7nmBTYf9ZEzZE67o66W6F5kpHJubqTQd12UO4JnwzxVv6BNbT4 2vDElI14cBvlNRVqmuwGZ95E4vJKjQ/8DLhXzZDPWSmS7yN3w7ldmj/HCPIhGm/+Lce9 fIgQymbYN+xkEHo7zAZioLuyfgvnajcBu7v09zXXt1UiR0UuPgytWJMMC/VdkUm86wsQ il7nBVUVZFGy/UpGdccIgP/jBlr8hu3SJgUqR3TwDWOuVFFSVb9WZEYmVlJCJm9FO7a4 5TDg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=blMUPvSB; 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; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c132si10234505pga.597.2018.12.16.22.50.41; Sun, 16 Dec 2018 22:50:57 -0800 (PST) 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=@gmail.com header.s=20161025 header.b=blMUPvSB; 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; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726467AbeLQGKw (ORCPT + 99 others); Mon, 17 Dec 2018 01:10:52 -0500 Received: from mail-pf1-f195.google.com ([209.85.210.195]:41574 "EHLO mail-pf1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726323AbeLQGKw (ORCPT ); Mon, 17 Dec 2018 01:10:52 -0500 Received: by mail-pf1-f195.google.com with SMTP id b7so5814921pfi.8; Sun, 16 Dec 2018 22:10:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=rrPidn3rCN1gHde9WS6H9hYiiDsvp4RLivG2flEdvlk=; b=blMUPvSBlOZ4uFE5q1H1udAJXgg0w04eMD/g7rD+4LvQbtI7zu7TZ8rG0IqmjV/q8q ZVy4+xDbjkyeQE41oUgHl2YGGn9dWfjClBlvR9E0iDaP4yUCk6qBhxjsbY4wzCzjzKYc 4wBzA3Vb7B/xhbZ61NI/wn7ETuzHUx3/KU15i97JE7eFLuqeDX3ygo3VZ52EYjkC412k wPGE7/sekte3m8ShHd5jqGeFPCFGm+tZTHRQ3SmEL2UMsfaJ9RpwTsLd2OEnkhAAYIIn AmSnA2/5SVPPFVvw9Csfg+6e51SGcS+rg8AGrvNpdLvOpPF3bhAl/zeyQzH1ECaWXBk9 ILfw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=rrPidn3rCN1gHde9WS6H9hYiiDsvp4RLivG2flEdvlk=; b=OSU3f3RkUo06d+1pXSMEGBpSbwrcJUHQrGyIEgXPH1mptJ81BYmI+e3D7FLhPCqzAf 64tBR7cK7tbIm96gPagm7Elsg4mE7FqaIfcEdHVqgcPEmGFW/L9TJHAgbxWRBRzUJBIv STmx7NaqZe5PAD5GKyvBb0ZdA/K5xm4zupk2U1B1fuVg5rt/MY3D7QqUbCk61bGjIa4V /KfvitU/gXgQLKpPr19UywL8Q3QPURhmsrFDa4D7x3lUgoT41pGqUzhbo2W44gE6YUrg Be8SDd07YISaMTNKyayMYb2rrcBI/KszEQLO/YMHnIcpGYJgdgIABwdhwIrhuXYwxFKm NPCA== X-Gm-Message-State: AA+aEWbUMzKYbLHc7RHt0EelYQZBUSmNBzde/ay+gcXPSDUyeeZ6a0OL +wSTLqmwcNd5lHKvmrFOfvD5dO81gQE= X-Received: by 2002:a63:451a:: with SMTP id s26mr11234997pga.150.1545027051210; Sun, 16 Dec 2018 22:10:51 -0800 (PST) Received: from localhost (27-32-189-129.static.tpgi.com.au. [27.32.189.129]) by smtp.gmail.com with ESMTPSA id v184sm16680890pfb.182.2018.12.16.22.10.49 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 16 Dec 2018 22:10:50 -0800 (PST) From: Andrew Worsley To: Greg Kroah-Hartman , Alan Stern , Mathias Nyman , Nicolas Boichat , Jon Flatley , Kai-Heng Feng , Bin Liu , Benson Leung , linux-usb@vger.kernel.org (open list:USB SUBSYSTEM), linux-kernel@vger.kernel.org (open list) Cc: Andrew Worsley Subject: [PATCH] Prevent race condition between USB authorisation and USB discovery events Date: Mon, 17 Dec 2018 17:10:33 +1100 Message-Id: <20181217061036.24143-1-amworsley@gmail.com> X-Mailer: git-send-email 2.19.2 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org A sysfs driven USB authorisation change can trigger a usb_set_configuration while a hub_event worker thread is running. This can result in a USB device being disabled just after it was configured and bringing down all the devices and impacting hardware and user processes that were established on top of this these interfaces. In some cases the USB disable never completed and the whole system hung. At my work I had an occasional hang due to this race condition. Roughly 1 in 50 boots had the race occurrence and 1 in 4 of those resulted in a hang. This patch fixed the problem and I had no problems (spurious disables or hangs) in 750+ boots. Signed-off-by: Andrew Worsley --- drivers/usb/core/hub.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index f76b2e0aba9d..dabd07aa8602 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -51,6 +51,9 @@ static DEFINE_SPINLOCK(device_state_lock); static struct workqueue_struct *hub_wq; static void hub_event(struct work_struct *work); +/* synchronize hub_event and authorize_device operations */ +DEFINE_MUTEX(usb_authorize_mutex); + /* synchronize hub-port add/remove and peering operations */ DEFINE_MUTEX(usb_port_peer_mutex); @@ -2538,6 +2541,7 @@ int usb_new_device(struct usb_device *udev) */ int usb_deauthorize_device(struct usb_device *usb_dev) { + mutex_lock(&usb_authorize_mutex); usb_lock_device(usb_dev); if (usb_dev->authorized == 0) goto out_unauthorized; @@ -2547,6 +2551,7 @@ int usb_deauthorize_device(struct usb_device *usb_dev) out_unauthorized: usb_unlock_device(usb_dev); + mutex_unlock(&usb_authorize_mutex); return 0; } @@ -2555,6 +2560,7 @@ int usb_authorize_device(struct usb_device *usb_dev) { int result = 0, c; + mutex_lock(&usb_authorize_mutex); usb_lock_device(usb_dev); if (usb_dev->authorized == 1) goto out_authorized; @@ -2596,6 +2602,7 @@ int usb_authorize_device(struct usb_device *usb_dev) error_autoresume: out_authorized: usb_unlock_device(usb_dev); /* complements locktree */ + mutex_unlock(&usb_authorize_mutex); return result; } @@ -5320,6 +5327,7 @@ static void hub_event(struct work_struct *work) hub_dev = hub->intfdev; intf = to_usb_interface(hub_dev); + mutex_lock(&usb_authorize_mutex); dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x\n", hdev->state, hdev->maxchild, /* NOTE: expects max 15 ports... */ @@ -5422,6 +5430,7 @@ static void hub_event(struct work_struct *work) usb_autopm_put_interface_no_suspend(intf); out_hdev_lock: usb_unlock_device(hdev); + mutex_unlock(&usb_authorize_mutex); /* Balance the stuff in kick_hub_wq() and allow autosuspend */ usb_autopm_put_interface(intf); -- 2.19.2