mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH net v2] net-sysfs: release queue trackers before allowing reuse
@ 2026-09-30 18:11 Chengfeng Ye
  2026-09-30 18:14 ` netdev-bot+sinfo
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Chengfeng Ye @ 2026-09-30 18:11 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Mark Brown, Christian Brauner, Antoine Tenart
  Cc: netdev, linux-kernel, Chengfeng Ye, stable

An interrupted sysfs_rtnl_lock() can drop the last kobject reference to a
removed TX queue without holding RTNL. netdev_queue_release() clears the
kobject before releasing queue->dev_tracker, allowing the queue to be
re-added while the old release still needs the shared tracker slot:

  CPU 0                               CPU 1
  netdev_queue_release()
    memset(kobj, 0, sizeof(*kobj))
                                      netdev_queue_add_kobject()
                                        state_initialized is clear
                                        netdev_hold() installs new tracker
    netdev_put() releases the new tracker

With CONFIG_NET_DEV_REFCNT_TRACKER enabled, the old tracker is leaked and
the new lifetime's tracker is released prematurely. A later queue release
then reports a double release. The numeric device references remain
balanced.

The kernel reported:

  ref_tracker: reference already released.
  ref_tracker: allocated in:
   netdev_queue_update_kobjects+0x23d/0x5c0
   netif_set_real_num_tx_queues+0x111/0x820
   veth_set_channels+0x327/0x930
   ethtool_set_channels+0x3ee/0x490
  ref_tracker: freed in:
   netdev_queue_release+0xbd/0x130
   kobject_put+0x1f9/0x280
   sysfs_rtnl_lock+0x18b/0x1f0
   xps_rxqs_show+0xad/0x250
  WARNING: lib/ref_tracker.c:322 at ref_tracker_free+0x49e/0x6d0
  Call Trace:
   netdev_queue_release+0xbd/0x130
   kobject_put+0x1f9/0x280
   netdev_queue_update_kobjects+0x3f9/0x5c0
   netif_set_real_num_tx_queues+0x111/0x820
   veth_set_channels+0x327/0x930
   ethtool_set_channels+0x3ee/0x490

RX queues have the same ordering. Their removal and re-addition are
normally serialized by RTNL, but CONFIG_DEBUG_KOBJECT_RELEASE can defer the
release callback to workqueue context and expose the same reuse window.

Release each tracker before clearing its kobject. Pair full memory barriers
on the release and add sides so that an add which observes
state_initialized clear cannot install a new tracker before the old release
has finished accessing the shared tracker slot. Keep the numeric device
reference until after the reset so that the queue storage remains alive
throughout the callback's accesses.

Fixes: b0b6fcfa6ad8 ("net-sysfs: remove rtnl_trylock from queue attributes")
Cc: stable@vger.kernel.org
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
---
Changes in v2:
- Add an explicit full memory barrier in the TX add path, paired with the
  release-side barrier.
- Apply the same tracker ordering and barrier pair to RX queues, whose
  release callback may be delayed with CONFIG_DEBUG_KOBJECT_RELEASE.
- Clarify the paired barrier comments.

Link: https://lore.kernel.org/r/20260926173315.2452612-1-nicoyip.dev@gmail.com/ [v1]

 net/core/net-sysfs.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 352173df7578..2af972f5d3c3 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -1156,8 +1156,11 @@ static void rx_queue_release(struct kobject *kobj)
 		kvfree_rcu_mightsleep(rps_tag_to_table(tag_ptr));
 #endif
 
+	netdev_tracker_free(queue->dev, &queue->dev_tracker);
+	/* Pairs with the smp_mb() in rx_queue_add_kobject(). */
+	smp_mb();
 	memset(kobj, 0, sizeof(*kobj));
-	netdev_put(queue->dev, &queue->dev_tracker);
+	__dev_put(queue->dev);
 }
 
 static const struct ns_common *rx_queue_namespace(const struct kobject *kobj)
@@ -1230,6 +1233,9 @@ static int rx_queue_add_kobject(struct net_device *dev, int index)
 		return -EAGAIN;
 	}
 
+	/* Pairs with the smp_mb() in rx_queue_release(). */
+	smp_mb();
+
 	/* Kobject_put later will trigger rx_queue_release call which
 	 * decreases dev refcount: Take that reference here
 	 */
@@ -1906,8 +1912,11 @@ static void netdev_queue_release(struct kobject *kobj)
 {
 	struct netdev_queue *queue = to_netdev_queue(kobj);
 
+	netdev_tracker_free(queue->dev, &queue->dev_tracker);
+	/* Pairs with the smp_mb() in netdev_queue_add_kobject(). */
+	smp_mb();
 	memset(kobj, 0, sizeof(*kobj));
-	netdev_put(queue->dev, &queue->dev_tracker);
+	__dev_put(queue->dev);
 }
 
 static const struct ns_common *netdev_queue_namespace(const struct kobject *kobj)
@@ -1967,6 +1976,9 @@ static int netdev_queue_add_kobject(struct net_device *dev, int index)
 		return -EAGAIN;
 	}
 
+	/* Pairs with the smp_mb() in netdev_queue_release(). */
+	smp_mb();
+
 	/* Kobject_put later will trigger netdev_queue_release call
 	 * which decreases dev refcount: Take that reference here
 	 */
-- 
2.43.0

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH net v2] net-sysfs: release queue trackers before allowing reuse
  2026-09-30 18:11 [PATCH net v2] net-sysfs: release queue trackers before allowing reuse Chengfeng Ye
@ 2026-09-30 18:14 ` netdev-bot+sinfo
  2026-09-30 19:19 ` Eric Dumazet
  2026-10-01  8:08 ` Antoine Tenart
  2 siblings, 0 replies; 4+ messages in thread
