Received: by 2002:a25:ad19:0:0:0:0:0 with SMTP id y25csp847728ybi; Fri, 12 Jul 2019 05:38:46 -0700 (PDT) X-Google-Smtp-Source: APXvYqyaKEQeIoRGSsMRp5j4syHiHH7PbgmK/EEEHrau1IXdLsfa6D1X9pPLmJtpBkabz50FKAUi X-Received: by 2002:a17:902:9004:: with SMTP id a4mr11311388plp.109.1562935126721; Fri, 12 Jul 2019 05:38:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1562935126; cv=none; d=google.com; s=arc-20160816; b=DOaQQGwlv7OUkGUkefjqD+1nxHp5O9lZAP+uaoxzaKKSCIYYn015BR4HL4AsyrvPqg Pi8lvDg66siln6r71uLfh6sfHyZqVxThBwOKfxEhPaJZorHWchsAKHm201j0/7vEHswv 0hdXbL9trJM7CnPzlaTi4vDOUUn9KQYHMoF2IKEu/j707slKFTp5djUva1kXXB9sZlOn lccIdFZPB8x8VNuFgr8SNPtUqtZkbFxVKJKQdKV7FegrMcbNtcGOCq96axuZH0vs9N23 pbX/NcP6j/9Nu9FaRBMKgjL+LLtkD7uA5gqf0fPJYfxDw6IcPaph1opl84O+ZqV++uL2 jlww== 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=gbcjQjlt96g2HauZouu9LaWuGU6932pz4TzkfPsZNyc=; b=n1luJCUQ36qtyDtRbPRNUBE/FtA2TRYbTm7JKJtGHG8JT+YMdfYZNQE88h5pXp/HJ0 FItQ+0qoHsXOO0fR8lxSuilrlwxsmwhpUdaQOfXMiunUFoCMJiiyh1t1bkS+V9zfwkFp BKuUGsuTeKezsSwRFzGnzGw7u7p9RXlDhK+Ex7GCMwSkAHxwKxMqAYqyYK27opOYRwFF C0B9A1JcTksyjHLR+QRs8q6QJaNqR4dLhda0SRJFRPyTiWxWHgx5/+U+fPGdUQaAGZsC K7QEQ81p3z4EdkT3T/570qTsZ96HmsWHZJHtI5OfOQDoiEzBG92iFY9nyrNgL6nj3/be ySXw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=lTsHfCt4; 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 c7si8016856pjo.88.2019.07.12.05.38.31; Fri, 12 Jul 2019 05:38: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; dkim=pass header.i=@kernel.org header.s=default header.b=lTsHfCt4; 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 S1728923AbfGLMgu (ORCPT + 99 others); Fri, 12 Jul 2019 08:36:50 -0400 Received: from mail.kernel.org ([198.145.29.99]:49022 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727045AbfGLMby (ORCPT ); Fri, 12 Jul 2019 08:31:54 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (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 9BD07208E4; Fri, 12 Jul 2019 12:31:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1562934713; bh=yoCpDKEXgc/jPOEZGenf4VgfdDgWReN7+VHm3FbOkeQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lTsHfCt4DoKmvULXPB8Sh9UUmPerbz4LC0YJp6gDCRLA1sDJ2NAcFxQ6VhHUCIwDb oxSjaHne3K1Hb//jW1DBNkkVR5jQqeG5JQ6c2SeraGaiNSmE178MWcQTSK5M3cbp/O iLQSWuGiq6O73VnmpPtYtt1MGtzGeaQ/QOgSs7Gk= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Alan Stern , Christian Lamparter , Kalle Valo Subject: [PATCH 5.1 128/138] carl9170: fix misuse of device driver API Date: Fri, 12 Jul 2019 14:19:52 +0200 Message-Id: <20190712121633.639972007@linuxfoundation.org> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190712121628.731888964@linuxfoundation.org> References: <20190712121628.731888964@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: Christian Lamparter commit feb09b2933275a70917a869989ea2823e7356be8 upstream. This patch follows Alan Stern's recent patch: "p54: Fix race between disconnect and firmware loading" that overhauled carl9170 buggy firmware loading and driver unbinding procedures. Since the carl9170 code was adapted from p54 it uses the same functions and is likely to have the same problem, but it's just that the syzbot hasn't reproduce them (yet). a summary from the changes (copied from the p54 patch): * Call usb_driver_release_interface() rather than device_release_driver(). * Lock udev (the interface's parent) before unbinding the driver instead of locking udev->parent. * During the firmware loading process, take a reference to the USB interface instead of the USB device. * Don't take an unnecessary reference to the device during probe (and then don't drop it during disconnect). and * Make sure to prevent use-after-free bugs by explicitly setting the driver context to NULL after signaling the completion. Cc: Cc: Alan Stern Signed-off-by: Christian Lamparter Acked-by: Alan Stern Signed-off-by: Kalle Valo Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/carl9170/usb.c | 39 +++++++++++++------------------- 1 file changed, 17 insertions(+), 22 deletions(-) --- a/drivers/net/wireless/ath/carl9170/usb.c +++ b/drivers/net/wireless/ath/carl9170/usb.c @@ -128,6 +128,8 @@ static const struct usb_device_id carl91 }; MODULE_DEVICE_TABLE(usb, carl9170_usb_ids); +static struct usb_driver carl9170_driver; + static void carl9170_usb_submit_data_urb(struct ar9170 *ar) { struct urb *urb; @@ -966,32 +968,28 @@ err_out: static void carl9170_usb_firmware_failed(struct ar9170 *ar) { - struct device *parent = ar->udev->dev.parent; - struct usb_device *udev; - - /* - * Store a copy of the usb_device pointer locally. - * This is because device_release_driver initiates - * carl9170_usb_disconnect, which in turn frees our - * driver context (ar). + /* Store a copies of the usb_interface and usb_device pointer locally. + * This is because release_driver initiates carl9170_usb_disconnect, + * which in turn frees our driver context (ar). */ - udev = ar->udev; + struct usb_interface *intf = ar->intf; + struct usb_device *udev = ar->udev; complete(&ar->fw_load_wait); + /* at this point 'ar' could be already freed. Don't use it anymore */ + ar = NULL; /* unbind anything failed */ - if (parent) - device_lock(parent); - - device_release_driver(&udev->dev); - if (parent) - device_unlock(parent); + usb_lock_device(udev); + usb_driver_release_interface(&carl9170_driver, intf); + usb_unlock_device(udev); - usb_put_dev(udev); + usb_put_intf(intf); } static void carl9170_usb_firmware_finish(struct ar9170 *ar) { + struct usb_interface *intf = ar->intf; int err; err = carl9170_parse_firmware(ar); @@ -1009,7 +1007,7 @@ static void carl9170_usb_firmware_finish goto err_unrx; complete(&ar->fw_load_wait); - usb_put_dev(ar->udev); + usb_put_intf(intf); return; err_unrx: @@ -1052,7 +1050,6 @@ static int carl9170_usb_probe(struct usb return PTR_ERR(ar); udev = interface_to_usbdev(intf); - usb_get_dev(udev); ar->udev = udev; ar->intf = intf; ar->features = id->driver_info; @@ -1094,15 +1091,14 @@ static int carl9170_usb_probe(struct usb atomic_set(&ar->rx_anch_urbs, 0); atomic_set(&ar->rx_pool_urbs, 0); - usb_get_dev(ar->udev); + usb_get_intf(intf); carl9170_set_state(ar, CARL9170_STOPPED); err = request_firmware_nowait(THIS_MODULE, 1, CARL9170FW_NAME, &ar->udev->dev, GFP_KERNEL, ar, carl9170_usb_firmware_step2); if (err) { - usb_put_dev(udev); - usb_put_dev(udev); + usb_put_intf(intf); carl9170_free(ar); } return err; @@ -1131,7 +1127,6 @@ static void carl9170_usb_disconnect(stru carl9170_release_firmware(ar); carl9170_free(ar); - usb_put_dev(udev); } #ifdef CONFIG_PM