openvswitch: use RCU protection in ovs_vport_cmd_fill_info()
ovs_vport_cmd_fill_info() can be called without RTNL or RCU.
Use RCU protection and dev_net_rcu() to avoid potential UAF.
Fixes: 9354d45203
("openvswitch: reliable interface indentification in port dumps")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Link: https://patch.msgid.link/20250207135841.1948589-6-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
a42b69f692
commit
90b2f49a50
1 changed files with 9 additions and 3 deletions
|
@ -2101,6 +2101,7 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb,
|
|||
{
|
||||
struct ovs_header *ovs_header;
|
||||
struct ovs_vport_stats vport_stats;
|
||||
struct net *net_vport;
|
||||
int err;
|
||||
|
||||
ovs_header = genlmsg_put(skb, portid, seq, &dp_vport_genl_family,
|
||||
|
@ -2117,12 +2118,15 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb,
|
|||
nla_put_u32(skb, OVS_VPORT_ATTR_IFINDEX, vport->dev->ifindex))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (!net_eq(net, dev_net(vport->dev))) {
|
||||
int id = peernet2id_alloc(net, dev_net(vport->dev), gfp);
|
||||
rcu_read_lock();
|
||||
net_vport = dev_net_rcu(vport->dev);
|
||||
if (!net_eq(net, net_vport)) {
|
||||
int id = peernet2id_alloc(net, net_vport, GFP_ATOMIC);
|
||||
|
||||
if (nla_put_s32(skb, OVS_VPORT_ATTR_NETNSID, id))
|
||||
goto nla_put_failure;
|
||||
goto nla_put_failure_unlock;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
ovs_vport_get_stats(vport, &vport_stats);
|
||||
if (nla_put_64bit(skb, OVS_VPORT_ATTR_STATS,
|
||||
|
@ -2143,6 +2147,8 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb,
|
|||
genlmsg_end(skb, ovs_header);
|
||||
return 0;
|
||||
|
||||
nla_put_failure_unlock:
|
||||
rcu_read_unlock();
|
||||
nla_put_failure:
|
||||
err = -EMSGSIZE;
|
||||
error:
|
||||
|
|
Loading…
Add table
Reference in a new issue