From: netdev-bot+sinfo @ 2026-09-30 18:14 UTC (permalink / raw)
  To: Chengfeng Ye
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Mark Brown, Christian Brauner, Antoine Tenart,
	netdev, linux-kernel, stable

Hi!

This is an automated message. This series looks like a fix, but its
commit messages seem to be missing some information:

 - How the issue was discovered, e.g. hit in production, hit during
   development, syzbot report, manual code inspection, LLM or static
   analysis tool scan.

Please do not repost the series just to address the above. Instead,
reply to this email with the missing information, so that reviewers
can take it into account. If the series needs another revision for
other reasons, please include the information in the commit messages
then.

The evaluation is done by an LLM so it may be wrong, if you think
that is the case please reply and explain.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH net v2] net-sysfs: release queue trackers before allowing reuse
  2026-09-30 18:11 [PATCH net v2] net-sysfs: release queue trackers before allowing reuse Chengfeng Ye
  2026-09-30 18:14 ` netdev-bot+sinfo
@ 2026-09-30 19:19 ` Eric Dumazet
  2026-10-01  8:08 ` Antoine Tenart
  2 siblings, 0 replies; 4+ messages in thread
From: Eric Dumazet @ 2026-09-30 19:19 UTC (permalink / raw)
  To: Chengfeng Ye
  Cc: David S. Miller, Jakub Kicinski, Paolo Abeni, Simon Horman,
	Mark Brown, Christian Brauner, Antoine Tenart, netdev,
	linux-kernel, stable

On Wed, Sep 30, 2026 at 8:11 PM Chengfeng Ye <nicoyip.dev@gmail.com> wrote:
>
> An interrupted sysfs_rtnl_lock() can drop the last kobject reference to a
> removed TX queue without holding RTNL. netdev_queue_release() clears the
> kobject before releasing queue->dev_tracker, allowing the queue to be
> re-added while the old release still needs the shared tracker slot:
>
>
> RX queues have the same ordering. Their removal and re-addition are
> normally serialized by RTNL, but CONFIG_DEBUG_KOBJECT_RELEASE can defer the
> release callback to workqueue context and expose the same reuse window.
>
> Release each tracker before clearing its kobject. Pair full memory barriers
> on the release and add sides so that an add which observes
> state_initialized clear cannot install a new tracker before the old release
> has finished accessing the shared tracker slot. Keep the numeric device
> reference until after the reset so that the queue storage remains alive
> throughout the callback's accesses.
>
> Fixes: b0b6fcfa6ad8 ("net-sysfs: remove rtnl_trylock from queue attributes")
> Cc: stable@vger.kernel.org
> Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>

Reviewed-by: Eric Dumazet <edumazet@kernel.org>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH net v2] net-sysfs: release queue trackers before allowing reuse
  2026-09-30 18:11 [PATCH net v2] net-sysfs: release queue trackers before allowing reuse Chengfeng Ye
  2026-09-30 18:14 ` netdev-bot+sinfo
  2026-09-30 19:19 ` Eric Dumazet
@ 2026-10-01  8:08 ` Antoine Tenart
  2 siblings, 0 replies; 4+ messages in thread
From: Antoine Tenart @ 2026-10-01  8:08 UTC (permalink / raw)
  To: Chengfeng Ye
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Mark Brown, Christian Brauner, netdev,
	linux-kernel, stable

