* [PATCH] Bluetooth: L2CAP: handle zero txwin_size in ERTM RFC option
@ 2026-04-17 22:16 Michael Bommarito
2026-04-17 22:55 ` bluez.test.bot
2026-04-20 19:06 ` [PATCH] " Luiz Augusto von Dentz
0 siblings, 2 replies; 7+ messages in thread
From: Michael Bommarito @ 2026-04-17 22:16 UTC (permalink / raw)
To: Marcel Holtmann, Luiz Augusto von Dentz
Cc: Mat Martineau, Hyunwoo Kim, linux-bluetooth, linux-kernel, stable
Bluetooth L2CAP ERTM configuration (RFC option, type 0x04) carries an
unsigned 8-bit txwin_size field. Core Spec v5.3, Vol 3 Part A, section
5.4 specifies a valid range of 1..63 (or 1..0x3fff under the Extended
Window Size extension). A peer-supplied value of zero is out of spec
but the current l2cap_parse_conf_req() path stores it into
chan->remote_tx_win unchanged whenever CONF_EWS_RECV is not set.
The zero then reaches l2cap_seq_list_init(size = 0), which computes
alloc_size = roundup_pow_of_two(size). Per include/linux/log2.h the
result is undefined for size == 0. The runtime behaviour is
architecture-dependent:
* x86, arm64, RISC-V, MIPS, s390x, LoongArch: the ISA shift
instruction masks the shift count by (word_bits - 1), so
1UL << word_bits evaluates to 1 rather than 0.
kmalloc_array(1, sizeof(u16)) returns a valid 2-byte slab
allocation with seq_list->mask == 0. ERTM retransmission
silently collapses every reqseq onto slot 0 (correctness bug,
no memory corruption).
* ARMv7 (AArch32), PowerPC 32-bit (slw), PowerPC 64-bit (sld):
the shift instruction returns 0 for shift counts >= word
width. 1UL << word_bits therefore evaluates to 0,
kmalloc_array(0, sizeof(u16)) returns ZERO_SIZE_PTR, and
seq_list->mask becomes ULONG_MAX. Any subsequent access to
seq_list->list dereferences ZERO_SIZE_PTR (0x10), which is
always an unmapped low-memory address, and the kernel Oopses.
This is a remote kernel panic driven by a single peer-sent
CONFIG_REQ; it is not a demonstrated code-execution primitive.
Verified on qemu-system-arm -M virt -cpu cortex-a15 (ARMv7-A, same
LSL register-shift semantics as the Cortex-A9 class still shipping
in automotive infotainment on NXP i.MX6 with long-term availability
through 2028). A KASAN-inline kernel built from mainline panics in
l2cap_seq_list_init on the first peer CONFIG_REQ carrying
mode = L2CAP_MODE_ERTM and txwin_size = 0:
Unable to handle kernel paging request at virtual address
9f000002 when read
Internal error: Oops: 5 [#1] SMP ARM
PC is at l2cap_seq_list_init+0x140/0x28c
r2 : 00000010 r1 : ffffffff
Register r2 information: zero-size pointer
Mode SVC_32 ISA ARM
Call trace:
l2cap_seq_list_init from l2cap_ertm_init+0x588/0x758
l2cap_ertm_init from l2cap_config_rsp+0xeac/0x1158
l2cap_config_rsp from l2cap_recv_frame+0x1260/0x8000
l2cap_recv_frame from l2cap_recv_acldata+0xb78/0xdb0
l2cap_recv_acldata from hci_rx_work
r2 = 0x10 is ZERO_SIZE_PTR (the kernel's own decoder annotates it
as such). r1 = 0xFFFFFFFF is seq_list->mask after the 0 - 1
underflow. Faulting address 0x9f000002 is the KASAN shadow for
pointer 0x10 (shadow_offset 0x9f000000 + (0x10 >> 3)).
Trigger is one peer-supplied CONFIG_REQ on an L2CAP ERTM channel;
no local privileges required, no pairing required, no local
interaction beyond being within BR/EDR radio range of an affected
host.
Fix in two places:
* l2cap_parse_conf_req(): when the peer sends txwin_size = 0 in
the RFC option, clamp it up to L2CAP_DEFAULT_TX_WINDOW before
the chan->remote_tx_win assignment. This matches the existing
clamp on the CONF_EWS_RECV branch in the same function and
mirrors the shape of commit 25f420a0d4cf ("Bluetooth: L2CAP:
Fix ERTM re-init and zero pdu_len infinite loop") for the
sibling RFC max_pdu_size field. This is the primary fix: it
prevents zero from ever reaching l2cap_seq_list_init() on the
normal config path.
* l2cap_seq_list_init(): return -EINVAL on size == 0 as a
defence-in-depth check for any current or future caller that
might pass an unclamped value. The existing error-propagation
in l2cap_ertm_init() and its callers already tears the channel
down on error, so the peer simply loses the ERTM channel
rather than silently corrupting an unmapped ZERO_SIZE_PTR
allocation.
Related but distinct from commit 25f420a0d4cf ("Bluetooth: L2CAP:
Fix ERTM re-init and zero pdu_len infinite loop") which addressed
the sibling zero-value issue on the RFC max_pdu_size field.
Fixes: 3c588192b5e5 ("Bluetooth: Add the l2cap_seq_list structure for tracking frames")
Cc: stable@vger.kernel.org
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Assisted-by: Claude:claude-opus-4-7
---
net/bluetooth/l2cap_core.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 95c65fece39b..b2fe094263ca 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -323,6 +323,17 @@ static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size)
{
size_t alloc_size, i;
+ /*
+ * A peer may send an ERTM RFC option with txwin_size = 0, which
+ * propagates here as size = 0. roundup_pow_of_two(0) is
+ * documented UB (see include/linux/log2.h) and produces a
+ * semantically broken seq_list that silently drops every
+ * retransmission slot. Reject size = 0 explicitly so the caller
+ * (l2cap_ertm_init) tears the channel down cleanly instead.
+ */
+ if (!size)
+ return -EINVAL;
+
/* Allocated size is a power of 2 to map sequence numbers
* (which may be up to 14 bits) in to a smaller array that is
* sized for the negotiated ERTM transmit windows.
@@ -3593,6 +3604,17 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data, size_t data
break;
case L2CAP_MODE_ERTM:
+ /*
+ * Peer-supplied RFC txwin_size = 0 is out of spec
+ * (Core Spec v5.3 Vol 3 Part A 5.4: ERTM tx window
+ * range is 1..63, or 1..0x3fff with EWS). Clamp up
+ * to the default window so the subsequent
+ * l2cap_seq_list_init(remote_tx_win) does not
+ * receive a zero size.
+ */
+ if (!rfc.txwin_size)
+ rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
+
if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
chan->remote_tx_win = rfc.txwin_size;
else
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* RE: Bluetooth: L2CAP: handle zero txwin_size in ERTM RFC option 2026-04-17 22:16 [PATCH] Bluetooth: L2CAP: handle zero txwin_size in ERTM RFC option Michael Bommarito @ 2026-04-17 22:55 ` bluez.test.bot 2026-04-20 19:06 ` [PATCH] " Luiz Augusto von Dentz 1 sibling, 0 replies; 7+ messages in thread From: bluez.test.bot @ 2026-04-17 22:55 UTC (permalink / raw) To: linux-bluetooth, michael.bommarito [-- Attachment #1: Type: text/plain, Size: 1746 bytes --] This is automated email and please do not reply to this email! Dear submitter, Thank you for submitting the patches to the linux bluetooth mailing list. This is a CI test results with your patch series: PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1082694 ---Test result--- Test Summary: CheckPatch FAIL 0.78 seconds GitLint PASS 0.38 seconds SubjectPrefix PASS 0.13 seconds BuildKernel PASS 25.65 seconds CheckAllWarning PASS 28.56 seconds CheckSparse PASS 26.63 seconds BuildKernel32 PASS 25.01 seconds TestRunnerSetup PASS 526.98 seconds TestRunner_l2cap-tester PASS 28.12 seconds IncrementalBuild PASS 24.83 seconds Details ############################## Test: CheckPatch - FAIL Desc: Run checkpatch.pl script Output: Bluetooth: L2CAP: handle zero txwin_size in ERTM RFC option WARNING: Non-standard signature: Assisted-by: #191: Assisted-by: Claude:claude-opus-4-7 ERROR: Unrecognized email address: 'Claude:claude-opus-4-7' #191: Assisted-by: Claude:claude-opus-4-7 total: 1 errors, 1 warnings, 0 checks, 34 lines checked NOTE: For some of the reported defects, checkpatch may be able to mechanically convert to the typical style using --fix or --fix-inplace. /github/workspace/src/patch/14528993.patch has style problems, please review. NOTE: Ignored message types: UNKNOWN_COMMIT_ID NOTE: If any of the errors are false positives, please report them to the maintainer, see CHECKPATCH in MAINTAINERS. https://github.com/bluez/bluetooth-next/pull/100 --- Regards, Linux Bluetooth ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Bluetooth: L2CAP: handle zero txwin_size in ERTM RFC option 2026-04-17 22:16 [PATCH] Bluetooth: L2CAP: handle zero txwin_size in ERTM RFC option Michael Bommarito 2026-04-17 22:55 ` bluez.test.bot @ 2026-04-20 19:06 ` Luiz Augusto von Dentz 2026-04-21 13:56 ` [PATCH v2 0/2] Bluetooth: L2CAP: fix zero txwin_size handling and repeated CONFIG_RSP re-init Michael Bommarito ` (2 more replies) 1 sibling, 3 replies; 7+ messages in thread From: Luiz Augusto von Dentz @ 2026-04-20 19:06 UTC (permalink / raw) To: Michael Bommarito Cc: Marcel Holtmann, Mat Martineau, Hyunwoo Kim, linux-bluetooth, linux-kernel, stable Hi Michael, On Fri, Apr 17, 2026 at 6:16 PM Michael Bommarito <michael.bommarito@gmail.com> wrote: > > Bluetooth L2CAP ERTM configuration (RFC option, type 0x04) carries an > unsigned 8-bit txwin_size field. Core Spec v5.3, Vol 3 Part A, section > 5.4 specifies a valid range of 1..63 (or 1..0x3fff under the Extended > Window Size extension). A peer-supplied value of zero is out of spec > but the current l2cap_parse_conf_req() path stores it into > chan->remote_tx_win unchanged whenever CONF_EWS_RECV is not set. > > The zero then reaches l2cap_seq_list_init(size = 0), which computes > alloc_size = roundup_pow_of_two(size). Per include/linux/log2.h the > result is undefined for size == 0. The runtime behaviour is > architecture-dependent: > > * x86, arm64, RISC-V, MIPS, s390x, LoongArch: the ISA shift > instruction masks the shift count by (word_bits - 1), so > 1UL << word_bits evaluates to 1 rather than 0. > kmalloc_array(1, sizeof(u16)) returns a valid 2-byte slab > allocation with seq_list->mask == 0. ERTM retransmission > silently collapses every reqseq onto slot 0 (correctness bug, > no memory corruption). > > * ARMv7 (AArch32), PowerPC 32-bit (slw), PowerPC 64-bit (sld): > the shift instruction returns 0 for shift counts >= word > width. 1UL << word_bits therefore evaluates to 0, > kmalloc_array(0, sizeof(u16)) returns ZERO_SIZE_PTR, and > seq_list->mask becomes ULONG_MAX. Any subsequent access to > seq_list->list dereferences ZERO_SIZE_PTR (0x10), which is > always an unmapped low-memory address, and the kernel Oopses. > This is a remote kernel panic driven by a single peer-sent > CONFIG_REQ; it is not a demonstrated code-execution primitive. > > Verified on qemu-system-arm -M virt -cpu cortex-a15 (ARMv7-A, same > LSL register-shift semantics as the Cortex-A9 class still shipping > in automotive infotainment on NXP i.MX6 with long-term availability > through 2028). A KASAN-inline kernel built from mainline panics in > l2cap_seq_list_init on the first peer CONFIG_REQ carrying > mode = L2CAP_MODE_ERTM and txwin_size = 0: > > Unable to handle kernel paging request at virtual address > 9f000002 when read > Internal error: Oops: 5 [#1] SMP ARM > PC is at l2cap_seq_list_init+0x140/0x28c > r2 : 00000010 r1 : ffffffff > Register r2 information: zero-size pointer > Mode SVC_32 ISA ARM > Call trace: > l2cap_seq_list_init from l2cap_ertm_init+0x588/0x758 > l2cap_ertm_init from l2cap_config_rsp+0xeac/0x1158 > l2cap_config_rsp from l2cap_recv_frame+0x1260/0x8000 > l2cap_recv_frame from l2cap_recv_acldata+0xb78/0xdb0 > l2cap_recv_acldata from hci_rx_work > > r2 = 0x10 is ZERO_SIZE_PTR (the kernel's own decoder annotates it > as such). r1 = 0xFFFFFFFF is seq_list->mask after the 0 - 1 > underflow. Faulting address 0x9f000002 is the KASAN shadow for > pointer 0x10 (shadow_offset 0x9f000000 + (0x10 >> 3)). > > Trigger is one peer-supplied CONFIG_REQ on an L2CAP ERTM channel; > no local privileges required, no pairing required, no local > interaction beyond being within BR/EDR radio range of an affected > host. > > Fix in two places: > > * l2cap_parse_conf_req(): when the peer sends txwin_size = 0 in > the RFC option, clamp it up to L2CAP_DEFAULT_TX_WINDOW before > the chan->remote_tx_win assignment. This matches the existing > clamp on the CONF_EWS_RECV branch in the same function and > mirrors the shape of commit 25f420a0d4cf ("Bluetooth: L2CAP: > Fix ERTM re-init and zero pdu_len infinite loop") for the > sibling RFC max_pdu_size field. This is the primary fix: it > prevents zero from ever reaching l2cap_seq_list_init() on the > normal config path. > > * l2cap_seq_list_init(): return -EINVAL on size == 0 as a > defence-in-depth check for any current or future caller that > might pass an unclamped value. The existing error-propagation > in l2cap_ertm_init() and its callers already tears the channel > down on error, so the peer simply loses the ERTM channel > rather than silently corrupting an unmapped ZERO_SIZE_PTR > allocation. > > Related but distinct from commit 25f420a0d4cf ("Bluetooth: L2CAP: > Fix ERTM re-init and zero pdu_len infinite loop") which addressed > the sibling zero-value issue on the RFC max_pdu_size field. > > Fixes: 3c588192b5e5 ("Bluetooth: Add the l2cap_seq_list structure for tracking frames") > Cc: stable@vger.kernel.org > Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com> > Assisted-by: Claude:claude-opus-4-7 > --- > net/bluetooth/l2cap_core.c | 22 ++++++++++++++++++++++ > 1 file changed, 22 insertions(+) > > diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c > index 95c65fece39b..b2fe094263ca 100644 > --- a/net/bluetooth/l2cap_core.c > +++ b/net/bluetooth/l2cap_core.c > @@ -323,6 +323,17 @@ static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size) > { > size_t alloc_size, i; > > + /* > + * A peer may send an ERTM RFC option with txwin_size = 0, which > + * propagates here as size = 0. roundup_pow_of_two(0) is > + * documented UB (see include/linux/log2.h) and produces a > + * semantically broken seq_list that silently drops every > + * retransmission slot. Reject size = 0 explicitly so the caller > + * (l2cap_ertm_init) tears the channel down cleanly instead. > + */ > + if (!size) > + return -EINVAL; > + > /* Allocated size is a power of 2 to map sequence numbers > * (which may be up to 14 bits) in to a smaller array that is > * sized for the negotiated ERTM transmit windows. > @@ -3593,6 +3604,17 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data, size_t data > break; > > case L2CAP_MODE_ERTM: > + /* > + * Peer-supplied RFC txwin_size = 0 is out of spec > + * (Core Spec v5.3 Vol 3 Part A 5.4: ERTM tx window > + * range is 1..63, or 1..0x3fff with EWS). Clamp up > + * to the default window so the subsequent > + * l2cap_seq_list_init(remote_tx_win) does not > + * receive a zero size. > + */ > + if (!rfc.txwin_size) > + rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW; > + > if (!test_bit(CONF_EWS_RECV, &chan->conf_state)) > chan->remote_tx_win = rfc.txwin_size; > else > -- > 2.53.0 https://sashiko.dev/#/patchset/20260417221628.1674866-1-michael.bommarito%40gmail.com We should probably fix the double free if it can occur; perhaps the others should be addressed in different patches. -- Luiz Augusto von Dentz ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 0/2] Bluetooth: L2CAP: fix zero txwin_size handling and repeated CONFIG_RSP re-init 2026-04-20 19:06 ` [PATCH] " Luiz Augusto von Dentz @ 2026-04-21 13:56 ` Michael Bommarito 2026-04-21 13:56 ` [PATCH v2 1/2] Bluetooth: L2CAP: handle zero txwin_size in ERTM RFC option Michael Bommarito 2026-04-21 13:56 ` [PATCH v2 2/2] Bluetooth: L2CAP: skip ERTM re-init on repeated CONFIG_RSP Michael Bommarito 2 siblings, 0 replies; 7+ messages in thread From: Michael Bommarito @ 2026-04-21 13:56 UTC (permalink / raw) To: Marcel Holtmann, Luiz Augusto von Dentz Cc: Mat Martineau, Hyunwoo Kim, linux-bluetooth, linux-kernel, stable Hi Luiz, Thanks for the review. v1 mixed the original zero-txwin fix with a defensive l2cap_seq_list_init(size == 0) error return. Re-checking that path made it clear the reroll should be split: 1. keep the original report focused on zero txwin_size, but fix it by normalizing zero window values at the actual inputs to the ERTM state machine and by making sequence-list teardown idempotent, rather than by introducing a new init-time failure path 2. handle the separate repeated-CONFIG_RSP ERTM re-init bug in its own patch, matching the BT_CONNECTED guard that commit 25f420a0d4cf already added on the CONFIG_REQ side While auditing the Sashiko comments, I also checked the claimed CONF_EWS_RECV bypass. I did not carry that theory into v2: in this tree CONF_EWS_RECV is declared but never set, so the concrete zero-window paths are the plain RFC option, the local L2CAP_OPTIONS socket setting, and the CONFIG_RSP / conf_rfc_get negotiation state. To make sure the reroll covered all the zero-entry sites (and only the zero-entry sites), I enumerated every assignment to tx_win / ack_win / remote_tx_win / txwin_size in net/bluetooth/l2cap_core.c and confirmed patch 1 normalizes the four reachable input paths -- the local L2CAP_OPTIONS setsockopt, l2cap_txwin_setup() on the outgoing RFC, the L2CAP_MODE_ERTM branch of l2cap_parse_conf_req(), and the EWS / RFC branches of l2cap_parse_conf_rsp() and l2cap_conf_rfc_get(). The only other writers are the channel-create defaults in l2cap_chan_create() (hard-coded to L2CAP_DEFAULT_TX_WINDOW) and the outgoing rfc.txwin_size = 0 assignments in L2CAP_MODE_BASIC / L2CAP_MODE_STREAMING branches, where a zero is spec-correct and never feeds ack_win. l2cap_seq_list_free()'s callers are l2cap_chan_del() (channel teardown) and l2cap_ertm_init()'s error path; clearing the list metadata after kfree() is safe for both and is what makes the partially-initialized re-entry in the failure path no longer a double-free source. For patch 2, the BT_CONNECTED guard added to l2cap_config_rsp() mirrors the existing one in l2cap_config_req() (lines 4339..4348 in this tree) so both sides of the CONFIG exchange now refuse to re-enter l2cap_ertm_init() once the channel is already connected. I did not pin down a single introducing commit for the CONFIG_RSP side during this pass, so patch 2 keeps Cc: stable@ without a speculative Fixes: tag; happy to add one if you'd prefer a specific reference. Changes since v1 ---------------- - Split the reroll into two patches: the zero-txwin fix and the separate repeated-CONFIG_RSP ERTM re-init fix. - Dropped the v1 l2cap_seq_list_init(size == 0) -> -EINVAL defence and instead normalize zero tx window values where they enter negotiated ERTM state. - Clamp the local L2CAP_OPTIONS txwin_size = 0 case back to L2CAP_DEFAULT_TX_WINDOW. - Normalize zero tx window values seen during CONFIG_RSP / RFC parsing so ack_win does not collapse to 0. - Make l2cap_seq_list_free() clear list metadata after kfree so later teardown cannot trip over a previously freed list. Michael Bommarito (2): Bluetooth: L2CAP: handle zero txwin_size in ERTM RFC option Bluetooth: L2CAP: skip ERTM re-init on repeated CONFIG_RSP net/bluetooth/l2cap_core.c | 39 +++++++++++++++++++++++++++----------- net/bluetooth/l2cap_sock.c | 3 +++ 2 files changed, 31 insertions(+), 11 deletions(-) -- 2.53.0 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 1/2] Bluetooth: L2CAP: handle zero txwin_size in ERTM RFC option 2026-04-20 19:06 ` [PATCH] " Luiz Augusto von Dentz 2026-04-21 13:56 ` [PATCH v2 0/2] Bluetooth: L2CAP: fix zero txwin_size handling and repeated CONFIG_RSP re-init Michael Bommarito @ 2026-04-21 13:56 ` Michael Bommarito 2026-04-21 14:51 ` [v2,1/2] " bluez.test.bot 2026-04-21 13:56 ` [PATCH v2 2/2] Bluetooth: L2CAP: skip ERTM re-init on repeated CONFIG_RSP Michael Bommarito 2 siblings, 1 reply; 7+ messages in thread From: Michael Bommarito @ 2026-04-21 13:56 UTC (permalink / raw) To: Marcel Holtmann, Luiz Augusto von Dentz Cc: Mat Martineau, Hyunwoo Kim, linux-bluetooth, linux-kernel, stable Peer-supplied ERTM RFC txwin_size = 0 can still propagate into the ERTM transmit-window state, and the same invalid value can be introduced locally through L2CAP_OPTIONS. In the request path that zero reaches l2cap_seq_list_init(..., 0); in the response path it can shrink ack_win to 0 and leave ERTM sequencing in a nonsensical state. Normalize zero tx window values back to L2CAP_DEFAULT_TX_WINDOW wherever they enter the ERTM state machine: local socket options, outgoing tx_win setup, incoming config requests, and config-response parsing. Also make l2cap_seq_list_free() clear its metadata after kfree so an init failure after freeing srej_list cannot be freed a second time during later channel teardown. Fixes: 3c588192b5e5 ("Bluetooth: Add the l2cap_seq_list structure for tracking frames") Cc: stable@vger.kernel.org Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com> Assisted-by: Claude:claude-opus-4-7 --- Changes in v2: - drop the v1 `l2cap_seq_list_init(size == 0) -> -EINVAL` approach and instead normalize zero tx window values at the socket / request / response inputs - clamp the local `L2CAP_OPTIONS` txwin_size = 0 case back to `L2CAP_DEFAULT_TX_WINDOW` - make `l2cap_seq_list_free()` clear its metadata after `kfree()` so later teardown cannot trip over a previously freed list - split the repeated `CONFIG_RSP` ERTM re-init fix into patch 2 net/bluetooth/l2cap_core.c | 23 +++++++++++++++++++---- net/bluetooth/l2cap_sock.c | 3 +++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 95c65fece39b..7ffafd117817 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -345,6 +345,10 @@ static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size) static inline void l2cap_seq_list_free(struct l2cap_seq_list *seq_list) { kfree(seq_list->list); + seq_list->list = NULL; + seq_list->mask = 0; + seq_list->head = L2CAP_SEQ_LIST_CLEAR; + seq_list->tail = L2CAP_SEQ_LIST_CLEAR; } static inline bool l2cap_seq_list_contains(struct l2cap_seq_list *seq_list, @@ -3234,8 +3238,15 @@ static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan, rfc->monitor_timeout = cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO); } +static inline u16 l2cap_txwin_default(u16 txwin) +{ + return txwin ? txwin : L2CAP_DEFAULT_TX_WINDOW; +} + static inline void l2cap_txwin_setup(struct l2cap_chan *chan) { + chan->tx_win = l2cap_txwin_default(chan->tx_win); + if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW && __l2cap_ews_supported(chan->conn)) { /* use extended control field */ @@ -3593,6 +3604,8 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data, size_t data break; case L2CAP_MODE_ERTM: + rfc.txwin_size = l2cap_txwin_default(rfc.txwin_size); + if (!test_bit(CONF_EWS_RECV, &chan->conf_state)) chan->remote_tx_win = rfc.txwin_size; else @@ -3715,7 +3728,8 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, case L2CAP_CONF_EWS: if (olen != 2) break; - chan->ack_win = min_t(u16, val, chan->ack_win); + chan->ack_win = min_t(u16, l2cap_txwin_default(val), + chan->ack_win); l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2, chan->tx_win, endptr - ptr); break; @@ -3756,7 +3770,7 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, chan->mps = le16_to_cpu(rfc.max_pdu_size); if (!test_bit(FLAG_EXT_CTRL, &chan->flags)) chan->ack_win = min_t(u16, chan->ack_win, - rfc.txwin_size); + l2cap_txwin_default(rfc.txwin_size)); if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) { chan->local_msdu = le16_to_cpu(efs.msdu); @@ -3970,10 +3984,11 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len) chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout); chan->mps = le16_to_cpu(rfc.max_pdu_size); if (test_bit(FLAG_EXT_CTRL, &chan->flags)) - chan->ack_win = min_t(u16, chan->ack_win, txwin_ext); + chan->ack_win = min_t(u16, chan->ack_win, + l2cap_txwin_default(txwin_ext)); else chan->ack_win = min_t(u16, chan->ack_win, - rfc.txwin_size); + l2cap_txwin_default(rfc.txwin_size)); break; case L2CAP_MODE_STREAMING: chan->mps = le16_to_cpu(rfc.max_pdu_size); diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 71e8c1b45bce..3b53e967bf40 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -765,6 +765,9 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, break; } + if (!opts.txwin_size) + opts.txwin_size = L2CAP_DEFAULT_TX_WINDOW; + if (!l2cap_valid_mtu(chan, opts.imtu)) { err = -EINVAL; break; -- 2.53.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* RE: [v2,1/2] Bluetooth: L2CAP: handle zero txwin_size in ERTM RFC option 2026-04-21 13:56 ` [PATCH v2 1/2] Bluetooth: L2CAP: handle zero txwin_size in ERTM RFC option Michael Bommarito @ 2026-04-21 14:51 ` bluez.test.bot 0 siblings, 0 replies; 7+ messages in thread From: bluez.test.bot @ 2026-04-21 14:51 UTC (permalink / raw) To: linux-bluetooth, michael.bommarito [-- Attachment #1: Type: text/plain, Size: 2553 bytes --] This is automated email and please do not reply to this email! Dear submitter, Thank you for submitting the patches to the linux bluetooth mailing list. This is a CI test results with your patch series: PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1083882 ---Test result--- Test Summary: CheckPatch FAIL 1.20 seconds GitLint PASS 0.45 seconds SubjectPrefix PASS 0.17 seconds BuildKernel PASS 20.51 seconds CheckAllWarning PASS 21.04 seconds CheckSparse PASS 23.68 seconds BuildKernel32 PASS 18.71 seconds TestRunnerSetup PASS 403.79 seconds TestRunner_l2cap-tester PASS 23.06 seconds IncrementalBuild PASS 21.36 seconds Details ############################## Test: CheckPatch - FAIL Desc: Run checkpatch.pl script Output: [v2,1/2] Bluetooth: L2CAP: handle zero txwin_size in ERTM RFC option WARNING: Non-standard signature: Assisted-by: #125: Assisted-by: Claude:claude-opus-4-7 ERROR: Unrecognized email address: 'Claude:claude-opus-4-7' #125: Assisted-by: Claude:claude-opus-4-7 total: 1 errors, 1 warnings, 0 checks, 72 lines checked NOTE: For some of the reported defects, checkpatch may be able to mechanically convert to the typical style using --fix or --fix-inplace. /github/workspace/src/patch/14532642.patch has style problems, please review. NOTE: Ignored message types: UNKNOWN_COMMIT_ID NOTE: If any of the errors are false positives, please report them to the maintainer, see CHECKPATCH in MAINTAINERS. [v2,2/2] Bluetooth: L2CAP: skip ERTM re-init on repeated CONFIG_RSP WARNING: Non-standard signature: Assisted-by: #124: Assisted-by: Claude:claude-opus-4-7 ERROR: Unrecognized email address: 'Claude:claude-opus-4-7' #124: Assisted-by: Claude:claude-opus-4-7 WARNING: The commit message has 'stable@', perhaps it also needs a 'Fixes:' tag? total: 1 errors, 2 warnings, 0 checks, 23 lines checked NOTE: For some of the reported defects, checkpatch may be able to mechanically convert to the typical style using --fix or --fix-inplace. /github/workspace/src/patch/14532643.patch has style problems, please review. NOTE: Ignored message types: UNKNOWN_COMMIT_ID NOTE: If any of the errors are false positives, please report them to the maintainer, see CHECKPATCH in MAINTAINERS. https://github.com/bluez/bluetooth-next/pull/111 --- Regards, Linux Bluetooth ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 2/2] Bluetooth: L2CAP: skip ERTM re-init on repeated CONFIG_RSP 2026-04-20 19:06 ` [PATCH] " Luiz Augusto von Dentz 2026-04-21 13:56 ` [PATCH v2 0/2] Bluetooth: L2CAP: fix zero txwin_size handling and repeated CONFIG_RSP re-init Michael Bommarito 2026-04-21 13:56 ` [PATCH v2 1/2] Bluetooth: L2CAP: handle zero txwin_size in ERTM RFC option Michael Bommarito @ 2026-04-21 13:56 ` Michael Bommarito 2 siblings, 0 replies; 7+ messages in thread From: Michael Bommarito @ 2026-04-21 13:56 UTC (permalink / raw) To: Marcel Holtmann, Luiz Augusto von Dentz Cc: Mat Martineau, Hyunwoo Kim, linux-bluetooth, linux-kernel, stable commit 25f420a0d4cf ("Bluetooth: L2CAP: Fix ERTM re-init and zero pdu_len infinite loop") taught l2cap_config_req() not to call l2cap_ertm_init() again once the channel is already in BT_CONNECTED. l2cap_config_rsp() still lacks the same guard. After the initial ERTM setup, any extra successful CONFIG_RSP re-enters l2cap_ertm_init(), reinitializes tx_q and srej_q, and allocates fresh sequence lists over the existing channel state. Mirror the existing BT_CONNECTED check in l2cap_config_rsp() so response parsing can still update negotiated parameters without reinitializing ERTM state or leaking the old resources. Cc: stable@vger.kernel.org Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com> Assisted-by: Claude:claude-opus-4-7 --- Changes in v2: - split out of the original zero-txwin patch so the repeated `CONFIG_RSP` ERTM re-init bug is reviewed as a distinct issue - mirror the existing `BT_CONNECTED` guard already present on the `CONFIG_REQ` side after commit 25f420a0d4cf net/bluetooth/l2cap_core.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 7ffafd117817..fe98f4821a90 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -4480,14 +4480,16 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) { set_default_fcs(chan); - if (chan->mode == L2CAP_MODE_ERTM || - chan->mode == L2CAP_MODE_STREAMING) - err = l2cap_ertm_init(chan); + if (chan->state != BT_CONNECTED) { + if (chan->mode == L2CAP_MODE_ERTM || + chan->mode == L2CAP_MODE_STREAMING) + err = l2cap_ertm_init(chan); - if (err < 0) - l2cap_send_disconn_req(chan, -err); - else - l2cap_chan_ready(chan); + if (err < 0) + l2cap_send_disconn_req(chan, -err); + else + l2cap_chan_ready(chan); + } } done: -- 2.53.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-04-21 14:51 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-04-17 22:16 [PATCH] Bluetooth: L2CAP: handle zero txwin_size in ERTM RFC option Michael Bommarito 2026-04-17 22:55 ` bluez.test.bot 2026-04-20 19:06 ` [PATCH] " Luiz Augusto von Dentz 2026-04-21 13:56 ` [PATCH v2 0/2] Bluetooth: L2CAP: fix zero txwin_size handling and repeated CONFIG_RSP re-init Michael Bommarito 2026-04-21 13:56 ` [PATCH v2 1/2] Bluetooth: L2CAP: handle zero txwin_size in ERTM RFC option Michael Bommarito 2026-04-21 14:51 ` [v2,1/2] " bluez.test.bot 2026-04-21 13:56 ` [PATCH v2 2/2] Bluetooth: L2CAP: skip ERTM re-init on repeated CONFIG_RSP Michael Bommarito
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox