Skip to content

Commit f7c4e3e

Browse files
edumazetklassert
authored andcommitted
xfrm: interface: use DEV_STATS_INC()
syzbot/KCSAN reported data-races in xfrm whenever dev->stats fields are updated. It appears all of these updates can happen from multiple cpus. Adopt SMP safe DEV_STATS_INC() to update dev->stats fields. BUG: KCSAN: data-race in xfrmi_xmit / xfrmi_xmit read-write to 0xffff88813726b160 of 8 bytes by task 23986 on cpu 1: xfrmi_xmit+0x74e/0xb20 net/xfrm/xfrm_interface_core.c:583 __netdev_start_xmit include/linux/netdevice.h:4889 [inline] netdev_start_xmit include/linux/netdevice.h:4903 [inline] xmit_one net/core/dev.c:3544 [inline] dev_hard_start_xmit+0x11b/0x3f0 net/core/dev.c:3560 __dev_queue_xmit+0xeee/0x1de0 net/core/dev.c:4340 dev_queue_xmit include/linux/netdevice.h:3082 [inline] neigh_connected_output+0x231/0x2a0 net/core/neighbour.c:1581 neigh_output include/net/neighbour.h:542 [inline] ip_finish_output2+0x74a/0x850 net/ipv4/ip_output.c:230 ip_finish_output+0xf4/0x240 net/ipv4/ip_output.c:318 NF_HOOK_COND include/linux/netfilter.h:293 [inline] ip_output+0xe5/0x1b0 net/ipv4/ip_output.c:432 dst_output include/net/dst.h:458 [inline] ip_local_out net/ipv4/ip_output.c:127 [inline] ip_send_skb+0x72/0xe0 net/ipv4/ip_output.c:1487 udp_send_skb+0x6a4/0x990 net/ipv4/udp.c:963 udp_sendmsg+0x1249/0x12d0 net/ipv4/udp.c:1246 inet_sendmsg+0x63/0x80 net/ipv4/af_inet.c:840 sock_sendmsg_nosec net/socket.c:730 [inline] sock_sendmsg net/socket.c:753 [inline] ____sys_sendmsg+0x37c/0x4d0 net/socket.c:2540 ___sys_sendmsg net/socket.c:2594 [inline] __sys_sendmmsg+0x269/0x500 net/socket.c:2680 __do_sys_sendmmsg net/socket.c:2709 [inline] __se_sys_sendmmsg net/socket.c:2706 [inline] __x64_sys_sendmmsg+0x57/0x60 net/socket.c:2706 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd read-write to 0xffff88813726b160 of 8 bytes by task 23987 on cpu 0: xfrmi_xmit+0x74e/0xb20 net/xfrm/xfrm_interface_core.c:583 __netdev_start_xmit include/linux/netdevice.h:4889 [inline] netdev_start_xmit include/linux/netdevice.h:4903 [inline] xmit_one net/core/dev.c:3544 [inline] dev_hard_start_xmit+0x11b/0x3f0 net/core/dev.c:3560 __dev_queue_xmit+0xeee/0x1de0 net/core/dev.c:4340 dev_queue_xmit include/linux/netdevice.h:3082 [inline] neigh_connected_output+0x231/0x2a0 net/core/neighbour.c:1581 neigh_output include/net/neighbour.h:542 [inline] ip_finish_output2+0x74a/0x850 net/ipv4/ip_output.c:230 ip_finish_output+0xf4/0x240 net/ipv4/ip_output.c:318 NF_HOOK_COND include/linux/netfilter.h:293 [inline] ip_output+0xe5/0x1b0 net/ipv4/ip_output.c:432 dst_output include/net/dst.h:458 [inline] ip_local_out net/ipv4/ip_output.c:127 [inline] ip_send_skb+0x72/0xe0 net/ipv4/ip_output.c:1487 udp_send_skb+0x6a4/0x990 net/ipv4/udp.c:963 udp_sendmsg+0x1249/0x12d0 net/ipv4/udp.c:1246 inet_sendmsg+0x63/0x80 net/ipv4/af_inet.c:840 sock_sendmsg_nosec net/socket.c:730 [inline] sock_sendmsg net/socket.c:753 [inline] ____sys_sendmsg+0x37c/0x4d0 net/socket.c:2540 ___sys_sendmsg net/socket.c:2594 [inline] __sys_sendmmsg+0x269/0x500 net/socket.c:2680 __do_sys_sendmmsg net/socket.c:2709 [inline] __se_sys_sendmmsg net/socket.c:2706 [inline] __x64_sys_sendmmsg+0x57/0x60 net/socket.c:2706 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd value changed: 0x00000000000010d7 -> 0x00000000000010d8 Reported by Kernel Concurrency Sanitizer on: CPU: 0 PID: 23987 Comm: syz-executor.5 Not tainted 6.5.0-syzkaller-10885-g0468be89b3fa #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/26/2023 Fixes: f203b76 ("xfrm: Add virtual xfrm interfaces") Reported-by: syzbot <syzkaller@googlegroups.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Steffen Klassert <steffen.klassert@secunet.com> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
1 parent 6d41d4f commit f7c4e3e

