From nobody Thu Sep 24 13:39:04 2026 Received: from mail-pf1-f198.google.com (mail-pf1-f198.google.com [209.85.210.198]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A786E468C1F for ; Wed, 23 Sep 2026 07:59:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.198 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790150348; cv=none; b=RSH6WNRndg2VsiTkXU5EGM5Evi/MD5V0ML0pSV99jG3xJd5KB3XavYgxyoPyXf/iweGM3lZ1jKNx5zbPGb2VPFzNc17UCP4u+ht4vSKghdSxxp84MwzfZaEvios5vVKsO0fs1BMbQLFS3uce6/yfVo1adBJTaYhk50waMmMielU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790150348; c=relaxed/simple; bh=GmCJYBbWM9KTGcJMPFVpHEJ+KrcM1iWznhbvX6v4yTE=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=sW/ZSrQhgbcs77f6c4FCq70iJJ7pjUnhw+s5ZVuVgx6LivshiAsIOIZifIQlbFv6zPxbnjdHvDpgM/MMA0xLL3hGTyvwI+y3KZOME8GX0dBW6NUWcTvbjaFwcs1cjNbutsp3EAF8Jev7TwtjCpyi+zUCuDEwhDqJ5q1GgLxhjig= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--khtsai.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=ANp1OX13; arc=none smtp.client-ip=209.85.210.198 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--khtsai.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="ANp1OX13" Received: by mail-pf1-f198.google.com with SMTP id d2e1a72fcca58-869b8d63e28so816178b3a.0 for ; Wed, 23 Sep 2026 00:59:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1790150345; x=1790755145; darn=vger.kernel.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:from:to:cc:subject:date:message-id:reply-to :content-type; bh=2pogbJ2sP8D91YksgSoEJ19QAvzZA3gwl/UMe/2M9Yc=; b=ANp1OX131OuG4/xqPReKOkwcPaiFy/KlYs4hBnWVE4ckN7zqrSyJhsACge+OiQDErI ByWOj5hg7guHU8g8yl4j+VoRt+FHKx46bxdLVxBOZygz/so5BkOse/myTBZEBe34ts7n 1FXzrOj//+uDBL9pCeXWqCkzdNqHVU5aXykMS6vL9QhEQPoumImGpoddCqoA5qBecimo nPjV+i6r+aSGMn1kS9AagxY86VMmFg8BqSEvPgm5W+zt9ko+YTHUXkbUXrYhHk4rfwR4 7eLTNBB6QJ/iE4F/bbzLUpkmDTX60uCck1Pe5QMOb0EZZGwoZfoIq2YYmgbpnAZPuIyn eeBw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790150345; x=1790755145; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=2pogbJ2sP8D91YksgSoEJ19QAvzZA3gwl/UMe/2M9Yc=; b=WVmGucdcCUyIQa1LBxtPxxdQ4bAlaJNrNxB3iUMAWAIAUX1F7lhVGarxyIMji83lcx nCTYutBzx0v7Jfvfl5oZJz5tXTx3XcJodgsJAxwCA+PB0nBIJfnZJzKa3WTrkFVFVWOK EEDYSQTpipPqxn3ZSau2MDu4P+DEPxGEdTTRPcR7BOFCFA5bPdH2y4LHB9F3dJaSwbb5 14+D8G/+m92Vm8/VS1w9B6st5HbAz1TwMP4uDj1Pm57mYqIwzBh/R8TzfdETHUmSEPS5 88iDC6AlDVZe1toQMkL/oLFN2HM+Vn7N5GnB/rYOLydU/nVU+kt6+377D73btAPjW2tT 4vNw== X-Forwarded-Encrypted: i=1; AKwUvBwknWf1GqosKU68t9F52wmQKq4bqmsfqJdOGojm7zLX4CnIfpBD0XV1GdwRp5TuLp0PPVnyzQzSaWzY5b4=@vger.kernel.org X-Gm-Message-State: AFuF++mJs/BXoerrH9K5W20Zx+Y+weOc/Pq4ES8wCFNhXw+Hn+Iod9Wk pkbuyC7Gwe1YWETr1m8lcTg/1kJAQqnaj1AtsH3gv/8v0EiBgoPgoRx6pIV88HwmOa2LKpxmUg4 OpVZX1g== X-Received: from pfbhu13.prod.google.com ([2002:a05:6a00:698d:b0:87d:7af8:2ad7]) (user=khtsai job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:1595:b0:87d:f8af:894a with SMTP id d2e1a72fcca58-87df8af8d85mr63628b3a.31.1790150344827; Wed, 23 Sep 2026 00:59:04 -0700 (PDT) Date: Wed, 23 Sep 2026 15:58:35 +0800 In-Reply-To: <20260923-u-ether-gadget-npe-v1-0-ff466c55ecc0@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260923-u-ether-gadget-npe-v1-0-ff466c55ecc0@google.com> X-Developer-Key: i=khtsai@google.com; a=ed25519; pk=abA4Pw6dY2ZufSbSXW9mtp7xiv1AVPtgRhCFWJSEqLE= X-Developer-Signature: v=1; a=ed25519-sha256; t=1790150340; l=9602; i=khtsai@google.com; s=20250916; h=from:subject:message-id; bh=GmCJYBbWM9KTGcJMPFVpHEJ+KrcM1iWznhbvX6v4yTE=; b=dJo718usBI56j7e1tPMtzTP1hr1SfyhUInLRP161ez993PBC+l4Y6hASGID/oxkwD/FWcxDoR qPpRknKkjI0DJ1QduYfiyYxxvFZ2k4mQ9vlyl0aCaokSOVI12wNzXhq X-Mailer: b4 0.14.3 Message-ID: <20260923-u-ether-gadget-npe-v1-1-ff466c55ecc0@google.com> Subject: [PATCH 1/2] usb: gadget: u_ether: Fix NULL pointer deref in debug logging From: Kuen-Han Tsai To: Greg Kroah-Hartman Cc: Ivaylo Dimitrov , Faqiang Zhu , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Kuen-Han Tsai , stable@vger.kernel.org Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Commit ec35c1969650 ("usb: gadget: f_ncm: Fix net_device lifecycle with device_move") and its counterparts reparent the net_device to /sys/devices/virtual during unbind and clear dev->gadget. However, the DBG(), VDBG(), ERROR(), and INFO() macros from dereference &dev->gadget->dev. When dynamic debug or CONFIG_USB_GADGET_DEBUG is enabled, any logging on the surviving net_device after unbind causes a NULL pointer dereference, such as in eth_stop() during function instance teardown: Unable to handle kernel NULL pointer dereference Call trace: dev_driver_string from __dynamic_dev_dbg+0x8c/0x118 __dynamic_dev_dbg from eth_stop+0x70/0x134 [u_ether] ... unregister_netdev from gether_cleanup+0x14/0x28 [u_ether] gether_cleanup [u_ether] from rndis_free_inst+0x2c/0x48 [usb_f_rndis] Replace the composite.h logging macros in u_ether.c with the standard netdev_*() helpers. Because dev->net remains valid for the entire lifetime of struct eth_dev and netdev_printk() natively handles unparented network devices, messages are logged safely both when attached and when detached from the gadget. Reported-by: Ivaylo Dimitrov Closes: https://lore.kernel.org/all/89e19e6e-7ee7-4bb0-abd6-60971b7fd601@gm= ail.com/ Fixes: ec35c1969650 ("usb: gadget: f_ncm: Fix net_device lifecycle with dev= ice_move") Cc: stable@vger.kernel.org Assisted-by: LLM Signed-off-by: Kuen-Han Tsai --- drivers/usb/gadget/function/u_ether.c | 61 +++++++++++++++++--------------= ---- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/fun= ction/u_ether.c index 59d85d6a84a8..043b4ec80808 100644 --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c @@ -135,9 +135,9 @@ static void defer_kevent(struct eth_dev *dev, int flag) if (test_and_set_bit(flag, &dev->todo)) return; if (!schedule_work(&dev->work)) - ERROR(dev, "kevent %d may have been dropped\n", flag); + netdev_err(dev->net, "kevent %d may have been dropped\n", flag); else - DBG(dev, "kevent %d scheduled\n", flag); + netdev_dbg(dev->net, "kevent %d scheduled\n", flag); } =20 static void rx_complete(struct usb_ep *ep, struct usb_request *req); @@ -190,7 +190,7 @@ rx_submit(struct eth_dev *dev, struct usb_request *req,= gfp_t gfp_flags) =20 skb =3D __netdev_alloc_skb(dev->net, size + NET_IP_ALIGN, gfp_flags); if (skb =3D=3D NULL) { - DBG(dev, "no rx skb\n"); + netdev_dbg(dev->net, "no rx skb\n"); goto enomem; } =20 @@ -211,7 +211,7 @@ rx_submit(struct eth_dev *dev, struct usb_request *req,= gfp_t gfp_flags) enomem: defer_kevent(dev, WORK_RX_MEMORY); if (retval) { - DBG(dev, "rx submit --> %d\n", retval); + netdev_dbg(dev->net, "rx submit --> %d\n", retval); if (skb) dev_kfree_skb_any(skb); spin_lock_irqsave(&dev->req_lock, flags); @@ -258,7 +258,7 @@ static void rx_complete(struct usb_ep *ep, struct usb_r= equest *req) || skb2->len > GETHER_MAX_ETH_FRAME_LEN) { dev->net->stats.rx_errors++; dev->net->stats.rx_length_errors++; - DBG(dev, "rx length %d\n", skb2->len); + netdev_dbg(dev->net, "rx length %d\n", skb2->len); dev_kfree_skb_any(skb2); goto next_frame; } @@ -278,12 +278,12 @@ static void rx_complete(struct usb_ep *ep, struct usb= _request *req) /* software-driven interface shutdown */ case -ECONNRESET: /* unlink */ case -ESHUTDOWN: /* disconnect etc */ - VDBG(dev, "rx shutdown, code %d\n", status); + netdev_vdbg(dev->net, "rx shutdown, code %d\n", status); goto quiesce; =20 /* for hardware automagic (such as pxa) */ case -ECONNABORTED: /* endpoint reset */ - DBG(dev, "rx %s reset\n", ep->name); + netdev_dbg(dev->net, "rx %s reset\n", ep->name); defer_kevent(dev, WORK_RX_MEMORY); quiesce: dev_kfree_skb_any(skb); @@ -296,7 +296,7 @@ static void rx_complete(struct usb_ep *ep, struct usb_r= equest *req) =20 default: dev->net->stats.rx_errors++; - DBG(dev, "rx status %d\n", status); + netdev_dbg(dev->net, "rx status %d\n", status); break; } =20 @@ -365,7 +365,7 @@ static int alloc_requests(struct eth_dev *dev, struct g= ether *link, unsigned n) goto fail; goto done; fail: - DBG(dev, "can't alloc requests\n"); + netdev_dbg(dev->net, "can't alloc requests\n"); done: spin_unlock(&dev->req_lock); return status; @@ -403,7 +403,7 @@ static void eth_work(struct work_struct *work) } =20 if (dev->todo) - DBG(dev, "work done, flags =3D 0x%lx\n", dev->todo); + netdev_dbg(dev->net, "work done, flags =3D 0x%lx\n", dev->todo); } =20 static void tx_complete(struct usb_ep *ep, struct usb_request *req) @@ -414,7 +414,7 @@ static void tx_complete(struct usb_ep *ep, struct usb_r= equest *req) switch (req->status) { default: dev->net->stats.tx_errors++; - VDBG(dev, "tx err %d\n", req->status); + netdev_vdbg(dev->net, "tx err %d\n", req->status); fallthrough; case -ECONNRESET: /* unlink */ case -ESHUTDOWN: /* disconnect etc */ @@ -475,7 +475,7 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb, } =20 if (dev->port_usb && dev->port_usb->is_suspend) { - DBG(dev, "Port suspended. Triggering wakeup\n"); + netdev_dbg(dev->net, "Port suspended. Triggering wakeup\n"); netif_stop_queue(net); spin_unlock_irqrestore(&dev->lock, flags); ether_wakeup_host(dev->port_usb); @@ -579,7 +579,7 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb, retval =3D usb_ep_queue(in, req, GFP_ATOMIC); switch (retval) { default: - DBG(dev, "tx queue err %d\n", retval); + netdev_dbg(dev->net, "tx queue err %d\n", retval); break; case 0: netif_trans_update(net); @@ -604,7 +604,7 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb, =20 static void eth_start(struct eth_dev *dev, gfp_t gfp_flags) { - DBG(dev, "%s\n", __func__); + netdev_dbg(dev->net, "%s\n", __func__); =20 /* fill the rx queue */ rx_fill(dev, gfp_flags); @@ -619,7 +619,7 @@ static int eth_open(struct net_device *net) struct eth_dev *dev =3D netdev_priv(net); struct gether *link; =20 - DBG(dev, "%s\n", __func__); + netdev_dbg(dev->net, "%s\n", __func__); if (netif_carrier_ok(dev->net)) eth_start(dev, GFP_KERNEL); =20 @@ -637,13 +637,12 @@ static int eth_stop(struct net_device *net) struct eth_dev *dev =3D netdev_priv(net); unsigned long flags; =20 - VDBG(dev, "%s\n", __func__); + netdev_vdbg(dev->net, "%s\n", __func__); netif_stop_queue(net); =20 - DBG(dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld\n", - dev->net->stats.rx_packets, dev->net->stats.tx_packets, - dev->net->stats.rx_errors, dev->net->stats.tx_errors - ); + netdev_dbg(dev->net, "stop stats: rx/tx %ld/%ld, errs %ld/%ld\n", + dev->net->stats.rx_packets, dev->net->stats.tx_packets, + dev->net->stats.rx_errors, dev->net->stats.tx_errors); =20 /* ensure there are no more active requests */ spin_lock_irqsave(&dev->lock, flags); @@ -669,7 +668,7 @@ static int eth_stop(struct net_device *net) usb_ep_disable(link->in_ep); usb_ep_disable(link->out_ep); if (netif_carrier_ok(net)) { - DBG(dev, "host still using in/out endpoints\n"); + netdev_dbg(dev->net, "host still using in/out endpoints\n"); link->in_ep->desc =3D in; link->out_ep->desc =3D out; usb_ep_enable(link->in_ep); @@ -799,8 +798,8 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g, free_netdev(net); dev =3D ERR_PTR(status); } else { - INFO(dev, "MAC %pM\n", net->dev_addr); - INFO(dev, "HOST MAC %pM\n", dev->host_mac); + netdev_info(net, "MAC %pM\n", net->dev_addr); + netdev_info(net, "HOST MAC %pM\n", dev->host_mac); =20 /* * two kinds of host-initiated state changes: @@ -875,8 +874,8 @@ int gether_register_netdev(struct net_device *net) dev_dbg(&g->dev, "register_netdev failed, %d\n", status); return status; } else { - INFO(dev, "HOST MAC %pM\n", dev->host_mac); - INFO(dev, "MAC %pM\n", dev->dev_mac); + netdev_info(net, "HOST MAC %pM\n", dev->host_mac); + netdev_info(net, "MAC %pM\n", dev->dev_mac); =20 /* two kinds of host-initiated state changes: * - iff DATA transfer is active, carrier is "on" @@ -1147,16 +1146,16 @@ struct net_device *gether_connect(struct gether *li= nk) link->in_ep->driver_data =3D dev; result =3D usb_ep_enable(link->in_ep); if (result !=3D 0) { - DBG(dev, "enable %s --> %d\n", - link->in_ep->name, result); + netdev_dbg(dev->net, "enable %s --> %d\n", + link->in_ep->name, result); goto fail0; } =20 link->out_ep->driver_data =3D dev; result =3D usb_ep_enable(link->out_ep); if (result !=3D 0) { - DBG(dev, "enable %s --> %d\n", - link->out_ep->name, result); + netdev_dbg(dev->net, "enable %s --> %d\n", + link->out_ep->name, result); goto fail1; } =20 @@ -1167,7 +1166,7 @@ struct net_device *gether_connect(struct gether *link) if (result =3D=3D 0) { dev->zlp =3D link->is_zlp_ok; dev->no_skb_reserve =3D gadget_avoids_skb_reserve(dev->gadget); - DBG(dev, "qlen %d\n", qlen(dev->gadget, dev->qmult)); + netdev_dbg(dev->net, "qlen %d\n", qlen(dev->gadget, dev->qmult)); =20 dev->header_len =3D link->header_len; dev->unwrap =3D link->unwrap; @@ -1223,7 +1222,7 @@ void gether_disconnect(struct gether *link) if (!dev) return; =20 - DBG(dev, "%s\n", __func__); + netdev_dbg(dev->net, "%s\n", __func__); =20 spin_lock(&dev->lock); dev->port_usb =3D NULL; --=20 2.55.0.1082.g2b9226bbc0-goog From nobody Thu Sep 24 13:39:04 2026 Received: from mail-pj1-f69.google.com (mail-pj1-f69.google.com [209.85.216.69]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A9BA846A61D for ; Wed, 23 Sep 2026 07:59:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.69 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790150349; cv=none; b=oECkavQ8vUJL/Hqq3QS4rnr8KclPbyhMSqDinKQZOnmWVPP2JsMO4QEC8zc55r99gdTbejs1P9jnmjD5ebQTjR3rDV5w2LazlE6r9RXvEbIKkWqyqV9No5oWvu/D0VDOeszxlctMdwXeihQRWxUFwLskNIZdtmqEhP+cSV4SciQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790150349; c=relaxed/simple; bh=yyJfPPAEIt/EVKO+2+O8gepOzQn6BvxvOS8WipJumGw=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=mNNq1DXelmnkfJCErW+rh3+eNoQmR/6K/vMVYStKmAEG9PSTerLtQUcTxAzdc8ccPE1cGEcoQZe5o8Kegzjd6XlcXeC3EvhZiKsqp/80TWjdubhmGTdBt/+6ezrULy562OIWw1yu/YiviQrdTC88okJbzC19RqnQgcZpGfOP/sc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--khtsai.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=kH1covcu; arc=none smtp.client-ip=209.85.216.69 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--khtsai.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="kH1covcu" Received: by mail-pj1-f69.google.com with SMTP id 98e67ed59e1d1-39e25a5f6e8so717835a91.0 for ; Wed, 23 Sep 2026 00:59:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1790150347; x=1790755147; darn=vger.kernel.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:from:to:cc:subject:date:message-id:reply-to :content-type; bh=0vLJZPmEwAEYLI74+W02hyeGgNOZF691D2NvOqlwqxA=; b=kH1covcuN8riMyj9vWAexE1+pnGqCjpXt9RY+vpfJQV/oNvVS8eWhx4yn2pLStJqa3 S/YaUgFDZQitI3A7p1Q1p5EsBK7T90H8p7zTVT4KrfNHlbBPmvpBX8MjtwuiYfk9BeOG zXwrKaJDQ6TyEiw6ZGzpoEVrGOkVXn1GmOd4DOWEOXrJ7mN+cSn4nwIMOdQAf729c8yh Jr0XrAx4Nf6gkaGJIMM+hptM1E+0mRdwT+R5g+Y+cFUc0uMkMZ7EPu69ws6SbIzv0oRm Evb4kyy/OLUQFMhxq9a/LggY2/PXGwNFt+GW/VXDXhbqNPRQbXi+q1EnI/yPsuFAc+8O h4zA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790150347; x=1790755147; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=0vLJZPmEwAEYLI74+W02hyeGgNOZF691D2NvOqlwqxA=; b=rUNet7NOP6e03/h2H6G9HvROViLGSgrj5ojOVjz4X4kmXoEUzShO8LYJIbvbXxPjVV isi1vsKx0Pq+hh4C52MRC8B5VF2ofaUfSue0Pjrhc3nMFUqfPC8rv4zy/qk5P41PSEuO udu2IDDmitYog/U+dc6yMFdvtXD053vqNBoytq/ctmqiEtrpsG0pDGJneAk2yOP1WiMY qIFwB4N0S9a0aLv0D6q6sXebpRNaiaOYJMD3Wa1y6ZjWFWynTNdpiiak7imRtx/vc6jB Won6rVgDNgQQYBfvPOtyKkVOtB2W+YhEOlBYJ7ZuRkK/cT6mtLH5Y/5l35+MCZu4cUec XETw== X-Forwarded-Encrypted: i=1; AKwUvBzlwtawGgIiwhLX6b3XzML7XAxMgdQprgX7SHnNI5n+zu5KCgJo/OfubkG6e6byeSC+NUn1BQoaNihZnao=@vger.kernel.org X-Gm-Message-State: AFuF++kFH0sgcbPhiixI9Sb2wWwnFBtfgHZiIsy+KzpCEhlDMV2lPEOh ZZaz2uOfS/FK303njjQOUuVbAtN+LnOWDQePaYymEQeoKvZk2NjP09mxrtz8jGgJuTD9CDJ/grm uDPwHHA== X-Received: from pjbmy12.prod.google.com ([2002:a17:90b:4c8c:b0:3a0:77da:6ec2]) (user=khtsai job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:3fc6:b0:39d:f4fd:8075 with SMTP id 98e67ed59e1d1-3a07e5ea295mr1605582a91.19.1790150346825; Wed, 23 Sep 2026 00:59:06 -0700 (PDT) Date: Wed, 23 Sep 2026 15:58:36 +0800 In-Reply-To: <20260923-u-ether-gadget-npe-v1-0-ff466c55ecc0@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260923-u-ether-gadget-npe-v1-0-ff466c55ecc0@google.com> X-Developer-Key: i=khtsai@google.com; a=ed25519; pk=abA4Pw6dY2ZufSbSXW9mtp7xiv1AVPtgRhCFWJSEqLE= X-Developer-Signature: v=1; a=ed25519-sha256; t=1790150341; l=3802; i=khtsai@google.com; s=20250916; h=from:subject:message-id; bh=yyJfPPAEIt/EVKO+2+O8gepOzQn6BvxvOS8WipJumGw=; b=G1ypuZYU8ICSu62zcu8z/GGCNpTHCpG0L+6Kp5XGF1sx4s8/1GQtGthUFk+WfGsVHSA7onAxL g5H1RyMRymoCZPOP5GXmkorDSpB71ifmVE3tuk/diGjja3MXYt6rGoV X-Mailer: b4 0.14.3 Message-ID: <20260923-u-ether-gadget-npe-v1-2-ff466c55ecc0@google.com> Subject: [PATCH 2/2] usb: gadget: u_ether: Protect dev->gadget access with dev->lock From: Kuen-Han Tsai To: Greg Kroah-Hartman Cc: Ivaylo Dimitrov , Faqiang Zhu , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Kuen-Han Tsai , stable@vger.kernel.org Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Commit e002e92e88e1 ("usb: gadget: u_ether: Fix NULL pointer deref in eth_get_drvinfo") added a NULL check for dev->gadget in eth_get_drvinfo(), but the check and subsequent dereferences are not serialized against gether_detach_gadget(). If unbind clears dev->gadget concurrently after the NULL check, eth_get_drvinfo() can still dereference a NULL or freed gadget pointer. Extend dev->lock to protect dev->gadget across gether_set_gadget(), gether_detach_gadget(), eth_get_drvinfo(), and rx_submit(). Also use gether_set_gadget() in gether_setup_name() for consistency. Reported-by: Faqiang Zhu Fixes: e002e92e88e1 ("usb: gadget: u_ether: Fix NULL pointer deref in eth_g= et_drvinfo") Fixes: ec35c1969650 ("usb: gadget: f_ncm: Fix net_device lifecycle with dev= ice_move") Cc: stable@vger.kernel.org Assisted-by: LLM Signed-off-by: Kuen-Han Tsai --- drivers/usb/gadget/function/u_ether.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/fun= ction/u_ether.c index 043b4ec80808..2a9ae598e612 100644 --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -54,8 +55,7 @@ #define GETHER_MAX_ETH_FRAME_LEN (GETHER_MAX_MTU_SIZE + ETH_HLEN) =20 struct eth_dev { - /* lock is held while accessing port_usb - */ + /* lock is held while accessing port_usb and gadget */ spinlock_t lock; struct gether *port_usb; =20 @@ -113,6 +113,8 @@ static void eth_get_drvinfo(struct net_device *net, str= uct ethtool_drvinfo *p) =20 strscpy(p->driver, "g_ether", sizeof(p->driver)); strscpy(p->version, UETH__VERSION, sizeof(p->version)); + + guard(spinlock_irqsave)(&dev->lock); if (dev->gadget) { strscpy(p->fw_version, dev->gadget->name, sizeof(p->fw_version)); strscpy(p->bus_info, dev_name(&dev->gadget->dev), sizeof(p->bus_info)); @@ -145,7 +147,7 @@ static void rx_complete(struct usb_ep *ep, struct usb_r= equest *req); static int rx_submit(struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags) { - struct usb_gadget *g =3D dev->gadget; + struct usb_gadget *g; struct sk_buff *skb; int retval =3D -ENOMEM; size_t size =3D 0; @@ -153,6 +155,7 @@ rx_submit(struct eth_dev *dev, struct usb_request *req,= gfp_t gfp_flags) unsigned long flags; =20 spin_lock_irqsave(&dev->lock, flags); + g =3D dev->gadget; if (dev->port_usb) out =3D dev->port_usb->out_ep; else @@ -788,8 +791,7 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g, net->min_mtu =3D ETH_HLEN; net->max_mtu =3D GETHER_MAX_MTU_SIZE; =20 - dev->gadget =3D g; - SET_NETDEV_DEV(net, &g->dev); + gether_set_gadget(net, g); SET_NETDEV_DEVTYPE(net, &gadget_type); =20 status =3D register_netdev(net); @@ -890,10 +892,11 @@ EXPORT_SYMBOL_GPL(gether_register_netdev); =20 void gether_set_gadget(struct net_device *net, struct usb_gadget *g) { - struct eth_dev *dev; + struct eth_dev *dev =3D netdev_priv(net); + + scoped_guard(spinlock_irqsave, &dev->lock) + dev->gadget =3D g; =20 - dev =3D netdev_priv(net); - dev->gadget =3D g; SET_NETDEV_DEV(net, &g->dev); } EXPORT_SYMBOL_GPL(gether_set_gadget); @@ -915,8 +918,10 @@ void gether_detach_gadget(struct net_device *net) { struct eth_dev *dev =3D netdev_priv(net); =20 + scoped_guard(spinlock_irqsave, &dev->lock) + dev->gadget =3D NULL; + device_move(&net->dev, NULL, DPM_ORDER_NONE); - dev->gadget =3D NULL; } EXPORT_SYMBOL_GPL(gether_detach_gadget); =20 --=20 2.55.0.1082.g2b9226bbc0-goog