On Thu, Oct 01, 2026 at 02:11:06AM +0800, Chengfeng Ye wrote:
> An interrupted sysfs_rtnl_lock() can drop the last kobject reference to a
> removed TX queue without holding RTNL. netdev_queue_release() clears the
> kobject before releasing queue->dev_tracker, allowing the queue to be
> re-added while the old release still needs the shared tracker slot:
> 
>   CPU 0                               CPU 1
>   netdev_queue_release()
>     memset(kobj, 0, sizeof(*kobj))
>                                       netdev_queue_add_kobject()
>                                         state_initialized is clear
>                                         netdev_hold() installs new tracker
>     netdev_put() releases the new tracker
> 
> With CONFIG_NET_DEV_REFCNT_TRACKER enabled, the old tracker is leaked and
> the new lifetime's tracker is released prematurely. A later queue release
> then reports a double release. The numeric device references remain
> balanced.
> 
> The kernel reported:
> 
>   ref_tracker: reference already released.
>   ref_tracker: allocated in:
>    netdev_queue_update_kobjects+0x23d/0x5c0
>    netif_set_real_num_tx_queues+0x111/0x820
>    veth_set_channels+0x327/0x930
>    ethtool_set_channels+0x3ee/0x490
>   ref_tracker: freed in:
>    netdev_queue_release+0xbd/0x130
>    kobject_put+0x1f9/0x280
>    sysfs_rtnl_lock+0x18b/0x1f0
>    xps_rxqs_show+0xad/0x250
>   WARNING: lib/ref_tracker.c:322 at ref_tracker_free+0x49e/0x6d0
>   Call Trace:
>    netdev_queue_release+0xbd/0x130
>    kobject_put+0x1f9/0x280
>    netdev_queue_update_kobjects+0x3f9/0x5c0
>    netif_set_real_num_tx_queues+0x111/0x820
>    veth_set_channels+0x327/0x930
>    ethtool_set_channels+0x3ee/0x490
> 
> RX queues have the same ordering. Their removal and re-addition are
> normally serialized by RTNL, but CONFIG_DEBUG_KOBJECT_RELEASE can defer the
> release callback to workqueue context and expose the same reuse window.
> 
> Release each tracker before clearing its kobject. Pair full memory barriers
> on the release and add sides so that an add which observes
> state_initialized clear cannot install a new tracker before the old release
> has finished accessing the shared tracker slot. Keep the numeric device
> reference until after the reset so that the queue storage remains alive
> throughout the callback's accesses.
> 
> Fixes: b0b6fcfa6ad8 ("net-sysfs: remove rtnl_trylock from queue attributes")
> Cc: stable@vger.kernel.org
> Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>

Reviewed-by: Antoine Tenart <atenart@kernel.org>

> ---
> Changes in v2:
> - Add an explicit full memory barrier in the TX add path, paired with the
>   release-side barrier.
> - Apply the same tracker ordering and barrier pair to RX queues, whose
>   release callback may be delayed with CONFIG_DEBUG_KOBJECT_RELEASE.
> - Clarify the paired barrier comments.
> 
> Link: https://lore.kernel.org/r/20260926173315.2452612-1-nicoyip.dev@gmail.com/ [v1]
> 
>  net/core/net-sysfs.c | 16 ++++++++++++++--
>  1 file changed, 14 insertions(+), 2 deletions(-)
> 
> diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
> index 352173df7578..2af972f5d3c3 100644
> --- a/net/core/net-sysfs.c
> +++ b/net/core/net-sysfs.c
> @@ -1156,8 +1156,11 @@ static void rx_queue_release(struct kobject *kobj)
>  		kvfree_rcu_mightsleep(rps_tag_to_table(tag_ptr));
>  #endif
>  
> +	netdev_tracker_free(queue->dev, &queue->dev_tracker);
> +	/* Pairs with the smp_mb() in rx_queue_add_kobject(). */
> +	smp_mb();
>  	memset(kobj, 0, sizeof(*kobj));
> -	netdev_put(queue->dev, &queue->dev_tracker);
> +	__dev_put(queue->dev);
>  }
>  
>  static const struct ns_common *rx_queue_namespace(const struct kobject *kobj)
> @@ -1230,6 +1233,9 @@ static int rx_queue_add_kobject(struct net_device *dev, int index)
>  		return -EAGAIN;
>  	}
>  
> +	/* Pairs with the smp_mb() in rx_queue_release(). */
> +	smp_mb();
> +
>  	/* Kobject_put later will trigger rx_queue_release call which
>  	 * decreases dev refcount: Take that reference here
>  	 */
> @@ -1906,8 +1912,11 @@ static void netdev_queue_release(struct kobject *kobj)
>  {
>  	struct netdev_queue *queue = to_netdev_queue(kobj);
>  
> +	netdev_tracker_free(queue->dev, &queue->dev_tracker);
> +	/* Pairs with the smp_mb() in netdev_queue_add_kobject(). */
> +	smp_mb();
>  	memset(kobj, 0, sizeof(*kobj));
> -	netdev_put(queue->dev, &queue->dev_tracker);
> +	__dev_put(queue->dev);
>  }
>  
>  static const struct ns_common *netdev_queue_namespace(const struct kobject *kobj)
> @@ -1967,6 +1976,9 @@ static int netdev_queue_add_kobject(struct net_device *dev, int index)
>  		return -EAGAIN;
>  	}
>  
> +	/* Pairs with the smp_mb() in netdev_queue_release(). */
> +	smp_mb();
> +
>  	/* Kobject_put later will trigger netdev_queue_release call
>  	 * which decreases dev refcount: Take that reference here
>  	 */
> -- 
> 2.43.0

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-10-01  8:08 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-30 18:11 [PATCH net v2] net-sysfs: release queue trackers before allowing reuse Chengfeng Ye
2026-09-30 18:14 ` netdev-bot+sinfo
2026-09-30 19:19 ` Eric Dumazet
2026-10-01  8:08 ` Antoine Tenart

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®