[PATCH 6.12 260/567] hsr: hold rcu and dev lock for hsr_get_port_ndev

Greg Kroah-Hartman
2026-01-06T17:28:33Z

From: Hangbin Liu <liuhangbin@gmail.com>

[ Upstream commit 847748fc66d08a89135a74e29362a66ba4e3ab15 ]

hsr_get_port_ndev calls hsr_for_each_port, which need to hold rcu lock.
On the other hand, before return the port device, we need to hold the
device reference to avoid UaF in the caller function.

Suggested-by: Paolo Abeni <pabeni@redhat.com>
Fixes: 9c10dd8eed74 ("net: hsr: Create and export hsr_get_port_ndev()")
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20250905091533.377443-4-liuhangbin@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
[ Drop multicast filtering changes ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/hsr/hsr_device.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)

--- a/net/hsr/hsr_device.c
+++ b/net/hsr/hsr_device.c
@@ -682,9 +682,14 @@ struct net_device *hsr_get_port_ndev(str
struct hsr_priv *hsr = netdev_priv(ndev);
struct hsr_port *port;

+ rcu_read_lock();
hsr_for_each_port(hsr, port)
- if (port->type == pt)
+ if (port->type == pt) {
+ dev_hold(port->dev);
+ rcu_read_unlock();
return port->dev;
+ }
+ rcu_read_unlock();
return NULL;
}
EXPORT_SYMBOL(hsr_get_port_ndev);