Commit 8a727100 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge tag 'for-net-2022-02-24' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth

Luiz Augusto von Dentz says:

====================
bluetooth pull request for net:

 - Fix regression with RFCOMM
 - Fix regression with LE devices using Privacy (RPA)
 - Fix regression with LE devices not waiting proper timeout to
   establish connections
 - Fix race in smp

* tag 'for-net-2022-02-24' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth:
  Bluetooth: hci_sync: Fix not using conn_timeout
  Bluetooth: hci_sync: Fix hci_update_accept_list_sync
  Bluetooth: assign len after null check
  Bluetooth: Fix bt_skb_sendmmsg not allocating partial chunks
  Bluetooth: fix data races in smp_unregister(), smp_del_chan()
  Bluetooth: hci_core: Fix leaking sent_cmd skb
====================

Link: https://lore.kernel.org/r/20220224210838.197787-1-luiz.dentz@gmail.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents d8152cfe a56a1138
...@@ -506,8 +506,7 @@ static inline struct sk_buff *bt_skb_sendmmsg(struct sock *sk, ...@@ -506,8 +506,7 @@ static inline struct sk_buff *bt_skb_sendmmsg(struct sock *sk,
tmp = bt_skb_sendmsg(sk, msg, len, mtu, headroom, tailroom); tmp = bt_skb_sendmsg(sk, msg, len, mtu, headroom, tailroom);
if (IS_ERR(tmp)) { if (IS_ERR(tmp)) {
kfree_skb(skb); return skb;
return tmp;
} }
len -= tmp->len; len -= tmp->len;
......
...@@ -1489,6 +1489,14 @@ void hci_conn_del_sysfs(struct hci_conn *conn); ...@@ -1489,6 +1489,14 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
/* Extended advertising support */ /* Extended advertising support */
#define ext_adv_capable(dev) (((dev)->le_features[1] & HCI_LE_EXT_ADV)) #define ext_adv_capable(dev) (((dev)->le_features[1] & HCI_LE_EXT_ADV))
/* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E page 1789:
*
* C24: Mandatory if the LE Controller supports Connection State and either
* LE Feature (LL Privacy) or LE Feature (Extended Advertising) is supported
*/
#define use_enhanced_conn_complete(dev) (ll_privacy_capable(dev) || \
ext_adv_capable(dev))
/* ----- HCI protocols ----- */ /* ----- HCI protocols ----- */
#define HCI_PROTO_DEFER 0x01 #define HCI_PROTO_DEFER 0x01
......
...@@ -2738,6 +2738,7 @@ void hci_release_dev(struct hci_dev *hdev) ...@@ -2738,6 +2738,7 @@ void hci_release_dev(struct hci_dev *hdev)
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
ida_simple_remove(&hci_index_ida, hdev->id); ida_simple_remove(&hci_index_ida, hdev->id);
kfree_skb(hdev->sent_cmd);
kfree(hdev); kfree(hdev);
} }
EXPORT_SYMBOL(hci_release_dev); EXPORT_SYMBOL(hci_release_dev);
......
...@@ -1841,6 +1841,7 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev) ...@@ -1841,6 +1841,7 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev)
struct bdaddr_list *b, *t; struct bdaddr_list *b, *t;
u8 num_entries = 0; u8 num_entries = 0;
bool pend_conn, pend_report; bool pend_conn, pend_report;
u8 filter_policy;
int err; int err;
/* Pause advertising if resolving list can be used as controllers are /* Pause advertising if resolving list can be used as controllers are
...@@ -1927,6 +1928,8 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev) ...@@ -1927,6 +1928,8 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev)
err = -EINVAL; err = -EINVAL;
done: done:
filter_policy = err ? 0x00 : 0x01;
/* Enable address resolution when LL Privacy is enabled. */ /* Enable address resolution when LL Privacy is enabled. */
err = hci_le_set_addr_resolution_enable_sync(hdev, 0x01); err = hci_le_set_addr_resolution_enable_sync(hdev, 0x01);
if (err) if (err)
...@@ -1937,7 +1940,7 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev) ...@@ -1937,7 +1940,7 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev)
hci_resume_advertising_sync(hdev); hci_resume_advertising_sync(hdev);
/* Select filter policy to use accept list */ /* Select filter policy to use accept list */
return err ? 0x00 : 0x01; return filter_policy;
} }
/* Returns true if an le connection is in the scanning state */ /* Returns true if an le connection is in the scanning state */
...@@ -3262,10 +3265,10 @@ static int hci_le_set_event_mask_sync(struct hci_dev *hdev) ...@@ -3262,10 +3265,10 @@ static int hci_le_set_event_mask_sync(struct hci_dev *hdev)
if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT)
events[0] |= 0x40; /* LE Data Length Change */ events[0] |= 0x40; /* LE Data Length Change */
/* If the controller supports LL Privacy feature, enable /* If the controller supports LL Privacy feature or LE Extended Adv,
* the corresponding event. * enable the corresponding event.
*/ */
if (hdev->le_features[0] & HCI_LE_LL_PRIVACY) if (use_enhanced_conn_complete(hdev))
events[1] |= 0x02; /* LE Enhanced Connection Complete */ events[1] |= 0x02; /* LE Enhanced Connection Complete */
/* If the controller supports Extended Scanner Filter /* If the controller supports Extended Scanner Filter
...@@ -4106,9 +4109,9 @@ int hci_dev_close_sync(struct hci_dev *hdev) ...@@ -4106,9 +4109,9 @@ int hci_dev_close_sync(struct hci_dev *hdev)
hci_inquiry_cache_flush(hdev); hci_inquiry_cache_flush(hdev);
hci_pend_le_actions_clear(hdev); hci_pend_le_actions_clear(hdev);
hci_conn_hash_flush(hdev); hci_conn_hash_flush(hdev);
hci_dev_unlock(hdev); /* Prevent data races on hdev->smp_data or hdev->smp_bredr_data */
smp_unregister(hdev); smp_unregister(hdev);
hci_dev_unlock(hdev);
hci_sock_dev_event(hdev, HCI_DEV_DOWN); hci_sock_dev_event(hdev, HCI_DEV_DOWN);
...@@ -5185,7 +5188,7 @@ int hci_le_ext_create_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, ...@@ -5185,7 +5188,7 @@ int hci_le_ext_create_conn_sync(struct hci_dev *hdev, struct hci_conn *conn,
return __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_EXT_CREATE_CONN, return __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_EXT_CREATE_CONN,
plen, data, plen, data,
HCI_EV_LE_ENHANCED_CONN_COMPLETE, HCI_EV_LE_ENHANCED_CONN_COMPLETE,
HCI_CMD_TIMEOUT, NULL); conn->conn_timeout, NULL);
} }
int hci_le_create_conn_sync(struct hci_dev *hdev, struct hci_conn *conn) int hci_le_create_conn_sync(struct hci_dev *hdev, struct hci_conn *conn)
...@@ -5270,9 +5273,18 @@ int hci_le_create_conn_sync(struct hci_dev *hdev, struct hci_conn *conn) ...@@ -5270,9 +5273,18 @@ int hci_le_create_conn_sync(struct hci_dev *hdev, struct hci_conn *conn)
cp.min_ce_len = cpu_to_le16(0x0000); cp.min_ce_len = cpu_to_le16(0x0000);
cp.max_ce_len = cpu_to_le16(0x0000); cp.max_ce_len = cpu_to_le16(0x0000);
/* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E page 2261:
*
* If this event is unmasked and the HCI_LE_Connection_Complete event
* is unmasked, only the HCI_LE_Enhanced_Connection_Complete event is
* sent when a new connection has been created.
*/
err = __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_CREATE_CONN, err = __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_CREATE_CONN,
sizeof(cp), &cp, HCI_EV_LE_CONN_COMPLETE, sizeof(cp), &cp,
HCI_CMD_TIMEOUT, NULL); use_enhanced_conn_complete(hdev) ?
HCI_EV_LE_ENHANCED_CONN_COMPLETE :
HCI_EV_LE_CONN_COMPLETE,
conn->conn_timeout, NULL);
done: done:
/* Re-enable advertising after the connection attempt is finished. */ /* Re-enable advertising after the connection attempt is finished. */
......
...@@ -77,11 +77,12 @@ int mgmt_send_event_skb(unsigned short channel, struct sk_buff *skb, int flag, ...@@ -77,11 +77,12 @@ int mgmt_send_event_skb(unsigned short channel, struct sk_buff *skb, int flag,
{ {
struct hci_dev *hdev; struct hci_dev *hdev;
struct mgmt_hdr *hdr; struct mgmt_hdr *hdr;
int len = skb->len; int len;
if (!skb) if (!skb)
return -EINVAL; return -EINVAL;
len = skb->len;
hdev = bt_cb(skb)->mgmt.hdev; hdev = bt_cb(skb)->mgmt.hdev;
/* Time stamp */ /* Time stamp */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment