Patch "net: tunnels: annotate lockless accesses to dev->needed_headroom" has been added to the 5.10-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    net: tunnels: annotate lockless accesses to dev->needed_headroom

to the 5.10-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     net-tunnels-annotate-lockless-accesses-to-dev-needed.patch
and it can be found in the queue-5.10 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit bfabaf9785f04f7c546e3cd6f81ce39aa6986463
Author: Eric Dumazet <edumazet@xxxxxxxxxx>
Date:   Fri Mar 10 19:11:09 2023 +0000

    net: tunnels: annotate lockless accesses to dev->needed_headroom
    
    [ Upstream commit 4b397c06cb987935b1b097336532aa6b4210e091 ]
    
    IP tunnels can apparently update dev->needed_headroom
    in their xmit path.
    
    This patch takes care of three tunnels xmit, and also the
    core LL_RESERVED_SPACE() and LL_RESERVED_SPACE_EXTRA()
    helpers.
    
    More changes might be needed for completeness.
    
    BUG: KCSAN: data-race in ip_tunnel_xmit / ip_tunnel_xmit
    
    read to 0xffff88815b9da0ec of 2 bytes by task 888 on cpu 1:
    ip_tunnel_xmit+0x1270/0x1730 net/ipv4/ip_tunnel.c:803
    __gre_xmit net/ipv4/ip_gre.c:469 [inline]
    ipgre_xmit+0x516/0x570 net/ipv4/ip_gre.c:661
    __netdev_start_xmit include/linux/netdevice.h:4881 [inline]
    netdev_start_xmit include/linux/netdevice.h:4895 [inline]
    xmit_one net/core/dev.c:3580 [inline]
    dev_hard_start_xmit+0x127/0x400 net/core/dev.c:3596
    __dev_queue_xmit+0x1007/0x1eb0 net/core/dev.c:4246
    dev_queue_xmit include/linux/netdevice.h:3051 [inline]
    neigh_direct_output+0x17/0x20 net/core/neighbour.c:1623
    neigh_output include/net/neighbour.h:546 [inline]
    ip_finish_output2+0x740/0x840 net/ipv4/ip_output.c:228
    ip_finish_output+0xf4/0x240 net/ipv4/ip_output.c:316
    NF_HOOK_COND include/linux/netfilter.h:291 [inline]
    ip_output+0xe5/0x1b0 net/ipv4/ip_output.c:430
    dst_output include/net/dst.h:444 [inline]
    ip_local_out+0x64/0x80 net/ipv4/ip_output.c:126
    iptunnel_xmit+0x34a/0x4b0 net/ipv4/ip_tunnel_core.c:82
    ip_tunnel_xmit+0x1451/0x1730 net/ipv4/ip_tunnel.c:813
    __gre_xmit net/ipv4/ip_gre.c:469 [inline]
    ipgre_xmit+0x516/0x570 net/ipv4/ip_gre.c:661
    __netdev_start_xmit include/linux/netdevice.h:4881 [inline]
    netdev_start_xmit include/linux/netdevice.h:4895 [inline]
    xmit_one net/core/dev.c:3580 [inline]
    dev_hard_start_xmit+0x127/0x400 net/core/dev.c:3596
    __dev_queue_xmit+0x1007/0x1eb0 net/core/dev.c:4246
    dev_queue_xmit include/linux/netdevice.h:3051 [inline]
    neigh_direct_output+0x17/0x20 net/core/neighbour.c:1623
    neigh_output include/net/neighbour.h:546 [inline]
    ip_finish_output2+0x740/0x840 net/ipv4/ip_output.c:228
    ip_finish_output+0xf4/0x240 net/ipv4/ip_output.c:316
    NF_HOOK_COND include/linux/netfilter.h:291 [inline]
    ip_output+0xe5/0x1b0 net/ipv4/ip_output.c:430
    dst_output include/net/dst.h:444 [inline]
    ip_local_out+0x64/0x80 net/ipv4/ip_output.c:126
    iptunnel_xmit+0x34a/0x4b0 net/ipv4/ip_tunnel_core.c:82
    ip_tunnel_xmit+0x1451/0x1730 net/ipv4/ip_tunnel.c:813
    __gre_xmit net/ipv4/ip_gre.c:469 [inline]
    ipgre_xmit+0x516/0x570 net/ipv4/ip_gre.c:661
    __netdev_start_xmit include/linux/netdevice.h:4881 [inline]
    netdev_start_xmit include/linux/netdevice.h:4895 [inline]
    xmit_one net/core/dev.c:3580 [inline]
    dev_hard_start_xmit+0x127/0x400 net/core/dev.c:3596
    __dev_queue_xmit+0x1007/0x1eb0 net/core/dev.c:4246
    dev_queue_xmit include/linux/netdevice.h:3051 [inline]
    neigh_direct_output+0x17/0x20 net/core/neighbour.c:1623
    neigh_output include/net/neighbour.h:546 [inline]
    ip_finish_output2+0x740/0x840 net/ipv4/ip_output.c:228
    ip_finish_output+0xf4/0x240 net/ipv4/ip_output.c:316
    NF_HOOK_COND include/linux/netfilter.h:291 [inline]
    ip_output+0xe5/0x1b0 net/ipv4/ip_output.c:430
    dst_output include/net/dst.h:444 [inline]
    ip_local_out+0x64/0x80 net/ipv4/ip_output.c:126
    iptunnel_xmit+0x34a/0x4b0 net/ipv4/ip_tunnel_core.c:82
    ip_tunnel_xmit+0x1451/0x1730 net/ipv4/ip_tunnel.c:813
    __gre_xmit net/ipv4/ip_gre.c:469 [inline]
    ipgre_xmit+0x516/0x570 net/ipv4/ip_gre.c:661
    __netdev_start_xmit include/linux/netdevice.h:4881 [inline]
    netdev_start_xmit include/linux/netdevice.h:4895 [inline]
    xmit_one net/core/dev.c:3580 [inline]
    dev_hard_start_xmit+0x127/0x400 net/core/dev.c:3596
    __dev_queue_xmit+0x1007/0x1eb0 net/core/dev.c:4246
    dev_queue_xmit include/linux/netdevice.h:3051 [inline]
    neigh_direct_output+0x17/0x20 net/core/neighbour.c:1623
    neigh_output include/net/neighbour.h:546 [inline]
    ip_finish_output2+0x740/0x840 net/ipv4/ip_output.c:228
    ip_finish_output+0xf4/0x240 net/ipv4/ip_output.c:316
    NF_HOOK_COND include/linux/netfilter.h:291 [inline]
    ip_output+0xe5/0x1b0 net/ipv4/ip_output.c:430
    dst_output include/net/dst.h:444 [inline]
    ip_local_out+0x64/0x80 net/ipv4/ip_output.c:126
    iptunnel_xmit+0x34a/0x4b0 net/ipv4/ip_tunnel_core.c:82
    ip_tunnel_xmit+0x1451/0x1730 net/ipv4/ip_tunnel.c:813
    __gre_xmit net/ipv4/ip_gre.c:469 [inline]
    ipgre_xmit+0x516/0x570 net/ipv4/ip_gre.c:661
    __netdev_start_xmit include/linux/netdevice.h:4881 [inline]
    netdev_start_xmit include/linux/netdevice.h:4895 [inline]
    xmit_one net/core/dev.c:3580 [inline]
    dev_hard_start_xmit+0x127/0x400 net/core/dev.c:3596
    __dev_queue_xmit+0x1007/0x1eb0 net/core/dev.c:4246
    dev_queue_xmit include/linux/netdevice.h:3051 [inline]
    neigh_direct_output+0x17/0x20 net/core/neighbour.c:1623
    neigh_output include/net/neighbour.h:546 [inline]
    ip_finish_output2+0x740/0x840 net/ipv4/ip_output.c:228
    ip_finish_output+0xf4/0x240 net/ipv4/ip_output.c:316
    NF_HOOK_COND include/linux/netfilter.h:291 [inline]
    ip_output+0xe5/0x1b0 net/ipv4/ip_output.c:430
    dst_output include/net/dst.h:444 [inline]
    ip_local_out+0x64/0x80 net/ipv4/ip_output.c:126
    iptunnel_xmit+0x34a/0x4b0 net/ipv4/ip_tunnel_core.c:82
    ip_tunnel_xmit+0x1451/0x1730 net/ipv4/ip_tunnel.c:813
    __gre_xmit net/ipv4/ip_gre.c:469 [inline]
    ipgre_xmit+0x516/0x570 net/ipv4/ip_gre.c:661
    __netdev_start_xmit include/linux/netdevice.h:4881 [inline]
    netdev_start_xmit include/linux/netdevice.h:4895 [inline]
    xmit_one net/core/dev.c:3580 [inline]
    dev_hard_start_xmit+0x127/0x400 net/core/dev.c:3596
    __dev_queue_xmit+0x1007/0x1eb0 net/core/dev.c:4246
    dev_queue_xmit include/linux/netdevice.h:3051 [inline]
    neigh_direct_output+0x17/0x20 net/core/neighbour.c:1623
    neigh_output include/net/neighbour.h:546 [inline]
    ip_finish_output2+0x740/0x840 net/ipv4/ip_output.c:228
    ip_finish_output+0xf4/0x240 net/ipv4/ip_output.c:316
    NF_HOOK_COND include/linux/netfilter.h:291 [inline]
    ip_output+0xe5/0x1b0 net/ipv4/ip_output.c:430
    dst_output include/net/dst.h:444 [inline]
    ip_local_out+0x64/0x80 net/ipv4/ip_output.c:126
    iptunnel_xmit+0x34a/0x4b0 net/ipv4/ip_tunnel_core.c:82
    ip_tunnel_xmit+0x1451/0x1730 net/ipv4/ip_tunnel.c:813
    __gre_xmit net/ipv4/ip_gre.c:469 [inline]
    ipgre_xmit+0x516/0x570 net/ipv4/ip_gre.c:661
    __netdev_start_xmit include/linux/netdevice.h:4881 [inline]
    netdev_start_xmit include/linux/netdevice.h:4895 [inline]
    xmit_one net/core/dev.c:3580 [inline]
    dev_hard_start_xmit+0x127/0x400 net/core/dev.c:3596
    __dev_queue_xmit+0x1007/0x1eb0 net/core/dev.c:4246
    
    write to 0xffff88815b9da0ec of 2 bytes by task 2379 on cpu 0:
    ip_tunnel_xmit+0x1294/0x1730 net/ipv4/ip_tunnel.c:804
    __gre_xmit net/ipv4/ip_gre.c:469 [inline]
    ipgre_xmit+0x516/0x570 net/ipv4/ip_gre.c:661
    __netdev_start_xmit include/linux/netdevice.h:4881 [inline]
    netdev_start_xmit include/linux/netdevice.h:4895 [inline]
    xmit_one net/core/dev.c:3580 [inline]
    dev_hard_start_xmit+0x127/0x400 net/core/dev.c:3596
    __dev_queue_xmit+0x1007/0x1eb0 net/core/dev.c:4246
    dev_queue_xmit include/linux/netdevice.h:3051 [inline]
    neigh_direct_output+0x17/0x20 net/core/neighbour.c:1623
    neigh_output include/net/neighbour.h:546 [inline]
    ip6_finish_output2+0x9bc/0xc50 net/ipv6/ip6_output.c:134
    __ip6_finish_output net/ipv6/ip6_output.c:195 [inline]
    ip6_finish_output+0x39a/0x4e0 net/ipv6/ip6_output.c:206
    NF_HOOK_COND include/linux/netfilter.h:291 [inline]
    ip6_output+0xeb/0x220 net/ipv6/ip6_output.c:227
    dst_output include/net/dst.h:444 [inline]
    NF_HOOK include/linux/netfilter.h:302 [inline]
    mld_sendpack+0x438/0x6a0 net/ipv6/mcast.c:1820
    mld_send_cr net/ipv6/mcast.c:2121 [inline]
    mld_ifc_work+0x519/0x7b0 net/ipv6/mcast.c:2653
    process_one_work+0x3e6/0x750 kernel/workqueue.c:2390
    worker_thread+0x5f2/0xa10 kernel/workqueue.c:2537
    kthread+0x1ac/0x1e0 kernel/kthread.c:376
    ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:308
    
    value changed: 0x0dd4 -> 0x0e14
    
    Reported by Kernel Concurrency Sanitizer on:
    CPU: 0 PID: 2379 Comm: kworker/0:0 Not tainted 6.3.0-rc1-syzkaller-00002-g8ca09d5fa354-dirty #0
    Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 03/02/2023
    Workqueue: mld mld_ifc_work
    
    Fixes: 8eb30be0352d ("ipv6: Create ip6_tnl_xmit")
    Reported-by: syzbot <syzkaller@xxxxxxxxxxxxxxxx>
    Signed-off-by: Eric Dumazet <edumazet@xxxxxxxxxx>
    Link: https://lore.kernel.org/r/20230310191109.2384387-1-edumazet@xxxxxxxxxx
    Signed-off-by: Jakub Kicinski <kuba@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index b478a16ef284d..9ef63bc14b002 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -270,9 +270,11 @@ struct hh_cache {
  * relationship HH alignment <= LL alignment.
  */
 #define LL_RESERVED_SPACE(dev) \
-	((((dev)->hard_header_len+(dev)->needed_headroom)&~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
+	((((dev)->hard_header_len + READ_ONCE((dev)->needed_headroom)) \
+	  & ~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
 #define LL_RESERVED_SPACE_EXTRA(dev,extra) \
-	((((dev)->hard_header_len+(dev)->needed_headroom+(extra))&~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
+	((((dev)->hard_header_len + READ_ONCE((dev)->needed_headroom) + (extra)) \
+	  & ~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
 
 struct header_ops {
 	int	(*create) (struct sk_buff *skb, struct net_device *dev,
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index be75b409445c2..99f70b990eb13 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -613,10 +613,10 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
 	}
 
 	headroom += LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len;
-	if (headroom > dev->needed_headroom)
-		dev->needed_headroom = headroom;
+	if (headroom > READ_ONCE(dev->needed_headroom))
+		WRITE_ONCE(dev->needed_headroom, headroom);
 
-	if (skb_cow_head(skb, dev->needed_headroom)) {
+	if (skb_cow_head(skb, READ_ONCE(dev->needed_headroom))) {
 		ip_rt_put(rt);
 		goto tx_dropped;
 	}
@@ -797,10 +797,10 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
 
 	max_headroom = LL_RESERVED_SPACE(rt->dst.dev) + sizeof(struct iphdr)
 			+ rt->dst.header_len + ip_encap_hlen(&tunnel->encap);
-	if (max_headroom > dev->needed_headroom)
-		dev->needed_headroom = max_headroom;
+	if (max_headroom > READ_ONCE(dev->needed_headroom))
+		WRITE_ONCE(dev->needed_headroom, max_headroom);
 
-	if (skb_cow_head(skb, dev->needed_headroom)) {
+	if (skb_cow_head(skb, READ_ONCE(dev->needed_headroom))) {
 		ip_rt_put(rt);
 		dev->stats.tx_dropped++;
 		kfree_skb(skb);
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 0d4cab94c5dd2..a03a322e0cc1c 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1267,8 +1267,8 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
 	 */
 	max_headroom = LL_RESERVED_SPACE(dst->dev) + sizeof(struct ipv6hdr)
 			+ dst->header_len + t->hlen;
-	if (max_headroom > dev->needed_headroom)
-		dev->needed_headroom = max_headroom;
+	if (max_headroom > READ_ONCE(dev->needed_headroom))
+		WRITE_ONCE(dev->needed_headroom, max_headroom);
 
 	err = ip6_tnl_encap(skb, t, &proto, fl6);
 	if (err)



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux