diff options
| author | Jakub Kicinski <[email protected]> | 2025-04-08 19:59:48 +0000 |
|---|---|---|
| committer | Jakub Kicinski <[email protected]> | 2025-04-10 00:01:51 +0000 |
| commit | a82dc19db13649aa4232ce37cb6f4ceff851e2fe (patch) | |
| tree | 1c0351ac95b54efb6cfe7fd9f5ae598bb12a6fb6 /net/core/dev.h | |
| parent | net: Drop unused @sk of __skb_try_recv_from_queue() (diff) | |
| download | kernel-a82dc19db13649aa4232ce37cb6f4ceff851e2fe.tar.gz kernel-a82dc19db13649aa4232ce37cb6f4ceff851e2fe.zip | |
net: avoid potential race between netdev_get_by_index_lock() and netns switch
netdev_get_by_index_lock() performs following steps:
rcu_lock();
dev = lookup(netns, ifindex);
dev_get(dev);
rcu_unlock();
[... lock & validate the dev ...]
return dev
Validation right now only checks if the device is registered but since
the lookup is netns-aware we must also protect against the device
switching netns right after we dropped the RCU lock. Otherwise
the caller in netns1 may get a pointer to a device which has just
switched to netns2.
We can't hold the lock for the entire netns change process (because of
the NETDEV_UNREGISTER notifier), and there's no existing marking to
indicate that the netns is unlisted because of netns move, so add one.
AFAIU none of the existing netdev_get_by_index_lock() callers can
suffer from this problem (NAPI code double checks the netns membership
and other callers are either under rtnl_lock or not ns-sensitive),
so this patch does not have to be treated as a fix.
Reviewed-by: Joe Damato <[email protected]>
Acked-by: Stanislav Fomichev <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
Diffstat (limited to 'net/core/dev.h')
| -rw-r--r-- | net/core/dev.h | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/net/core/dev.h b/net/core/dev.h index 710abc05ebdb..e7bf21f52fc7 100644 --- a/net/core/dev.h +++ b/net/core/dev.h @@ -30,7 +30,7 @@ netdev_napi_by_id_lock(struct net *net, unsigned int napi_id); struct net_device *dev_get_by_napi_id(unsigned int napi_id); struct net_device *netdev_get_by_index_lock(struct net *net, int ifindex); -struct net_device *__netdev_put_lock(struct net_device *dev); +struct net_device *__netdev_put_lock(struct net_device *dev, struct net *net); struct net_device * netdev_xa_find_lock(struct net *net, struct net_device *dev, unsigned long *index); |
