Skip to content

Commit 765c2a9

Browse files
Johan HedbergGustavo F. Padovan
authored andcommitted
Bluetooth: Fix race condition with conn->sec_level
The conn->sec_level value is supposed to represent the current level of security that the connection has. However, by assigning to it before requesting authentication it will have the wrong value during the authentication procedure. To fix this a pending_sec_level variable is added which is used to track the desired security level while making sure that sec_level always represents the current level of security. Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
1 parent d00ef24 commit 765c2a9

File tree

3 files changed

+12
-6
lines changed

3 files changed

+12
-6
lines changed

include/net/bluetooth/hci_core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ struct hci_conn {
184184
__u32 link_mode;
185185
__u8 auth_type;
186186
__u8 sec_level;
187+
__u8 pending_sec_level;
187188
__u8 power_save;
188189
__u16 disc_timeout;
189190
unsigned long pend;

net/bluetooth/hci_conn.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,8 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
379379
hci_conn_hold(acl);
380380

381381
if (acl->state == BT_OPEN || acl->state == BT_CLOSED) {
382-
acl->sec_level = sec_level;
382+
acl->sec_level = BT_SECURITY_LOW;
383+
acl->pending_sec_level = sec_level;
383384
acl->auth_type = auth_type;
384385
hci_acl_connect(acl);
385386
}
@@ -437,8 +438,11 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
437438
{
438439
BT_DBG("conn %p", conn);
439440

441+
if (conn->pending_sec_level > sec_level)
442+
sec_level = conn->pending_sec_level;
443+
440444
if (sec_level > conn->sec_level)
441-
conn->sec_level = sec_level;
445+
conn->pending_sec_level = sec_level;
442446
else if (conn->link_mode & HCI_LM_AUTH)
443447
return 1;
444448

net/bluetooth/hci_event.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -692,13 +692,13 @@ static int hci_outgoing_auth_needed(struct hci_dev *hdev,
692692
if (conn->state != BT_CONFIG || !conn->out)
693693
return 0;
694694

695-
if (conn->sec_level == BT_SECURITY_SDP)
695+
if (conn->pending_sec_level == BT_SECURITY_SDP)
696696
return 0;
697697

698698
/* Only request authentication for SSP connections or non-SSP
699699
* devices with sec_level HIGH */
700700
if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) &&
701-
conn->sec_level != BT_SECURITY_HIGH)
701+
conn->pending_sec_level != BT_SECURITY_HIGH)
702702
return 0;
703703

704704
return 1;
@@ -1095,9 +1095,10 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
10951095

10961096
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
10971097
if (conn) {
1098-
if (!ev->status)
1098+
if (!ev->status) {
10991099
conn->link_mode |= HCI_LM_AUTH;
1100-
else
1100+
conn->sec_level = conn->pending_sec_level;
1101+
} else
11011102
conn->sec_level = BT_SECURITY_LOW;
11021103

11031104
clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);

0 commit comments

Comments
 (0)