mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-07-05 13:25:20 +02:00
Bluetooth: L2CAP: Fix not checking l2cap_chan security level
[ Upstream commit 7af8479d9eb4319b4ba7b47a8c4d2c55af1c31e1 ] l2cap_check_enc_key_size shall check the security level of the l2cap_chan rather than the hci_conn since for incoming connection request that may be different as hci_conn may already been encrypted using a different security level. Fixes: 522e9ed157e3 ("Bluetooth: l2cap: Check encryption key size on incoming connection") Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
ca51db2316
commit
1e8b7e96f7
|
@ -1411,7 +1411,8 @@ static void l2cap_request_info(struct l2cap_conn *conn)
|
||||||
sizeof(req), &req);
|
sizeof(req), &req);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool l2cap_check_enc_key_size(struct hci_conn *hcon)
|
static bool l2cap_check_enc_key_size(struct hci_conn *hcon,
|
||||||
|
struct l2cap_chan *chan)
|
||||||
{
|
{
|
||||||
/* The minimum encryption key size needs to be enforced by the
|
/* The minimum encryption key size needs to be enforced by the
|
||||||
* host stack before establishing any L2CAP connections. The
|
* host stack before establishing any L2CAP connections. The
|
||||||
|
@ -1425,7 +1426,7 @@ static bool l2cap_check_enc_key_size(struct hci_conn *hcon)
|
||||||
int min_key_size = hcon->hdev->min_enc_key_size;
|
int min_key_size = hcon->hdev->min_enc_key_size;
|
||||||
|
|
||||||
/* On FIPS security level, key size must be 16 bytes */
|
/* On FIPS security level, key size must be 16 bytes */
|
||||||
if (hcon->sec_level == BT_SECURITY_FIPS)
|
if (chan->sec_level == BT_SECURITY_FIPS)
|
||||||
min_key_size = 16;
|
min_key_size = 16;
|
||||||
|
|
||||||
return (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags) ||
|
return (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags) ||
|
||||||
|
@ -1453,7 +1454,7 @@ static void l2cap_do_start(struct l2cap_chan *chan)
|
||||||
!__l2cap_no_conn_pending(chan))
|
!__l2cap_no_conn_pending(chan))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (l2cap_check_enc_key_size(conn->hcon))
|
if (l2cap_check_enc_key_size(conn->hcon, chan))
|
||||||
l2cap_start_connection(chan);
|
l2cap_start_connection(chan);
|
||||||
else
|
else
|
||||||
__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
|
__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
|
||||||
|
@ -1528,7 +1529,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (l2cap_check_enc_key_size(conn->hcon))
|
if (l2cap_check_enc_key_size(conn->hcon, chan))
|
||||||
l2cap_start_connection(chan);
|
l2cap_start_connection(chan);
|
||||||
else
|
else
|
||||||
l2cap_chan_close(chan, ECONNREFUSED);
|
l2cap_chan_close(chan, ECONNREFUSED);
|
||||||
|
@ -3957,7 +3958,7 @@ static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
|
||||||
/* Check if the ACL is secure enough (if not SDP) */
|
/* Check if the ACL is secure enough (if not SDP) */
|
||||||
if (psm != cpu_to_le16(L2CAP_PSM_SDP) &&
|
if (psm != cpu_to_le16(L2CAP_PSM_SDP) &&
|
||||||
(!hci_conn_check_link_mode(conn->hcon) ||
|
(!hci_conn_check_link_mode(conn->hcon) ||
|
||||||
!l2cap_check_enc_key_size(conn->hcon))) {
|
!l2cap_check_enc_key_size(conn->hcon, pchan))) {
|
||||||
conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
|
conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
|
||||||
result = L2CAP_CR_SEC_BLOCK;
|
result = L2CAP_CR_SEC_BLOCK;
|
||||||
goto response;
|
goto response;
|
||||||
|
@ -7317,7 +7318,7 @@ static void l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chan->state == BT_CONNECT) {
|
if (chan->state == BT_CONNECT) {
|
||||||
if (!status && l2cap_check_enc_key_size(hcon))
|
if (!status && l2cap_check_enc_key_size(hcon, chan))
|
||||||
l2cap_start_connection(chan);
|
l2cap_start_connection(chan);
|
||||||
else
|
else
|
||||||
__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
|
__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
|
||||||
|
@ -7327,7 +7328,7 @@ static void l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
|
||||||
struct l2cap_conn_rsp rsp;
|
struct l2cap_conn_rsp rsp;
|
||||||
__u16 res, stat;
|
__u16 res, stat;
|
||||||
|
|
||||||
if (!status && l2cap_check_enc_key_size(hcon)) {
|
if (!status && l2cap_check_enc_key_size(hcon, chan)) {
|
||||||
if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
|
if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
|
||||||
res = L2CAP_CR_PEND;
|
res = L2CAP_CR_PEND;
|
||||||
stat = L2CAP_CS_AUTHOR_PEND;
|
stat = L2CAP_CS_AUTHOR_PEND;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user