diff mbox series

[net-next,1/8] vxlan: Annotate FDB data races

Message ID 20250204145549.1216254-2-idosch@nvidia.com (mailing list archive)
State New
Delegated to: Netdev Maintainers
Headers show
Series vxlan: Age FDB entries based on Rx traffic | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers success CCed 6 of 6 maintainers
netdev/build_clang success Errors and warnings before: 2 this patch: 2
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 1 this patch: 1
netdev/checkpatch warning WARNING: Comparing jiffies is almost always wrong; prefer time_after, time_before and friends WARNING: The commit message has 'BUG: KCSAN: ', perhaps it also needs a 'Fixes:' tag? WARNING: line length of 84 exceeds 80 columns
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
netdev/contest success net-next-2025-02-05--00-00 (tests: 886)

Commit Message

Ido Schimmel Feb. 4, 2025, 2:55 p.m. UTC
The 'used' and 'updated' fields in the FDB entry structure can be
accessed concurrently by multiple threads, leading to reports such as
[1]. Can be reproduced using [2].

Suppress these reports by annotating these accesses using
READ_ONCE() / WRITE_ONCE().

[1]
BUG: KCSAN: data-race in vxlan_xmit / vxlan_xmit

write to 0xffff942604d263a8 of 8 bytes by task 286 on cpu 0:
 vxlan_xmit+0xb29/0x2380
 dev_hard_start_xmit+0x84/0x2f0
 __dev_queue_xmit+0x45a/0x1650
 packet_xmit+0x100/0x150
 packet_sendmsg+0x2114/0x2ac0
 __sys_sendto+0x318/0x330
 __x64_sys_sendto+0x76/0x90
 x64_sys_call+0x14e8/0x1c00
 do_syscall_64+0x9e/0x1a0
 entry_SYSCALL_64_after_hwframe+0x77/0x7f

read to 0xffff942604d263a8 of 8 bytes by task 287 on cpu 2:
 vxlan_xmit+0xadf/0x2380
 dev_hard_start_xmit+0x84/0x2f0
 __dev_queue_xmit+0x45a/0x1650
 packet_xmit+0x100/0x150
 packet_sendmsg+0x2114/0x2ac0
 __sys_sendto+0x318/0x330
 __x64_sys_sendto+0x76/0x90
 x64_sys_call+0x14e8/0x1c00
 do_syscall_64+0x9e/0x1a0
 entry_SYSCALL_64_after_hwframe+0x77/0x7f

value changed: 0x00000000fffbac6e -> 0x00000000fffbac6f

Reported by Kernel Concurrency Sanitizer on:
CPU: 2 UID: 0 PID: 287 Comm: mausezahn Not tainted 6.13.0-rc7-01544-gb4b270f11a02 #5
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-3.fc41 04/01/2014

[2]
 #!/bin/bash

 set +H
 echo whitelist > /sys/kernel/debug/kcsan
 echo !vxlan_xmit > /sys/kernel/debug/kcsan

 ip link add name vx0 up type vxlan id 10010 dstport 4789 local 192.0.2.1
 bridge fdb add 00:11:22:33:44:55 dev vx0 self static dst 198.51.100.1
 taskset -c 0 mausezahn vx0 -a own -b 00:11:22:33:44:55 -c 0 -q &
 taskset -c 2 mausezahn vx0 -a own -b 00:11:22:33:44:55 -c 0 -q &

Reviewed-by: Petr Machata <petrm@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
 drivers/net/vxlan/vxlan_core.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

Comments

Eric Dumazet Feb. 4, 2025, 3:41 p.m. UTC | #1
On Tue, Feb 4, 2025 at 3:56 PM Ido Schimmel <idosch@nvidia.com> wrote:
>
> The 'used' and 'updated' fields in the FDB entry structure can be
> accessed concurrently by multiple threads, leading to reports such as
> [1]. Can be reproduced using [2].
>
> Suppress these reports by annotating these accesses using
> READ_ONCE() / WRITE_ONCE().
>
>
> Reviewed-by: Petr Machata <petrm@nvidia.com>
> Signed-off-by: Ido Schimmel <idosch@nvidia.com>
>

