]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-client.git/commitdiff
Bluetooth: L2CAP: Fix not checking output MTU is acceptable on L2CAP_ECRED_CONN_REQ
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Tue, 17 Feb 2026 18:29:43 +0000 (13:29 -0500)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Mon, 23 Feb 2026 21:07:55 +0000 (16:07 -0500)
Upon receiving L2CAP_ECRED_CONN_REQ the given MTU shall be checked
against the suggested MTU of the listening socket as that is required
by the likes of PTS L2CAP/ECFC/BV-27-C test which expects
L2CAP_CR_LE_UNACCEPT_PARAMS if the MTU is lowers than socket omtu.

In order to be able to set chan->omtu the code now allows setting
setsockopt(BT_SNDMTU), but it is only allowed when connection has not
been stablished since there is no procedure to reconfigure the output
MTU.

Link: https://github.com/bluez/bluez/issues/1895
Fixes: 15f02b910562 ("Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode")
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
net/bluetooth/l2cap_core.c
net/bluetooth/l2cap_sock.c

index 9452c6179acbf3734a8ad413bc515a924689fed1..90676ca0e92b6802f6f71f4bb486ff4a6cc9339d 100644 (file)
@@ -5117,6 +5117,14 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
                goto unlock;
        }
 
+       /* Check if the listening channel has set an output MTU then the
+        * requested MTU shall be less than or equal to that value.
+        */
+       if (pchan->omtu && mtu < pchan->omtu) {
+               result = L2CAP_CR_LE_UNACCEPT_PARAMS;
+               goto unlock;
+       }
+
        result = L2CAP_CR_LE_SUCCESS;
 
        for (i = 0; i < num_scid; i++) {
index 62ceda979f39467592beb37db78d608d49d1491b..477b4d1454593207717d79fd2e08cded47e8699a 100644 (file)
@@ -1029,10 +1029,17 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
                        break;
                }
 
-               /* Setting is not supported as it's the remote side that
-                * decides this.
-                */
-               err = -EPERM;
+               /* Only allow setting output MTU when not connected */
+               if (sk->sk_state == BT_CONNECTED) {
+                       err = -EISCONN;
+                       break;
+               }
+
+               err = copy_safe_from_sockptr(&mtu, sizeof(mtu), optval, optlen);
+               if (err)
+                       break;
+
+               chan->omtu = mtu;
                break;
 
        case BT_RCVMTU: