mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [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

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®