[PATCH] net: shaper: use kfree_rcu() in net_shaper_flush()

Subsystems: networking [general], the rest

STALE109d

2 messages, 2 authors, 2026-05-28 · open the first message on its own page

[PATCH] net: shaper: use kfree_rcu() in net_shaper_flush()

From: Tristan Madani <hidden>
Date: 2026-05-28 16:08:48

net_shaper_flush() frees shaper objects with plain kfree() after
xa_erase(), but net_shaper_nl_get_doit() and net_shaper_nl_get_dumpit()
read shaper objects under rcu_read_lock() via xa_load().  This creates a
use-after-free window where an RCU reader may still hold a pointer to a
shaper object that has been freed.

The race is:

  CPU 0 (reader)                    CPU 1 (flush/unregister)
  rcu_read_lock()
  shaper = xa_load(...)             xa_lock()
  // shaper points to valid obj     __xa_erase(...)
                                    kfree(shaper)  <- frees immediately
  net_shaper_fill_one(shaper)       xa_unlock()
  // use-after-free
  rcu_read_unlock()

Other code paths in the same file already use kfree_rcu() correctly
(net_shaper_pre_insert error path, net_shaper_notify_down,
net_shaper_cap_pair_update, and net_shaper_rollback as of commit
b8d7519352ba).  The struct net_shaper already contains an rcu_head field.

Fix by replacing kfree() with kfree_rcu() in net_shaper_flush() to
defer freeing until after the RCU grace period.

Found by source code audit.

Fixes: ff7d4deb1f3e ("net-shapers: implement shaper cleanup on queue deletion")
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: stable@vger.kernel.org
Signed-off-by: Tristan Madani <redacted>
---
 net/shaper/shaper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/shaper/shaper.c b/net/shaper/shaper.c
index dea9270f3e57d..92a6939787240 100644
--- a/net/shaper/shaper.c
+++ b/net/shaper/shaper.c
@@ -1475,7 +1475,7 @@ static void net_shaper_flush(struct net_shaper_binding *binding)
 	xa_lock(&hierarchy->shapers);
 	xa_for_each(&hierarchy->shapers, index, cur) {
 		__xa_erase(&hierarchy->shapers, index);
-		kfree(cur);
+		kfree_rcu(cur, rcu);
 	}
 	xa_unlock(&hierarchy->shapers);
 
-- 
2.47.3

Re: [PATCH] net: shaper: use kfree_rcu() in net_shaper_flush()

From: Jakub Kicinski <kuba@kernel.org>
Date: 2026-05-28 18:34:07

On Thu, 28 May 2026 16:08:45 +0000 Tristan Madani wrote:
net_shaper_flush() frees shaper objects with plain kfree() after
xa_erase(), but net_shaper_nl_get_doit() and net_shaper_nl_get_dumpit()
read shaper objects under rcu_read_lock() via xa_load().  This creates a
use-after-free window where an RCU reader may still hold a pointer to a
shaper object that has been freed.

The race is:

  CPU 0 (reader)                    CPU 1 (flush/unregister)
  rcu_read_lock()
  shaper = xa_load(...)             xa_lock()
  // shaper points to valid obj     __xa_erase(...)
                                    kfree(shaper)  <- frees immediately
  net_shaper_fill_one(shaper)       xa_unlock()
  // use-after-free
  rcu_read_unlock()

Other code paths in the same file already use kfree_rcu() correctly
(net_shaper_pre_insert error path, net_shaper_notify_down,
net_shaper_cap_pair_update, and net_shaper_rollback as of commit
b8d7519352ba).  The struct net_shaper already contains an rcu_head field.

Fix by replacing kfree() with kfree_rcu() in net_shaper_flush() to
defer freeing until after the RCU grace period.

Found by source code audit.
No, the device is fully invisible at this point.

Please don't send fixes unless you can actually trigger the crash.
-- 
pw-bot: reject
pv-bot: slop
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help