[PATCH net] net: fix potential out-of-bound access in set_rps_cpu()
From: Eric Dumazet <edumazet@google.com>
Date: 2026-02-20 14:43:46
Subsystem:
networking [general], the rest · Maintainers:
"David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
Blamed commit forgot that set_rps_cpu() was reloading
rxqueue->rps_flow_table.
If this pointer has changed between get_rps_cpu() read it initially,
and the new table size is smaller than @flow_id,
we can access out-of-bound data and either corrupt memory or crash.
Fix this by passing the flow_table pointer from get_rps_cpu()
to set_rps_cpu(), more in line with RCU rules.
Fixes: 48aa30443e52 ("net: Cache hash and flow_id to avoid recalculation")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Krishna Kumar <redacted>
---
net/core/dev.c | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index 096b3ff13f6b9bf685cb74d0e762a2b00e97d9de..7c5e69c771caf7fd590e602384be49019853b490 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c@@ -4993,13 +4993,11 @@ static bool rps_flow_is_active(struct rps_dev_flow *rflow, static struct rps_dev_flow * set_rps_cpu(struct net_device *dev, struct sk_buff *skb, struct rps_dev_flow *rflow, u16 next_cpu, u32 hash, - u32 flow_id) + u32 flow_id, struct rps_dev_flow_table *flow_table) { if (next_cpu < nr_cpu_ids) { u32 head; #ifdef CONFIG_RFS_ACCEL - struct netdev_rx_queue *rxqueue; - struct rps_dev_flow_table *flow_table; struct rps_dev_flow *old_rflow; struct rps_dev_flow *tmp_rflow; unsigned int tmp_cpu;
@@ -5014,11 +5012,6 @@ set_rps_cpu(struct net_device *dev, struct sk_buff *skb, if (rxq_index == skb_get_rx_queue(skb)) goto out; - rxqueue = dev->_rx + rxq_index; - flow_table = rcu_dereference(rxqueue->rps_flow_table); - if (!flow_table) - goto out; - tmp_rflow = &flow_table->flows[flow_id]; tmp_cpu = READ_ONCE(tmp_rflow->cpu);
@@ -5134,7 +5127,7 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, rflow->last_qtail)) >= 0)) { tcpu = next_cpu; rflow = set_rps_cpu(dev, skb, rflow, next_cpu, hash, - flow_id); + flow_id, flow_table); } if (tcpu < nr_cpu_ids && cpu_online(tcpu)) {
--
2.53.0.345.g96ddfc5eaa-goog