Received: by 2002:a05:7412:f584:b0:e2:908c:2ebd with SMTP id eh4csp2003448rdb; Tue, 5 Sep 2023 11:13:15 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHgHV4uKrP9ZaeTUUtoU7CbYsKX9yyALcJvdUFEmSXIFX6H8U67+YGa6p/MRSbfkpdm/tyF X-Received: by 2002:a17:906:5187:b0:9a1:edb0:2a89 with SMTP id y7-20020a170906518700b009a1edb02a89mr486917ejk.9.1693937595366; Tue, 05 Sep 2023 11:13:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1693937595; cv=none; d=google.com; s=arc-20160816; b=OZTZcgRAWn8HKVcePUhT/of8OcpvXOJECQveQIdW5SslxNbVt8mv14encT3u4KakaD FZaGYykupbmWS4/wG+azeIHi3Slq8YyftVlIM4zxOQEA7MYBB7XvgLPOem7qv4x8UAFI lKvmXet4VRNPWhOrzLku+djRzlt/M3YkFtQ9NBr3PTJGUQS315IVVPr56khwHJXnboHC d7eb949qQZjiqRDitGZoF92BNEdvSDOaZy30bqjYp60exxm1olUKeI/THvUmSZQSh2Lk tx2/L0463qkOeyKAHykuuh8rYlCMjTbTkymr/p18nbdaPqhB5U6c3mtPltzWvtw0v4Wk yNyA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-disposition:mime-version :references:mail-followup-to:message-id:subject:to:from:date :dkim-signature; bh=igEYuR5IFutSOGV2XTxzMIcOUm0YFC8H2FdnNn89iD4=; fh=T+xMi/co6eq6uz4WPaX9JT78hUl9DxovaEpizwAO1Kg=; b=Q6gCg20xCY8YJyRdBO9KDFFZyRTttnDQnVpudb8zn8R0HT4wfuUPrUSVNAuUyk4NaP dcIyhUo8dylKGq5tx4x0g6veLJm5hGtrSaOLJVjvH6d0L0tHBUnCpHEPCV9ayyw4bvWh zlQ7tTXQmzAbtxkmJf5XBELEKztRox56CSthqx36fKLTwRQUuv+Qn87wVxH3r9xH3NXI GC/xHjBOQmDp2NG6PrEsrvqD1HvMkGfvP280Tm11Tl90JO5tYScffPBYxMSyP5t/aHG6 kWPQkFKTO0nGYdZV7CyuqOjDqEOE+ORBJZ5GwrIHbkWVlwJeTga/eZWQy4nrd6Y72vme MyWw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@xff.cz header.s=mail header.b=sCAZbCxG; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=xff.cz Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id kg12-20020a17090776ec00b0099cc98af80fsi8474628ejc.552.2023.09.05.11.13.13; Tue, 05 Sep 2023 11:13:15 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@xff.cz header.s=mail header.b=sCAZbCxG; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=xff.cz Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239690AbjIEANA (ORCPT + 4 others); Mon, 4 Sep 2023 20:13:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44266 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237503AbjIEAM7 (ORCPT ); Mon, 4 Sep 2023 20:12:59 -0400 Received: from vps.xff.cz (vps.xff.cz [195.181.215.36]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E0CCFE4D; Mon, 4 Sep 2023 17:12:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xff.cz; s=mail; t=1693872761; bh=BdHr5xYzJaXpVVjrVQyCyMhqKo0QPrh0h1mxW+BeCdk=; h=Date:From:To:Subject:X-My-GPG-KeyId:References:From; b=sCAZbCxG4vDYd8PkSat1sRd/mrRSogl2lERQpDPcT0EpkfGeutxnj0JDslll30xMP SUFbCkURxw4uAOAP+fSPk7VL24AZe+I1tyxIfgR1rhN8JlSWFFqNMgqUyJewpC+lih w28bXq0ZLiHQhLX5YFnqIIDZjFwmoPkDKwqWh6M0= Date: Tue, 5 Sep 2023 02:12:40 +0200 From: =?utf-8?Q?Ond=C5=99ej?= Jirman To: Sascha Hauer , linux-usb@vger.kernel.org, Greg Kroah-Hartman , linux-kernel@vger.kernel.org, kernel@pengutronix.de Subject: Re: [PATCH 1/2] usb: gadget: u_ether: Do not make UDC parent of the net device Message-ID: Mail-Followup-To: =?utf-8?Q?Ond=C5=99ej?= Jirman , Sascha Hauer , linux-usb@vger.kernel.org, Greg Kroah-Hartman , linux-kernel@vger.kernel.org, kernel@pengutronix.de X-My-GPG-KeyId: EBFBDDE11FB918D44D1F56C1F9F0A873BE9777ED References: <20221104131031.850850-1-s.hauer@pengutronix.de> <20221104131031.850850-2-s.hauer@pengutronix.de> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, Sep 04, 2023 at 03:14:30PM +0200, megi xff wrote: > > Hi, > > On Fri, Nov 04, 2022 at 02:10:30PM +0100, Sascha Hauer wrote: > > ing-List: linux-kernel@vger.kernel.org > > > > The UDC is not a suitable parent of the net device as the UDC can > > change or vanish during the lifecycle of the ethernet gadget. This > > can be illustrated with the following: > > > > mkdir -p /sys/kernel/config/usb_gadget/mygadget > > cd /sys/kernel/config/usb_gadget/mygadget > > mkdir -p configs/c.1/strings/0x409 > > echo "C1:Composite Device" > configs/c.1/strings/0x409/configuration > > mkdir -p functions/ecm.usb0 > > ln -s functions/ecm.usb0 configs/c.1/ > > echo "dummy_udc.0" > UDC > > rmmod dummy_hcd > > > > The 'rmmod' removes the UDC from the just created gadget, leaving > > the still existing net device with a no longer existing parent. > > I have an even simpler reproducer on Pinephone Pro/RK3399 SoC. All it takes to > trigger the use after free and kernel panic in my case is to plug in a USB dock > to make DWC3 DRD switch to host mode and then unplug it to make it switch back to > peripheral mode. > > This triggers a call to dwc3_gadget_exit and then to dwc3_gadget_init later on > > https://elixir.bootlin.com/linux/latest/source/drivers/usb/dwc3/gadget.c#L4546 > > Then symlink to the net device becames broken in sysfs: > > https://megous.com/dl/tmp/3d8061f1749a7b2b.png > > And after this happens, there's a kernel panic when removing the rndis gadget > configuration from configfs: https://paste.mozilla.org/Z5DFP9BV > (and possibly other issues, but the kernel panic is the most noticable :)) > > Applaying this patch makes the issue go away. So there definitely seems to > be some device lifetime issue somewhere in there. Looks like this patch just masks an underlying issue. Eg. with DWC3 as UDC, rndis_bind/rndis_unbind is called multiple times (each time USB role switches from host to peripheral). This is because DWC3 re-creates the gadget device each time. During every call rndis_bind gets a pointer to a newly created gadget, but gether_set_gadget() is only called: if (!rndis_opts->bound) { ... } which only happens on the first call to rndis_bind. On any further calls to rndis_bind(), gether_set_gadget is not called, because rndis_opts->bound is already set and thus netdev private data keep pointing to some old, deleted gadget device. https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/f_rndis.c#L704 https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/u_ether.c#L890 It looks like this whole code was not really written with assumption that gadget devices can be deleted and re-added like this. Not sure where the bug really is... if f_* drivers should better handle gadget changes, or DWC3 should not re-create the gadget like it does on mode changes, or elsewhere. kind regards, o. > kind regards, > o. > > > Accessing the ethernet device with commands like: > > > > ip --details link show usb0 > > > > will result in a KASAN splat: > > > > ================================================================== > > BUG: KASAN: use-after-free in if_nlmsg_size+0x3e8/0x528 > > Read of size 4 at addr c5c84754 by task ip/357 > > > > CPU: 3 PID: 357 Comm: ip Not tainted 6.1.0-rc3-00013-gd14953726b24-dirty #324 > > Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) > > unwind_backtrace from show_stack+0x10/0x14 > > show_stack from dump_stack_lvl+0x58/0x70 > > dump_stack_lvl from print_report+0x134/0x4d4 > > print_report from kasan_report+0x78/0x10c > > kasan_report from if_nlmsg_size+0x3e8/0x528 > > if_nlmsg_size from rtnl_getlink+0x2b4/0x4d0 > > rtnl_getlink from rtnetlink_rcv_msg+0x1f4/0x674 > > rtnetlink_rcv_msg from netlink_rcv_skb+0xb4/0x1f8 > > netlink_rcv_skb from netlink_unicast+0x294/0x478 > > netlink_unicast from netlink_sendmsg+0x328/0x640 > > netlink_sendmsg from ____sys_sendmsg+0x2a4/0x3b4 > > ____sys_sendmsg from ___sys_sendmsg+0xc8/0x12c > > ___sys_sendmsg from sys_sendmsg+0xa0/0x120 > > sys_sendmsg from ret_fast_syscall+0x0/0x1c > > > > Solve this by not setting the parent of the ethernet device. > > > > Signed-off-by: Sascha Hauer > > --- > > drivers/usb/gadget/function/u_ether.c | 4 ---- > > 1 file changed, 4 deletions(-) > > > > diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c > > index e06022873df16..8f12f3f8f6eeb 100644 > > --- a/drivers/usb/gadget/function/u_ether.c > > +++ b/drivers/usb/gadget/function/u_ether.c > > @@ -798,7 +798,6 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g, > > net->max_mtu = GETHER_MAX_MTU_SIZE; > > > > dev->gadget = g; > > - SET_NETDEV_DEV(net, &g->dev); > > SET_NETDEV_DEVTYPE(net, &gadget_type); > > > > status = register_netdev(net); > > @@ -873,8 +872,6 @@ int gether_register_netdev(struct net_device *net) > > struct usb_gadget *g; > > int status; > > > > - if (!net->dev.parent) > > - return -EINVAL; > > dev = netdev_priv(net); > > g = dev->gadget; > > > > @@ -905,7 +902,6 @@ void gether_set_gadget(struct net_device *net, struct usb_gadget *g) > > > > dev = netdev_priv(net); > > dev->gadget = g; > > - SET_NETDEV_DEV(net, &g->dev); > > } > > EXPORT_SYMBOL_GPL(gether_set_gadget); > > > > -- > > 2.30.2 > >