Received: by 2002:a25:8b12:0:0:0:0:0 with SMTP id i18csp3859629ybl; Mon, 26 Aug 2019 01:30:47 -0700 (PDT) X-Google-Smtp-Source: APXvYqwzsD6uCHHWR6Y9fHiHNS6OEZE8qImf17I1YZCxd7cvTW0XZHXAwH9be9ECv9BbClWv1ACS X-Received: by 2002:aa7:9a81:: with SMTP id w1mr18998246pfi.24.1566808247214; Mon, 26 Aug 2019 01:30:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1566808247; cv=none; d=google.com; s=arc-20160816; b=nJfN1VhpYOX0yVpndjgBcGPp0cwkYJPs3XVlRxhRhOrSxlIgZI7iiYSpEPc+y/iycB 2250LWp0OMWODxUANXHRuS8Lahe8Uh4MUIeOQlG5E3+9bZQy0KZUQB5JYgxhsUON+b7Z U7dKzPC4Tud4Mfq+BT1Kk9Pe/Y/eTnM6TprKkMac/h5RMLDL++qq9cdIUcvJAbkZUfbA RZxNMg/sz1iMKbOYR4zTK+y6yUzhw5VIquDwlf2Tu8+4v9H2wlDp5snUtkoCTAuLuEIk JI6Qay2q4AIlx9CCnx8OKQr/9gdqpVTXO6N5wl59Uv54ayUZnNWs/GGYedMA+PHVYopX de9g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=gjtXwc6uWBjbYeNxWQINJLUvFHZALBu2ElRrlxI08CE=; b=kQ6FHck+TdEgJ0FFsTy0ywaIIt0fiPhoRhA7FBAo1FxsgRVEwzic2Sn55Wll65PEWp wrw5H0j2liOfHkxTi6diR4jHUn+CqssE9sfrxUMMRYOG8cB0VHvX1AC9n2nUM5Ouux0I PH+e3KqQeU61rTo7UAtSA5m/V5+izt7pa+OTfZA9WEr1ubH3Eu5NR5GrY6pZ5/x1Whqt 3eB9aNmdw3eq/Yv6tK9NnkEJlBtrjIxgVkGN1Eq/hX1jpbinp4FIbgWFP6KSEipqjKlN KY98gj2vG0SPQgIgHHGittb0o4hM5Corrlh7aoj6WTmD72pXpLZiQW8kwkGTiFrHId2z JRQQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b="aTU/uhsS"; 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=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h187si8428154pgc.6.2019.08.26.01.30.32; Mon, 26 Aug 2019 01:30:47 -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=@chromium.org header.s=google header.b="aTU/uhsS"; 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=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729410AbfHZGld (ORCPT + 99 others); Mon, 26 Aug 2019 02:41:33 -0400 Received: from mail-ua1-f66.google.com ([209.85.222.66]:37075 "EHLO mail-ua1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729222AbfHZGld (ORCPT ); Mon, 26 Aug 2019 02:41:33 -0400 Received: by mail-ua1-f66.google.com with SMTP id f9so5350826uaj.4 for ; Sun, 25 Aug 2019 23:41:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=gjtXwc6uWBjbYeNxWQINJLUvFHZALBu2ElRrlxI08CE=; b=aTU/uhsSlzt3jbOo33gPmFrycabLXGD/C6tt2tgF++HjYTVydmg4zuqQEsztine73C 5jYXXM3EkRQJRBAb7NLGRRmd2mf1+PHPWR6Tra2r+JJzR3jZuDOAtNOTJhKHT1XKGt0w r+FABLjqHTysV+z7OllVBO0m634fsN9DkUBQ8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=gjtXwc6uWBjbYeNxWQINJLUvFHZALBu2ElRrlxI08CE=; b=bXuez2M8w7s60/GREACptoEX9kA0XPY0iKXU1ucWyJGo9Ylyi98FSILkgtP2KP4K6l S7WwtXw1h5ujN2GOlyX+qm7nOs7I0/rk1B0qOEhNYg9NXdZmTyiXTgIqK/0pX49+NmW2 nBUt+YHMSypOgj4aMAFYXqoFHnhvLfyYTS3/rp//kIT856SZoAdMq5F7r319xNq3/dYn ZANZ6LV2ERbz+VAq6JmAtndAs8imppYOjzmkVKUGmxg9w6K0IaJ45+w1VcSIa0sTHUGq woziPW/Wkomb7UN3TjwXBYa1Ha94FT9FCfSIj46Mcq2ZO0Ms5dAKi6Pf4GMeLZylgYiY XQfA== X-Gm-Message-State: APjAAAXikhlMRSrewPhSUM4lBJIRYxUTf6ycl4g/vFGw3p0DmCHDN352 lPrMq74f3xCI4gC8QQ2IHeE9N4+zSIyPz3bY3UhWmw== X-Received: by 2002:ab0:136d:: with SMTP id h42mr7786917uae.123.1566801691824; Sun, 25 Aug 2019 23:41:31 -0700 (PDT) MIME-Version: 1.0 References: <20190811082259.48176-1-ikjn@chromium.org> <5883d03d-31c4-206a-26c1-ca641dbf845c@linux.intel.com> In-Reply-To: <5883d03d-31c4-206a-26c1-ca641dbf845c@linux.intel.com> From: Ikjoon Jang Date: Mon, 26 Aug 2019 14:41:20 +0800 Message-ID: Subject: Re: [PATCH] xhci: fix memleak on setup address fails. To: Mathias Nyman Cc: Mathias Nyman , Greg Kroah-Hartman , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, Aug 14, 2019 at 9:57 PM Mathias Nyman wrote: > > On 11.8.2019 11.22, Ikjoon Jang wrote: > > Xhci re-enables a slot on transaction error in set_address using > > xhci_disable_slot() + xhci_alloc_dev(). > > > > But in this case, xhci_alloc_dev() creates debugfs entries upon an > > existing device without cleaning up old entries, thus memory leaks. > > > > So this patch simply moves calling xhci_debugfs_free_dev() from > > xhci_free_dev() to xhci_disable_slot(). > > > > Othwerwise this looks good, but xhci_alloc_dev() will call xhci_disable_slot() > in some failure cases before the slot debugfs entry is created. > > In these cases xhci_debugfs_remove_slot() will be called without > xhci_debugfs_create_slot() ever being called. > > This might not be an issue as xhci_debugfs_remove_slot() checks > if (!dev || !dev->debugfs_private) before doing anything, but should > be checked out. > I checked out the case by adding simple fault injection on xhci_alloc_dev(), to simulate xhci_debugfs_remove_slot() can be called without xhci_debugfs_create_slot() being called. Here is the test codes used in a test: --- drivers/usb/host/xhci-debugfs.c | 11 ++++++++++- drivers/usb/host/xhci.c | 4 ++++ drivers/usb/host/xhci.h | 3 +++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-debugfs.c b/drivers/usb/host/xhci-debugfs.c index 7ba6afc7ef23..4dd3873856e7 100644 --- a/drivers/usb/host/xhci-debugfs.c +++ b/drivers/usb/host/xhci-debugfs.c @@ -13,6 +13,8 @@ #include "xhci.h" #include "xhci-debugfs.h" +static DECLARE_FAULT_ATTR(fail_default_attr); + static const struct debugfs_reg32 xhci_cap_regs[] = { dump_register(CAPLENGTH), dump_register(HCSPARAMS1), @@ -500,8 +502,10 @@ void xhci_debugfs_remove_slot(struct xhci_hcd *xhci, int slot_id) struct xhci_slot_priv *priv; struct xhci_virt_device *dev = xhci->devs[slot_id]; - if (!dev || !dev->debugfs_private) + if (!dev || !dev->debugfs_private) { + xhci_warn(xhci, "trying to remove a non-existent debugfs on slot %d.\n", slot_id); return; + } priv = dev->debugfs_private; @@ -585,6 +589,11 @@ void xhci_debugfs_init(struct xhci_hcd *xhci) xhci->debugfs_slots = debugfs_create_dir("devices", xhci->debugfs_root); xhci_debugfs_create_ports(xhci, xhci->debugfs_root); + + xhci->fail_alloc_dev = fail_default_attr; + + fault_create_debugfs_attr("fail_alloc_dev", xhci->debugfs_root, + &xhci->fail_alloc_dev); } void xhci_debugfs_exit(struct xhci_hcd *xhci) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 8c5cbd065edd..b01f2a2e7b91 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "xhci.h" #include "xhci-trace.h" @@ -3880,6 +3881,9 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) xhci_free_command(xhci, command); + if (should_fail(&xhci->fail_alloc_dev, 1)) + goto disable_slot; + if ((xhci->quirks & XHCI_EP_LIMIT_QUIRK)) { spin_lock_irqsave(&xhci->lock, flags); ret = xhci_reserve_host_control_ep_resources(xhci); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 5dad11d223e0..2ab4d2b5e935 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -17,6 +17,7 @@ #include #include #include +#include /* Code sharing between pci-quirks and xhci hcd */ #include "xhci-ext-caps.h" @@ -1895,6 +1896,8 @@ struct xhci_hcd { struct dentry *debugfs_slots; struct list_head regset_list; + struct fault_attr fail_alloc_dev; + void *dbc; /* platform-specific data -- must come last */ unsigned long priv[0] __aligned(sizeof(s64)); -- and here is the test result: [ 117.528523] FAULT_INJECTION: forcing a failure. [ 117.528523] name fail_alloc_dev, interval 1, probability 100, space 0, times 1 ... [ 117.600764] xxxx.xhci: trying to remove a non-existent debugfs on slot 0. [ 117.608943] usb 1-1.2-port2: couldn't allocate usb_device > -Mathias