summaryrefslogtreecommitdiff
path: root/net/bluetooth
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2021-03-15 23:04:37 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-04-05 12:23:36 +0300
commit77a61df0a0e6cf9495b5524e65ffb32e06000871 (patch)
treebf33cb3be107d133417e1ac3b0e3c355904a4c2e /net/bluetooth
parent65ceb170749b65292bb70406c74cd6dd6afcc013 (diff)
downloadlinux-77a61df0a0e6cf9495b5524e65ffb32e06000871.tar.xz
Bluetooth: L2CAP: Fix not checking for maximum number of DCID
[ Upstream commit 7cf3b1dd6aa603fd80969e9e7160becf1455a0eb ] When receiving L2CAP_CREDIT_BASED_CONNECTION_REQ the remote may request more channels than allowed by the spec (10 octecs = 5 CIDs) so this checks if the number of channels is bigger than the maximum allowed and respond with an error. Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org> Stable-dep-of: 9aa9d9473f15 ("Bluetooth: L2CAP: Fix responding with wrong PDU type") Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/l2cap_core.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index bde90df6b497..b01677882e38 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -5952,7 +5952,7 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
struct l2cap_ecred_conn_req *req = (void *) data;
struct {
struct l2cap_ecred_conn_rsp rsp;
- __le16 dcid[5];
+ __le16 dcid[L2CAP_ECRED_MAX_CID];
} __packed pdu;
struct l2cap_chan *chan, *pchan;
u16 mtu, mps;
@@ -5969,6 +5969,14 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
goto response;
}
+ cmd_len -= sizeof(*req);
+ num_scid = cmd_len / sizeof(u16);
+
+ if (num_scid > ARRAY_SIZE(pdu.dcid)) {
+ result = L2CAP_CR_LE_INVALID_PARAMS;
+ goto response;
+ }
+
mtu = __le16_to_cpu(req->mtu);
mps = __le16_to_cpu(req->mps);
@@ -6013,8 +6021,6 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
}
result = L2CAP_CR_LE_SUCCESS;
- cmd_len -= sizeof(*req);
- num_scid = cmd_len / sizeof(u16);
for (i = 0; i < num_scid; i++) {
u16 scid = __le16_to_cpu(req->scid[i]);