summaryrefslogtreecommitdiffstats
path: root/net/devlink
diff options
context:
space:
mode:
authorJiri Pirko <jiri@nvidia.com>2023-10-13 14:10:24 +0200
committerDavid S. Miller <davem@davemloft.net>2023-10-18 09:23:01 +0100
commitc503bc7df602257e9d03851654a347649a33f3c3 (patch)
treebc45f05aa5587b0c10c8369949a3430d8267e3f5 /net/devlink
parent2034d90ae41ae93e30d492ebcf1f06f97a9cfba6 (diff)
downloadlinux-stable-c503bc7df602257e9d03851654a347649a33f3c3.tar.gz
linux-stable-c503bc7df602257e9d03851654a347649a33f3c3.tar.bz2
linux-stable-c503bc7df602257e9d03851654a347649a33f3c3.zip
devlink: call peernet2id_alloc() with net pointer under RCU read lock
peernet2id_alloc() allows to be called lockless with peer net pointer obtained in RCU critical section and makes sure to return ns ID if net namespaces is not being removed concurrently. Benefit from read_pnet_rcu() helper addition, use it to obtain net pointer under RCU read lock and pass it to peernet2id_alloc() to get ns ID. Fixes: c137743bce02 ("devlink: introduce object and nested devlink relationship infra") Signed-off-by: Jiri Pirko <jiri@nvidia.com> Reviewed-by: Simon Horman <horms@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/devlink')
-rw-r--r--net/devlink/netlink.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/net/devlink/netlink.c b/net/devlink/netlink.c
index 499304d9de49..809bfc3ba8c4 100644
--- a/net/devlink/netlink.c
+++ b/net/devlink/netlink.c
@@ -86,18 +86,24 @@ int devlink_nl_put_nested_handle(struct sk_buff *msg, struct net *net,
struct devlink *devlink, int attrtype)
{
struct nlattr *nested_attr;
+ struct net *devl_net;
nested_attr = nla_nest_start(msg, attrtype);
if (!nested_attr)
return -EMSGSIZE;
if (devlink_nl_put_handle(msg, devlink))
goto nla_put_failure;
- if (!net_eq(net, devlink_net(devlink))) {
- int id = peernet2id_alloc(net, devlink_net(devlink),
- GFP_KERNEL);
+ rcu_read_lock();
+ devl_net = read_pnet_rcu(&devlink->_net);
+ if (!net_eq(net, devl_net)) {
+ int id = peernet2id_alloc(net, devl_net, GFP_ATOMIC);
+
+ rcu_read_unlock();
if (nla_put_s32(msg, DEVLINK_ATTR_NETNS_ID, id))
return -EMSGSIZE;
+ } else {
+ rcu_read_unlock();
}
nla_nest_end(msg, nested_attr);