mirror of
https://github.com/torvalds/linux.git
synced 2026-10-23 15:32:04 +02:00
bluetooth pull request for net:
Core: - hci_core: Serialize ACL scheduling with channel deletion - hci_core: Serialize SCO and ISO scheduling with teardown - hci_core: Serialize fragmented ISO packet queueing - hci_core: Fix inquiry cache timestamps on 64-bit systems - hci_core: free the HCI ID if naming fails - hci_conn: Lock parent access during enhanced SCO setup - hci_sync: Fix inquiry cache use-after-free - hci_sync: don't drain cmd_sync backlog on unregister - RFCOMM: Fix initial port reference race - SMP: Serialize SMP remote OOB data access Drivers: - btintel: fix buffer over-read in btintel_hw_error() - btintel: validate DDC record lengths - btintel_pcie: fix plen overflow in btintel_pcie_recv_frame() - btintel_pcie: reject oversized TX packets in send_frame() -----BEGIN PGP SIGNATURE----- iQJNBAABCgA3FiEE7E6oRXp8w05ovYr/9JCA4xAyCykFAmq6h1YZHGx1aXoudm9u LmRlbnR6QGludGVsLmNvbQAKCRD0kIDjEDILKZEND/42wPb5lDOUU7VgMG6THiU/ G6r4LMsjHkpGfkZox4OIAzXEbWvby9hZgilO2M8uXvHUqHrZ9IcfsA8rXgK+Bort EcoQGzq0X6RSysoJ3XOXj1QW6jXR8XqN9SongdaCR6I6xlGtXkMkbD8+APSII3oI xo5oU3MrsDPqIL+ow6GmYtAA1aGoD95QZL5S1tBaYwUB8mThDJQchE0DTzNk2jZ0 gjgvfNBXkFjeIzrlVw/zhs7hJVebCgAZvrSlriCK1rvgU/3D2UKYYQPOu8ztjM18 ITtKniIddPmALaXmJHiR/zt6nruw3/CUEkIdjd3a/XiP1n6xGCsGd9tte98Qr/8X Mr9ID7i7Old2WZc5nx+pOf+Bliy2omluzIsiqGO3KaoSCht2wZOwjKMEaIS1cS/m YdMTZ+nQshHRpO0w8nVObIC1lGLYBPjnwVv5IFXWiepT90vBij7pgDZHUgx2HO2n a7ejJcgDyHkGWI7loXAs1qZPNjcTRFO9IQ84wpARe94Hc7NaRcGBUCz3b3HH/5+H TuihQbVGVkV96jzeF7cIDifcZRky8yoUW/AoEfAuZzkQjonn9NBZ063ulUdZhEFc W8Psa1e/zrYqKgH7U9l4gfDn5yu1mEIFBKgAqZ2e0CbsJAklt3yY08xj0KI1kgaB FMRl+SFuGtDThQUk1ifFng== =ToWl -----END PGP SIGNATURE----- Merge tag 'for-net-2026-09-28' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth Luiz Augusto von Dentz says: ==================== bluetooth pull request for net: Core: - hci_core: Serialize ACL scheduling with channel deletion - hci_core: Serialize SCO and ISO scheduling with teardown - hci_core: Serialize fragmented ISO packet queueing - hci_core: Fix inquiry cache timestamps on 64-bit systems - hci_core: free the HCI ID if naming fails - hci_conn: Lock parent access during enhanced SCO setup - hci_sync: Fix inquiry cache use-after-free - hci_sync: don't drain cmd_sync backlog on unregister - RFCOMM: Fix initial port reference race - SMP: Serialize SMP remote OOB data access Drivers: - btintel: fix buffer over-read in btintel_hw_error() - btintel: validate DDC record lengths - btintel_pcie: fix plen overflow in btintel_pcie_recv_frame() - btintel_pcie: reject oversized TX packets in send_frame() * tag 'for-net-2026-09-28' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth: Bluetooth: hci_core: Serialize SCO and ISO scheduling with teardown Bluetooth: hci_core: Serialize ACL scheduling with channel deletion Bluetooth: Serialize SMP remote OOB data access Bluetooth: RFCOMM: Fix initial port reference race Bluetooth: hci_sync: Fix inquiry cache use-after-free Bluetooth: hci_sync: don't drain cmd_sync backlog on unregister Bluetooth: hci_core: Serialize fragmented ISO packet queueing Bluetooth: hci_conn: Lock parent access during enhanced SCO setup Bluetooth: btintel: validate DDC record lengths Bluetooth: hci_core: free the HCI ID if naming fails Bluetooth: hci_core: Fix inquiry cache timestamps on 64-bit systems Bluetooth: btintel_pcie: reject oversized TX packets in send_frame() Bluetooth: btintel_pcie: fix plen overflow in btintel_pcie_recv_frame() Bluetooth: btintel: fix buffer over-read in btintel_hw_error() ==================== Link: https://patch.msgid.link/20260928152919.942973-1-luiz.dentz@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
382cf97689
|
|
@ -289,7 +289,8 @@ void btintel_hw_error(struct hci_dev *hdev, u8 code)
|
|||
goto unlock;
|
||||
}
|
||||
|
||||
bt_dev_err(hdev, "Exception info %s", (char *)(skb->data + 1));
|
||||
bt_dev_err(hdev, "Exception info %.*s", (int)(skb->len - 1),
|
||||
(char *)(skb->data + 1));
|
||||
|
||||
kfree_skb(skb);
|
||||
|
||||
|
|
@ -408,8 +409,16 @@ int btintel_load_ddc_config(struct hci_dev *hdev, const char *ddc_name)
|
|||
/* DDC file contains one or more DDC structure which has
|
||||
* Length (1 byte), DDC ID (2 bytes), and DDC value (Length - 2).
|
||||
*/
|
||||
while (fw->size > fw_ptr - fw->data) {
|
||||
u8 cmd_plen = fw_ptr[0] + sizeof(u8);
|
||||
while (fw->size > (size_t)(fw_ptr - fw->data)) {
|
||||
size_t remaining = fw->size - (fw_ptr - fw->data);
|
||||
unsigned int cmd_plen = fw_ptr[0] + 1U;
|
||||
|
||||
if (cmd_plen < 3 || cmd_plen > U8_MAX || cmd_plen > remaining) {
|
||||
bt_dev_err(hdev, "Malformed DDC record (plen=%u, remaining=%zu)",
|
||||
cmd_plen, remaining);
|
||||
release_firmware(fw);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
skb = __hci_cmd_sync(hdev, 0xfc8b, cmd_plen, fw_ptr,
|
||||
HCI_INIT_TIMEOUT);
|
||||
|
|
|
|||
|
|
@ -1197,7 +1197,7 @@ static int btintel_pcie_recv_frame(struct btintel_pcie_data *data,
|
|||
{
|
||||
int ret;
|
||||
u8 pkt_type;
|
||||
u16 plen;
|
||||
u32 plen;
|
||||
u32 pcie_pkt_type;
|
||||
void *pdata;
|
||||
struct hci_dev *hdev = data->hdev;
|
||||
|
|
@ -2219,6 +2219,16 @@ static int btintel_pcie_send_frame(struct hci_dev *hdev,
|
|||
if (test_bit(BTINTEL_PCIE_RECOVERY_IN_PROGRESS, &data->flags))
|
||||
return -ENODEV;
|
||||
|
||||
/* Account for the 4-byte PCIe type header prepended before the
|
||||
* DMA copy. Written as a subtraction to avoid wrap-around on
|
||||
* attacker-controlled skb->len.
|
||||
*/
|
||||
if (skb->len > BTINTEL_PCIE_BUFFER_SIZE - BTINTEL_PCIE_HCI_TYPE_LEN) {
|
||||
bt_dev_err(hdev, "Packet too large: %u > %u", skb->len,
|
||||
BTINTEL_PCIE_BUFFER_SIZE - BTINTEL_PCIE_HCI_TYPE_LEN);
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
/* Due to the fw limitation, the type header of the packet should be
|
||||
* 4 bytes unlike 1 byte for UART. In UART, the firmware can read
|
||||
* the first byte to get the packet type and redirect the rest of data
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ struct inquiry_entry {
|
|||
NAME_PENDING,
|
||||
NAME_KNOWN,
|
||||
} name_state;
|
||||
__u32 timestamp;
|
||||
unsigned long timestamp;
|
||||
struct inquiry_data data;
|
||||
};
|
||||
|
||||
|
|
@ -78,7 +78,7 @@ struct discovery_state {
|
|||
struct list_head all; /* All devices found during inquiry */
|
||||
struct list_head unknown; /* Name state not known */
|
||||
struct list_head resolve; /* Name needs to be resolved */
|
||||
__u32 timestamp;
|
||||
unsigned long timestamp;
|
||||
bdaddr_t last_adv_addr;
|
||||
u8 last_adv_addr_type;
|
||||
s8 last_adv_rssi;
|
||||
|
|
@ -562,6 +562,7 @@ struct hci_dev {
|
|||
struct list_head link_keys;
|
||||
struct list_head long_term_keys;
|
||||
struct list_head identity_resolving_keys;
|
||||
struct mutex remote_oob_lock;
|
||||
struct list_head remote_oob_data;
|
||||
struct list_head le_accept_list;
|
||||
struct list_head le_resolv_list;
|
||||
|
|
|
|||
|
|
@ -302,11 +302,13 @@ static int hci_enhanced_setup_sync(struct hci_dev *hdev, void *data)
|
|||
cp.tx_bandwidth = cpu_to_le32(0x00001f40);
|
||||
cp.rx_bandwidth = cpu_to_le32(0x00001f40);
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
switch (conn->codec.id) {
|
||||
case BT_CODEC_MSBC:
|
||||
if (!find_next_esco_param(conn, esco_param_msbc,
|
||||
ARRAY_SIZE(esco_param_msbc)))
|
||||
return -EINVAL;
|
||||
goto unlock;
|
||||
|
||||
param = &esco_param_msbc[conn->attempt - 1];
|
||||
cp.tx_coding_format.id = 0x05;
|
||||
|
|
@ -332,7 +334,7 @@ static int hci_enhanced_setup_sync(struct hci_dev *hdev, void *data)
|
|||
case BT_CODEC_TRANSPARENT:
|
||||
if (!find_next_esco_param(conn, esco_param_msbc,
|
||||
ARRAY_SIZE(esco_param_msbc)))
|
||||
return -EINVAL;
|
||||
goto unlock;
|
||||
|
||||
param = &esco_param_msbc[conn->attempt - 1];
|
||||
cp.tx_coding_format.id = 0x03;
|
||||
|
|
@ -359,11 +361,11 @@ static int hci_enhanced_setup_sync(struct hci_dev *hdev, void *data)
|
|||
if (conn->parent && lmp_esco_capable(conn->parent)) {
|
||||
if (!find_next_esco_param(conn, esco_param_cvsd,
|
||||
ARRAY_SIZE(esco_param_cvsd)))
|
||||
return -EINVAL;
|
||||
goto unlock;
|
||||
param = &esco_param_cvsd[conn->attempt - 1];
|
||||
} else {
|
||||
if (conn->attempt > ARRAY_SIZE(sco_param_cvsd))
|
||||
return -EINVAL;
|
||||
goto unlock;
|
||||
param = &sco_param_cvsd[conn->attempt - 1];
|
||||
}
|
||||
cp.tx_coding_format.id = 2;
|
||||
|
|
@ -386,9 +388,11 @@ static int hci_enhanced_setup_sync(struct hci_dev *hdev, void *data)
|
|||
cp.out_transport_unit_size = 16;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
hci_dev_unlock(hdev);
|
||||
|
||||
cp.retrans_effort = param->retrans_effort;
|
||||
cp.pkt_type = __cpu_to_le16(param->pkt_type);
|
||||
cp.max_latency = __cpu_to_le16(param->max_latency);
|
||||
|
|
@ -397,6 +401,10 @@ static int hci_enhanced_setup_sync(struct hci_dev *hdev, void *data)
|
|||
return -EIO;
|
||||
|
||||
return 0;
|
||||
|
||||
unlock:
|
||||
hci_dev_unlock(hdev);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static bool hci_setup_sync_conn(struct hci_conn *conn, __u16 handle)
|
||||
|
|
|
|||
|
|
@ -1489,8 +1489,10 @@ int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
|
|||
|
||||
BT_DBG("%s removing %pMR (%u)", hdev->name, bdaddr, bdaddr_type);
|
||||
|
||||
mutex_lock(&hdev->remote_oob_lock);
|
||||
list_del(&data->list);
|
||||
kfree(data);
|
||||
mutex_unlock(&hdev->remote_oob_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1499,10 +1501,12 @@ void hci_remote_oob_data_clear(struct hci_dev *hdev)
|
|||
{
|
||||
struct oob_data *data, *n;
|
||||
|
||||
mutex_lock(&hdev->remote_oob_lock);
|
||||
list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
|
||||
list_del(&data->list);
|
||||
kfree(data);
|
||||
}
|
||||
mutex_unlock(&hdev->remote_oob_lock);
|
||||
}
|
||||
|
||||
int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
|
||||
|
|
@ -1511,11 +1515,14 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
|
|||
{
|
||||
struct oob_data *data;
|
||||
|
||||
mutex_lock(&hdev->remote_oob_lock);
|
||||
data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
|
||||
if (!data) {
|
||||
data = kmalloc_obj(*data);
|
||||
if (!data)
|
||||
if (!data) {
|
||||
mutex_unlock(&hdev->remote_oob_lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
bacpy(&data->bdaddr, bdaddr);
|
||||
data->bdaddr_type = bdaddr_type;
|
||||
|
|
@ -1548,6 +1555,8 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
|
|||
|
||||
BT_DBG("%s for %pMR", hdev->name, bdaddr);
|
||||
|
||||
mutex_unlock(&hdev->remote_oob_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -2485,6 +2494,7 @@ struct hci_dev *hci_alloc_dev_priv(int sizeof_priv)
|
|||
mutex_init(&hdev->lock);
|
||||
mutex_init(&hdev->req_lock);
|
||||
mutex_init(&hdev->mgmt_pending_lock);
|
||||
mutex_init(&hdev->remote_oob_lock);
|
||||
|
||||
ida_init(&hdev->unset_handle_ida);
|
||||
|
||||
|
|
@ -2557,8 +2567,10 @@ int hci_register_dev(struct hci_dev *hdev)
|
|||
return id;
|
||||
|
||||
error = dev_set_name(&hdev->dev, "hci%u", id);
|
||||
if (error)
|
||||
if (error) {
|
||||
ida_free(&hci_index_ida, id);
|
||||
return error;
|
||||
}
|
||||
|
||||
hdev->name = dev_name(&hdev->dev);
|
||||
hdev->id = id;
|
||||
|
|
@ -3325,6 +3337,8 @@ static void hci_queue_iso(struct hci_conn *conn, struct sk_buff_head *queue,
|
|||
|
||||
skb_shinfo(skb)->frag_list = NULL;
|
||||
|
||||
spin_lock_bh(&queue->lock);
|
||||
|
||||
__skb_queue_tail(queue, skb);
|
||||
|
||||
do {
|
||||
|
|
@ -3339,6 +3353,8 @@ static void hci_queue_iso(struct hci_conn *conn, struct sk_buff_head *queue,
|
|||
|
||||
__skb_queue_tail(queue, skb);
|
||||
} while (list);
|
||||
|
||||
spin_unlock_bh(&queue->lock);
|
||||
}
|
||||
|
||||
bt_dev_dbg(hdev, "hcon %p queued %d", conn, skb_queue_len(queue));
|
||||
|
|
@ -3402,9 +3418,6 @@ static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
|
|||
struct hci_conn *conn = NULL, *c;
|
||||
unsigned int num = 0, min = ~0;
|
||||
|
||||
/* We don't have to lock device here. Connections are always
|
||||
* added and removed with TX task disabled. */
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
list_for_each_entry_rcu(c, &h->list, list) {
|
||||
|
|
@ -3609,13 +3622,15 @@ static void __check_timeout(struct hci_dev *hdev, unsigned int cnt, u8 type)
|
|||
}
|
||||
|
||||
/* Schedule SCO */
|
||||
static void hci_sched_sco(struct hci_dev *hdev, __u8 type)
|
||||
static void __hci_sched_sco(struct hci_dev *hdev, __u8 type)
|
||||
{
|
||||
struct hci_conn *conn;
|
||||
struct sk_buff *skb;
|
||||
int quote, *cnt;
|
||||
unsigned int pkts = hdev->sco_pkts;
|
||||
|
||||
lockdep_assert_held(&hdev->lock);
|
||||
|
||||
bt_dev_dbg(hdev, "type %u", type);
|
||||
|
||||
if (!hci_conn_num(hdev, type) || !pkts)
|
||||
|
|
@ -3650,6 +3665,13 @@ static void hci_sched_sco(struct hci_dev *hdev, __u8 type)
|
|||
queue_work(hdev->workqueue, &hdev->tx_work);
|
||||
}
|
||||
|
||||
static void hci_sched_sco(struct hci_dev *hdev, __u8 type)
|
||||
{
|
||||
hci_dev_lock(hdev);
|
||||
__hci_sched_sco(hdev, type);
|
||||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
static void hci_sched_acl_pkt(struct hci_dev *hdev)
|
||||
{
|
||||
unsigned int cnt = hdev->acl_cnt;
|
||||
|
|
@ -3659,6 +3681,8 @@ static void hci_sched_acl_pkt(struct hci_dev *hdev)
|
|||
|
||||
__check_timeout(hdev, cnt, ACL_LINK);
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
while (hdev->acl_cnt &&
|
||||
(chan = hci_chan_sent(hdev, ACL_LINK, "e))) {
|
||||
u32 priority = (skb_peek(&chan->data_q))->priority;
|
||||
|
|
@ -3683,13 +3707,15 @@ static void hci_sched_acl_pkt(struct hci_dev *hdev)
|
|||
chan->conn->sent++;
|
||||
|
||||
/* Send pending SCO packets right away */
|
||||
hci_sched_sco(hdev, SCO_LINK);
|
||||
hci_sched_sco(hdev, ESCO_LINK);
|
||||
__hci_sched_sco(hdev, SCO_LINK);
|
||||
__hci_sched_sco(hdev, ESCO_LINK);
|
||||
}
|
||||
}
|
||||
|
||||
if (cnt != hdev->acl_cnt)
|
||||
hci_prio_recalculate(hdev, ACL_LINK);
|
||||
|
||||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
static void hci_sched_acl(struct hci_dev *hdev)
|
||||
|
|
@ -3718,6 +3744,8 @@ static void hci_sched_le(struct hci_dev *hdev)
|
|||
|
||||
__check_timeout(hdev, *cnt, LE_LINK);
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
tmp = *cnt;
|
||||
while (*cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) {
|
||||
u32 priority = (skb_peek(&chan->data_q))->priority;
|
||||
|
|
@ -3739,13 +3767,15 @@ static void hci_sched_le(struct hci_dev *hdev)
|
|||
chan->conn->sent++;
|
||||
|
||||
/* Send pending SCO packets right away */
|
||||
hci_sched_sco(hdev, SCO_LINK);
|
||||
hci_sched_sco(hdev, ESCO_LINK);
|
||||
__hci_sched_sco(hdev, SCO_LINK);
|
||||
__hci_sched_sco(hdev, ESCO_LINK);
|
||||
}
|
||||
}
|
||||
|
||||
if (*cnt != tmp)
|
||||
hci_prio_recalculate(hdev, LE_LINK);
|
||||
|
||||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
/* Schedule iso */
|
||||
|
|
@ -3764,6 +3794,8 @@ static void hci_sched_iso(struct hci_dev *hdev, __u8 type)
|
|||
|
||||
__check_timeout(hdev, *cnt, type);
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
while (*cnt && (conn = hci_low_sent(hdev, type, "e))) {
|
||||
while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
|
||||
BT_DBG("skb %p len %d", skb, skb->len);
|
||||
|
|
@ -3777,6 +3809,8 @@ static void hci_sched_iso(struct hci_dev *hdev, __u8 type)
|
|||
(*cnt)--;
|
||||
}
|
||||
}
|
||||
|
||||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
static void hci_tx_work(struct work_struct *work)
|
||||
|
|
|
|||
|
|
@ -364,7 +364,7 @@ static int inquiry_cache_show(struct seq_file *f, void *p)
|
|||
|
||||
list_for_each_entry(e, &cache->all, all) {
|
||||
struct inquiry_data *data = &e->data;
|
||||
seq_printf(f, "%pMR %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n",
|
||||
seq_printf(f, "%pMR %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %lu\n",
|
||||
&data->bdaddr,
|
||||
data->pscan_rep_mode, data->pscan_period_mode,
|
||||
data->pscan_mode, data->dev_class[2],
|
||||
|
|
|
|||
|
|
@ -312,6 +312,10 @@ static void hci_cmd_sync_work(struct work_struct *work)
|
|||
while (1) {
|
||||
struct hci_cmd_sync_work_entry *entry;
|
||||
|
||||
/* Leave the backlog to hci_cmd_sync_clear() */
|
||||
if (hci_dev_test_flag(hdev, HCI_UNREGISTER))
|
||||
break;
|
||||
|
||||
mutex_lock(&hdev->cmd_sync_work_lock);
|
||||
entry = list_first_entry_or_null(&hdev->cmd_sync_work_list,
|
||||
struct hci_cmd_sync_work_entry,
|
||||
|
|
@ -658,6 +662,8 @@ void hci_cmd_sync_clear(struct hci_dev *hdev)
|
|||
{
|
||||
struct hci_cmd_sync_work_entry *entry, *tmp;
|
||||
|
||||
/* cmd_work is disabled, the pending request can only time out */
|
||||
hci_cmd_sync_cancel_sync(hdev, ENODEV);
|
||||
cancel_work_sync(&hdev->cmd_sync_work);
|
||||
cancel_work_sync(&hdev->reenable_adv_work);
|
||||
|
||||
|
|
@ -5764,6 +5770,7 @@ int hci_stop_discovery_sync(struct hci_dev *hdev)
|
|||
{
|
||||
struct discovery_state *d = &hdev->discovery;
|
||||
struct inquiry_entry *e;
|
||||
bdaddr_t addr;
|
||||
int err;
|
||||
|
||||
bt_dev_dbg(hdev, "state %u", hdev->discovery.state);
|
||||
|
|
@ -5799,15 +5806,21 @@ int hci_stop_discovery_sync(struct hci_dev *hdev)
|
|||
return 0;
|
||||
|
||||
if (d->state == DISCOVERY_RESOLVING || d->state == DISCOVERY_STOPPING) {
|
||||
hci_dev_lock(hdev);
|
||||
e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY,
|
||||
NAME_PENDING);
|
||||
if (!e)
|
||||
if (!e) {
|
||||
hci_dev_unlock(hdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bacpy(&addr, &e->data.bdaddr);
|
||||
hci_dev_unlock(hdev);
|
||||
|
||||
/* Ignore cancel errors since it should interfere with stopping
|
||||
* of the discovery.
|
||||
*/
|
||||
hci_remote_name_cancel_sync(hdev, &e->data.bdaddr);
|
||||
hci_remote_name_cancel_sync(hdev, &addr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -7236,6 +7249,7 @@ static int hci_acl_create_conn_sync(struct hci_dev *hdev, void *data)
|
|||
bacpy(&cp.bdaddr, &conn->dst);
|
||||
cp.pscan_rep_mode = 0x02;
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
|
||||
if (ie) {
|
||||
if (inquiry_entry_age(ie) <= INQUIRY_ENTRY_AGE_MAX) {
|
||||
|
|
@ -7247,6 +7261,7 @@ static int hci_acl_create_conn_sync(struct hci_dev *hdev, void *data)
|
|||
|
||||
memcpy(conn->dev_class, ie->data.dev_class, 3);
|
||||
}
|
||||
hci_dev_unlock(hdev);
|
||||
|
||||
cp.pkt_type = cpu_to_le16(conn->pkt_type);
|
||||
if (lmp_rswitch_capable(hdev) && !(hdev->link_mode & HCI_LM_MASTER))
|
||||
|
|
|
|||
|
|
@ -462,7 +462,7 @@ static int __rfcomm_release_dev(void __user *arg)
|
|||
/* Shut down TTY synchronously before freeing rfcomm_dev */
|
||||
tty_port_tty_vhangup(&dev->port);
|
||||
|
||||
if (!test_bit(RFCOMM_TTY_OWNED, &dev->status))
|
||||
if (!test_and_set_bit(RFCOMM_TTY_OWNED, &dev->status))
|
||||
tty_port_put(&dev->port);
|
||||
|
||||
tty_port_put(&dev->port);
|
||||
|
|
@ -724,10 +724,9 @@ static int rfcomm_tty_install(struct tty_driver *driver, struct tty_struct *tty)
|
|||
* when the last process closes the tty. The behaviour is expected by
|
||||
* userspace.
|
||||
*/
|
||||
if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) {
|
||||
set_bit(RFCOMM_TTY_OWNED, &dev->status);
|
||||
if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags) &&
|
||||
!test_and_set_bit(RFCOMM_TTY_OWNED, &dev->status))
|
||||
tty_port_put(&dev->port);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -662,6 +662,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn,
|
|||
else
|
||||
bdaddr_type = BDADDR_LE_RANDOM;
|
||||
|
||||
mutex_lock(&hdev->remote_oob_lock);
|
||||
oob_data = hci_find_remote_oob_data(hdev, &hcon->dst,
|
||||
bdaddr_type);
|
||||
if (oob_data && oob_data->present) {
|
||||
|
|
@ -672,6 +673,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn,
|
|||
SMP_DBG("OOB Remote Confirmation: %16phN", smp->pcnf);
|
||||
SMP_DBG("OOB Remote Random: %16phN", smp->rr);
|
||||
}
|
||||
mutex_unlock(&hdev->remote_oob_lock);
|
||||
|
||||
} else {
|
||||
authreq &= ~SMP_AUTH_SC;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user