Received: by 2002:a5b:505:0:0:0:0:0 with SMTP id o5csp1366416ybp; Thu, 17 Oct 2019 11:42:18 -0700 (PDT) X-Google-Smtp-Source: APXvYqzAYDWaXEZP+Gi3j6rjPu9lhIlE5YTflImDDJd0p0ukJelhCOfc/452ncoQ3X/8Gd19t+/F X-Received: by 2002:a05:6402:6c9:: with SMTP id n9mr5183370edy.190.1571337738761; Thu, 17 Oct 2019 11:42:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1571337738; cv=none; d=google.com; s=arc-20160816; b=BrWNmmGsPzdVhScwZ/Bp9tmGVp3kYpUZxw+meZF1ESP8A8MU5DuaRv+JhwjGqdE/Jm c25X7jpc6XN7P2hNmYkSC2W2hQoew3ADbFCUuBjNELAXpu65uFnbNM9nlqD41vi1dv07 RmdIel2GKs29OZGxoJAe1ooiu68Tri8QHSY9e9aA4WCyTW7+yvpEi0JPumOJBj7NwTmL pKgukextFzs7Zd+nQ7U+gH6/RP+AVt55LjP8mktnoXxEEBEFT2F/j2JTfCJx3Ro1E/av kGqIv7wjnyKZpL0HNsnnGdaVyO7XKsQjRMLFH8frSERpZ1DH61p2A1+1/zRZqI1TyD2X LqbA== 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=ILpxapTgk2rDIfWB/Ir6TID9lboC5rVn7YQsCA4sg6U=; b=Oh6v4cwmJj6MAu9wXeffplBOlTf1ETTMozhvxTUxkLsGO4MYxV4X3uIaMLbFre1Fxv vYjsrs7hp9d0U6FQV1MSu1Swz3mBBoSdu4YgB2oYDKvgGH0GUiC2XdgOws4cBSWofILE Gx3A2TrD/lFXYid5zKrzfF1dsf1mq4GXWuaP1srY8A2U55nj03ie1X40q9sYyoQFS8+1 umVXVBd12wpuN9ZNr0aPa7rn9If/U+Tf5eZOPtRuwRndN0Nc9i+HBf/e8ZCKHcm7oX4l VrOFsOVwhZ0MKk18N0d13qOnmvT/jkTetnJBALwLpXFE1P/ty46zNMX2kZTT7KAr2KDH I/JA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="cI/39r+V"; 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 q10si2266766eda.293.2019.10.17.11.41.55; Thu, 17 Oct 2019 11:42:18 -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="cI/39r+V"; 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 S2407193AbfJPWKZ (ORCPT + 99 others); Wed, 16 Oct 2019 18:10:25 -0400 Received: from mail.kernel.org ([198.145.29.99]:49756 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729429AbfJPV5Q (ORCPT ); Wed, 16 Oct 2019 17:57:16 -0400 Received: from localhost (unknown [192.55.54.58]) (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 8877720872; Wed, 16 Oct 2019 21:57:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1571263035; bh=5iTKraSr6YCzgOAbZj3fnmt3DlD0mJRxEZgpQheQyyc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cI/39r+VB8KwFkd1PyrRh2LzxYYXlbS5aIdkAhI5Rxzm1iVTLzmDGi/7BWMpz6aRr UYkJbz+OzdgqZS/IZc5cxQ6eg4oq3VXlHH1jT0/RK+5hvI9V7qC0uZ9WVP75XtGVDI 857UiUg046cLGFLZig0QBV8WocNk5HoMDmz970cQ= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Johan Hovold Subject: [PATCH 4.19 05/81] USB: yurex: fix NULL-derefs on disconnect Date: Wed, 16 Oct 2019 14:50:16 -0700 Message-Id: <20191016214809.831170094@linuxfoundation.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191016214805.727399379@linuxfoundation.org> References: <20191016214805.727399379@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: Johan Hovold commit aafb00a977cf7d81821f7c9d12e04c558c22dc3c upstream. The driver was using its struct usb_interface pointer as an inverted disconnected flag, but was setting it to NULL without making sure all code paths that used it were done with it. Before commit ef61eb43ada6 ("USB: yurex: Fix protection fault after device removal") this included the interrupt-in completion handler, but there are further accesses in dev_err and dev_dbg statements in yurex_write() and the driver-data destructor (sic!). Fix this by unconditionally stopping also the control URB at disconnect and by using a dedicated disconnected flag. Note that we need to take a reference to the struct usb_interface to avoid a use-after-free in the destructor whenever the device was disconnected while the character device was still open. Fixes: aadd6472d904 ("USB: yurex.c: remove dbg() usage") Fixes: 45714104b9e8 ("USB: yurex.c: remove err() usage") Cc: stable # 3.5: ef61eb43ada6 Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20191009153848.8664-6-johan@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/yurex.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) --- a/drivers/usb/misc/yurex.c +++ b/drivers/usb/misc/yurex.c @@ -60,6 +60,7 @@ struct usb_yurex { struct kref kref; struct mutex io_mutex; + unsigned long disconnected:1; struct fasync_struct *async_queue; wait_queue_head_t waitq; @@ -107,6 +108,7 @@ static void yurex_delete(struct kref *kr dev->int_buffer, dev->urb->transfer_dma); usb_free_urb(dev->urb); } + usb_put_intf(dev->interface); usb_put_dev(dev->udev); kfree(dev); } @@ -205,7 +207,7 @@ static int yurex_probe(struct usb_interf init_waitqueue_head(&dev->waitq); dev->udev = usb_get_dev(interface_to_usbdev(interface)); - dev->interface = interface; + dev->interface = usb_get_intf(interface); /* set up the endpoint information */ iface_desc = interface->cur_altsetting; @@ -316,8 +318,9 @@ static void yurex_disconnect(struct usb_ /* prevent more I/O from starting */ usb_poison_urb(dev->urb); + usb_poison_urb(dev->cntl_urb); mutex_lock(&dev->io_mutex); - dev->interface = NULL; + dev->disconnected = 1; mutex_unlock(&dev->io_mutex); /* wakeup waiters */ @@ -405,7 +408,7 @@ static ssize_t yurex_read(struct file *f dev = file->private_data; mutex_lock(&dev->io_mutex); - if (!dev->interface) { /* already disconnected */ + if (dev->disconnected) { /* already disconnected */ mutex_unlock(&dev->io_mutex); return -ENODEV; } @@ -440,7 +443,7 @@ static ssize_t yurex_write(struct file * goto error; mutex_lock(&dev->io_mutex); - if (!dev->interface) { /* already disconnected */ + if (dev->disconnected) { /* already disconnected */ mutex_unlock(&dev->io_mutex); retval = -ENODEV; goto error;