All of lore.kernel.org
 help / color / mirror / Atom feed
From: Cen Zhang <zzzccc427@gmail.com>
To: marcel@holtmann.org, luiz.dentz@gmail.com
Cc: linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org,
	baijiaju1990@gmail.com, jjzuming@gmail.com, zzzccc427@gmail.com
Subject: [PATCH] Bluetooth: 6LoWPAN: Use RCU-safe device list removal
Date: Tue,  6 Oct 2026 15:35:23 +0800	[thread overview]
Message-ID: <pm-bluetooth-objects-candidate-0231-v5-32295fa35099b0d50b92@gmail.com> (raw)

RCU readers of bt_6lowpan_devices must be able to follow an adapter's
forward link until their read-side critical section ends. The entries
are published with list_add_rcu(), but device_event() removes an entry
on NETDEV_UNREGISTER with list_del(), poisoning that link.

When an adapter is being unregistered and 6LoWPAN is enabled, a
6lowpan_control debugfs write with an existing LE L2CAP connection can
enter lookup_peer() after unregister's first synchronize_net(). If the
connection has no peer on that adapter, the reader must advance to the
next list entry. Neither RTNL nor devices_lock excludes this RCU reader.

The last peer's chan_close_cb() schedules delete_netdev(), which reaches
unregister_netdevice_many_notify() through unregister_dev() and
lowpan_unregister_netdev(). The following ordering is possible:

  Unregister worker                 Control writer
  -----------------                 --------------
  synchronize_net() returns
                                    lowpan_control_write()
                                    lookup_peer(): rcu_read_lock()
                                    reach adapter; no matching peer
  device_event(): devices_lock
  list_del(&entry->list)
  spin_unlock(&devices_lock)
                                    follow poisoned next link
                                    read invalid adapter address
  post-notifier synchronize_net()
    waits for the reader

This invalid pointer access can fault in lookup_peer(). The first grace
period drains existing readers but permits new ones to start, and the
later grace period cannot prevent the intervening poisoned-link access.

Use list_del_rcu() under the existing devices_lock to preserve the
forward link for readers that already reached the adapter. The existing
post-notifier synchronize_net() waits for those readers before netdevice
teardown frees the private storage containing lowpan_btle_dev.

