Commit 8a727100 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files
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.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents d8152cfe a56a1138
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -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);
		if (IS_ERR(tmp)) {
			kfree_skb(skb);
			return tmp;
			return skb;
		}

		len -= tmp->len;
+8 −0
Original line number Diff line number Diff line
@@ -1489,6 +1489,14 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
/* Extended advertising support */
#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 ----- */
#define HCI_PROTO_DEFER             0x01

+1 −0
Original line number Diff line number Diff line
@@ -2738,6 +2738,7 @@ void hci_release_dev(struct hci_dev *hdev)
	hci_dev_unlock(hdev);

	ida_simple_remove(&hci_index_ida, hdev->id);
	kfree_skb(hdev->sent_cmd);
	kfree(hdev);
}
EXPORT_SYMBOL(hci_release_dev);
+21 −9
Original line number Diff line number Diff line
@@ -1841,6 +1841,7 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev)
	struct bdaddr_list *b, *t;
	u8 num_entries = 0;
	bool pend_conn, pend_report;
	u8 filter_policy;
	int err;

	/* 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)
		err = -EINVAL;

done:
	filter_policy = err ? 0x00 : 0x01;

	/* Enable address resolution when LL Privacy is enabled. */
	err = hci_le_set_addr_resolution_enable_sync(hdev, 0x01);
	if (err)
@@ -1937,7 +1940,7 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev)
		hci_resume_advertising_sync(hdev);

	/* 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 */
@@ -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)
		events[0] |= 0x40;	/* LE Data Length Change */

	/* If the controller supports LL Privacy feature, enable
	 * the corresponding event.
	/* If the controller supports LL Privacy feature or LE Extended Adv,
	 * 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 */

	/* If the controller supports Extended Scanner Filter
@@ -4106,9 +4109,9 @@ int hci_dev_close_sync(struct hci_dev *hdev)
	hci_inquiry_cache_flush(hdev);
	hci_pend_le_actions_clear(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);
	hci_dev_unlock(hdev);

	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,
	return __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_EXT_CREATE_CONN,
					plen, data,
					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)
@@ -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.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,
				       sizeof(cp), &cp, HCI_EV_LE_CONN_COMPLETE,
				       HCI_CMD_TIMEOUT, NULL);
				       sizeof(cp), &cp,
				       use_enhanced_conn_complete(hdev) ?
				       HCI_EV_LE_ENHANCED_CONN_COMPLETE :
				       HCI_EV_LE_CONN_COMPLETE,
				       conn->conn_timeout, NULL);

done:
	/* Re-enable advertising after the connection attempt is finished. */
+2 −1
Original line number Diff line number Diff line
@@ -77,11 +77,12 @@ int mgmt_send_event_skb(unsigned short channel, struct sk_buff *skb, int flag,
{
	struct hci_dev *hdev;
	struct mgmt_hdr *hdr;
	int len = skb->len;
	int len;

	if (!skb)
		return -EINVAL;

	len = skb->len;
	hdev = bt_cb(skb)->mgmt.hdev;

	/* Time stamp */