1 file changed

Lines changed: 10 additions & 12 deletions

File tree

net/xfrm/xfrm_interface_core.c

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -380,8 +380,8 @@ static int xfrmi_rcv_cb(struct sk_buff *skb, int err)
380380
skb->dev = dev;
381381

382382
if (err) {
383-
dev->stats.rx_errors++;
384-
dev->stats.rx_dropped++;
383+
DEV_STATS_INC(dev, rx_errors);
384+
DEV_STATS_INC(dev, rx_dropped);
385385

386386
return 0;
387387
}
@@ -426,7 +426,6 @@ static int
426426
xfrmi_xmit2(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
427427
{
428428
struct xfrm_if *xi = netdev_priv(dev);
429-
struct net_device_stats *stats = &xi->dev->stats;
430429
struct dst_entry *dst = skb_dst(skb);
431430
unsigned int length = skb->len;
432431
struct net_device *tdev;
@@ -473,7 +472,7 @@ xfrmi_xmit2(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
473472
tdev = dst->dev;
474473

475474
if (tdev == dev) {
476-
stats->collisions++;
475+
DEV_STATS_INC(dev, collisions);
477476
net_warn_ratelimited("%s: Local routing loop detected!\n",
478477
dev->name);
479478
goto tx_err_dst_release;
@@ -512,13 +511,13 @@ xfrmi_xmit2(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
512511
if (net_xmit_eval(err) == 0) {
513512
dev_sw_netstats_tx_add(dev, 1, length);
514513
} else {
515-
stats->tx_errors++;
516-
stats->tx_aborted_errors++;
514+
DEV_STATS_INC(dev, tx_errors);
515+
DEV_STATS_INC(dev, tx_aborted_errors);
517516
}
518517

519518
return 0;
520519
tx_err_link_failure:
521-
stats->tx_carrier_errors++;
520+
DEV_STATS_INC(dev, tx_carrier_errors);
522521
dst_link_failure(skb);
523522
tx_err_dst_release:
524523
dst_release(dst);
@@ -528,7 +527,6 @@ xfrmi_xmit2(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
528527
static netdev_tx_t xfrmi_xmit(struct sk_buff *skb, struct net_device *dev)
529528
{
530529
struct xfrm_if *xi = netdev_priv(dev);
531-
struct net_device_stats *stats = &xi->dev->stats;
532530
struct dst_entry *dst = skb_dst(skb);
533531
struct flowi fl;
534532
int ret;
@@ -545,7 +543,7 @@ static netdev_tx_t xfrmi_xmit(struct sk_buff *skb, struct net_device *dev)
545543
dst = ip6_route_output(dev_net(dev), NULL, &fl.u.ip6);
546544
if (dst->error) {
547545
dst_release(dst);
548-
stats->tx_carrier_errors++;
546+
DEV_STATS_INC(dev, tx_carrier_errors);
549547
goto tx_err;
550548
}
551549
skb_dst_set(skb, dst);
@@ -561,7 +559,7 @@ static netdev_tx_t xfrmi_xmit(struct sk_buff *skb, struct net_device *dev)
561559
fl.u.ip4.flowi4_flags |= FLOWI_FLAG_ANYSRC;
562560
rt = __ip_route_output_key(dev_net(dev), &fl.u.ip4);
563561
if (IS_ERR(rt)) {
564-
stats->tx_carrier_errors++;
562+
DEV_STATS_INC(dev, tx_carrier_errors);
565563
goto tx_err;
566564
}
567565
skb_dst_set(skb, &rt->dst);
@@ -580,8 +578,8 @@ static netdev_tx_t xfrmi_xmit(struct sk_buff *skb, struct net_device *dev)
580578
return NETDEV_TX_OK;
581579

582580
tx_err:
583-
stats->tx_errors++;
584-
stats->tx_dropped++;
581+
DEV_STATS_INC(dev, tx_errors);
582+
DEV_STATS_INC(dev, tx_dropped);
585583
kfree_skb(skb);
586584
return NETDEV_TX_OK;
587585
}

0 commit comments

Comments
 (0)