From: Philipp Dunkel <pip@pipobscure.com>
To: linux-bluetooth@vger.kernel.org
Cc: Philipp Dunkel <pip@pipobscure.com>
Subject: [PATCH BlueZ 0/2] Don't auto-bond on reactive GATT security elevation
Date: Sat, 18 Jul 2026 21:42:28 +0200 [thread overview]
Message-ID: <20260718194230.35959-1-pip@pipobscure.com> (raw)
bluetoothd probes every freshly connected LE peer as a GATT client
through its built-in profiles (battery, mcp, ...). When such a probe
reads a characteristic the peer has protected, the peer answers with
Insufficient Authentication (0x05), and change_security() reacts by
raising BT_SECURITY on the ATT socket. On an unbonded LE link that
starts SMP pairing, so the user is shown a pairing prompt for a device
that merely came into range -- a bond nobody requested, logged as a
device_bonding_complete() bond with a (nil) requestor.
The existing opt-out does not help: change_security() only bails when
chan->sec_level != BT_ATT_SECURITY_AUTO, but sec_level is recorded for
BT_ATT_LOCAL channels only, so an L2CAP/LE channel stays at AUTO for its
whole lifetime and always elevates.
Patch 1 adds bt_att_set_no_auto_sec(), a per-bt_att flag that makes
change_security() refuse to elevate, and sets it from gatt_client_init()
for any link that is neither bonded nor in a requested bonding.
In-progress Pair() and already-bonded devices keep their existing
elevation paths untouched.
Patch 2 adds a unit test: it arms AUTO security and then forbids
elevation, asserting the auth error is delivered to the caller with no
retry on the wire. Without patch 1 the client retries and the test
aborts on the unexpected Read Request.
Tested against Android (Galaxy Z Flip 4), iOS (iPhone) and macOS
(MacBook): each connects and is probed with no unsolicited pairing
prompt, while explicit pairing continues to work.
Both patches were developed with the assistance of an AI model
(Claude Opus 4.8), disclosed per-patch with an Assisted-by: trailer.
Every line was reviewed by me and the result was built, run and tested
on the hardware above -- behaviour observed, not inferred.
Philipp Dunkel (2):
shared/att: don't auto-bond on reactive elevation
unit/test-gatt: cover no-auto-sec on auth error
src/device.c | 13 +++++++++++++
src/shared/att.c | 20 ++++++++++++++++++++
src/shared/att.h | 1 +
unit/test-gatt.c | 28 ++++++++++++++++++++++++++++
4 files changed, 62 insertions(+)
--
2.55.0
next reply other threads:[~2026-07-18 19:42 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-18 19:42 Philipp Dunkel [this message]
2026-07-18 19:42 ` [PATCH BlueZ 1/2] shared/att: don't auto-bond on reactive elevation Philipp Dunkel
2026-07-18 21:22 ` Don't auto-bond on reactive GATT security elevation bluez.test.bot
2026-07-18 19:42 ` [PATCH BlueZ 2/2] unit/test-gatt: cover no-auto-sec on auth error Philipp Dunkel
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=20260718194230.35959-1-pip@pipobscure.com \
--to=pip@pipobscure.com \
--cc=linux-bluetooth@vger.kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox