* [PATCH v2] Bluetooth: keep dst_type with dst when reusing an LE connection
@ 2026-09-13 20:28 Radek Podgorny
2026-09-14 14:30 ` patchwork-bot+bluetooth
0 siblings, 1 reply; 2+ messages in thread
From: Radek Podgorny @ 2026-09-13 20:28 UTC (permalink / raw)
To: Marcel Holtmann, Luiz Augusto von Dentz
Cc: Luiz Augusto von Dentz, linux-bluetooth, linux-kernel, stable,
Radek Podgorny
hci_connect_le() swaps the caller's identity address for the peer's
cached RPA when one is known, and stamps the matching
ADDR_LE_DEV_RANDOM on the local dst_type. On the conn-reuse path only
the address is copied into the connection:
if (conn) {
bacpy(&conn->dst, dst);
so conn->dst ends up holding an RPA while conn->dst_type still names the
identity it was resolved from, and hci_le_create_conn_sync() puts that
pair on air unchanged. An RPA declared as a public address is not
something any peer can answer.
Measured on a CYW43438 against a peer advertising an RPA the host holds
the IRK for, connecting to the identity address over a raw L2CAP socket.
The first attempt creates the connection, the second takes the reuse
path:
LE Create Connection 3C:78:95:78:37:C3 type public
LE Create Connection 5B:75:A2:26:D6:18 type public
LE Connection Complete: Unknown Connection Identifier (0x02)
The second address is the peer's RPA. btmon annotates it with an OUI
lookup rather than "(Resolvable)" precisely because the command declares
it public; the same bit pattern annotates as resolvable once the type is
right.
The mistyped pair is also why nothing downstream repairs it.
hci_bdaddr_is_rpa() tests the type before the address, so an RPA carrying
a public type is not recognised as one, and hci_find_irk_by_addr() then
searches for an identity address that does not match it either.
Copy the type along with the address.
The assignment used to be unconditional just below this block and covered
both paths; it moved into hci_conn_add_unset(), which the reuse path does
not go through.
Cc: stable@vger.kernel.org
Fixes: 14b06c3a88f7 ("Bluetooth: HCI: Always use the identity address when initializing a connection")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Radek Podgorny <radek@podgorny.cz>
---
Changes in v2:
- no functional change: the diff is byte for byte the one sent in v1
- reindent the two quoted lines of code in the commit message with
spaces instead of tabs, so gitlint stops failing the patch on B3
(hard tab characters). That was the only red check on v1 that was
not one of the two known flaky testers
- rebase onto bt-next/master, which now carries the "dial the address
the peer is actually on air with" series. That series changed which
address __hci_conn_add() stores for a new connection; it did not
touch the reuse path in hci_connect_le(), which still copies
conn->dst without conn->dst_type, so this fix is still needed and
applies unchanged
- per Documentation/process/generated-content.rst: developed with the
Claude coding assistant (model as in the Assisted-by trailer). The
prompts described the misdirected create-connection and the btmon
captures taken before and after, and asked where dst_type is set on
each of the two paths through hci_connect_le(). The measurement on
real hardware, the analysis and the review are the human author's
v1: https://lore.kernel.org/linux-bluetooth/20260908012048.3681904-1-radek@podgorny.cz/
---
net/bluetooth/hci_conn.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index c9466cb2c7c0..fa72cf8aaa7a 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -1518,7 +1518,15 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
}
if (conn) {
+ /* dst may just have been swapped for the peer's RPA above, and
+ * dst_type describes dst -- it has to travel with it. Leaving
+ * the identity type behind makes the pair describe a peer that
+ * does not exist, and nothing downstream repairs it:
+ * hci_bdaddr_is_rpa() tests the type before the address, so
+ * the RPA is never treated as one.
+ */
bacpy(&conn->dst, dst);
+ conn->dst_type = dst_type;
} else {
conn = hci_conn_add_unset(hdev, LE_LINK, dst, dst_type, role);
if (IS_ERR(conn))
---
base-commit: e40edfa049b967f0b9379bf549c59431302ad181
change-id: 20260911-for-upstream-le-conn-reuse-dst-type-f3b916d8c89d
--
Radek Podgorny <radek@podgorny.cz>
^ permalink raw reply [flat|nested] 2+ messages in thread* Re: [PATCH v2] Bluetooth: keep dst_type with dst when reusing an LE connection
2026-09-13 20:28 [PATCH v2] Bluetooth: keep dst_type with dst when reusing an LE connection Radek Podgorny
@ 2026-09-14 14:30 ` patchwork-bot+bluetooth
0 siblings, 0 replies; 2+ messages in thread
From: patchwork-bot+bluetooth @ 2026-09-14 14:30 UTC (permalink / raw)
To: Radek Podgorny
Cc: marcel, luiz.dentz, luiz.von.dentz, linux-bluetooth,
linux-kernel, stable
Hello:
This patch was applied to bluetooth/bluetooth-next.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:
On Sun, 13 Sep 2026 22:28:02 +0200 you wrote:
> hci_connect_le() swaps the caller's identity address for the peer's
> cached RPA when one is known, and stamps the matching
> ADDR_LE_DEV_RANDOM on the local dst_type. On the conn-reuse path only
> the address is copied into the connection:
>
> if (conn) {
> bacpy(&conn->dst, dst);
>
> [...]
Here is the summary with links:
- [v2] Bluetooth: keep dst_type with dst when reusing an LE connection
https://git.kernel.org/bluetooth/bluetooth-next/c/1e892ee7af70
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-09-14 14:31 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-13 20:28 [PATCH v2] Bluetooth: keep dst_type with dst when reusing an LE connection Radek Podgorny
2026-09-14 14:30 ` patchwork-bot+bluetooth
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®