mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
net: rmnet: annotate data-races around mux_id
priv->mux_id is written under RTNL from rmnet_vnd_newlink() and rmnet_changelink(), but rmnet_egress_handler() reads it from the transmit path without any lock. Likewise ep->mux_id is written under RTNL from rmnet_changelink(), while rmnet_get_endpoint() reads it from the receive path under RCU only. Add the missing READ_ONCE()/WRITE_ONCE() annotations. While at it, publish ep->mux_id before inserting the endpoint in its new bucket in rmnet_changelink(). Otherwise a concurrent rmnet_get_endpoint() walking the new bucket could find the endpoint still carrying its old mux_id, and drop the packet. Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Sean Tranchetti <sean.tranchetti@oss.qualcomm.com> Reviewed-by: Subash Abhinov Kasiviswanathan <subash.a.kasiviswanathan@oss.qualcomm.com> Link: https://patch.msgid.link/20260916132231.1780091-3-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
c863bf6a7d
commit
0067187dbe
|
|
@ -337,11 +337,11 @@ static int rmnet_changelink(struct net_device *dev, struct nlattr *tb[],
|
|||
}
|
||||
|
||||
hlist_del_init_rcu(&ep->hlnode);
|
||||
WRITE_ONCE(ep->mux_id, mux_id);
|
||||
hlist_add_head_rcu(&ep->hlnode,
|
||||
&port->muxed_ep[mux_id]);
|
||||
|
||||
ep->mux_id = mux_id;
|
||||
priv->mux_id = mux_id;
|
||||
WRITE_ONCE(priv->mux_id, mux_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -433,7 +433,7 @@ struct rmnet_endpoint *rmnet_get_endpoint(struct rmnet_port *port, u8 mux_id)
|
|||
|
||||
hlist_for_each_entry_rcu(ep, &port->muxed_ep[mux_id], hlnode,
|
||||
lockdep_rtnl_is_held()) {
|
||||
if (ep->mux_id == mux_id)
|
||||
if (READ_ONCE(ep->mux_id) == mux_id)
|
||||
return ep;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -261,7 +261,7 @@ void rmnet_egress_handler(struct sk_buff *skb)
|
|||
orig_dev = skb->dev;
|
||||
priv = netdev_priv(orig_dev);
|
||||
skb->dev = priv->real_dev;
|
||||
mux_id = priv->mux_id;
|
||||
mux_id = READ_ONCE(priv->mux_id);
|
||||
|
||||
port = rmnet_get_port_rcu(skb->dev);
|
||||
if (!port)
|
||||
|
|
|
|||
|
|
@ -341,7 +341,7 @@ int rmnet_vnd_newlink(u8 id, struct net_device *rmnet_dev,
|
|||
|
||||
rmnet_dev->rtnl_link_ops = &rmnet_link_ops;
|
||||
|
||||
priv->mux_id = id;
|
||||
WRITE_ONCE(priv->mux_id, id);
|
||||
|
||||
netdev_dbg(rmnet_dev, "rmnet dev created\n");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user