Reviewed-by: Eric Dumazet <edumazet@google.com>
Nikolay Aleksandrov Feb. 4, 2025, 4:36 p.m. UTC | #2
On 2/4/25 16:55, Ido Schimmel wrote:
> The 'used' and 'updated' fields in the FDB entry structure can be
> accessed concurrently by multiple threads, leading to reports such as
> [1]. Can be reproduced using [2].
> 
> Suppress these reports by annotating these accesses using
> READ_ONCE() / WRITE_ONCE().
> 
> [1]
> BUG: KCSAN: data-race in vxlan_xmit / vxlan_xmit
> 
> write to 0xffff942604d263a8 of 8 bytes by task 286 on cpu 0:
>  vxlan_xmit+0xb29/0x2380
>  dev_hard_start_xmit+0x84/0x2f0
>  __dev_queue_xmit+0x45a/0x1650
>  packet_xmit+0x100/0x150
>  packet_sendmsg+0x2114/0x2ac0
>  __sys_sendto+0x318/0x330
>  __x64_sys_sendto+0x76/0x90
>  x64_sys_call+0x14e8/0x1c00
>  do_syscall_64+0x9e/0x1a0
>  entry_SYSCALL_64_after_hwframe+0x77/0x7f
> 
> read to 0xffff942604d263a8 of 8 bytes by task 287 on cpu 2:
>  vxlan_xmit+0xadf/0x2380
>  dev_hard_start_xmit+0x84/0x2f0
>  __dev_queue_xmit+0x45a/0x1650
>  packet_xmit+0x100/0x150
>  packet_sendmsg+0x2114/0x2ac0
>  __sys_sendto+0x318/0x330
>  __x64_sys_sendto+0x76/0x90
>  x64_sys_call+0x14e8/0x1c00
>  do_syscall_64+0x9e/0x1a0
>  entry_SYSCALL_64_after_hwframe+0x77/0x7f
> 
> value changed: 0x00000000fffbac6e -> 0x00000000fffbac6f
> 
> Reported by Kernel Concurrency Sanitizer on:
> CPU: 2 UID: 0 PID: 287 Comm: mausezahn Not tainted 6.13.0-rc7-01544-gb4b270f11a02 #5
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-3.fc41 04/01/2014
> 
> [2]
>  #!/bin/bash
> 
>  set +H
>  echo whitelist > /sys/kernel/debug/kcsan
>  echo !vxlan_xmit > /sys/kernel/debug/kcsan
> 
>  ip link add name vx0 up type vxlan id 10010 dstport 4789 local 192.0.2.1
>  bridge fdb add 00:11:22:33:44:55 dev vx0 self static dst 198.51.100.1
>  taskset -c 0 mausezahn vx0 -a own -b 00:11:22:33:44:55 -c 0 -q &
>  taskset -c 2 mausezahn vx0 -a own -b 00:11:22:33:44:55 -c 0 -q &
> 
> Reviewed-by: Petr Machata <petrm@nvidia.com>
> Signed-off-by: Ido Schimmel <idosch@nvidia.com>
> ---
>  drivers/net/vxlan/vxlan_core.c | 18 +++++++++---------
>  1 file changed, 9 insertions(+), 9 deletions(-)
> 

Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
diff mbox series

Patch

diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
index 05c10acb2a57..2f2c6606f719 100644
--- a/drivers/net/vxlan/vxlan_core.c
+++ b/drivers/net/vxlan/vxlan_core.c
@@ -227,9 +227,9 @@  static int vxlan_fdb_info(struct sk_buff *skb, struct vxlan_dev *vxlan,
 			be32_to_cpu(fdb->vni)))
 		goto nla_put_failure;
 
-	ci.ndm_used	 = jiffies_to_clock_t(now - fdb->used);
+	ci.ndm_used	 = jiffies_to_clock_t(now - READ_ONCE(fdb->used));
 	ci.ndm_confirmed = 0;
-	ci.ndm_updated	 = jiffies_to_clock_t(now - fdb->updated);
+	ci.ndm_updated	 = jiffies_to_clock_t(now - READ_ONCE(fdb->updated));
 	ci.ndm_refcnt	 = 0;
 
 	if (nla_put(skb, NDA_CACHEINFO, sizeof(ci), &ci))
@@ -434,8 +434,8 @@  static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan,
 	struct vxlan_fdb *f;
 
 	f = __vxlan_find_mac(vxlan, mac, vni);
-	if (f && f->used != jiffies)
-		f->used = jiffies;
+	if (f && READ_ONCE(f->used) != jiffies)
+		WRITE_ONCE(f->used, jiffies);
 
 	return f;
 }
@@ -1009,12 +1009,12 @@  static int vxlan_fdb_update_existing(struct vxlan_dev *vxlan,
 	    !(f->flags & NTF_VXLAN_ADDED_BY_USER)) {
 		if (f->state != state) {
 			f->state = state;
-			f->updated = jiffies;
+			WRITE_ONCE(f->updated, jiffies);
 			notify = 1;
 		}
 		if (f->flags != fdb_flags) {
 			f->flags = fdb_flags;
-			f->updated = jiffies;
+			WRITE_ONCE(f->updated, jiffies);
 			notify = 1;
 		}
 	}
@@ -1048,7 +1048,7 @@  static int vxlan_fdb_update_existing(struct vxlan_dev *vxlan,
 	}
 
 	if (ndm_flags & NTF_USE)
-		f->used = jiffies;
+		WRITE_ONCE(f->used, jiffies);
 
 	if (notify) {
 		if (rd == NULL)
@@ -1481,7 +1481,7 @@  static enum skb_drop_reason vxlan_snoop(struct net_device *dev,
 				    src_mac, &rdst->remote_ip.sa, &src_ip->sa);
 
 		rdst->remote_ip = *src_ip;
-		f->updated = jiffies;
+		WRITE_ONCE(f->updated, jiffies);
 		vxlan_fdb_notify(vxlan, f, rdst, RTM_NEWNEIGH, true, NULL);
 	} else {
 		u32 hash_index = fdb_head_index(vxlan, src_mac, vni);
@@ -2852,7 +2852,7 @@  static void vxlan_cleanup(struct timer_list *t)
 			if (f->flags & NTF_EXT_LEARNED)
 				continue;
 
-			timeout = f->used + vxlan->cfg.age_interval * HZ;
+			timeout = READ_ONCE(f->used) + vxlan->cfg.age_interval * HZ;
 			if (time_before_eq(timeout, jiffies)) {
 				netdev_dbg(vxlan->dev,
 					   "garbage collect %pM\n",