diff options
author | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2021-03-15 23:04:37 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2023-04-05 12:23:36 +0300 |
commit | 77a61df0a0e6cf9495b5524e65ffb32e06000871 (patch) | |
tree | bf33cb3be107d133417e1ac3b0e3c355904a4c2e /net/bluetooth | |
parent | 65ceb170749b65292bb70406c74cd6dd6afcc013 (diff) | |
download | linux-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.c | 12 |
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]); |