ipv6/sit: use DEV_STATS_INC() to avoid data-races
[ Upstream commit cb34b7cf17
]
syzbot/KCSAN reported that multiple cpus are updating dev->stats.tx_error
concurrently.
This is because sit tunnels are NETIF_F_LLTX, meaning their ndo_start_xmit()
is not protected by a spinlock.
While original KCSAN report was about tx path, rx path has the same issue.
Reported-by: syzbot <syzkaller@googlegroups.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
9921d1b68c
commit
207501a986
|
@ -694,7 +694,7 @@ static int ipip6_rcv(struct sk_buff *skb)
|
|||
skb->dev = tunnel->dev;
|
||||
|
||||
if (packet_is_spoofed(skb, iph, tunnel)) {
|
||||
tunnel->dev->stats.rx_errors++;
|
||||
DEV_STATS_INC(tunnel->dev, rx_errors);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -714,8 +714,8 @@ static int ipip6_rcv(struct sk_buff *skb)
|
|||
net_info_ratelimited("non-ECT from %pI4 with TOS=%#x\n",
|
||||
&iph->saddr, iph->tos);
|
||||
if (err > 1) {
|
||||
++tunnel->dev->stats.rx_frame_errors;
|
||||
++tunnel->dev->stats.rx_errors;
|
||||
DEV_STATS_INC(tunnel->dev, rx_frame_errors);
|
||||
DEV_STATS_INC(tunnel->dev, rx_errors);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
@ -942,7 +942,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
|
|||
if (!rt) {
|
||||
rt = ip_route_output_flow(tunnel->net, &fl4, NULL);
|
||||
if (IS_ERR(rt)) {
|
||||
dev->stats.tx_carrier_errors++;
|
||||
DEV_STATS_INC(dev, tx_carrier_errors);
|
||||
goto tx_error_icmp;
|
||||
}
|
||||
dst_cache_set_ip4(&tunnel->dst_cache, &rt->dst, fl4.saddr);
|
||||
|
@ -950,14 +950,14 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
|
|||
|
||||
if (rt->rt_type != RTN_UNICAST && rt->rt_type != RTN_LOCAL) {
|
||||
ip_rt_put(rt);
|
||||
dev->stats.tx_carrier_errors++;
|
||||
DEV_STATS_INC(dev, tx_carrier_errors);
|
||||
goto tx_error_icmp;
|
||||
}
|
||||
tdev = rt->dst.dev;
|
||||
|
||||
if (tdev == dev) {
|
||||
ip_rt_put(rt);
|
||||
dev->stats.collisions++;
|
||||
DEV_STATS_INC(dev, collisions);
|
||||
goto tx_error;
|
||||
}
|
||||
|
||||
|
@ -970,7 +970,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
|
|||
mtu = dst_mtu(&rt->dst) - t_hlen;
|
||||
|
||||
if (mtu < IPV4_MIN_MTU) {
|
||||
dev->stats.collisions++;
|
||||
DEV_STATS_INC(dev, collisions);
|
||||
ip_rt_put(rt);
|
||||
goto tx_error;
|
||||
}
|
||||
|
@ -1009,7 +1009,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
|
|||
struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
|
||||
if (!new_skb) {
|
||||
ip_rt_put(rt);
|
||||
dev->stats.tx_dropped++;
|
||||
DEV_STATS_INC(dev, tx_dropped);
|
||||
kfree_skb(skb);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
@ -1039,7 +1039,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
|
|||
dst_link_failure(skb);
|
||||
tx_error:
|
||||
kfree_skb(skb);
|
||||
dev->stats.tx_errors++;
|
||||
DEV_STATS_INC(dev, tx_errors);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
|
@ -1058,7 +1058,7 @@ static netdev_tx_t sit_tunnel_xmit__(struct sk_buff *skb,
|
|||
return NETDEV_TX_OK;
|
||||
tx_error:
|
||||
kfree_skb(skb);
|
||||
dev->stats.tx_errors++;
|
||||
DEV_STATS_INC(dev, tx_errors);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
|
@ -1087,7 +1087,7 @@ static netdev_tx_t sit_tunnel_xmit(struct sk_buff *skb,
|
|||
return NETDEV_TX_OK;
|
||||
|
||||
tx_err:
|
||||
dev->stats.tx_errors++;
|
||||
DEV_STATS_INC(dev, tx_errors);
|
||||
kfree_skb(skb);
|
||||
return NETDEV_TX_OK;
|
||||
|
||||
|
|
Loading…
Reference in New Issue