* [PATCH] Bluetooth: L2CAP: Keep credits from completing security upgrades
@ 2026-10-15 5:20 Kyle Pepper
0 siblings, 0 replies; only message in thread
From: Kyle Pepper @ 2026-10-15 5:20 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Marcel Holtmann, Luiz Augusto von Dentz, linux-kernel
Credit indications can invoke resume on fixed or unready channels.
Connected LE credit-based sockets can also resume during a security
upgrade because credits and security share the socket suspend flag.
Validate the target mode and state for every identifier. Track pending
LE/ECRED security upgrades and retain credits without sending queued
data or resuming the socket until encryption meets the requested level.
Drain queued data after security completes and keep credit-starved
sockets suspended.
Fixes: fad5fc89594d ("Bluetooth: Add LE flow control discipline")
Assisted-by: OpenCode:gpt-6.1-sol
Signed-off-by: Kyle Pepper <cochcoder@proton.me>
---
New standalone security/target-state fix, not a resend of the zero-identifier
interoperability RFC. The zero-ID revision will be submitted separately and
depends on this fix; this patch does not accept identifier zero.
Refreshed without functional changes from the reviewed candidate onto current
bluetooth-next 397464709a20. The referenced Fixes commit's full ID and subject
were verified from its Git object:
fad5fc89594de31388572a26f33caa7c30a23782
On this refreshed base, both security-only and security+compatibility guest
kernels build with KASAN/lockdep and pass all nine focused security controls.
The 14 public credit controls pass 13/14 with this patch alone: the sole failure
is the intentionally unsupported positive zero-ID case. With the separate
compatibility patch they pass 14/14. No skips or captured KASAN/lockdep alerts
occurred in these focused runs. GCC W=1 changed objects and source-extracted
target/security and zero-ID fixtures pass.
The refreshed full-suite attempt is NOT a pass: SCI Fast Mode times out after
an invalid HCI Read Connection Interval response length for opcode 0x20a3, and
the runner reaches its outer timeout without a complete summary. The same SCI
failure reproduces on the unpatched current-base guest. It is not diagnosed as
a credit regression or claimed fixed here. An initial filter containing spaces
was split by the VM runner; corrected space-free filtered runs are reported above.
Earlier reference-base results were security-only 133/134 (the expected zero-ID
failure) and combined 134/134; those are historical, not fresh full-suite results.
The combined Arch integration was built and is reported working on hardware,
but that is not isolated attribution, over-the-air exploit evidence, complete
security/lifetime coverage or a remote-CI pass. No severity/CVE claim is made.
The private reproducer and detailed private regression logs are not included.
net/bluetooth/l2cap_core.c | 33 +++++++++++++++++++++++++++++++--
net/bluetooth/l2cap_sock.c | 9 +++++++--
2 files changed, 38 insertions(+), 4 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 4dd56e007..7a7f30531 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -5391,6 +5391,11 @@ static inline int l2cap_le_credits(struct l2cap_conn *conn,
l2cap_chan_lock(chan);
+ if (chan->state != BT_CONNECTED ||
+ (chan->mode != L2CAP_MODE_LE_FLOWCTL &&
+ chan->mode != L2CAP_MODE_EXT_FLOWCTL))
+ goto unlock;
+
max_credits = LE_FLOWCTL_MAX_CREDITS - chan->tx_credits;
if (credits > max_credits) {
BT_ERR("LE credits overflow");
@@ -5404,6 +5409,9 @@ static inline int l2cap_le_credits(struct l2cap_conn *conn,
chan->tx_credits += credits;
+ if (test_bit(FLAG_PENDING_SECURITY, &chan->flags))
+ goto unlock;
+
/* Resume sending */
l2cap_le_flowctl_send(chan);
@@ -7967,6 +7975,8 @@ static void l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
mutex_lock(&conn->lock);
list_for_each_entry(chan, &conn->chan_l, list) {
+ bool pending_le;
+
l2cap_chan_lock(chan);
lockdep_assert_held(&chan->conn->lock);
@@ -7974,7 +7984,12 @@ static void l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
state_to_string(chan->state));
- if (!status && encrypt)
+ pending_le = hcon->type == LE_LINK &&
+ (chan->mode == L2CAP_MODE_LE_FLOWCTL ||
+ chan->mode == L2CAP_MODE_EXT_FLOWCTL) &&
+ test_bit(FLAG_PENDING_SECURITY, &chan->flags);
+
+ if (!status && encrypt && !pending_le)
chan->sec_level = hcon->sec_level;
if (!__l2cap_no_conn_pending(chan)) {
@@ -7984,7 +7999,21 @@ static void l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
if (!status && (chan->state == BT_CONNECTED ||
chan->state == BT_CONFIG)) {
- chan->ops->resume(chan);
+ if (pending_le) {
+ if (!encrypt ||
+ !smp_sufficient_security(hcon, chan->sec_level,
+ SMP_ALLOW_STK)) {
+ l2cap_chan_unlock(chan);
+ continue;
+ }
+
+ clear_bit(FLAG_PENDING_SECURITY, &chan->flags);
+ chan->sec_level = hcon->sec_level;
+ l2cap_le_flowctl_send(chan);
+ }
+
+ if (!pending_le || chan->tx_credits)
+ chan->ops->resume(chan);
l2cap_check_encryption(chan, encrypt);
l2cap_chan_unlock(chan);
continue;
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index c396987c5..2d7f2935c 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -993,10 +993,15 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
} else if ((sk->sk_state == BT_CONNECT2 &&
test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) ||
sk->sk_state == BT_CONNECTED) {
- if (!l2cap_chan_check_security(chan, true))
+ if (!l2cap_chan_check_security(chan, true)) {
+ if (conn->hcon->type == LE_LINK &&
+ (chan->mode == L2CAP_MODE_LE_FLOWCTL ||
+ chan->mode == L2CAP_MODE_EXT_FLOWCTL))
+ set_bit(FLAG_PENDING_SECURITY, &chan->flags);
set_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
- else
+ } else {
sk->sk_state_change(sk);
+ }
} else {
err = -EINVAL;
}
base-commit: 397464709a204da9b8dc3b01d6ea42539d951cd2
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-10-15 5:20 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-15 5:20 [PATCH] Bluetooth: L2CAP: Keep credits from completing security upgrades Kyle Pepper
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®