Re: [PATCH 2/4] Bluetooth: L2CAP: CoC: Disconnect if received packet size exceeds MPS

From: Christian Eggers

Date: Wed Feb 25 2026 - 12:35:18 EST


Hi Luiz,

On Wednesday, 25 February 2026, 18:24:16 CET, Luiz Augusto von Dentz wrote:
> Hi Christian,
>
> On Wed, Feb 25, 2026 at 12:07 PM Christian Eggers <ceggers@xxxxxxx> wrote:
> >
> > Core 6.0, Vol 3, Part A, 3.4.3:
> > "... If the payload size of any K-frame exceeds the receiver's MPS, the
> > receiver shall disconnect the channel..."
> >
> > This fixes L2CAP/LE/CFC/BV-27-C (running together with 'l2test -r -P
> > 0x0027 -V le_public -I 100').
> >
> > Signed-off-by: Christian Eggers <ceggers@xxxxxxx>
> > ---
> > Maybe the naming of 'mps_orig_le' could be improved...
> >
> > include/net/bluetooth/l2cap.h | 1 +
> > net/bluetooth/l2cap_core.c | 4 +++-
> > 2 files changed, 4 insertions(+), 1 deletion(-)
> >
> > diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
> > index 010f1a8fd15f..c6744cce75b1 100644
> > --- a/include/net/bluetooth/l2cap.h
> > +++ b/include/net/bluetooth/l2cap.h
> > @@ -552,6 +552,7 @@ struct l2cap_chan {
> > __u16 retrans_timeout;
> > __u16 monitor_timeout;
> > __u16 mps;
> > + __u16 mps_orig_le;
>
> Hmm, I wonder if it wouldn't make more sense to have imps/mps_rx and
> omps/mps_tx? I guess that is why you need a separate field; otherwise,
> the MPS is updated with the remote MPS, causing us to accept the
> packets as valid.

I can confirm that I needed to introduce the new member because of this.

> That said it would need to change quite a few more
> places it seems

I feel that I don't have enough oversight for fixing this everywhere (but of
course I could try). I just did the minimum amount of changes to fix this
particular test.

Could you eventually take this over and propose a patch?

Thanks,
Christian
>
> >
> > __u16 tx_credits;
> > __u16 rx_credits;
> > diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> > index ddac5b9270bf..c9555b0a3461 100644
> > --- a/net/bluetooth/l2cap_core.c
> > +++ b/net/bluetooth/l2cap_core.c
> > @@ -568,6 +568,7 @@ static void l2cap_le_flowctl_init(struct l2cap_chan *chan, u16 tx_credits)
> > chan->tx_credits = tx_credits;
> > /* Derive MPS from connection MTU to stop HCI fragmentation */
> > chan->mps = min_t(u16, chan->imtu, chan->conn->mtu - L2CAP_HDR_SIZE);
> > + chan->mps_orig_le = chan->mps;
> > chan->rx_credits = l2cap_le_rx_credits(chan);
> >
> > skb_queue_head_init(&chan->tx_q);
> > @@ -580,6 +581,7 @@ static void l2cap_ecred_init(struct l2cap_chan *chan, u16 tx_credits)
> > /* L2CAP implementations shall support a minimum MPS of 64 octets */
> > if (chan->mps < L2CAP_ECRED_MIN_MPS) {
> > chan->mps = L2CAP_ECRED_MIN_MPS;
> > + chan->mps_orig_le = L2CAP_ECRED_MIN_MPS;
> > chan->rx_credits = l2cap_le_rx_credits(chan);
> > }
> > }
> > @@ -6662,7 +6664,7 @@ static int l2cap_ecred_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
> > return -ENOBUFS;
> > }
> >
> > - if (chan->imtu < skb->len) {
> > + if (chan->mps_orig_le < skb->len || chan->imtu < skb->len) {
> > BT_ERR("Too big LE L2CAP PDU");
> > l2cap_send_disconn_req(chan, ECONNRESET);
> > return -ENOBUFS;
> > --
> > 2.44.4
> >
>
>
>