KASAN report as below:

    [...]
    [   45.867526] Oops: general protection fault, probably for non-canonical address 0xfbd59c0000000023: 0000 [#1] SMP KASAN NOPTI
    [   45.869489] KASAN: maybe wild-memory-access in range [0xdead000000000118-0xdead00000000011f]
    [   45.870981] CPU: 1 UID: 0 PID: 646 Comm: sh Not tainted 7.2.0-rc6-pmb-bt-functional-v1+ #4 PREEMPT(lazy) 
    [   45.872609] Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
    [   45.874380] RIP: 0010:lookup_peer+0x1ba/0x320
    [   45.875067] Code: 48 89 d9 ba 04 00 00 00 4c 89 fe bf a0 06 00 00 e8 2b e8 ad fb e9 56 ff ff ff e8 01 1e c3 fb 49 8d 7f 18 48 89 f8 48 c1 e8 03 <80> 3c 28 00 0f 85 4a 01 00 00 4d 8b 47 18 4c 89 f1 ba 04 00 00 00
    [   45.878206] RSP: 0018:ffff888114d67b90 EFLAGS: 00010212
    [   45.879106] RAX: 1bd5a00000000023 RBX: 0000000000000000 RCX: ffffffff85c1d19f
    [   45.880334] RDX: ffff88810dc35700 RSI: 0000000000000000 RDI: dead000000000118
    [   45.881455] RBP: dffffc0000000000 R08: 0000000000000001 R09: 0000000000000001
    [   45.882546] R10: ffffffff893d3057 R11: ffff88810dc35700 R12: ffff88810a690000
    [   45.883839] R13: ffff888115451038 R14: ffff88810a690000 R15: dead000000000100
    [   45.885186] FS:  00007fa889bac780(0000) GS:ffff8881fd852000(0000) knlGS:0000000000000000
    [   45.886539] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    [   45.887527] CR2: 00007ffe304f2f80 CR3: 0000000104f64005 CR4: 0000000000770ef0
    [   45.888687] PKRU: 55555554
    [   45.889183] Call Trace:
    [   45.889666]  <TASK>
    [   45.890061]  lowpan_control_write+0x445/0x9e0
    [   45.890854]  ? __pfx_lowpan_control_write+0x10/0x10
    [   45.891738]  ? srso_alias_return_thunk+0x5/0xfbef5
    [   45.892603]  ? srso_alias_return_thunk+0x5/0xfbef5
    [   45.893383]  ? __debugfs_file_get+0x1bd/0x7f0
    [   45.894057]  ? srso_alias_return_thunk+0x5/0xfbef5
    [   45.894902]  ? lock_acquire+0x17b/0x2f0
    [   45.895593]  ? ksys_write+0x111/0x200
    [   45.896290]  full_proxy_write+0x11f/0x180
    [   45.896991]  vfs_write+0x25a/0x1010
    [   45.897642]  ? __pfx_full_proxy_write+0x10/0x10
    [   45.898440]  ? __pfx_vfs_write+0x10/0x10
    [   45.899178]  ? lock_release+0x11f/0x280
    [   45.899855]  ksys_write+0x111/0x200
    [   45.900435]  ? __pfx_ksys_write+0x10/0x10
    [   45.901074]  ? irqentry_exit+0xbe/0x820
    [   45.901722]  ? srso_alias_return_thunk+0x5/0xfbef5
    [   45.902489]  do_syscall_64+0x115/0x6a0
    [   45.903064]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
    [   45.903813] RIP: 0033:0x7fa889c3e687
    [   45.904359] Code: 48 89 fa 4c 89 df e8 58 b3 00 00 8b 93 08 03 00 00 59 5e 48 83 f8 fc 74 1a 5b c3 0f 1f 84 00 00 00 00 00 48 8b 44 24 10 0f 05 <5b> c3 0f 1f 80 00 00 00 00 83 e2 39 83 fa 08 75 de e8 23 ff ff ff
    [   45.906981] RSP: 002b:00007ffd7651b960 EFLAGS: 00000202 ORIG_RAX: 0000000000000001
    [   45.908070] RAX: ffffffffffffffda RBX: 00007fa889bac780 RCX: 00007fa889c3e687
    [   45.909102] RDX: 000000000000001c RSI: 00005570f25e8d10 RDI: 0000000000000001
    [   45.910133] RBP: 00005570f25e8d10 R08: 0000000000000000 R09: 0000000000000000
    [   45.911162] R10: 0000000000000000 R11: 0000000000000202 R12: 0000000000000001
    [   45.912190] R13: 000000000000001c R14: 0000000000000000 R15: 00005570f25e8a78
    [   45.913208]  </TASK>
    [   45.913530] Modules linked in:
    [   45.914022] ---[ end trace 0000000000000000 ]---
    [   45.914709] RIP: 0010:lookup_peer+0x1ba/0x320
    [   45.915436] Code: 48 89 d9 ba 04 00 00 00 4c 89 fe bf a0 06 00 00 e8 2b e8 ad fb e9 56 ff ff ff e8 01 1e c3 fb 49 8d 7f 18 48 89 f8 48 c1 e8 03 <80> 3c 28 00 0f 85 4a 01 00 00 4d 8b 47 18 4c 89 f1 ba 04 00 00 00
    [   45.919191] RSP: 0018:ffff888114d67b90 EFLAGS: 00010212
    [   45.920046] RAX: 1bd5a00000000023 RBX: 0000000000000000 RCX: ffffffff85c1d19f
    [   45.921129] RDX: ffff88810dc35700 RSI: 0000000000000000 RDI: dead000000000118
    [   45.922553] RBP: dffffc0000000000 R08: 0000000000000001 R09: 0000000000000001
    [   45.923653] R10: ffffffff893d3057 R11: ffff88810dc35700 R12: ffff88810a690000
    [   45.925119] R13: ffff888115451038 R14: ffff88810a690000 R15: dead000000000100
    [   45.926180] FS:  00007fa889bac780(0000) GS:ffff8881fd852000(0000) knlGS:0000000000000000
    [   45.927817] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    [   45.928726] CR2: 00007ffe304f2f80 CR3: 0000000104f64005 CR4: 0000000000770ef0
    [   45.930069] PKRU: 55555554
    [   45.930456] Kernel panic - not syncing: Fatal exception
    [   45.931542] Kernel Offset: disabled
    [   45.932040] Rebooting in 1 seconds..

Fixes: 90305829635d ("Bluetooth: 6lowpan: Converting rwlocks to use RCU")
Assisted-by: LLM
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
---
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 836add41f5..4b05409929 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -1274,7 +1274,7 @@ static int device_event(struct notifier_block *unused,
 			if (entry->netdev == netdev) {
 				BT_DBG("Unregistered netdev %s %p",
 				       netdev->name, netdev);
-				list_del(&entry->list);
+				list_del_rcu(&entry->list);
 				break;
 			}
 		}

             reply	other threads:[~2026-10-06  7:35 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-06  7:35 Cen Zhang [this message]
2026-10-06  8:31 ` Bluetooth: 6LoWPAN: Use RCU-safe device list removal bluez.test.bot
2026-10-07 17:30 ` [PATCH] " patchwork-bot+bluetooth

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=pm-bluetooth-objects-candidate-0231-v5-32295fa35099b0d50b92@gmail.com \
    --to=zzzccc427@gmail.com \
    --cc=baijiaju1990@gmail.com \
    --cc=jjzuming@gmail.com \
    --cc=linux-bluetooth@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luiz.dentz@gmail.com \
    --cc=marcel@holtmann.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.