Received: by 2002:a25:b794:0:0:0:0:0 with SMTP id n20csp6913889ybh; Thu, 8 Aug 2019 07:34:38 -0700 (PDT) X-Google-Smtp-Source: APXvYqzD+EdQYP5b/IPUy170pX1MH4uqXn/VCTMWnWdydmySd60nY3WROYq4XXeSIa8fmXKPfb3Q X-Received: by 2002:a65:48c2:: with SMTP id o2mr13152492pgs.45.1565274878529; Thu, 08 Aug 2019 07:34:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1565274878; cv=none; d=google.com; s=arc-20160816; b=T+YQb/VtAfM6x9YU4sE8c96vWDJ7YmreWVHGaOQg6VALuDIj37ldXwevAh2wm8USNv bsm7TNj9K5Uki1SJhXz/a4Mh2EjxzozbcR0KTSvb3qyhwWgQGb2cWFcRe1WVgk9Kmm+c RutHK+LFiRYJiHqLdknzVG1Hphpv/hD0fmVdwr65+j3ZKnswvLWecZzADYzP/7lxvIB5 yfLS2aOItO4MWEpcALNfe0uxc8S7BUZ0mVIG46d/tjLUGJ27/mKPcLrHAY9EDeAlZoev 30k3VgawhZjwwCWtpkmj3cwKrBjn+XuDcDktjvO0LTmjcTI45E8H4bPLHkdGDpJVykgL OaZg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:message-id:in-reply-to :subject:cc:to:from:date; bh=wjk8unUfydvCuL5Q8RNIQEDs/30dfkfT0sZM1NjD39E=; b=c6ltGpK3a3fqpX7jzg4exCR/6TC2HaeI3h1ux7UAEnj2L+MaMXFwmPrgNO9Cr02HBS YKTly5HXMGKoBtyPOEk3qbSoo1eHBvW8kY1Uay/+RDQbfXidfOZyWYQ0sD3m3lFRxfm1 eTr0vL+abtm9zGTVZIR1QtibeSWpC9gy9pzPCjHoOQE2bMME9XLkoo4p3ypCBKW94IWb msfZclj1RrWnHv4213G3aQLDYP5yDsAyB+ukxJFVjBMW6XEoAN7Vmxn1eN0pKTARVNr9 qsYb3wIimKUFCRHalKLW1lX/wnV8uxjcCwL/JJFMKd2GfGLiKBHycHzhqvaaj+vfBiDf qHHQ== 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 l6si55553432pgr.378.2019.08.08.07.34.20; Thu, 08 Aug 2019 07:34:38 -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 S1732427AbfHHOdY (ORCPT + 99 others); Thu, 8 Aug 2019 10:33:24 -0400 Received: from iolanthe.rowland.org ([192.131.102.54]:41786 "HELO iolanthe.rowland.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1727096AbfHHOdY (ORCPT ); Thu, 8 Aug 2019 10:33:24 -0400 Received: (qmail 4729 invoked by uid 2102); 8 Aug 2019 10:33:23 -0400 Received: from localhost (sendmail-bs@127.0.0.1) by localhost with SMTP; 8 Aug 2019 10:33:23 -0400 Date: Thu, 8 Aug 2019 10:33:23 -0400 (EDT) From: Alan Stern X-X-Sender: stern@iolanthe.rowland.org To: Oliver Neukum cc: andreyknvl@google.com, , , syzbot , Kernel development list , USB list Subject: Re: possible deadlock in open_rio In-Reply-To: <1565187142.15973.3.camel@neukum.org> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, 7 Aug 2019, Oliver Neukum wrote: > Am Mittwoch, den 07.08.2019, 10:07 -0400 schrieb Alan Stern: > > On Wed, 7 Aug 2019, Oliver Neukum wrote: > > > technically yes. However in practical terms the straight revert I sent > > > out yesterday should fix it. > > > > I didn't see the revert, and it doesn't appear to have reached the > > mailing list archive. Can you post it again? > > As soon as our VPN server is back up again. The revert may not be necessay; a little fix should get rid of the locking violation. The key is to avoid calling the registration or deregistration routines while holding the rio500_mutex, and to recognize that the probe and disconnect routines are both protected by the device mutex. How does this patch look? Alan Stern #syz test: https://github.com/google/kasan.git 7f7867ff Index: usb-devel/drivers/usb/misc/rio500.c =================================================================== --- usb-devel.orig/drivers/usb/misc/rio500.c +++ usb-devel/drivers/usb/misc/rio500.c @@ -454,52 +454,54 @@ static int probe_rio(struct usb_interfac { struct usb_device *dev = interface_to_usbdev(intf); struct rio_usb_data *rio = &rio_instance; - int retval = 0; + int retval; + char *ibuf, *obuf; - mutex_lock(&rio500_mutex); if (rio->present) { dev_info(&intf->dev, "Second USB Rio at address %d refused\n", dev->devnum); - retval = -EBUSY; - goto bail_out; - } else { - dev_info(&intf->dev, "USB Rio found at address %d\n", dev->devnum); + return -EBUSY; } + dev_info(&intf->dev, "USB Rio found at address %d\n", dev->devnum); retval = usb_register_dev(intf, &usb_rio_class); if (retval) { dev_err(&dev->dev, "Not able to get a minor for this device.\n"); - retval = -ENOMEM; - goto bail_out; + goto err_register; } - rio->rio_dev = dev; - - if (!(rio->obuf = kmalloc(OBUF_SIZE, GFP_KERNEL))) { + obuf = kmalloc(OBUF_SIZE, GFP_KERNEL); + if (!obuf) { dev_err(&dev->dev, "probe_rio: Not enough memory for the output buffer\n"); - usb_deregister_dev(intf, &usb_rio_class); - retval = -ENOMEM; - goto bail_out; + goto err_obuf; } - dev_dbg(&intf->dev, "obuf address:%p\n", rio->obuf); + dev_dbg(&intf->dev, "obuf address: %p\n", obuf); - if (!(rio->ibuf = kmalloc(IBUF_SIZE, GFP_KERNEL))) { + ibuf = kmalloc(IBUF_SIZE, GFP_KERNEL); + if (!ibuf) { dev_err(&dev->dev, "probe_rio: Not enough memory for the input buffer\n"); - usb_deregister_dev(intf, &usb_rio_class); - kfree(rio->obuf); - retval = -ENOMEM; - goto bail_out; + goto err_ibuf; } - dev_dbg(&intf->dev, "ibuf address:%p\n", rio->ibuf); + dev_dbg(&intf->dev, "ibuf address: %p\n", ibuf); + mutex_lock(&rio500_mutex); + rio->rio_dev = dev; + rio->ibuf = ibuf; + rio->obuf = obuf; usb_set_intfdata (intf, rio); rio->present = 1; -bail_out: mutex_unlock(&rio500_mutex); return retval; + + err_ibuf: + kfree(obuf); + err_obuf: + usb_deregister_dev(intf, &usb_rio_class); + err_register: + return -ENOMEM; } static void disconnect_rio(struct usb_interface *intf) @@ -507,10 +509,10 @@ static void disconnect_rio(struct usb_in struct rio_usb_data *rio = usb_get_intfdata (intf); usb_set_intfdata (intf, NULL); - mutex_lock(&rio500_mutex); if (rio) { usb_deregister_dev(intf, &usb_rio_class); + mutex_lock(&rio500_mutex); if (rio->isopen) { rio->isopen = 0; /* better let it finish - the release will do whats needed */ @@ -524,8 +526,8 @@ static void disconnect_rio(struct usb_in dev_info(&intf->dev, "USB Rio disconnected.\n"); rio->present = 0; + mutex_unlock(&rio500_mutex); } - mutex_unlock(&rio500_mutex); } static const struct usb_device_id rio_table[] = {