diff options
author | Johan Hedberg <johan.hedberg@nokia.com> | 2011-01-19 01:36:52 -0500 |
---|---|---|
committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-01-19 11:43:11 -0500 |
commit | 765c2a964b49bd06b61a52991519281c85d82b67 (patch) | |
tree | e646cb50bd43f9a74583391805529d3397934f42 /net/bluetooth/hci_event.c | |
parent | d00ef24fc2923b65fdd440dc6445903e965841ac (diff) |
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>
Diffstat (limited to 'net/bluetooth/hci_event.c')
-rw-r--r-- | net/bluetooth/hci_event.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 38100170d380..a290854fdaa6 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -692,13 +692,13 @@ static int hci_outgoing_auth_needed(struct hci_dev *hdev, | |||
692 | if (conn->state != BT_CONFIG || !conn->out) | 692 | if (conn->state != BT_CONFIG || !conn->out) |
693 | return 0; | 693 | return 0; |
694 | 694 | ||
695 | if (conn->sec_level == BT_SECURITY_SDP) | 695 | if (conn->pending_sec_level == BT_SECURITY_SDP) |
696 | return 0; | 696 | return 0; |
697 | 697 | ||
698 | /* Only request authentication for SSP connections or non-SSP | 698 | /* Only request authentication for SSP connections or non-SSP |
699 | * devices with sec_level HIGH */ | 699 | * devices with sec_level HIGH */ |
700 | if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) && | 700 | if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) && |
701 | conn->sec_level != BT_SECURITY_HIGH) | 701 | conn->pending_sec_level != BT_SECURITY_HIGH) |
702 | return 0; | 702 | return 0; |
703 | 703 | ||
704 | return 1; | 704 | return 1; |
@@ -1095,9 +1095,10 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
1095 | 1095 | ||
1096 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); | 1096 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); |
1097 | if (conn) { | 1097 | if (conn) { |
1098 | if (!ev->status) | 1098 | if (!ev->status) { |
1099 | conn->link_mode |= HCI_LM_AUTH; | 1099 | conn->link_mode |= HCI_LM_AUTH; |
1100 | else | 1100 | conn->sec_level = conn->pending_sec_level; |
1101 | } else | ||
1101 | conn->sec_level = BT_SECURITY_LOW; | 1102 | conn->sec_level = BT_SECURITY_LOW; |
1102 | 1103 | ||
1103 | clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); | 1104 | clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); |