2020-01-16 23:55:57 +00:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
|
|
|
/*
|
|
|
|
* BlueZ - Bluetooth protocol stack for Linux
|
|
|
|
*
|
|
|
|
* Copyright (C) 2022 Intel Corporation
|
2024-02-23 13:14:41 +00:00
|
|
|
* Copyright 2023-2024 NXP
|
2020-01-16 23:55:57 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/debugfs.h>
|
|
|
|
#include <linux/seq_file.h>
|
|
|
|
#include <linux/sched/signal.h>
|
|
|
|
|
|
|
|
#include <net/bluetooth/bluetooth.h>
|
|
|
|
#include <net/bluetooth/hci_core.h>
|
|
|
|
#include <net/bluetooth/iso.h>
|
2023-09-28 08:02:08 +00:00
|
|
|
#include "eir.h"
|
2020-01-16 23:55:57 +00:00
|
|
|
|
|
|
|
static const struct proto_ops iso_sock_ops;
|
|
|
|
|
|
|
|
static struct bt_sock_list iso_sk_list = {
|
|
|
|
.lock = __RW_LOCK_UNLOCKED(iso_sk_list.lock)
|
|
|
|
};
|
|
|
|
|
|
|
|
/* ---- ISO connections ---- */
|
|
|
|
struct iso_conn {
|
|
|
|
struct hci_conn *hcon;
|
|
|
|
|
|
|
|
/* @lock: spinlock protecting changes to iso_conn fields */
|
|
|
|
spinlock_t lock;
|
|
|
|
struct sock *sk;
|
|
|
|
|
|
|
|
struct delayed_work timeout_work;
|
|
|
|
|
|
|
|
struct sk_buff *rx_skb;
|
|
|
|
__u32 rx_len;
|
|
|
|
__u16 tx_sn;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define iso_conn_lock(c) spin_lock(&(c)->lock)
|
|
|
|
#define iso_conn_unlock(c) spin_unlock(&(c)->lock)
|
|
|
|
|
|
|
|
static void iso_sock_close(struct sock *sk);
|
|
|
|
static void iso_sock_kill(struct sock *sk);
|
|
|
|
|
|
|
|
/* ----- ISO socket info ----- */
|
|
|
|
#define iso_pi(sk) ((struct iso_pinfo *)sk)
|
|
|
|
|
2022-07-29 18:03:27 +00:00
|
|
|
#define EIR_SERVICE_DATA_LENGTH 4
|
|
|
|
#define BASE_MAX_LENGTH (HCI_MAX_PER_AD_LENGTH - EIR_SERVICE_DATA_LENGTH)
|
2023-09-28 08:02:08 +00:00
|
|
|
#define EIR_BAA_SERVICE_UUID 0x1851
|
2022-07-29 18:03:27 +00:00
|
|
|
|
2023-07-03 07:02:38 +00:00
|
|
|
/* iso_pinfo flags values */
|
|
|
|
enum {
|
|
|
|
BT_SK_BIG_SYNC,
|
2023-08-17 06:44:27 +00:00
|
|
|
BT_SK_PA_SYNC,
|
2023-07-03 07:02:38 +00:00
|
|
|
};
|
|
|
|
|
2020-01-16 23:55:57 +00:00
|
|
|
struct iso_pinfo {
|
|
|
|
struct bt_sock bt;
|
|
|
|
bdaddr_t src;
|
|
|
|
__u8 src_type;
|
|
|
|
bdaddr_t dst;
|
|
|
|
__u8 dst_type;
|
2022-03-09 21:14:41 +00:00
|
|
|
__u8 bc_sid;
|
|
|
|
__u8 bc_num_bis;
|
|
|
|
__u8 bc_bis[ISO_MAX_NUM_BIS];
|
|
|
|
__u16 sync_handle;
|
2023-07-03 07:02:38 +00:00
|
|
|
unsigned long flags;
|
2020-01-16 23:55:57 +00:00
|
|
|
struct bt_iso_qos qos;
|
2023-03-31 15:38:01 +00:00
|
|
|
bool qos_user_set;
|
2022-03-09 21:14:41 +00:00
|
|
|
__u8 base_len;
|
2022-07-29 18:03:27 +00:00
|
|
|
__u8 base[BASE_MAX_LENGTH];
|
2020-01-16 23:55:57 +00:00
|
|
|
struct iso_conn *conn;
|
|
|
|
};
|
|
|
|
|
2023-03-31 15:38:01 +00:00
|
|
|
static struct bt_iso_qos default_qos;
|
|
|
|
|
|
|
|
static bool check_ucast_qos(struct bt_iso_qos *qos);
|
|
|
|
static bool check_bcast_qos(struct bt_iso_qos *qos);
|
2023-08-17 06:44:27 +00:00
|
|
|
static bool iso_match_sid(struct sock *sk, void *data);
|
2023-09-06 14:01:03 +00:00
|
|
|
static bool iso_match_sync_handle(struct sock *sk, void *data);
|
2024-04-02 11:39:31 +00:00
|
|
|
static bool iso_match_sync_handle_pa_report(struct sock *sk, void *data);
|
2023-08-17 06:44:27 +00:00
|
|
|
static void iso_sock_disconn(struct sock *sk);
|
2023-03-31 15:38:01 +00:00
|
|
|
|
2023-12-05 16:11:40 +00:00
|
|
|
typedef bool (*iso_sock_match_t)(struct sock *sk, void *data);
|
|
|
|
|
2024-04-02 11:39:30 +00:00
|
|
|
static struct sock *iso_get_sock(bdaddr_t *src, bdaddr_t *dst,
|
|
|
|
enum bt_sock_state state,
|
|
|
|
iso_sock_match_t match, void *data);
|
2023-12-05 16:11:40 +00:00
|
|
|
|
2020-01-16 23:55:57 +00:00
|
|
|
/* ---- ISO timers ---- */
|
|
|
|
#define ISO_CONN_TIMEOUT (HZ * 40)
|
|
|
|
#define ISO_DISCONN_TIMEOUT (HZ * 2)
|
|
|
|
|
|
|
|
static void iso_sock_timeout(struct work_struct *work)
|
|
|
|
{
|
|
|
|
struct iso_conn *conn = container_of(work, struct iso_conn,
|
|
|
|
timeout_work.work);
|
|
|
|
struct sock *sk;
|
|
|
|
|
|
|
|
iso_conn_lock(conn);
|
|
|
|
sk = conn->sk;
|
|
|
|
if (sk)
|
|
|
|
sock_hold(sk);
|
|
|
|
iso_conn_unlock(conn);
|
|
|
|
|
|
|
|
if (!sk)
|
|
|
|
return;
|
|
|
|
|
|
|
|
BT_DBG("sock %p state %d", sk, sk->sk_state);
|
|
|
|
|
|
|
|
lock_sock(sk);
|
|
|
|
sk->sk_err = ETIMEDOUT;
|
|
|
|
sk->sk_state_change(sk);
|
|
|
|
release_sock(sk);
|
|
|
|
sock_put(sk);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void iso_sock_set_timer(struct sock *sk, long timeout)
|
|
|
|
{
|
|
|
|
if (!iso_pi(sk)->conn)
|
|
|
|
return;
|
|
|
|
|
|
|
|
BT_DBG("sock %p state %d timeout %ld", sk, sk->sk_state, timeout);
|
|
|
|
cancel_delayed_work(&iso_pi(sk)->conn->timeout_work);
|
|
|
|
schedule_delayed_work(&iso_pi(sk)->conn->timeout_work, timeout);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void iso_sock_clear_timer(struct sock *sk)
|
|
|
|
{
|
|
|
|
if (!iso_pi(sk)->conn)
|
|
|
|
return;
|
|
|
|
|
|
|
|
BT_DBG("sock %p state %d", sk, sk->sk_state);
|
|
|
|
cancel_delayed_work(&iso_pi(sk)->conn->timeout_work);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ---- ISO connections ---- */
|
|
|
|
static struct iso_conn *iso_conn_add(struct hci_conn *hcon)
|
|
|
|
{
|
|
|
|
struct iso_conn *conn = hcon->iso_data;
|
|
|
|
|
Bluetooth: ISO: fix iso_conn related locking and validity issues
sk->sk_state indicates whether iso_pi(sk)->conn is valid. Operations
that check/update sk_state and access conn should hold lock_sock,
otherwise they can race.
The order of taking locks is hci_dev_lock > lock_sock > iso_conn_lock,
which is how it is in connect/disconnect_cfm -> iso_conn_del ->
iso_chan_del.
Fix locking in iso_connect_cis/bis and sendmsg/recvmsg to take lock_sock
around updating sk_state and conn.
iso_conn_del must not occur during iso_connect_cis/bis, as it frees the
iso_conn. Hold hdev->lock longer to prevent that.
This should not reintroduce the issue fixed in commit 241f51931c35
("Bluetooth: ISO: Avoid circular locking dependency"), since the we
acquire locks in order. We retain the fix in iso_sock_connect to release
lock_sock before iso_connect_* acquires hdev->lock.
Similarly for commit 6a5ad251b7cd ("Bluetooth: ISO: Fix possible
circular locking dependency"). We retain the fix in iso_conn_ready to
not acquire iso_conn_lock before lock_sock.
iso_conn_add shall return iso_conn with valid hcon. Make it so also when
reusing an old CIS connection waiting for disconnect timeout (see
__iso_sock_close where conn->hcon is set to NULL).
Trace with iso_conn_del after iso_chan_add in iso_connect_cis:
===============================================================
iso_sock_create:771: sock 00000000be9b69b7
iso_sock_init:693: sk 000000004dff667e
iso_sock_bind:827: sk 000000004dff667e 70:1a:b8:98:ff:a2 type 1
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_connect:875: sk 000000004dff667e
iso_connect_cis:353: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
hci_get_route:1199: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
hci_conn_add:1005: hci0 dst 28:3d:c2:4a:7e:da
iso_conn_add:140: hcon 000000007b65d182 conn 00000000daf8625e
__iso_chan_add:214: conn 00000000daf8625e
iso_connect_cfm:1700: hcon 000000007b65d182 bdaddr 28:3d:c2:4a:7e:da status 12
iso_conn_del:187: hcon 000000007b65d182 conn 00000000daf8625e, err 16
iso_sock_clear_timer:117: sock 000000004dff667e state 3
<Note: sk_state is BT_BOUND (3), so iso_connect_cis is still
running at this point>
iso_chan_del:153: sk 000000004dff667e, conn 00000000daf8625e, err 16
hci_conn_del:1151: hci0 hcon 000000007b65d182 handle 65535
hci_conn_unlink:1102: hci0: hcon 000000007b65d182
hci_chan_list_flush:2780: hcon 000000007b65d182
iso_sock_getsockopt:1376: sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getsockopt:1376: sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_shutdown:1434: sock 00000000be9b69b7, sk 000000004dff667e, how 1
__iso_sock_close:632: sk 000000004dff667e state 5 socket 00000000be9b69b7
<Note: sk_state is BT_CONNECT (5), even though iso_chan_del sets
BT_CLOSED (6). Only iso_connect_cis sets it to BT_CONNECT, so it
must be that iso_chan_del occurred between iso_chan_add and end of
iso_connect_cis.>
BUG: kernel NULL pointer dereference, address: 0000000000000000
PGD 8000000006467067 P4D 8000000006467067 PUD 3f5f067 PMD 0
Oops: 0000 [#1] PREEMPT SMP PTI
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:__iso_sock_close (net/bluetooth/iso.c:664) bluetooth
===============================================================
Trace with iso_conn_del before iso_chan_add in iso_connect_cis:
===============================================================
iso_connect_cis:356: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
...
iso_conn_add:140: hcon 0000000093bc551f conn 00000000768ae504
hci_dev_put:1487: hci0 orig refcnt 21
hci_event_packet:7607: hci0: event 0x0e
hci_cmd_complete_evt:4231: hci0: opcode 0x2062
hci_cc_le_set_cig_params:3846: hci0: status 0x07
hci_sent_cmd_data:3107: hci0 opcode 0x2062
iso_connect_cfm:1703: hcon 0000000093bc551f bdaddr 28:3d:c2:4a:7e:da status 7
iso_conn_del:187: hcon 0000000093bc551f conn 00000000768ae504, err 12
hci_conn_del:1151: hci0 hcon 0000000093bc551f handle 65535
hci_conn_unlink:1102: hci0: hcon 0000000093bc551f
hci_chan_list_flush:2780: hcon 0000000093bc551f
__iso_chan_add:214: conn 00000000768ae504
<Note: this conn was already freed in iso_conn_del above>
iso_sock_clear_timer:117: sock 0000000098323f95 state 3
general protection fault, probably for non-canonical address 0x30b29c630930aec8: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 1920 Comm: bluetoothd Tainted: G E 6.3.0-rc7+ #4
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:detach_if_pending+0x28/0xd0
Code: 90 90 0f 1f 44 00 00 48 8b 47 08 48 85 c0 0f 84 ad 00 00 00 55 89 d5 53 48 83 3f 00 48 89 fb 74 7d 66 90 48 8b 03 48 8b 53 08 <>
RSP: 0018:ffffb90841a67d08 EFLAGS: 00010007
RAX: 0000000000000000 RBX: ffff9141bd5061b8 RCX: 0000000000000000
RDX: 30b29c630930aec8 RSI: ffff9141fdd21e80 RDI: ffff9141bd5061b8
RBP: 0000000000000001 R08: 0000000000000000 R09: ffffb90841a67b88
R10: 0000000000000003 R11: ffffffff8613f558 R12: ffff9141fdd21e80
R13: 0000000000000000 R14: ffff9141b5976010 R15: ffff914185755338
FS: 00007f45768bd840(0000) GS:ffff9141fdd00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000619000424074 CR3: 0000000009f5e005 CR4: 0000000000170ee0
Call Trace:
<TASK>
timer_delete+0x48/0x80
try_to_grab_pending+0xdf/0x170
__cancel_work+0x37/0xb0
iso_connect_cis+0x141/0x400 [bluetooth]
===============================================================
Trace with NULL conn->hcon in state BT_CONNECT:
===============================================================
__iso_sock_close:619: sk 00000000f7c71fc5 state 1 socket 00000000d90c5fe5
...
__iso_sock_close:619: sk 00000000f7c71fc5 state 8 socket 00000000d90c5fe5
iso_chan_del:153: sk 00000000f7c71fc5, conn 0000000022c03a7e, err 104
...
iso_sock_connect:862: sk 00000000129b56c3
iso_connect_cis:348: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7d:2a
hci_get_route:1199: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7d:2a
hci_dev_hold:1495: hci0 orig refcnt 19
__iso_chan_add:214: conn 0000000022c03a7e
<Note: reusing old conn>
iso_sock_clear_timer:117: sock 00000000129b56c3 state 3
...
iso_sock_ready:1485: sk 00000000129b56c3
...
iso_sock_sendmsg:1077: sock 00000000e5013966, sk 00000000129b56c3
BUG: kernel NULL pointer dereference, address: 00000000000006a8
PGD 0 P4D 0
Oops: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 1403 Comm: wireplumber Tainted: G E 6.3.0-rc7+ #4
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:iso_sock_sendmsg+0x63/0x2a0 [bluetooth]
===============================================================
Fixes: 241f51931c35 ("Bluetooth: ISO: Avoid circular locking dependency")
Fixes: 6a5ad251b7cd ("Bluetooth: ISO: Fix possible circular locking dependency")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2023-06-18 22:04:33 +00:00
|
|
|
if (conn) {
|
|
|
|
if (!conn->hcon)
|
|
|
|
conn->hcon = hcon;
|
2020-01-16 23:55:57 +00:00
|
|
|
return conn;
|
Bluetooth: ISO: fix iso_conn related locking and validity issues
sk->sk_state indicates whether iso_pi(sk)->conn is valid. Operations
that check/update sk_state and access conn should hold lock_sock,
otherwise they can race.
The order of taking locks is hci_dev_lock > lock_sock > iso_conn_lock,
which is how it is in connect/disconnect_cfm -> iso_conn_del ->
iso_chan_del.
Fix locking in iso_connect_cis/bis and sendmsg/recvmsg to take lock_sock
around updating sk_state and conn.
iso_conn_del must not occur during iso_connect_cis/bis, as it frees the
iso_conn. Hold hdev->lock longer to prevent that.
This should not reintroduce the issue fixed in commit 241f51931c35
("Bluetooth: ISO: Avoid circular locking dependency"), since the we
acquire locks in order. We retain the fix in iso_sock_connect to release
lock_sock before iso_connect_* acquires hdev->lock.
Similarly for commit 6a5ad251b7cd ("Bluetooth: ISO: Fix possible
circular locking dependency"). We retain the fix in iso_conn_ready to
not acquire iso_conn_lock before lock_sock.
iso_conn_add shall return iso_conn with valid hcon. Make it so also when
reusing an old CIS connection waiting for disconnect timeout (see
__iso_sock_close where conn->hcon is set to NULL).
Trace with iso_conn_del after iso_chan_add in iso_connect_cis:
===============================================================
iso_sock_create:771: sock 00000000be9b69b7
iso_sock_init:693: sk 000000004dff667e
iso_sock_bind:827: sk 000000004dff667e 70:1a:b8:98:ff:a2 type 1
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_connect:875: sk 000000004dff667e
iso_connect_cis:353: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
hci_get_route:1199: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
hci_conn_add:1005: hci0 dst 28:3d:c2:4a:7e:da
iso_conn_add:140: hcon 000000007b65d182 conn 00000000daf8625e
__iso_chan_add:214: conn 00000000daf8625e
iso_connect_cfm:1700: hcon 000000007b65d182 bdaddr 28:3d:c2:4a:7e:da status 12
iso_conn_del:187: hcon 000000007b65d182 conn 00000000daf8625e, err 16
iso_sock_clear_timer:117: sock 000000004dff667e state 3
<Note: sk_state is BT_BOUND (3), so iso_connect_cis is still
running at this point>
iso_chan_del:153: sk 000000004dff667e, conn 00000000daf8625e, err 16
hci_conn_del:1151: hci0 hcon 000000007b65d182 handle 65535
hci_conn_unlink:1102: hci0: hcon 000000007b65d182
hci_chan_list_flush:2780: hcon 000000007b65d182
iso_sock_getsockopt:1376: sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getsockopt:1376: sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_shutdown:1434: sock 00000000be9b69b7, sk 000000004dff667e, how 1
__iso_sock_close:632: sk 000000004dff667e state 5 socket 00000000be9b69b7
<Note: sk_state is BT_CONNECT (5), even though iso_chan_del sets
BT_CLOSED (6). Only iso_connect_cis sets it to BT_CONNECT, so it
must be that iso_chan_del occurred between iso_chan_add and end of
iso_connect_cis.>
BUG: kernel NULL pointer dereference, address: 0000000000000000
PGD 8000000006467067 P4D 8000000006467067 PUD 3f5f067 PMD 0
Oops: 0000 [#1] PREEMPT SMP PTI
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:__iso_sock_close (net/bluetooth/iso.c:664) bluetooth
===============================================================
Trace with iso_conn_del before iso_chan_add in iso_connect_cis:
===============================================================
iso_connect_cis:356: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
...
iso_conn_add:140: hcon 0000000093bc551f conn 00000000768ae504
hci_dev_put:1487: hci0 orig refcnt 21
hci_event_packet:7607: hci0: event 0x0e
hci_cmd_complete_evt:4231: hci0: opcode 0x2062
hci_cc_le_set_cig_params:3846: hci0: status 0x07
hci_sent_cmd_data:3107: hci0 opcode 0x2062
iso_connect_cfm:1703: hcon 0000000093bc551f bdaddr 28:3d:c2:4a:7e:da status 7
iso_conn_del:187: hcon 0000000093bc551f conn 00000000768ae504, err 12
hci_conn_del:1151: hci0 hcon 0000000093bc551f handle 65535
hci_conn_unlink:1102: hci0: hcon 0000000093bc551f
hci_chan_list_flush:2780: hcon 0000000093bc551f
__iso_chan_add:214: conn 00000000768ae504
<Note: this conn was already freed in iso_conn_del above>
iso_sock_clear_timer:117: sock 0000000098323f95 state 3
general protection fault, probably for non-canonical address 0x30b29c630930aec8: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 1920 Comm: bluetoothd Tainted: G E 6.3.0-rc7+ #4
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:detach_if_pending+0x28/0xd0
Code: 90 90 0f 1f 44 00 00 48 8b 47 08 48 85 c0 0f 84 ad 00 00 00 55 89 d5 53 48 83 3f 00 48 89 fb 74 7d 66 90 48 8b 03 48 8b 53 08 <>
RSP: 0018:ffffb90841a67d08 EFLAGS: 00010007
RAX: 0000000000000000 RBX: ffff9141bd5061b8 RCX: 0000000000000000
RDX: 30b29c630930aec8 RSI: ffff9141fdd21e80 RDI: ffff9141bd5061b8
RBP: 0000000000000001 R08: 0000000000000000 R09: ffffb90841a67b88
R10: 0000000000000003 R11: ffffffff8613f558 R12: ffff9141fdd21e80
R13: 0000000000000000 R14: ffff9141b5976010 R15: ffff914185755338
FS: 00007f45768bd840(0000) GS:ffff9141fdd00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000619000424074 CR3: 0000000009f5e005 CR4: 0000000000170ee0
Call Trace:
<TASK>
timer_delete+0x48/0x80
try_to_grab_pending+0xdf/0x170
__cancel_work+0x37/0xb0
iso_connect_cis+0x141/0x400 [bluetooth]
===============================================================
Trace with NULL conn->hcon in state BT_CONNECT:
===============================================================
__iso_sock_close:619: sk 00000000f7c71fc5 state 1 socket 00000000d90c5fe5
...
__iso_sock_close:619: sk 00000000f7c71fc5 state 8 socket 00000000d90c5fe5
iso_chan_del:153: sk 00000000f7c71fc5, conn 0000000022c03a7e, err 104
...
iso_sock_connect:862: sk 00000000129b56c3
iso_connect_cis:348: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7d:2a
hci_get_route:1199: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7d:2a
hci_dev_hold:1495: hci0 orig refcnt 19
__iso_chan_add:214: conn 0000000022c03a7e
<Note: reusing old conn>
iso_sock_clear_timer:117: sock 00000000129b56c3 state 3
...
iso_sock_ready:1485: sk 00000000129b56c3
...
iso_sock_sendmsg:1077: sock 00000000e5013966, sk 00000000129b56c3
BUG: kernel NULL pointer dereference, address: 00000000000006a8
PGD 0 P4D 0
Oops: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 1403 Comm: wireplumber Tainted: G E 6.3.0-rc7+ #4
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:iso_sock_sendmsg+0x63/0x2a0 [bluetooth]
===============================================================
Fixes: 241f51931c35 ("Bluetooth: ISO: Avoid circular locking dependency")
Fixes: 6a5ad251b7cd ("Bluetooth: ISO: Fix possible circular locking dependency")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2023-06-18 22:04:33 +00:00
|
|
|
}
|
2020-01-16 23:55:57 +00:00
|
|
|
|
|
|
|
conn = kzalloc(sizeof(*conn), GFP_KERNEL);
|
|
|
|
if (!conn)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
spin_lock_init(&conn->lock);
|
|
|
|
INIT_DELAYED_WORK(&conn->timeout_work, iso_sock_timeout);
|
|
|
|
|
|
|
|
hcon->iso_data = conn;
|
|
|
|
conn->hcon = hcon;
|
|
|
|
conn->tx_sn = 0;
|
|
|
|
|
|
|
|
BT_DBG("hcon %p conn %p", hcon, conn);
|
|
|
|
|
|
|
|
return conn;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Delete channel. Must be called on the locked socket. */
|
|
|
|
static void iso_chan_del(struct sock *sk, int err)
|
|
|
|
{
|
|
|
|
struct iso_conn *conn;
|
2022-03-09 21:14:41 +00:00
|
|
|
struct sock *parent;
|
2020-01-16 23:55:57 +00:00
|
|
|
|
|
|
|
conn = iso_pi(sk)->conn;
|
|
|
|
|
|
|
|
BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
|
|
|
|
|
|
|
|
if (conn) {
|
|
|
|
iso_conn_lock(conn);
|
|
|
|
conn->sk = NULL;
|
|
|
|
iso_pi(sk)->conn = NULL;
|
|
|
|
iso_conn_unlock(conn);
|
|
|
|
|
|
|
|
if (conn->hcon)
|
|
|
|
hci_conn_drop(conn->hcon);
|
|
|
|
}
|
|
|
|
|
|
|
|
sk->sk_state = BT_CLOSED;
|
|
|
|
sk->sk_err = err;
|
2022-03-09 21:14:41 +00:00
|
|
|
|
|
|
|
parent = bt_sk(sk)->parent;
|
|
|
|
if (parent) {
|
|
|
|
bt_accept_unlink(sk);
|
|
|
|
parent->sk_data_ready(parent);
|
|
|
|
} else {
|
|
|
|
sk->sk_state_change(sk);
|
|
|
|
}
|
2020-01-16 23:55:57 +00:00
|
|
|
|
|
|
|
sock_set_flag(sk, SOCK_ZAPPED);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void iso_conn_del(struct hci_conn *hcon, int err)
|
|
|
|
{
|
|
|
|
struct iso_conn *conn = hcon->iso_data;
|
|
|
|
struct sock *sk;
|
|
|
|
|
|
|
|
if (!conn)
|
|
|
|
return;
|
|
|
|
|
|
|
|
BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
|
|
|
|
|
|
|
|
/* Kill socket */
|
|
|
|
iso_conn_lock(conn);
|
|
|
|
sk = conn->sk;
|
|
|
|
if (sk)
|
|
|
|
sock_hold(sk);
|
|
|
|
iso_conn_unlock(conn);
|
|
|
|
|
|
|
|
if (sk) {
|
|
|
|
lock_sock(sk);
|
|
|
|
iso_sock_clear_timer(sk);
|
|
|
|
iso_chan_del(sk, err);
|
|
|
|
release_sock(sk);
|
|
|
|
sock_put(sk);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Ensure no more work items will run before freeing conn. */
|
|
|
|
cancel_delayed_work_sync(&conn->timeout_work);
|
|
|
|
|
|
|
|
hcon->iso_data = NULL;
|
|
|
|
kfree(conn);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int __iso_chan_add(struct iso_conn *conn, struct sock *sk,
|
|
|
|
struct sock *parent)
|
|
|
|
{
|
|
|
|
BT_DBG("conn %p", conn);
|
|
|
|
|
|
|
|
if (iso_pi(sk)->conn == conn && conn->sk == sk)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (conn->sk) {
|
|
|
|
BT_ERR("conn->sk already set");
|
|
|
|
return -EBUSY;
|
|
|
|
}
|
|
|
|
|
|
|
|
iso_pi(sk)->conn = conn;
|
|
|
|
conn->sk = sk;
|
|
|
|
|
|
|
|
if (parent)
|
|
|
|
bt_accept_enqueue(parent, sk, true);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int iso_chan_add(struct iso_conn *conn, struct sock *sk,
|
|
|
|
struct sock *parent)
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
|
|
|
iso_conn_lock(conn);
|
|
|
|
err = __iso_chan_add(conn, sk, parent);
|
|
|
|
iso_conn_unlock(conn);
|
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2022-10-11 19:25:33 +00:00
|
|
|
static inline u8 le_addr_type(u8 bdaddr_type)
|
|
|
|
{
|
|
|
|
if (bdaddr_type == BDADDR_LE_PUBLIC)
|
|
|
|
return ADDR_LE_DEV_PUBLIC;
|
|
|
|
else
|
|
|
|
return ADDR_LE_DEV_RANDOM;
|
|
|
|
}
|
|
|
|
|
2022-03-09 21:14:41 +00:00
|
|
|
static int iso_connect_bis(struct sock *sk)
|
|
|
|
{
|
|
|
|
struct iso_conn *conn;
|
|
|
|
struct hci_conn *hcon;
|
|
|
|
struct hci_dev *hdev;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
BT_DBG("%pMR", &iso_pi(sk)->src);
|
|
|
|
|
|
|
|
hdev = hci_get_route(&iso_pi(sk)->dst, &iso_pi(sk)->src,
|
|
|
|
iso_pi(sk)->src_type);
|
|
|
|
if (!hdev)
|
|
|
|
return -EHOSTUNREACH;
|
|
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
|
|
if (!bis_capable(hdev)) {
|
|
|
|
err = -EOPNOTSUPP;
|
2022-12-07 00:34:42 +00:00
|
|
|
goto unlock;
|
2022-03-09 21:14:41 +00:00
|
|
|
}
|
|
|
|
|
2023-03-31 15:38:01 +00:00
|
|
|
/* Fail if user set invalid QoS */
|
|
|
|
if (iso_pi(sk)->qos_user_set && !check_bcast_qos(&iso_pi(sk)->qos)) {
|
|
|
|
iso_pi(sk)->qos = default_qos;
|
|
|
|
err = -EINVAL;
|
|
|
|
goto unlock;
|
|
|
|
}
|
|
|
|
|
2022-03-09 21:14:41 +00:00
|
|
|
/* Fail if out PHYs are marked as disabled */
|
2023-03-31 15:38:01 +00:00
|
|
|
if (!iso_pi(sk)->qos.bcast.out.phy) {
|
2022-03-09 21:14:41 +00:00
|
|
|
err = -EINVAL;
|
2022-12-07 00:34:42 +00:00
|
|
|
goto unlock;
|
2022-03-09 21:14:41 +00:00
|
|
|
}
|
|
|
|
|
Bluetooth: ISO: Add support for connecting multiple BISes
It is required for some configurations to have multiple BISes as part
of the same BIG.
Similar to the flow implemented for unicast, DEFER_SETUP will also be
used to bind multiple BISes for the same BIG, before starting Periodic
Advertising and creating the BIG.
The user will have to open a new socket for each BIS. By setting the
BT_DEFER_SETUP socket option and calling connect, a new connection
will be added for the BIG and advertising handle set by the socket
QoS parameters. Since all BISes will be bound for the same BIG and
advertising handle, the socket QoS options and base parameters should
match for all connections.
By calling connect on a socket that does not have the BT_DEFER_SETUP
option set, periodic advertising will be started and the BIG will
be created, with a BIS for each previously bound connection. Since
a BIG cannot be reconfigured with additional BISes after creation,
no more connections can be bound for the BIG after the start periodic
advertising and create BIG commands have been queued.
The bis_cleanup function has also been updated, so that the advertising
set and the BIG will not be terminated unless there are no more
bound or connected BISes.
The HCI_CONN_BIG_CREATED connection flag has been added to indicate
that the BIG has been successfully created. This flag is checked at
bis_cleanup, so that the BIG is only terminated if the
HCI_LE_Create_BIG_Complete has been received.
This implementation has been tested on hardware, using the "isotest"
tool with an additional command line option, to specify the number of
BISes to create as part of the desired BIG:
tools/isotest -i hci0 -s 00:00:00:00:00:00 -N 2 -G 1 -T 1
The btmon log shows that a BIG containing 2 BISes has been created:
< HCI Command: LE Create Broadcast Isochronous Group (0x08|0x0068) plen 31
Handle: 0x01
Advertising Handle: 0x01
Number of BIS: 2
SDU Interval: 10000 us (0x002710)
Maximum SDU size: 40
Maximum Latency: 10 ms (0x000a)
RTN: 0x02
PHY: LE 2M (0x02)
Packing: Sequential (0x00)
Framing: Unframed (0x00)
Encryption: 0x00
Broadcast Code: 00000000000000000000000000000000
> HCI Event: Command Status (0x0f) plen 4
LE Create Broadcast Isochronous Group (0x08|0x0068) ncmd 1
Status: Success (0x00)
> HCI Event: LE Meta Event (0x3e) plen 23
LE Broadcast Isochronous Group Complete (0x1b)
Status: Success (0x00)
Handle: 0x01
BIG Synchronization Delay: 1974 us (0x0007b6)
Transport Latency: 1974 us (0x0007b6)
PHY: LE 2M (0x02)
NSE: 3
BN: 1
PTO: 1
IRC: 3
Maximum PDU: 40
ISO Interval: 10.00 msec (0x0008)
Connection Handle #0: 10
Connection Handle #1: 11
< HCI Command: LE Setup Isochronous Data Path (0x08|0x006e) plen 13
Handle: 10
Data Path Direction: Input (Host to Controller) (0x00)
Data Path: HCI (0x00)
Coding Format: Transparent (0x03)
Company Codec ID: Ericsson Technology Licensing (0)
Vendor Codec ID: 0
Controller Delay: 0 us (0x000000)
Codec Configuration Length: 0
Codec Configuration:
> HCI Event: Command Complete (0x0e) plen 6
LE Setup Isochronous Data Path (0x08|0x006e) ncmd 1
Status: Success (0x00)
Handle: 10
< HCI Command: LE Setup Isochronous Data Path (0x08|0x006e) plen 13
Handle: 11
Data Path Direction: Input (Host to Controller) (0x00)
Data Path: HCI (0x00)
Coding Format: Transparent (0x03)
Company Codec ID: Ericsson Technology Licensing (0)
Vendor Codec ID: 0
Controller Delay: 0 us (0x000000)
Codec Configuration Length: 0
Codec Configuration:
> HCI Event: Command Complete (0x0e) plen 6
LE Setup Isochronous Data Path (0x08|0x006e) ncmd 1
Status: Success (0x00)
Handle: 11
< ISO Data TX: Handle 10 flags 0x02 dlen 44
< ISO Data TX: Handle 11 flags 0x02 dlen 44
> HCI Event: Number of Completed Packets (0x13) plen 5
Num handles: 1
Handle: 10
Count: 1
> HCI Event: Number of Completed Packets (0x13) plen 5
Num handles: 1
Handle: 11
Count: 1
Signed-off-by: Iulia Tanasescu <iulia.tanasescu@nxp.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2023-05-30 14:21:59 +00:00
|
|
|
/* Just bind if DEFER_SETUP has been set */
|
|
|
|
if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
|
|
|
|
hcon = hci_bind_bis(hdev, &iso_pi(sk)->dst,
|
|
|
|
&iso_pi(sk)->qos, iso_pi(sk)->base_len,
|
|
|
|
iso_pi(sk)->base);
|
|
|
|
if (IS_ERR(hcon)) {
|
|
|
|
err = PTR_ERR(hcon);
|
|
|
|
goto unlock;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
hcon = hci_connect_bis(hdev, &iso_pi(sk)->dst,
|
|
|
|
le_addr_type(iso_pi(sk)->dst_type),
|
|
|
|
&iso_pi(sk)->qos, iso_pi(sk)->base_len,
|
|
|
|
iso_pi(sk)->base);
|
|
|
|
if (IS_ERR(hcon)) {
|
|
|
|
err = PTR_ERR(hcon);
|
|
|
|
goto unlock;
|
|
|
|
}
|
2022-03-09 21:14:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
conn = iso_conn_add(hcon);
|
|
|
|
if (!conn) {
|
|
|
|
hci_conn_drop(hcon);
|
|
|
|
err = -ENOMEM;
|
2022-12-07 00:34:42 +00:00
|
|
|
goto unlock;
|
2022-03-09 21:14:41 +00:00
|
|
|
}
|
|
|
|
|
Bluetooth: ISO: fix iso_conn related locking and validity issues
sk->sk_state indicates whether iso_pi(sk)->conn is valid. Operations
that check/update sk_state and access conn should hold lock_sock,
otherwise they can race.
The order of taking locks is hci_dev_lock > lock_sock > iso_conn_lock,
which is how it is in connect/disconnect_cfm -> iso_conn_del ->
iso_chan_del.
Fix locking in iso_connect_cis/bis and sendmsg/recvmsg to take lock_sock
around updating sk_state and conn.
iso_conn_del must not occur during iso_connect_cis/bis, as it frees the
iso_conn. Hold hdev->lock longer to prevent that.
This should not reintroduce the issue fixed in commit 241f51931c35
("Bluetooth: ISO: Avoid circular locking dependency"), since the we
acquire locks in order. We retain the fix in iso_sock_connect to release
lock_sock before iso_connect_* acquires hdev->lock.
Similarly for commit 6a5ad251b7cd ("Bluetooth: ISO: Fix possible
circular locking dependency"). We retain the fix in iso_conn_ready to
not acquire iso_conn_lock before lock_sock.
iso_conn_add shall return iso_conn with valid hcon. Make it so also when
reusing an old CIS connection waiting for disconnect timeout (see
__iso_sock_close where conn->hcon is set to NULL).
Trace with iso_conn_del after iso_chan_add in iso_connect_cis:
===============================================================
iso_sock_create:771: sock 00000000be9b69b7
iso_sock_init:693: sk 000000004dff667e
iso_sock_bind:827: sk 000000004dff667e 70:1a:b8:98:ff:a2 type 1
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_connect:875: sk 000000004dff667e
iso_connect_cis:353: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
hci_get_route:1199: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
hci_conn_add:1005: hci0 dst 28:3d:c2:4a:7e:da
iso_conn_add:140: hcon 000000007b65d182 conn 00000000daf8625e
__iso_chan_add:214: conn 00000000daf8625e
iso_connect_cfm:1700: hcon 000000007b65d182 bdaddr 28:3d:c2:4a:7e:da status 12
iso_conn_del:187: hcon 000000007b65d182 conn 00000000daf8625e, err 16
iso_sock_clear_timer:117: sock 000000004dff667e state 3
<Note: sk_state is BT_BOUND (3), so iso_connect_cis is still
running at this point>
iso_chan_del:153: sk 000000004dff667e, conn 00000000daf8625e, err 16
hci_conn_del:1151: hci0 hcon 000000007b65d182 handle 65535
hci_conn_unlink:1102: hci0: hcon 000000007b65d182
hci_chan_list_flush:2780: hcon 000000007b65d182
iso_sock_getsockopt:1376: sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getsockopt:1376: sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_shutdown:1434: sock 00000000be9b69b7, sk 000000004dff667e, how 1
__iso_sock_close:632: sk 000000004dff667e state 5 socket 00000000be9b69b7
<Note: sk_state is BT_CONNECT (5), even though iso_chan_del sets
BT_CLOSED (6). Only iso_connect_cis sets it to BT_CONNECT, so it
must be that iso_chan_del occurred between iso_chan_add and end of
iso_connect_cis.>
BUG: kernel NULL pointer dereference, address: 0000000000000000
PGD 8000000006467067 P4D 8000000006467067 PUD 3f5f067 PMD 0
Oops: 0000 [#1] PREEMPT SMP PTI
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:__iso_sock_close (net/bluetooth/iso.c:664) bluetooth
===============================================================
Trace with iso_conn_del before iso_chan_add in iso_connect_cis:
===============================================================
iso_connect_cis:356: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
...
iso_conn_add:140: hcon 0000000093bc551f conn 00000000768ae504
hci_dev_put:1487: hci0 orig refcnt 21
hci_event_packet:7607: hci0: event 0x0e
hci_cmd_complete_evt:4231: hci0: opcode 0x2062
hci_cc_le_set_cig_params:3846: hci0: status 0x07
hci_sent_cmd_data:3107: hci0 opcode 0x2062
iso_connect_cfm:1703: hcon 0000000093bc551f bdaddr 28:3d:c2:4a:7e:da status 7
iso_conn_del:187: hcon 0000000093bc551f conn 00000000768ae504, err 12
hci_conn_del:1151: hci0 hcon 0000000093bc551f handle 65535
hci_conn_unlink:1102: hci0: hcon 0000000093bc551f
hci_chan_list_flush:2780: hcon 0000000093bc551f
__iso_chan_add:214: conn 00000000768ae504
<Note: this conn was already freed in iso_conn_del above>
iso_sock_clear_timer:117: sock 0000000098323f95 state 3
general protection fault, probably for non-canonical address 0x30b29c630930aec8: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 1920 Comm: bluetoothd Tainted: G E 6.3.0-rc7+ #4
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:detach_if_pending+0x28/0xd0
Code: 90 90 0f 1f 44 00 00 48 8b 47 08 48 85 c0 0f 84 ad 00 00 00 55 89 d5 53 48 83 3f 00 48 89 fb 74 7d 66 90 48 8b 03 48 8b 53 08 <>
RSP: 0018:ffffb90841a67d08 EFLAGS: 00010007
RAX: 0000000000000000 RBX: ffff9141bd5061b8 RCX: 0000000000000000
RDX: 30b29c630930aec8 RSI: ffff9141fdd21e80 RDI: ffff9141bd5061b8
RBP: 0000000000000001 R08: 0000000000000000 R09: ffffb90841a67b88
R10: 0000000000000003 R11: ffffffff8613f558 R12: ffff9141fdd21e80
R13: 0000000000000000 R14: ffff9141b5976010 R15: ffff914185755338
FS: 00007f45768bd840(0000) GS:ffff9141fdd00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000619000424074 CR3: 0000000009f5e005 CR4: 0000000000170ee0
Call Trace:
<TASK>
timer_delete+0x48/0x80
try_to_grab_pending+0xdf/0x170
__cancel_work+0x37/0xb0
iso_connect_cis+0x141/0x400 [bluetooth]
===============================================================
Trace with NULL conn->hcon in state BT_CONNECT:
===============================================================
__iso_sock_close:619: sk 00000000f7c71fc5 state 1 socket 00000000d90c5fe5
...
__iso_sock_close:619: sk 00000000f7c71fc5 state 8 socket 00000000d90c5fe5
iso_chan_del:153: sk 00000000f7c71fc5, conn 0000000022c03a7e, err 104
...
iso_sock_connect:862: sk 00000000129b56c3
iso_connect_cis:348: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7d:2a
hci_get_route:1199: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7d:2a
hci_dev_hold:1495: hci0 orig refcnt 19
__iso_chan_add:214: conn 0000000022c03a7e
<Note: reusing old conn>
iso_sock_clear_timer:117: sock 00000000129b56c3 state 3
...
iso_sock_ready:1485: sk 00000000129b56c3
...
iso_sock_sendmsg:1077: sock 00000000e5013966, sk 00000000129b56c3
BUG: kernel NULL pointer dereference, address: 00000000000006a8
PGD 0 P4D 0
Oops: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 1403 Comm: wireplumber Tainted: G E 6.3.0-rc7+ #4
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:iso_sock_sendmsg+0x63/0x2a0 [bluetooth]
===============================================================
Fixes: 241f51931c35 ("Bluetooth: ISO: Avoid circular locking dependency")
Fixes: 6a5ad251b7cd ("Bluetooth: ISO: Fix possible circular locking dependency")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2023-06-18 22:04:33 +00:00
|
|
|
lock_sock(sk);
|
2022-12-07 00:34:42 +00:00
|
|
|
|
2023-01-10 21:24:51 +00:00
|
|
|
err = iso_chan_add(conn, sk, NULL);
|
Bluetooth: ISO: fix iso_conn related locking and validity issues
sk->sk_state indicates whether iso_pi(sk)->conn is valid. Operations
that check/update sk_state and access conn should hold lock_sock,
otherwise they can race.
The order of taking locks is hci_dev_lock > lock_sock > iso_conn_lock,
which is how it is in connect/disconnect_cfm -> iso_conn_del ->
iso_chan_del.
Fix locking in iso_connect_cis/bis and sendmsg/recvmsg to take lock_sock
around updating sk_state and conn.
iso_conn_del must not occur during iso_connect_cis/bis, as it frees the
iso_conn. Hold hdev->lock longer to prevent that.
This should not reintroduce the issue fixed in commit 241f51931c35
("Bluetooth: ISO: Avoid circular locking dependency"), since the we
acquire locks in order. We retain the fix in iso_sock_connect to release
lock_sock before iso_connect_* acquires hdev->lock.
Similarly for commit 6a5ad251b7cd ("Bluetooth: ISO: Fix possible
circular locking dependency"). We retain the fix in iso_conn_ready to
not acquire iso_conn_lock before lock_sock.
iso_conn_add shall return iso_conn with valid hcon. Make it so also when
reusing an old CIS connection waiting for disconnect timeout (see
__iso_sock_close where conn->hcon is set to NULL).
Trace with iso_conn_del after iso_chan_add in iso_connect_cis:
===============================================================
iso_sock_create:771: sock 00000000be9b69b7
iso_sock_init:693: sk 000000004dff667e
iso_sock_bind:827: sk 000000004dff667e 70:1a:b8:98:ff:a2 type 1
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_connect:875: sk 000000004dff667e
iso_connect_cis:353: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
hci_get_route:1199: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
hci_conn_add:1005: hci0 dst 28:3d:c2:4a:7e:da
iso_conn_add:140: hcon 000000007b65d182 conn 00000000daf8625e
__iso_chan_add:214: conn 00000000daf8625e
iso_connect_cfm:1700: hcon 000000007b65d182 bdaddr 28:3d:c2:4a:7e:da status 12
iso_conn_del:187: hcon 000000007b65d182 conn 00000000daf8625e, err 16
iso_sock_clear_timer:117: sock 000000004dff667e state 3
<Note: sk_state is BT_BOUND (3), so iso_connect_cis is still
running at this point>
iso_chan_del:153: sk 000000004dff667e, conn 00000000daf8625e, err 16
hci_conn_del:1151: hci0 hcon 000000007b65d182 handle 65535
hci_conn_unlink:1102: hci0: hcon 000000007b65d182
hci_chan_list_flush:2780: hcon 000000007b65d182
iso_sock_getsockopt:1376: sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getsockopt:1376: sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_shutdown:1434: sock 00000000be9b69b7, sk 000000004dff667e, how 1
__iso_sock_close:632: sk 000000004dff667e state 5 socket 00000000be9b69b7
<Note: sk_state is BT_CONNECT (5), even though iso_chan_del sets
BT_CLOSED (6). Only iso_connect_cis sets it to BT_CONNECT, so it
must be that iso_chan_del occurred between iso_chan_add and end of
iso_connect_cis.>
BUG: kernel NULL pointer dereference, address: 0000000000000000
PGD 8000000006467067 P4D 8000000006467067 PUD 3f5f067 PMD 0
Oops: 0000 [#1] PREEMPT SMP PTI
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:__iso_sock_close (net/bluetooth/iso.c:664) bluetooth
===============================================================
Trace with iso_conn_del before iso_chan_add in iso_connect_cis:
===============================================================
iso_connect_cis:356: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
...
iso_conn_add:140: hcon 0000000093bc551f conn 00000000768ae504
hci_dev_put:1487: hci0 orig refcnt 21
hci_event_packet:7607: hci0: event 0x0e
hci_cmd_complete_evt:4231: hci0: opcode 0x2062
hci_cc_le_set_cig_params:3846: hci0: status 0x07
hci_sent_cmd_data:3107: hci0 opcode 0x2062
iso_connect_cfm:1703: hcon 0000000093bc551f bdaddr 28:3d:c2:4a:7e:da status 7
iso_conn_del:187: hcon 0000000093bc551f conn 00000000768ae504, err 12
hci_conn_del:1151: hci0 hcon 0000000093bc551f handle 65535
hci_conn_unlink:1102: hci0: hcon 0000000093bc551f
hci_chan_list_flush:2780: hcon 0000000093bc551f
__iso_chan_add:214: conn 00000000768ae504
<Note: this conn was already freed in iso_conn_del above>
iso_sock_clear_timer:117: sock 0000000098323f95 state 3
general protection fault, probably for non-canonical address 0x30b29c630930aec8: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 1920 Comm: bluetoothd Tainted: G E 6.3.0-rc7+ #4
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:detach_if_pending+0x28/0xd0
Code: 90 90 0f 1f 44 00 00 48 8b 47 08 48 85 c0 0f 84 ad 00 00 00 55 89 d5 53 48 83 3f 00 48 89 fb 74 7d 66 90 48 8b 03 48 8b 53 08 <>
RSP: 0018:ffffb90841a67d08 EFLAGS: 00010007
RAX: 0000000000000000 RBX: ffff9141bd5061b8 RCX: 0000000000000000
RDX: 30b29c630930aec8 RSI: ffff9141fdd21e80 RDI: ffff9141bd5061b8
RBP: 0000000000000001 R08: 0000000000000000 R09: ffffb90841a67b88
R10: 0000000000000003 R11: ffffffff8613f558 R12: ffff9141fdd21e80
R13: 0000000000000000 R14: ffff9141b5976010 R15: ffff914185755338
FS: 00007f45768bd840(0000) GS:ffff9141fdd00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000619000424074 CR3: 0000000009f5e005 CR4: 0000000000170ee0
Call Trace:
<TASK>
timer_delete+0x48/0x80
try_to_grab_pending+0xdf/0x170
__cancel_work+0x37/0xb0
iso_connect_cis+0x141/0x400 [bluetooth]
===============================================================
Trace with NULL conn->hcon in state BT_CONNECT:
===============================================================
__iso_sock_close:619: sk 00000000f7c71fc5 state 1 socket 00000000d90c5fe5
...
__iso_sock_close:619: sk 00000000f7c71fc5 state 8 socket 00000000d90c5fe5
iso_chan_del:153: sk 00000000f7c71fc5, conn 0000000022c03a7e, err 104
...
iso_sock_connect:862: sk 00000000129b56c3
iso_connect_cis:348: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7d:2a
hci_get_route:1199: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7d:2a
hci_dev_hold:1495: hci0 orig refcnt 19
__iso_chan_add:214: conn 0000000022c03a7e
<Note: reusing old conn>
iso_sock_clear_timer:117: sock 00000000129b56c3 state 3
...
iso_sock_ready:1485: sk 00000000129b56c3
...
iso_sock_sendmsg:1077: sock 00000000e5013966, sk 00000000129b56c3
BUG: kernel NULL pointer dereference, address: 00000000000006a8
PGD 0 P4D 0
Oops: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 1403 Comm: wireplumber Tainted: G E 6.3.0-rc7+ #4
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:iso_sock_sendmsg+0x63/0x2a0 [bluetooth]
===============================================================
Fixes: 241f51931c35 ("Bluetooth: ISO: Avoid circular locking dependency")
Fixes: 6a5ad251b7cd ("Bluetooth: ISO: Fix possible circular locking dependency")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2023-06-18 22:04:33 +00:00
|
|
|
if (err) {
|
|
|
|
release_sock(sk);
|
|
|
|
goto unlock;
|
|
|
|
}
|
2022-12-07 00:34:42 +00:00
|
|
|
|
2022-03-09 21:14:41 +00:00
|
|
|
/* Update source addr of the socket */
|
|
|
|
bacpy(&iso_pi(sk)->src, &hcon->src);
|
|
|
|
|
|
|
|
if (hcon->state == BT_CONNECTED) {
|
|
|
|
iso_sock_clear_timer(sk);
|
|
|
|
sk->sk_state = BT_CONNECTED;
|
Bluetooth: ISO: Add support for connecting multiple BISes
It is required for some configurations to have multiple BISes as part
of the same BIG.
Similar to the flow implemented for unicast, DEFER_SETUP will also be
used to bind multiple BISes for the same BIG, before starting Periodic
Advertising and creating the BIG.
The user will have to open a new socket for each BIS. By setting the
BT_DEFER_SETUP socket option and calling connect, a new connection
will be added for the BIG and advertising handle set by the socket
QoS parameters. Since all BISes will be bound for the same BIG and
advertising handle, the socket QoS options and base parameters should
match for all connections.
By calling connect on a socket that does not have the BT_DEFER_SETUP
option set, periodic advertising will be started and the BIG will
be created, with a BIS for each previously bound connection. Since
a BIG cannot be reconfigured with additional BISes after creation,
no more connections can be bound for the BIG after the start periodic
advertising and create BIG commands have been queued.
The bis_cleanup function has also been updated, so that the advertising
set and the BIG will not be terminated unless there are no more
bound or connected BISes.
The HCI_CONN_BIG_CREATED connection flag has been added to indicate
that the BIG has been successfully created. This flag is checked at
bis_cleanup, so that the BIG is only terminated if the
HCI_LE_Create_BIG_Complete has been received.
This implementation has been tested on hardware, using the "isotest"
tool with an additional command line option, to specify the number of
BISes to create as part of the desired BIG:
tools/isotest -i hci0 -s 00:00:00:00:00:00 -N 2 -G 1 -T 1
The btmon log shows that a BIG containing 2 BISes has been created:
< HCI Command: LE Create Broadcast Isochronous Group (0x08|0x0068) plen 31
Handle: 0x01
Advertising Handle: 0x01
Number of BIS: 2
SDU Interval: 10000 us (0x002710)
Maximum SDU size: 40
Maximum Latency: 10 ms (0x000a)
RTN: 0x02
PHY: LE 2M (0x02)
Packing: Sequential (0x00)
Framing: Unframed (0x00)
Encryption: 0x00
Broadcast Code: 00000000000000000000000000000000
> HCI Event: Command Status (0x0f) plen 4
LE Create Broadcast Isochronous Group (0x08|0x0068) ncmd 1
Status: Success (0x00)
> HCI Event: LE Meta Event (0x3e) plen 23
LE Broadcast Isochronous Group Complete (0x1b)
Status: Success (0x00)
Handle: 0x01
BIG Synchronization Delay: 1974 us (0x0007b6)
Transport Latency: 1974 us (0x0007b6)
PHY: LE 2M (0x02)
NSE: 3
BN: 1
PTO: 1
IRC: 3
Maximum PDU: 40
ISO Interval: 10.00 msec (0x0008)
Connection Handle #0: 10
Connection Handle #1: 11
< HCI Command: LE Setup Isochronous Data Path (0x08|0x006e) plen 13
Handle: 10
Data Path Direction: Input (Host to Controller) (0x00)
Data Path: HCI (0x00)
Coding Format: Transparent (0x03)
Company Codec ID: Ericsson Technology Licensing (0)
Vendor Codec ID: 0
Controller Delay: 0 us (0x000000)
Codec Configuration Length: 0
Codec Configuration:
> HCI Event: Command Complete (0x0e) plen 6
LE Setup Isochronous Data Path (0x08|0x006e) ncmd 1
Status: Success (0x00)
Handle: 10
< HCI Command: LE Setup Isochronous Data Path (0x08|0x006e) plen 13
Handle: 11
Data Path Direction: Input (Host to Controller) (0x00)
Data Path: HCI (0x00)
Coding Format: Transparent (0x03)
Company Codec ID: Ericsson Technology Licensing (0)
Vendor Codec ID: 0
Controller Delay: 0 us (0x000000)
Codec Configuration Length: 0
Codec Configuration:
> HCI Event: Command Complete (0x0e) plen 6
LE Setup Isochronous Data Path (0x08|0x006e) ncmd 1
Status: Success (0x00)
Handle: 11
< ISO Data TX: Handle 10 flags 0x02 dlen 44
< ISO Data TX: Handle 11 flags 0x02 dlen 44
> HCI Event: Number of Completed Packets (0x13) plen 5
Num handles: 1
Handle: 10
Count: 1
> HCI Event: Number of Completed Packets (0x13) plen 5
Num handles: 1
Handle: 11
Count: 1
Signed-off-by: Iulia Tanasescu <iulia.tanasescu@nxp.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2023-05-30 14:21:59 +00:00
|
|
|
} else if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
|
|
|
|
iso_sock_clear_timer(sk);
|
|
|
|
sk->sk_state = BT_CONNECT;
|
2022-03-09 21:14:41 +00:00
|
|
|
} else {
|
|
|
|
sk->sk_state = BT_CONNECT;
|
|
|
|
iso_sock_set_timer(sk, sk->sk_sndtimeo);
|
|
|
|
}
|
|
|
|
|
2022-12-07 00:34:42 +00:00
|
|
|
release_sock(sk);
|
|
|
|
|
|
|
|
unlock:
|
2022-03-09 21:14:41 +00:00
|
|
|
hci_dev_unlock(hdev);
|
|
|
|
hci_dev_put(hdev);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int iso_connect_cis(struct sock *sk)
|
2020-01-16 23:55:57 +00:00
|
|
|
{
|
|
|
|
struct iso_conn *conn;
|
|
|
|
struct hci_conn *hcon;
|
|
|
|
struct hci_dev *hdev;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
BT_DBG("%pMR -> %pMR", &iso_pi(sk)->src, &iso_pi(sk)->dst);
|
|
|
|
|
|
|
|
hdev = hci_get_route(&iso_pi(sk)->dst, &iso_pi(sk)->src,
|
|
|
|
iso_pi(sk)->src_type);
|
|
|
|
if (!hdev)
|
|
|
|
return -EHOSTUNREACH;
|
|
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
|
|
if (!cis_central_capable(hdev)) {
|
|
|
|
err = -EOPNOTSUPP;
|
2022-12-07 00:34:42 +00:00
|
|
|
goto unlock;
|
2020-01-16 23:55:57 +00:00
|
|
|
}
|
|
|
|
|
2023-03-31 15:38:01 +00:00
|
|
|
/* Fail if user set invalid QoS */
|
|
|
|
if (iso_pi(sk)->qos_user_set && !check_ucast_qos(&iso_pi(sk)->qos)) {
|
|
|
|
iso_pi(sk)->qos = default_qos;
|
|
|
|
err = -EINVAL;
|
|
|
|
goto unlock;
|
|
|
|
}
|
|
|
|
|
2020-01-16 23:55:57 +00:00
|
|
|
/* Fail if either PHYs are marked as disabled */
|
2023-03-31 15:38:01 +00:00
|
|
|
if (!iso_pi(sk)->qos.ucast.in.phy && !iso_pi(sk)->qos.ucast.out.phy) {
|
2020-01-16 23:55:57 +00:00
|
|
|
err = -EINVAL;
|
2022-12-07 00:34:42 +00:00
|
|
|
goto unlock;
|
2020-01-16 23:55:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Just bind if DEFER_SETUP has been set */
|
|
|
|
if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
|
|
|
|
hcon = hci_bind_cis(hdev, &iso_pi(sk)->dst,
|
2022-10-11 19:25:33 +00:00
|
|
|
le_addr_type(iso_pi(sk)->dst_type),
|
|
|
|
&iso_pi(sk)->qos);
|
2020-01-16 23:55:57 +00:00
|
|
|
if (IS_ERR(hcon)) {
|
|
|
|
err = PTR_ERR(hcon);
|
2022-12-07 00:34:42 +00:00
|
|
|
goto unlock;
|
2020-01-16 23:55:57 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
hcon = hci_connect_cis(hdev, &iso_pi(sk)->dst,
|
2022-10-11 19:25:33 +00:00
|
|
|
le_addr_type(iso_pi(sk)->dst_type),
|
|
|
|
&iso_pi(sk)->qos);
|
2020-01-16 23:55:57 +00:00
|
|
|
if (IS_ERR(hcon)) {
|
|
|
|
err = PTR_ERR(hcon);
|
2022-12-07 00:34:42 +00:00
|
|
|
goto unlock;
|
2020-01-16 23:55:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
conn = iso_conn_add(hcon);
|
|
|
|
if (!conn) {
|
|
|
|
hci_conn_drop(hcon);
|
|
|
|
err = -ENOMEM;
|
2022-12-07 00:34:42 +00:00
|
|
|
goto unlock;
|
2020-01-16 23:55:57 +00:00
|
|
|
}
|
|
|
|
|
Bluetooth: ISO: fix iso_conn related locking and validity issues
sk->sk_state indicates whether iso_pi(sk)->conn is valid. Operations
that check/update sk_state and access conn should hold lock_sock,
otherwise they can race.
The order of taking locks is hci_dev_lock > lock_sock > iso_conn_lock,
which is how it is in connect/disconnect_cfm -> iso_conn_del ->
iso_chan_del.
Fix locking in iso_connect_cis/bis and sendmsg/recvmsg to take lock_sock
around updating sk_state and conn.
iso_conn_del must not occur during iso_connect_cis/bis, as it frees the
iso_conn. Hold hdev->lock longer to prevent that.
This should not reintroduce the issue fixed in commit 241f51931c35
("Bluetooth: ISO: Avoid circular locking dependency"), since the we
acquire locks in order. We retain the fix in iso_sock_connect to release
lock_sock before iso_connect_* acquires hdev->lock.
Similarly for commit 6a5ad251b7cd ("Bluetooth: ISO: Fix possible
circular locking dependency"). We retain the fix in iso_conn_ready to
not acquire iso_conn_lock before lock_sock.
iso_conn_add shall return iso_conn with valid hcon. Make it so also when
reusing an old CIS connection waiting for disconnect timeout (see
__iso_sock_close where conn->hcon is set to NULL).
Trace with iso_conn_del after iso_chan_add in iso_connect_cis:
===============================================================
iso_sock_create:771: sock 00000000be9b69b7
iso_sock_init:693: sk 000000004dff667e
iso_sock_bind:827: sk 000000004dff667e 70:1a:b8:98:ff:a2 type 1
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_connect:875: sk 000000004dff667e
iso_connect_cis:353: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
hci_get_route:1199: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
hci_conn_add:1005: hci0 dst 28:3d:c2:4a:7e:da
iso_conn_add:140: hcon 000000007b65d182 conn 00000000daf8625e
__iso_chan_add:214: conn 00000000daf8625e
iso_connect_cfm:1700: hcon 000000007b65d182 bdaddr 28:3d:c2:4a:7e:da status 12
iso_conn_del:187: hcon 000000007b65d182 conn 00000000daf8625e, err 16
iso_sock_clear_timer:117: sock 000000004dff667e state 3
<Note: sk_state is BT_BOUND (3), so iso_connect_cis is still
running at this point>
iso_chan_del:153: sk 000000004dff667e, conn 00000000daf8625e, err 16
hci_conn_del:1151: hci0 hcon 000000007b65d182 handle 65535
hci_conn_unlink:1102: hci0: hcon 000000007b65d182
hci_chan_list_flush:2780: hcon 000000007b65d182
iso_sock_getsockopt:1376: sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getsockopt:1376: sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_shutdown:1434: sock 00000000be9b69b7, sk 000000004dff667e, how 1
__iso_sock_close:632: sk 000000004dff667e state 5 socket 00000000be9b69b7
<Note: sk_state is BT_CONNECT (5), even though iso_chan_del sets
BT_CLOSED (6). Only iso_connect_cis sets it to BT_CONNECT, so it
must be that iso_chan_del occurred between iso_chan_add and end of
iso_connect_cis.>
BUG: kernel NULL pointer dereference, address: 0000000000000000
PGD 8000000006467067 P4D 8000000006467067 PUD 3f5f067 PMD 0
Oops: 0000 [#1] PREEMPT SMP PTI
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:__iso_sock_close (net/bluetooth/iso.c:664) bluetooth
===============================================================
Trace with iso_conn_del before iso_chan_add in iso_connect_cis:
===============================================================
iso_connect_cis:356: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
...
iso_conn_add:140: hcon 0000000093bc551f conn 00000000768ae504
hci_dev_put:1487: hci0 orig refcnt 21
hci_event_packet:7607: hci0: event 0x0e
hci_cmd_complete_evt:4231: hci0: opcode 0x2062
hci_cc_le_set_cig_params:3846: hci0: status 0x07
hci_sent_cmd_data:3107: hci0 opcode 0x2062
iso_connect_cfm:1703: hcon 0000000093bc551f bdaddr 28:3d:c2:4a:7e:da status 7
iso_conn_del:187: hcon 0000000093bc551f conn 00000000768ae504, err 12
hci_conn_del:1151: hci0 hcon 0000000093bc551f handle 65535
hci_conn_unlink:1102: hci0: hcon 0000000093bc551f
hci_chan_list_flush:2780: hcon 0000000093bc551f
__iso_chan_add:214: conn 00000000768ae504
<Note: this conn was already freed in iso_conn_del above>
iso_sock_clear_timer:117: sock 0000000098323f95 state 3
general protection fault, probably for non-canonical address 0x30b29c630930aec8: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 1920 Comm: bluetoothd Tainted: G E 6.3.0-rc7+ #4
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:detach_if_pending+0x28/0xd0
Code: 90 90 0f 1f 44 00 00 48 8b 47 08 48 85 c0 0f 84 ad 00 00 00 55 89 d5 53 48 83 3f 00 48 89 fb 74 7d 66 90 48 8b 03 48 8b 53 08 <>
RSP: 0018:ffffb90841a67d08 EFLAGS: 00010007
RAX: 0000000000000000 RBX: ffff9141bd5061b8 RCX: 0000000000000000
RDX: 30b29c630930aec8 RSI: ffff9141fdd21e80 RDI: ffff9141bd5061b8
RBP: 0000000000000001 R08: 0000000000000000 R09: ffffb90841a67b88
R10: 0000000000000003 R11: ffffffff8613f558 R12: ffff9141fdd21e80
R13: 0000000000000000 R14: ffff9141b5976010 R15: ffff914185755338
FS: 00007f45768bd840(0000) GS:ffff9141fdd00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000619000424074 CR3: 0000000009f5e005 CR4: 0000000000170ee0
Call Trace:
<TASK>
timer_delete+0x48/0x80
try_to_grab_pending+0xdf/0x170
__cancel_work+0x37/0xb0
iso_connect_cis+0x141/0x400 [bluetooth]
===============================================================
Trace with NULL conn->hcon in state BT_CONNECT:
===============================================================
__iso_sock_close:619: sk 00000000f7c71fc5 state 1 socket 00000000d90c5fe5
...
__iso_sock_close:619: sk 00000000f7c71fc5 state 8 socket 00000000d90c5fe5
iso_chan_del:153: sk 00000000f7c71fc5, conn 0000000022c03a7e, err 104
...
iso_sock_connect:862: sk 00000000129b56c3
iso_connect_cis:348: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7d:2a
hci_get_route:1199: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7d:2a
hci_dev_hold:1495: hci0 orig refcnt 19
__iso_chan_add:214: conn 0000000022c03a7e
<Note: reusing old conn>
iso_sock_clear_timer:117: sock 00000000129b56c3 state 3
...
iso_sock_ready:1485: sk 00000000129b56c3
...
iso_sock_sendmsg:1077: sock 00000000e5013966, sk 00000000129b56c3
BUG: kernel NULL pointer dereference, address: 00000000000006a8
PGD 0 P4D 0
Oops: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 1403 Comm: wireplumber Tainted: G E 6.3.0-rc7+ #4
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:iso_sock_sendmsg+0x63/0x2a0 [bluetooth]
===============================================================
Fixes: 241f51931c35 ("Bluetooth: ISO: Avoid circular locking dependency")
Fixes: 6a5ad251b7cd ("Bluetooth: ISO: Fix possible circular locking dependency")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2023-06-18 22:04:33 +00:00
|
|
|
lock_sock(sk);
|
2022-12-07 00:34:42 +00:00
|
|
|
|
2023-01-10 21:24:51 +00:00
|
|
|
err = iso_chan_add(conn, sk, NULL);
|
Bluetooth: ISO: fix iso_conn related locking and validity issues
sk->sk_state indicates whether iso_pi(sk)->conn is valid. Operations
that check/update sk_state and access conn should hold lock_sock,
otherwise they can race.
The order of taking locks is hci_dev_lock > lock_sock > iso_conn_lock,
which is how it is in connect/disconnect_cfm -> iso_conn_del ->
iso_chan_del.
Fix locking in iso_connect_cis/bis and sendmsg/recvmsg to take lock_sock
around updating sk_state and conn.
iso_conn_del must not occur during iso_connect_cis/bis, as it frees the
iso_conn. Hold hdev->lock longer to prevent that.
This should not reintroduce the issue fixed in commit 241f51931c35
("Bluetooth: ISO: Avoid circular locking dependency"), since the we
acquire locks in order. We retain the fix in iso_sock_connect to release
lock_sock before iso_connect_* acquires hdev->lock.
Similarly for commit 6a5ad251b7cd ("Bluetooth: ISO: Fix possible
circular locking dependency"). We retain the fix in iso_conn_ready to
not acquire iso_conn_lock before lock_sock.
iso_conn_add shall return iso_conn with valid hcon. Make it so also when
reusing an old CIS connection waiting for disconnect timeout (see
__iso_sock_close where conn->hcon is set to NULL).
Trace with iso_conn_del after iso_chan_add in iso_connect_cis:
===============================================================
iso_sock_create:771: sock 00000000be9b69b7
iso_sock_init:693: sk 000000004dff667e
iso_sock_bind:827: sk 000000004dff667e 70:1a:b8:98:ff:a2 type 1
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_connect:875: sk 000000004dff667e
iso_connect_cis:353: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
hci_get_route:1199: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
hci_conn_add:1005: hci0 dst 28:3d:c2:4a:7e:da
iso_conn_add:140: hcon 000000007b65d182 conn 00000000daf8625e
__iso_chan_add:214: conn 00000000daf8625e
iso_connect_cfm:1700: hcon 000000007b65d182 bdaddr 28:3d:c2:4a:7e:da status 12
iso_conn_del:187: hcon 000000007b65d182 conn 00000000daf8625e, err 16
iso_sock_clear_timer:117: sock 000000004dff667e state 3
<Note: sk_state is BT_BOUND (3), so iso_connect_cis is still
running at this point>
iso_chan_del:153: sk 000000004dff667e, conn 00000000daf8625e, err 16
hci_conn_del:1151: hci0 hcon 000000007b65d182 handle 65535
hci_conn_unlink:1102: hci0: hcon 000000007b65d182
hci_chan_list_flush:2780: hcon 000000007b65d182
iso_sock_getsockopt:1376: sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getsockopt:1376: sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_shutdown:1434: sock 00000000be9b69b7, sk 000000004dff667e, how 1
__iso_sock_close:632: sk 000000004dff667e state 5 socket 00000000be9b69b7
<Note: sk_state is BT_CONNECT (5), even though iso_chan_del sets
BT_CLOSED (6). Only iso_connect_cis sets it to BT_CONNECT, so it
must be that iso_chan_del occurred between iso_chan_add and end of
iso_connect_cis.>
BUG: kernel NULL pointer dereference, address: 0000000000000000
PGD 8000000006467067 P4D 8000000006467067 PUD 3f5f067 PMD 0
Oops: 0000 [#1] PREEMPT SMP PTI
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:__iso_sock_close (net/bluetooth/iso.c:664) bluetooth
===============================================================
Trace with iso_conn_del before iso_chan_add in iso_connect_cis:
===============================================================
iso_connect_cis:356: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
...
iso_conn_add:140: hcon 0000000093bc551f conn 00000000768ae504
hci_dev_put:1487: hci0 orig refcnt 21
hci_event_packet:7607: hci0: event 0x0e
hci_cmd_complete_evt:4231: hci0: opcode 0x2062
hci_cc_le_set_cig_params:3846: hci0: status 0x07
hci_sent_cmd_data:3107: hci0 opcode 0x2062
iso_connect_cfm:1703: hcon 0000000093bc551f bdaddr 28:3d:c2:4a:7e:da status 7
iso_conn_del:187: hcon 0000000093bc551f conn 00000000768ae504, err 12
hci_conn_del:1151: hci0 hcon 0000000093bc551f handle 65535
hci_conn_unlink:1102: hci0: hcon 0000000093bc551f
hci_chan_list_flush:2780: hcon 0000000093bc551f
__iso_chan_add:214: conn 00000000768ae504
<Note: this conn was already freed in iso_conn_del above>
iso_sock_clear_timer:117: sock 0000000098323f95 state 3
general protection fault, probably for non-canonical address 0x30b29c630930aec8: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 1920 Comm: bluetoothd Tainted: G E 6.3.0-rc7+ #4
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:detach_if_pending+0x28/0xd0
Code: 90 90 0f 1f 44 00 00 48 8b 47 08 48 85 c0 0f 84 ad 00 00 00 55 89 d5 53 48 83 3f 00 48 89 fb 74 7d 66 90 48 8b 03 48 8b 53 08 <>
RSP: 0018:ffffb90841a67d08 EFLAGS: 00010007
RAX: 0000000000000000 RBX: ffff9141bd5061b8 RCX: 0000000000000000
RDX: 30b29c630930aec8 RSI: ffff9141fdd21e80 RDI: ffff9141bd5061b8
RBP: 0000000000000001 R08: 0000000000000000 R09: ffffb90841a67b88
R10: 0000000000000003 R11: ffffffff8613f558 R12: ffff9141fdd21e80
R13: 0000000000000000 R14: ffff9141b5976010 R15: ffff914185755338
FS: 00007f45768bd840(0000) GS:ffff9141fdd00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000619000424074 CR3: 0000000009f5e005 CR4: 0000000000170ee0
Call Trace:
<TASK>
timer_delete+0x48/0x80
try_to_grab_pending+0xdf/0x170
__cancel_work+0x37/0xb0
iso_connect_cis+0x141/0x400 [bluetooth]
===============================================================
Trace with NULL conn->hcon in state BT_CONNECT:
===============================================================
__iso_sock_close:619: sk 00000000f7c71fc5 state 1 socket 00000000d90c5fe5
...
__iso_sock_close:619: sk 00000000f7c71fc5 state 8 socket 00000000d90c5fe5
iso_chan_del:153: sk 00000000f7c71fc5, conn 0000000022c03a7e, err 104
...
iso_sock_connect:862: sk 00000000129b56c3
iso_connect_cis:348: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7d:2a
hci_get_route:1199: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7d:2a
hci_dev_hold:1495: hci0 orig refcnt 19
__iso_chan_add:214: conn 0000000022c03a7e
<Note: reusing old conn>
iso_sock_clear_timer:117: sock 00000000129b56c3 state 3
...
iso_sock_ready:1485: sk 00000000129b56c3
...
iso_sock_sendmsg:1077: sock 00000000e5013966, sk 00000000129b56c3
BUG: kernel NULL pointer dereference, address: 00000000000006a8
PGD 0 P4D 0
Oops: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 1403 Comm: wireplumber Tainted: G E 6.3.0-rc7+ #4
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:iso_sock_sendmsg+0x63/0x2a0 [bluetooth]
===============================================================
Fixes: 241f51931c35 ("Bluetooth: ISO: Avoid circular locking dependency")
Fixes: 6a5ad251b7cd ("Bluetooth: ISO: Fix possible circular locking dependency")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2023-06-18 22:04:33 +00:00
|
|
|
if (err) {
|
|
|
|
release_sock(sk);
|
|
|
|
goto unlock;
|
|
|
|
}
|
2022-12-07 00:34:42 +00:00
|
|
|
|
2020-01-16 23:55:57 +00:00
|
|
|
/* Update source addr of the socket */
|
|
|
|
bacpy(&iso_pi(sk)->src, &hcon->src);
|
|
|
|
|
|
|
|
if (hcon->state == BT_CONNECTED) {
|
|
|
|
iso_sock_clear_timer(sk);
|
|
|
|
sk->sk_state = BT_CONNECTED;
|
|
|
|
} else if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
|
|
|
|
iso_sock_clear_timer(sk);
|
|
|
|
sk->sk_state = BT_CONNECT;
|
|
|
|
} else {
|
|
|
|
sk->sk_state = BT_CONNECT;
|
|
|
|
iso_sock_set_timer(sk, sk->sk_sndtimeo);
|
|
|
|
}
|
|
|
|
|
2022-12-07 00:34:42 +00:00
|
|
|
release_sock(sk);
|
|
|
|
|
|
|
|
unlock:
|
2020-01-16 23:55:57 +00:00
|
|
|
hci_dev_unlock(hdev);
|
|
|
|
hci_dev_put(hdev);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2022-08-05 21:02:21 +00:00
|
|
|
static struct bt_iso_qos *iso_sock_get_qos(struct sock *sk)
|
|
|
|
{
|
|
|
|
if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONNECT2)
|
|
|
|
return &iso_pi(sk)->conn->hcon->iso_qos;
|
|
|
|
|
|
|
|
return &iso_pi(sk)->qos;
|
|
|
|
}
|
|
|
|
|
2020-01-16 23:55:57 +00:00
|
|
|
static int iso_send_frame(struct sock *sk, struct sk_buff *skb)
|
|
|
|
{
|
|
|
|
struct iso_conn *conn = iso_pi(sk)->conn;
|
2022-08-05 21:02:21 +00:00
|
|
|
struct bt_iso_qos *qos = iso_sock_get_qos(sk);
|
2020-01-16 23:55:57 +00:00
|
|
|
struct hci_iso_data_hdr *hdr;
|
|
|
|
int len = 0;
|
|
|
|
|
|
|
|
BT_DBG("sk %p len %d", sk, skb->len);
|
|
|
|
|
2023-03-31 15:38:01 +00:00
|
|
|
if (skb->len > qos->ucast.out.sdu)
|
2020-01-16 23:55:57 +00:00
|
|
|
return -EMSGSIZE;
|
|
|
|
|
|
|
|
len = skb->len;
|
|
|
|
|
|
|
|
/* Push ISO data header */
|
|
|
|
hdr = skb_push(skb, HCI_ISO_DATA_HDR_SIZE);
|
|
|
|
hdr->sn = cpu_to_le16(conn->tx_sn++);
|
|
|
|
hdr->slen = cpu_to_le16(hci_iso_data_len_pack(len,
|
|
|
|
HCI_ISO_STATUS_VALID));
|
|
|
|
|
|
|
|
if (sk->sk_state == BT_CONNECTED)
|
|
|
|
hci_send_iso(conn->hcon, skb);
|
|
|
|
else
|
|
|
|
len = -ENOTCONN;
|
|
|
|
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void iso_recv_frame(struct iso_conn *conn, struct sk_buff *skb)
|
|
|
|
{
|
|
|
|
struct sock *sk;
|
|
|
|
|
|
|
|
iso_conn_lock(conn);
|
|
|
|
sk = conn->sk;
|
|
|
|
iso_conn_unlock(conn);
|
|
|
|
|
|
|
|
if (!sk)
|
|
|
|
goto drop;
|
|
|
|
|
|
|
|
BT_DBG("sk %p len %d", sk, skb->len);
|
|
|
|
|
|
|
|
if (sk->sk_state != BT_CONNECTED)
|
|
|
|
goto drop;
|
|
|
|
|
|
|
|
if (!sock_queue_rcv_skb(sk, skb))
|
|
|
|
return;
|
|
|
|
|
|
|
|
drop:
|
|
|
|
kfree_skb(skb);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* -------- Socket interface ---------- */
|
2023-08-28 20:05:45 +00:00
|
|
|
static struct sock *__iso_get_sock_listen_by_addr(bdaddr_t *src, bdaddr_t *dst)
|
2020-01-16 23:55:57 +00:00
|
|
|
{
|
|
|
|
struct sock *sk;
|
|
|
|
|
|
|
|
sk_for_each(sk, &iso_sk_list.head) {
|
|
|
|
if (sk->sk_state != BT_LISTEN)
|
|
|
|
continue;
|
|
|
|
|
2023-08-28 20:05:45 +00:00
|
|
|
if (bacmp(&iso_pi(sk)->dst, dst))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (!bacmp(&iso_pi(sk)->src, src))
|
2020-01-16 23:55:57 +00:00
|
|
|
return sk;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2022-03-09 21:14:41 +00:00
|
|
|
static struct sock *__iso_get_sock_listen_by_sid(bdaddr_t *ba, bdaddr_t *bc,
|
|
|
|
__u8 sid)
|
|
|
|
{
|
|
|
|
struct sock *sk;
|
|
|
|
|
|
|
|
sk_for_each(sk, &iso_sk_list.head) {
|
|
|
|
if (sk->sk_state != BT_LISTEN)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (bacmp(&iso_pi(sk)->src, ba))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (bacmp(&iso_pi(sk)->dst, bc))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (iso_pi(sk)->bc_sid == sid)
|
|
|
|
return sk;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2024-04-02 11:39:30 +00:00
|
|
|
/* Find socket in given state:
|
2022-03-09 21:14:41 +00:00
|
|
|
* source bdaddr (Unicast)
|
|
|
|
* destination bdaddr (Broadcast only)
|
|
|
|
* match func - pass NULL to ignore
|
|
|
|
* match func data - pass -1 to ignore
|
2020-01-16 23:55:57 +00:00
|
|
|
* Returns closest match.
|
|
|
|
*/
|
2024-04-02 11:39:30 +00:00
|
|
|
static struct sock *iso_get_sock(bdaddr_t *src, bdaddr_t *dst,
|
|
|
|
enum bt_sock_state state,
|
|
|
|
iso_sock_match_t match, void *data)
|
2020-01-16 23:55:57 +00:00
|
|
|
{
|
|
|
|
struct sock *sk = NULL, *sk1 = NULL;
|
|
|
|
|
|
|
|
read_lock(&iso_sk_list.lock);
|
|
|
|
|
|
|
|
sk_for_each(sk, &iso_sk_list.head) {
|
2024-04-02 11:39:30 +00:00
|
|
|
if (sk->sk_state != state)
|
2020-01-16 23:55:57 +00:00
|
|
|
continue;
|
|
|
|
|
2022-03-09 21:14:41 +00:00
|
|
|
/* Match Broadcast destination */
|
|
|
|
if (bacmp(dst, BDADDR_ANY) && bacmp(&iso_pi(sk)->dst, dst))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* Use Match function if provided */
|
|
|
|
if (match && !match(sk, data))
|
|
|
|
continue;
|
|
|
|
|
2020-01-16 23:55:57 +00:00
|
|
|
/* Exact match. */
|
2023-11-13 15:38:00 +00:00
|
|
|
if (!bacmp(&iso_pi(sk)->src, src)) {
|
|
|
|
sock_hold(sk);
|
2020-01-16 23:55:57 +00:00
|
|
|
break;
|
2023-11-13 15:38:00 +00:00
|
|
|
}
|
2020-01-16 23:55:57 +00:00
|
|
|
|
|
|
|
/* Closest match */
|
2023-11-13 15:38:00 +00:00
|
|
|
if (!bacmp(&iso_pi(sk)->src, BDADDR_ANY)) {
|
|
|
|
if (sk1)
|
|
|
|
sock_put(sk1);
|
|
|
|
|
2020-01-16 23:55:57 +00:00
|
|
|
sk1 = sk;
|
2023-11-13 15:38:00 +00:00
|
|
|
sock_hold(sk1);
|
|
|
|
}
|
2020-01-16 23:55:57 +00:00
|
|
|
}
|
|
|
|
|
2023-11-13 15:38:00 +00:00
|
|
|
if (sk && sk1)
|
|
|
|
sock_put(sk1);
|
|
|
|
|
2020-01-16 23:55:57 +00:00
|
|
|
read_unlock(&iso_sk_list.lock);
|
|
|
|
|
|
|
|
return sk ? sk : sk1;
|
|
|
|
}
|
|
|
|
|
2023-11-13 15:38:00 +00:00
|
|
|
static struct sock *iso_get_sock_big(struct sock *match_sk, bdaddr_t *src,
|
|
|
|
bdaddr_t *dst, uint8_t big)
|
|
|
|
{
|
|
|
|
struct sock *sk = NULL;
|
|
|
|
|
|
|
|
read_lock(&iso_sk_list.lock);
|
|
|
|
|
|
|
|
sk_for_each(sk, &iso_sk_list.head) {
|
|
|
|
if (match_sk == sk)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* Look for sockets that have already been
|
|
|
|
* connected to the BIG
|
|
|
|
*/
|
|
|
|
if (sk->sk_state != BT_CONNECTED &&
|
|
|
|
sk->sk_state != BT_CONNECT)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* Match Broadcast destination */
|
|
|
|
if (bacmp(&iso_pi(sk)->dst, dst))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* Match BIG handle */
|
|
|
|
if (iso_pi(sk)->qos.bcast.big != big)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* Match source address */
|
|
|
|
if (bacmp(&iso_pi(sk)->src, src))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
sock_hold(sk);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
read_unlock(&iso_sk_list.lock);
|
|
|
|
|
|
|
|
return sk;
|
|
|
|
}
|
|
|
|
|
2020-01-16 23:55:57 +00:00
|
|
|
static void iso_sock_destruct(struct sock *sk)
|
|
|
|
{
|
|
|
|
BT_DBG("sk %p", sk);
|
|
|
|
|
|
|
|
skb_queue_purge(&sk->sk_receive_queue);
|
|
|
|
skb_queue_purge(&sk->sk_write_queue);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void iso_sock_cleanup_listen(struct sock *parent)
|
|
|
|
{
|
|
|
|
struct sock *sk;
|
|
|
|
|
|
|
|
BT_DBG("parent %p", parent);
|
|
|
|
|
|
|
|
/* Close not yet accepted channels */
|
|
|
|
while ((sk = bt_accept_dequeue(parent, NULL))) {
|
|
|
|
iso_sock_close(sk);
|
|
|
|
iso_sock_kill(sk);
|
|
|
|
}
|
|
|
|
|
2024-02-23 13:14:41 +00:00
|
|
|
/* If listening socket has a hcon, properly disconnect it */
|
|
|
|
if (iso_pi(parent)->conn && iso_pi(parent)->conn->hcon) {
|
2023-08-17 06:44:27 +00:00
|
|
|
iso_sock_disconn(parent);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-01-16 23:55:57 +00:00
|
|
|
parent->sk_state = BT_CLOSED;
|
|
|
|
sock_set_flag(parent, SOCK_ZAPPED);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Kill socket (only if zapped and orphan)
|
|
|
|
* Must be called on unlocked socket.
|
|
|
|
*/
|
|
|
|
static void iso_sock_kill(struct sock *sk)
|
|
|
|
{
|
|
|
|
if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket ||
|
|
|
|
sock_flag(sk, SOCK_DEAD))
|
|
|
|
return;
|
|
|
|
|
|
|
|
BT_DBG("sk %p state %d", sk, sk->sk_state);
|
|
|
|
|
|
|
|
/* Kill poor orphan */
|
|
|
|
bt_sock_unlink(&iso_sk_list, sk);
|
|
|
|
sock_set_flag(sk, SOCK_DEAD);
|
|
|
|
sock_put(sk);
|
|
|
|
}
|
|
|
|
|
2023-08-17 06:44:27 +00:00
|
|
|
static void iso_sock_disconn(struct sock *sk)
|
|
|
|
{
|
2023-11-13 15:38:00 +00:00
|
|
|
struct sock *bis_sk;
|
|
|
|
struct hci_conn *hcon = iso_pi(sk)->conn->hcon;
|
|
|
|
|
|
|
|
if (test_bit(HCI_CONN_BIG_CREATED, &hcon->flags)) {
|
|
|
|
bis_sk = iso_get_sock_big(sk, &iso_pi(sk)->src,
|
|
|
|
&iso_pi(sk)->dst,
|
|
|
|
iso_pi(sk)->qos.bcast.big);
|
|
|
|
|
|
|
|
/* If there are any other connected sockets for the
|
|
|
|
* same BIG, just delete the sk and leave the bis
|
|
|
|
* hcon active, in case later rebinding is needed.
|
|
|
|
*/
|
|
|
|
if (bis_sk) {
|
|
|
|
hcon->state = BT_OPEN;
|
|
|
|
iso_pi(sk)->conn->hcon = NULL;
|
|
|
|
iso_sock_clear_timer(sk);
|
|
|
|
iso_chan_del(sk, bt_to_errno(hcon->abort_reason));
|
|
|
|
sock_put(bis_sk);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-17 06:44:27 +00:00
|
|
|
sk->sk_state = BT_DISCONN;
|
|
|
|
iso_sock_set_timer(sk, ISO_DISCONN_TIMEOUT);
|
|
|
|
iso_conn_lock(iso_pi(sk)->conn);
|
|
|
|
hci_conn_drop(iso_pi(sk)->conn->hcon);
|
|
|
|
iso_pi(sk)->conn->hcon = NULL;
|
|
|
|
iso_conn_unlock(iso_pi(sk)->conn);
|
|
|
|
}
|
|
|
|
|
2020-01-16 23:55:57 +00:00
|
|
|
static void __iso_sock_close(struct sock *sk)
|
|
|
|
{
|
|
|
|
BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
|
|
|
|
|
|
|
|
switch (sk->sk_state) {
|
|
|
|
case BT_LISTEN:
|
|
|
|
iso_sock_cleanup_listen(sk);
|
|
|
|
break;
|
|
|
|
|
2023-07-26 21:25:26 +00:00
|
|
|
case BT_CONNECT:
|
2020-01-16 23:55:57 +00:00
|
|
|
case BT_CONNECTED:
|
|
|
|
case BT_CONFIG:
|
2023-08-17 06:44:27 +00:00
|
|
|
if (iso_pi(sk)->conn->hcon)
|
|
|
|
iso_sock_disconn(sk);
|
|
|
|
else
|
2020-01-16 23:55:57 +00:00
|
|
|
iso_chan_del(sk, ECONNRESET);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BT_CONNECT2:
|
2023-08-17 06:44:27 +00:00
|
|
|
if (iso_pi(sk)->conn->hcon &&
|
|
|
|
(test_bit(HCI_CONN_PA_SYNC, &iso_pi(sk)->conn->hcon->flags) ||
|
|
|
|
test_bit(HCI_CONN_PA_SYNC_FAILED, &iso_pi(sk)->conn->hcon->flags)))
|
|
|
|
iso_sock_disconn(sk);
|
|
|
|
else
|
|
|
|
iso_chan_del(sk, ECONNRESET);
|
2020-01-16 23:55:57 +00:00
|
|
|
break;
|
|
|
|
case BT_DISCONN:
|
|
|
|
iso_chan_del(sk, ECONNRESET);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
sock_set_flag(sk, SOCK_ZAPPED);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Must be called on unlocked socket. */
|
|
|
|
static void iso_sock_close(struct sock *sk)
|
|
|
|
{
|
|
|
|
iso_sock_clear_timer(sk);
|
|
|
|
lock_sock(sk);
|
|
|
|
__iso_sock_close(sk);
|
|
|
|
release_sock(sk);
|
|
|
|
iso_sock_kill(sk);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void iso_sock_init(struct sock *sk, struct sock *parent)
|
|
|
|
{
|
|
|
|
BT_DBG("sk %p", sk);
|
|
|
|
|
|
|
|
if (parent) {
|
|
|
|
sk->sk_type = parent->sk_type;
|
|
|
|
bt_sk(sk)->flags = bt_sk(parent)->flags;
|
|
|
|
security_sk_clone(parent, sk);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct proto iso_proto = {
|
|
|
|
.name = "ISO",
|
|
|
|
.owner = THIS_MODULE,
|
|
|
|
.obj_size = sizeof(struct iso_pinfo)
|
|
|
|
};
|
|
|
|
|
|
|
|
#define DEFAULT_IO_QOS \
|
|
|
|
{ \
|
|
|
|
.interval = 10000u, \
|
|
|
|
.latency = 10u, \
|
|
|
|
.sdu = 40u, \
|
|
|
|
.phy = BT_ISO_PHY_2M, \
|
|
|
|
.rtn = 2u, \
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct bt_iso_qos default_qos = {
|
2023-03-31 15:38:01 +00:00
|
|
|
.bcast = {
|
|
|
|
.big = BT_ISO_QOS_BIG_UNSET,
|
|
|
|
.bis = BT_ISO_QOS_BIS_UNSET,
|
2023-06-08 18:12:18 +00:00
|
|
|
.sync_factor = 0x01,
|
2023-03-31 15:38:01 +00:00
|
|
|
.packing = 0x00,
|
|
|
|
.framing = 0x00,
|
|
|
|
.in = DEFAULT_IO_QOS,
|
|
|
|
.out = DEFAULT_IO_QOS,
|
|
|
|
.encryption = 0x00,
|
|
|
|
.bcode = {0x00},
|
|
|
|
.options = 0x00,
|
|
|
|
.skip = 0x0000,
|
2024-03-07 16:58:17 +00:00
|
|
|
.sync_timeout = BT_ISO_SYNC_TIMEOUT,
|
2023-03-31 15:38:01 +00:00
|
|
|
.sync_cte_type = 0x00,
|
|
|
|
.mse = 0x00,
|
2024-03-07 16:58:17 +00:00
|
|
|
.timeout = BT_ISO_SYNC_TIMEOUT,
|
2023-03-31 15:38:01 +00:00
|
|
|
},
|
2020-01-16 23:55:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static struct sock *iso_sock_alloc(struct net *net, struct socket *sock,
|
|
|
|
int proto, gfp_t prio, int kern)
|
|
|
|
{
|
|
|
|
struct sock *sk;
|
|
|
|
|
2023-05-25 23:46:41 +00:00
|
|
|
sk = bt_sock_alloc(net, sock, &iso_proto, proto, prio, kern);
|
2020-01-16 23:55:57 +00:00
|
|
|
if (!sk)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
sk->sk_destruct = iso_sock_destruct;
|
|
|
|
sk->sk_sndtimeo = ISO_CONN_TIMEOUT;
|
|
|
|
|
|
|
|
/* Set address type as public as default src address is BDADDR_ANY */
|
|
|
|
iso_pi(sk)->src_type = BDADDR_LE_PUBLIC;
|
|
|
|
|
|
|
|
iso_pi(sk)->qos = default_qos;
|
2024-04-02 11:39:31 +00:00
|
|
|
iso_pi(sk)->sync_handle = -1;
|
2020-01-16 23:55:57 +00:00
|
|
|
|
|
|
|
bt_sock_link(&iso_sk_list, sk);
|
|
|
|
return sk;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int iso_sock_create(struct net *net, struct socket *sock, int protocol,
|
|
|
|
int kern)
|
|
|
|
{
|
|
|
|
struct sock *sk;
|
|
|
|
|
|
|
|
BT_DBG("sock %p", sock);
|
|
|
|
|
|
|
|
sock->state = SS_UNCONNECTED;
|
|
|
|
|
|
|
|
if (sock->type != SOCK_SEQPACKET)
|
|
|
|
return -ESOCKTNOSUPPORT;
|
|
|
|
|
|
|
|
sock->ops = &iso_sock_ops;
|
|
|
|
|
|
|
|
sk = iso_sock_alloc(net, sock, protocol, GFP_ATOMIC, kern);
|
|
|
|
if (!sk)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
iso_sock_init(sk, NULL);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-03-09 21:14:41 +00:00
|
|
|
static int iso_sock_bind_bc(struct socket *sock, struct sockaddr *addr,
|
|
|
|
int addr_len)
|
|
|
|
{
|
|
|
|
struct sockaddr_iso *sa = (struct sockaddr_iso *)addr;
|
|
|
|
struct sock *sk = sock->sk;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
BT_DBG("sk %p bc_sid %u bc_num_bis %u", sk, sa->iso_bc->bc_sid,
|
|
|
|
sa->iso_bc->bc_num_bis);
|
|
|
|
|
2023-10-24 10:57:35 +00:00
|
|
|
if (addr_len != sizeof(*sa) + sizeof(*sa->iso_bc))
|
2022-03-09 21:14:41 +00:00
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
bacpy(&iso_pi(sk)->dst, &sa->iso_bc->bc_bdaddr);
|
2023-10-24 10:57:35 +00:00
|
|
|
|
|
|
|
/* Check if the address type is of LE type */
|
|
|
|
if (!bdaddr_type_is_le(sa->iso_bc->bc_bdaddr_type))
|
|
|
|
return -EINVAL;
|
|
|
|
|
2022-03-09 21:14:41 +00:00
|
|
|
iso_pi(sk)->dst_type = sa->iso_bc->bc_bdaddr_type;
|
2023-10-24 10:57:35 +00:00
|
|
|
|
|
|
|
if (sa->iso_bc->bc_sid > 0x0f)
|
|
|
|
return -EINVAL;
|
|
|
|
|
2022-03-09 21:14:41 +00:00
|
|
|
iso_pi(sk)->bc_sid = sa->iso_bc->bc_sid;
|
2023-10-24 10:57:35 +00:00
|
|
|
|
|
|
|
if (sa->iso_bc->bc_num_bis > ISO_MAX_NUM_BIS)
|
|
|
|
return -EINVAL;
|
|
|
|
|
2022-03-09 21:14:41 +00:00
|
|
|
iso_pi(sk)->bc_num_bis = sa->iso_bc->bc_num_bis;
|
|
|
|
|
2023-10-24 10:57:35 +00:00
|
|
|
for (i = 0; i < iso_pi(sk)->bc_num_bis; i++)
|
2022-03-09 21:14:41 +00:00
|
|
|
if (sa->iso_bc->bc_bis[i] < 0x01 ||
|
|
|
|
sa->iso_bc->bc_bis[i] > 0x1f)
|
|
|
|
return -EINVAL;
|
|
|
|
|
2023-10-24 10:57:35 +00:00
|
|
|
memcpy(iso_pi(sk)->bc_bis, sa->iso_bc->bc_bis,
|
|
|
|
iso_pi(sk)->bc_num_bis);
|
2022-03-09 21:14:41 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-10-24 10:57:35 +00:00
|
|
|
static int iso_sock_bind_pa_sk(struct sock *sk, struct sockaddr_iso *sa,
|
|
|
|
int addr_len)
|
|
|
|
{
|
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
if (sk->sk_type != SOCK_SEQPACKET) {
|
|
|
|
err = -EINVAL;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (addr_len != sizeof(*sa) + sizeof(*sa->iso_bc)) {
|
|
|
|
err = -EINVAL;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sa->iso_bc->bc_num_bis > ISO_MAX_NUM_BIS) {
|
|
|
|
err = -EINVAL;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
iso_pi(sk)->bc_num_bis = sa->iso_bc->bc_num_bis;
|
|
|
|
|
|
|
|
for (int i = 0; i < iso_pi(sk)->bc_num_bis; i++)
|
|
|
|
if (sa->iso_bc->bc_bis[i] < 0x01 ||
|
|
|
|
sa->iso_bc->bc_bis[i] > 0x1f) {
|
|
|
|
err = -EINVAL;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(iso_pi(sk)->bc_bis, sa->iso_bc->bc_bis,
|
|
|
|
iso_pi(sk)->bc_num_bis);
|
|
|
|
|
|
|
|
done:
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2020-01-16 23:55:57 +00:00
|
|
|
static int iso_sock_bind(struct socket *sock, struct sockaddr *addr,
|
|
|
|
int addr_len)
|
|
|
|
{
|
|
|
|
struct sockaddr_iso *sa = (struct sockaddr_iso *)addr;
|
|
|
|
struct sock *sk = sock->sk;
|
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
BT_DBG("sk %p %pMR type %u", sk, &sa->iso_bdaddr, sa->iso_bdaddr_type);
|
|
|
|
|
|
|
|
if (!addr || addr_len < sizeof(struct sockaddr_iso) ||
|
|
|
|
addr->sa_family != AF_BLUETOOTH)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
lock_sock(sk);
|
|
|
|
|
2023-10-24 10:57:35 +00:00
|
|
|
/* Allow the user to bind a PA sync socket to a number
|
|
|
|
* of BISes to sync to.
|
|
|
|
*/
|
2024-04-02 11:39:31 +00:00
|
|
|
if ((sk->sk_state == BT_CONNECT2 ||
|
|
|
|
sk->sk_state == BT_CONNECTED) &&
|
2023-10-24 10:57:35 +00:00
|
|
|
test_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags)) {
|
|
|
|
err = iso_sock_bind_pa_sk(sk, sa, addr_len);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2020-01-16 23:55:57 +00:00
|
|
|
if (sk->sk_state != BT_OPEN) {
|
|
|
|
err = -EBADFD;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sk->sk_type != SOCK_SEQPACKET) {
|
|
|
|
err = -EINVAL;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if the address type is of LE type */
|
|
|
|
if (!bdaddr_type_is_le(sa->iso_bdaddr_type)) {
|
|
|
|
err = -EINVAL;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
bacpy(&iso_pi(sk)->src, &sa->iso_bdaddr);
|
|
|
|
iso_pi(sk)->src_type = sa->iso_bdaddr_type;
|
|
|
|
|
2022-03-09 21:14:41 +00:00
|
|
|
/* Check for Broadcast address */
|
|
|
|
if (addr_len > sizeof(*sa)) {
|
|
|
|
err = iso_sock_bind_bc(sock, addr, addr_len);
|
|
|
|
if (err)
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2020-01-16 23:55:57 +00:00
|
|
|
sk->sk_state = BT_BOUND;
|
|
|
|
|
|
|
|
done:
|
|
|
|
release_sock(sk);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int iso_sock_connect(struct socket *sock, struct sockaddr *addr,
|
|
|
|
int alen, int flags)
|
|
|
|
{
|
|
|
|
struct sockaddr_iso *sa = (struct sockaddr_iso *)addr;
|
|
|
|
struct sock *sk = sock->sk;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
BT_DBG("sk %p", sk);
|
|
|
|
|
|
|
|
if (alen < sizeof(struct sockaddr_iso) ||
|
|
|
|
addr->sa_family != AF_BLUETOOTH)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND)
|
|
|
|
return -EBADFD;
|
|
|
|
|
|
|
|
if (sk->sk_type != SOCK_SEQPACKET)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
/* Check if the address type is of LE type */
|
|
|
|
if (!bdaddr_type_is_le(sa->iso_bdaddr_type))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
lock_sock(sk);
|
|
|
|
|
|
|
|
bacpy(&iso_pi(sk)->dst, &sa->iso_bdaddr);
|
|
|
|
iso_pi(sk)->dst_type = sa->iso_bdaddr_type;
|
|
|
|
|
2022-12-07 00:34:42 +00:00
|
|
|
release_sock(sk);
|
|
|
|
|
2022-03-09 21:14:41 +00:00
|
|
|
if (bacmp(&iso_pi(sk)->dst, BDADDR_ANY))
|
|
|
|
err = iso_connect_cis(sk);
|
|
|
|
else
|
|
|
|
err = iso_connect_bis(sk);
|
|
|
|
|
2020-01-16 23:55:57 +00:00
|
|
|
if (err)
|
2022-12-07 00:34:42 +00:00
|
|
|
return err;
|
|
|
|
|
|
|
|
lock_sock(sk);
|
2020-01-16 23:55:57 +00:00
|
|
|
|
|
|
|
if (!test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
|
|
|
|
err = bt_sock_wait_state(sk, BT_CONNECTED,
|
|
|
|
sock_sndtimeo(sk, flags & O_NONBLOCK));
|
|
|
|
}
|
|
|
|
|
|
|
|
release_sock(sk);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2022-03-09 21:14:41 +00:00
|
|
|
static int iso_listen_bis(struct sock *sk)
|
|
|
|
{
|
|
|
|
struct hci_dev *hdev;
|
|
|
|
int err = 0;
|
2024-02-23 13:14:41 +00:00
|
|
|
struct iso_conn *conn;
|
|
|
|
struct hci_conn *hcon;
|
2022-03-09 21:14:41 +00:00
|
|
|
|
|
|
|
BT_DBG("%pMR -> %pMR (SID 0x%2.2x)", &iso_pi(sk)->src,
|
|
|
|
&iso_pi(sk)->dst, iso_pi(sk)->bc_sid);
|
|
|
|
|
|
|
|
write_lock(&iso_sk_list.lock);
|
|
|
|
|
|
|
|
if (__iso_get_sock_listen_by_sid(&iso_pi(sk)->src, &iso_pi(sk)->dst,
|
|
|
|
iso_pi(sk)->bc_sid))
|
|
|
|
err = -EADDRINUSE;
|
|
|
|
|
|
|
|
write_unlock(&iso_sk_list.lock);
|
|
|
|
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
hdev = hci_get_route(&iso_pi(sk)->dst, &iso_pi(sk)->src,
|
|
|
|
iso_pi(sk)->src_type);
|
|
|
|
if (!hdev)
|
|
|
|
return -EHOSTUNREACH;
|
|
|
|
|
2024-02-23 13:14:41 +00:00
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
2023-03-31 15:38:01 +00:00
|
|
|
/* Fail if user set invalid QoS */
|
|
|
|
if (iso_pi(sk)->qos_user_set && !check_bcast_qos(&iso_pi(sk)->qos)) {
|
|
|
|
iso_pi(sk)->qos = default_qos;
|
2024-02-23 13:14:41 +00:00
|
|
|
err = -EINVAL;
|
|
|
|
goto unlock;
|
2023-03-31 15:38:01 +00:00
|
|
|
}
|
|
|
|
|
2024-02-23 13:14:41 +00:00
|
|
|
hcon = hci_pa_create_sync(hdev, &iso_pi(sk)->dst,
|
|
|
|
le_addr_type(iso_pi(sk)->dst_type),
|
|
|
|
iso_pi(sk)->bc_sid, &iso_pi(sk)->qos);
|
|
|
|
if (IS_ERR(hcon)) {
|
|
|
|
err = PTR_ERR(hcon);
|
|
|
|
goto unlock;
|
|
|
|
}
|
|
|
|
|
|
|
|
conn = iso_conn_add(hcon);
|
|
|
|
if (!conn) {
|
|
|
|
hci_conn_drop(hcon);
|
|
|
|
err = -ENOMEM;
|
|
|
|
goto unlock;
|
|
|
|
}
|
|
|
|
|
|
|
|
err = iso_chan_add(conn, sk, NULL);
|
|
|
|
if (err) {
|
|
|
|
hci_conn_drop(hcon);
|
|
|
|
goto unlock;
|
|
|
|
}
|
2022-03-09 21:14:41 +00:00
|
|
|
|
2022-11-09 02:39:06 +00:00
|
|
|
hci_dev_put(hdev);
|
2022-03-09 21:14:41 +00:00
|
|
|
|
2024-02-23 13:14:41 +00:00
|
|
|
unlock:
|
|
|
|
hci_dev_unlock(hdev);
|
2022-03-09 21:14:41 +00:00
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int iso_listen_cis(struct sock *sk)
|
|
|
|
{
|
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
BT_DBG("%pMR", &iso_pi(sk)->src);
|
|
|
|
|
|
|
|
write_lock(&iso_sk_list.lock);
|
|
|
|
|
2023-08-28 20:05:45 +00:00
|
|
|
if (__iso_get_sock_listen_by_addr(&iso_pi(sk)->src, &iso_pi(sk)->dst))
|
2022-03-09 21:14:41 +00:00
|
|
|
err = -EADDRINUSE;
|
|
|
|
|
|
|
|
write_unlock(&iso_sk_list.lock);
|
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2020-01-16 23:55:57 +00:00
|
|
|
static int iso_sock_listen(struct socket *sock, int backlog)
|
|
|
|
{
|
|
|
|
struct sock *sk = sock->sk;
|
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
BT_DBG("sk %p backlog %d", sk, backlog);
|
|
|
|
|
|
|
|
lock_sock(sk);
|
|
|
|
|
|
|
|
if (sk->sk_state != BT_BOUND) {
|
|
|
|
err = -EBADFD;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sk->sk_type != SOCK_SEQPACKET) {
|
|
|
|
err = -EINVAL;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2022-03-09 21:14:41 +00:00
|
|
|
if (!bacmp(&iso_pi(sk)->dst, BDADDR_ANY))
|
|
|
|
err = iso_listen_cis(sk);
|
|
|
|
else
|
|
|
|
err = iso_listen_bis(sk);
|
2020-01-16 23:55:57 +00:00
|
|
|
|
2022-03-09 21:14:41 +00:00
|
|
|
if (err)
|
|
|
|
goto done;
|
2020-01-16 23:55:57 +00:00
|
|
|
|
|
|
|
sk->sk_max_ack_backlog = backlog;
|
|
|
|
sk->sk_ack_backlog = 0;
|
|
|
|
|
|
|
|
sk->sk_state = BT_LISTEN;
|
|
|
|
|
|
|
|
done:
|
|
|
|
release_sock(sk);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int iso_sock_accept(struct socket *sock, struct socket *newsock,
|
2024-05-09 15:20:08 +00:00
|
|
|
struct proto_accept_arg *arg)
|
2020-01-16 23:55:57 +00:00
|
|
|
{
|
|
|
|
DEFINE_WAIT_FUNC(wait, woken_wake_function);
|
|
|
|
struct sock *sk = sock->sk, *ch;
|
|
|
|
long timeo;
|
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
lock_sock(sk);
|
|
|
|
|
2024-05-09 15:20:08 +00:00
|
|
|
timeo = sock_rcvtimeo(sk, arg->flags & O_NONBLOCK);
|
2020-01-16 23:55:57 +00:00
|
|
|
|
|
|
|
BT_DBG("sk %p timeo %ld", sk, timeo);
|
|
|
|
|
|
|
|
/* Wait for an incoming connection. (wake-one). */
|
|
|
|
add_wait_queue_exclusive(sk_sleep(sk), &wait);
|
|
|
|
while (1) {
|
|
|
|
if (sk->sk_state != BT_LISTEN) {
|
|
|
|
err = -EBADFD;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
ch = bt_accept_dequeue(sk, newsock);
|
|
|
|
if (ch)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (!timeo) {
|
|
|
|
err = -EAGAIN;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (signal_pending(current)) {
|
|
|
|
err = sock_intr_errno(timeo);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
release_sock(sk);
|
|
|
|
|
|
|
|
timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, timeo);
|
|
|
|
lock_sock(sk);
|
|
|
|
}
|
|
|
|
remove_wait_queue(sk_sleep(sk), &wait);
|
|
|
|
|
|
|
|
if (err)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
newsock->state = SS_CONNECTED;
|
|
|
|
|
|
|
|
BT_DBG("new socket %p", ch);
|
|
|
|
|
|
|
|
done:
|
|
|
|
release_sock(sk);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int iso_sock_getname(struct socket *sock, struct sockaddr *addr,
|
|
|
|
int peer)
|
|
|
|
{
|
|
|
|
struct sockaddr_iso *sa = (struct sockaddr_iso *)addr;
|
|
|
|
struct sock *sk = sock->sk;
|
|
|
|
|
|
|
|
BT_DBG("sock %p, sk %p", sock, sk);
|
|
|
|
|
|
|
|
addr->sa_family = AF_BLUETOOTH;
|
|
|
|
|
|
|
|
if (peer) {
|
|
|
|
bacpy(&sa->iso_bdaddr, &iso_pi(sk)->dst);
|
|
|
|
sa->iso_bdaddr_type = iso_pi(sk)->dst_type;
|
|
|
|
} else {
|
|
|
|
bacpy(&sa->iso_bdaddr, &iso_pi(sk)->src);
|
|
|
|
sa->iso_bdaddr_type = iso_pi(sk)->src_type;
|
|
|
|
}
|
|
|
|
|
|
|
|
return sizeof(struct sockaddr_iso);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int iso_sock_sendmsg(struct socket *sock, struct msghdr *msg,
|
|
|
|
size_t len)
|
|
|
|
{
|
|
|
|
struct sock *sk = sock->sk;
|
|
|
|
struct sk_buff *skb, **frag;
|
Bluetooth: ISO: fix iso_conn related locking and validity issues
sk->sk_state indicates whether iso_pi(sk)->conn is valid. Operations
that check/update sk_state and access conn should hold lock_sock,
otherwise they can race.
The order of taking locks is hci_dev_lock > lock_sock > iso_conn_lock,
which is how it is in connect/disconnect_cfm -> iso_conn_del ->
iso_chan_del.
Fix locking in iso_connect_cis/bis and sendmsg/recvmsg to take lock_sock
around updating sk_state and conn.
iso_conn_del must not occur during iso_connect_cis/bis, as it frees the
iso_conn. Hold hdev->lock longer to prevent that.
This should not reintroduce the issue fixed in commit 241f51931c35
("Bluetooth: ISO: Avoid circular locking dependency"), since the we
acquire locks in order. We retain the fix in iso_sock_connect to release
lock_sock before iso_connect_* acquires hdev->lock.
Similarly for commit 6a5ad251b7cd ("Bluetooth: ISO: Fix possible
circular locking dependency"). We retain the fix in iso_conn_ready to
not acquire iso_conn_lock before lock_sock.
iso_conn_add shall return iso_conn with valid hcon. Make it so also when
reusing an old CIS connection waiting for disconnect timeout (see
__iso_sock_close where conn->hcon is set to NULL).
Trace with iso_conn_del after iso_chan_add in iso_connect_cis:
===============================================================
iso_sock_create:771: sock 00000000be9b69b7
iso_sock_init:693: sk 000000004dff667e
iso_sock_bind:827: sk 000000004dff667e 70:1a:b8:98:ff:a2 type 1
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_connect:875: sk 000000004dff667e
iso_connect_cis:353: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
hci_get_route:1199: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
hci_conn_add:1005: hci0 dst 28:3d:c2:4a:7e:da
iso_conn_add:140: hcon 000000007b65d182 conn 00000000daf8625e
__iso_chan_add:214: conn 00000000daf8625e
iso_connect_cfm:1700: hcon 000000007b65d182 bdaddr 28:3d:c2:4a:7e:da status 12
iso_conn_del:187: hcon 000000007b65d182 conn 00000000daf8625e, err 16
iso_sock_clear_timer:117: sock 000000004dff667e state 3
<Note: sk_state is BT_BOUND (3), so iso_connect_cis is still
running at this point>
iso_chan_del:153: sk 000000004dff667e, conn 00000000daf8625e, err 16
hci_conn_del:1151: hci0 hcon 000000007b65d182 handle 65535
hci_conn_unlink:1102: hci0: hcon 000000007b65d182
hci_chan_list_flush:2780: hcon 000000007b65d182
iso_sock_getsockopt:1376: sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getsockopt:1376: sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_shutdown:1434: sock 00000000be9b69b7, sk 000000004dff667e, how 1
__iso_sock_close:632: sk 000000004dff667e state 5 socket 00000000be9b69b7
<Note: sk_state is BT_CONNECT (5), even though iso_chan_del sets
BT_CLOSED (6). Only iso_connect_cis sets it to BT_CONNECT, so it
must be that iso_chan_del occurred between iso_chan_add and end of
iso_connect_cis.>
BUG: kernel NULL pointer dereference, address: 0000000000000000
PGD 8000000006467067 P4D 8000000006467067 PUD 3f5f067 PMD 0
Oops: 0000 [#1] PREEMPT SMP PTI
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:__iso_sock_close (net/bluetooth/iso.c:664) bluetooth
===============================================================
Trace with iso_conn_del before iso_chan_add in iso_connect_cis:
===============================================================
iso_connect_cis:356: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
...
iso_conn_add:140: hcon 0000000093bc551f conn 00000000768ae504
hci_dev_put:1487: hci0 orig refcnt 21
hci_event_packet:7607: hci0: event 0x0e
hci_cmd_complete_evt:4231: hci0: opcode 0x2062
hci_cc_le_set_cig_params:3846: hci0: status 0x07
hci_sent_cmd_data:3107: hci0 opcode 0x2062
iso_connect_cfm:1703: hcon 0000000093bc551f bdaddr 28:3d:c2:4a:7e:da status 7
iso_conn_del:187: hcon 0000000093bc551f conn 00000000768ae504, err 12
hci_conn_del:1151: hci0 hcon 0000000093bc551f handle 65535
hci_conn_unlink:1102: hci0: hcon 0000000093bc551f
hci_chan_list_flush:2780: hcon 0000000093bc551f
__iso_chan_add:214: conn 00000000768ae504
<Note: this conn was already freed in iso_conn_del above>
iso_sock_clear_timer:117: sock 0000000098323f95 state 3
general protection fault, probably for non-canonical address 0x30b29c630930aec8: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 1920 Comm: bluetoothd Tainted: G E 6.3.0-rc7+ #4
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:detach_if_pending+0x28/0xd0
Code: 90 90 0f 1f 44 00 00 48 8b 47 08 48 85 c0 0f 84 ad 00 00 00 55 89 d5 53 48 83 3f 00 48 89 fb 74 7d 66 90 48 8b 03 48 8b 53 08 <>
RSP: 0018:ffffb90841a67d08 EFLAGS: 00010007
RAX: 0000000000000000 RBX: ffff9141bd5061b8 RCX: 0000000000000000
RDX: 30b29c630930aec8 RSI: ffff9141fdd21e80 RDI: ffff9141bd5061b8
RBP: 0000000000000001 R08: 0000000000000000 R09: ffffb90841a67b88
R10: 0000000000000003 R11: ffffffff8613f558 R12: ffff9141fdd21e80
R13: 0000000000000000 R14: ffff9141b5976010 R15: ffff914185755338
FS: 00007f45768bd840(0000) GS:ffff9141fdd00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000619000424074 CR3: 0000000009f5e005 CR4: 0000000000170ee0
Call Trace:
<TASK>
timer_delete+0x48/0x80
try_to_grab_pending+0xdf/0x170
__cancel_work+0x37/0xb0
iso_connect_cis+0x141/0x400 [bluetooth]
===============================================================
Trace with NULL conn->hcon in state BT_CONNECT:
===============================================================
__iso_sock_close:619: sk 00000000f7c71fc5 state 1 socket 00000000d90c5fe5
...
__iso_sock_close:619: sk 00000000f7c71fc5 state 8 socket 00000000d90c5fe5
iso_chan_del:153: sk 00000000f7c71fc5, conn 0000000022c03a7e, err 104
...
iso_sock_connect:862: sk 00000000129b56c3
iso_connect_cis:348: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7d:2a
hci_get_route:1199: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7d:2a
hci_dev_hold:1495: hci0 orig refcnt 19
__iso_chan_add:214: conn 0000000022c03a7e
<Note: reusing old conn>
iso_sock_clear_timer:117: sock 00000000129b56c3 state 3
...
iso_sock_ready:1485: sk 00000000129b56c3
...
iso_sock_sendmsg:1077: sock 00000000e5013966, sk 00000000129b56c3
BUG: kernel NULL pointer dereference, address: 00000000000006a8
PGD 0 P4D 0
Oops: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 1403 Comm: wireplumber Tainted: G E 6.3.0-rc7+ #4
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:iso_sock_sendmsg+0x63/0x2a0 [bluetooth]
===============================================================
Fixes: 241f51931c35 ("Bluetooth: ISO: Avoid circular locking dependency")
Fixes: 6a5ad251b7cd ("Bluetooth: ISO: Fix possible circular locking dependency")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2023-06-18 22:04:33 +00:00
|
|
|
size_t mtu;
|
2020-01-16 23:55:57 +00:00
|
|
|
int err;
|
|
|
|
|
|
|
|
BT_DBG("sock %p, sk %p", sock, sk);
|
|
|
|
|
|
|
|
err = sock_error(sk);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
if (msg->msg_flags & MSG_OOB)
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
|
Bluetooth: ISO: fix iso_conn related locking and validity issues
sk->sk_state indicates whether iso_pi(sk)->conn is valid. Operations
that check/update sk_state and access conn should hold lock_sock,
otherwise they can race.
The order of taking locks is hci_dev_lock > lock_sock > iso_conn_lock,
which is how it is in connect/disconnect_cfm -> iso_conn_del ->
iso_chan_del.
Fix locking in iso_connect_cis/bis and sendmsg/recvmsg to take lock_sock
around updating sk_state and conn.
iso_conn_del must not occur during iso_connect_cis/bis, as it frees the
iso_conn. Hold hdev->lock longer to prevent that.
This should not reintroduce the issue fixed in commit 241f51931c35
("Bluetooth: ISO: Avoid circular locking dependency"), since the we
acquire locks in order. We retain the fix in iso_sock_connect to release
lock_sock before iso_connect_* acquires hdev->lock.
Similarly for commit 6a5ad251b7cd ("Bluetooth: ISO: Fix possible
circular locking dependency"). We retain the fix in iso_conn_ready to
not acquire iso_conn_lock before lock_sock.
iso_conn_add shall return iso_conn with valid hcon. Make it so also when
reusing an old CIS connection waiting for disconnect timeout (see
__iso_sock_close where conn->hcon is set to NULL).
Trace with iso_conn_del after iso_chan_add in iso_connect_cis:
===============================================================
iso_sock_create:771: sock 00000000be9b69b7
iso_sock_init:693: sk 000000004dff667e
iso_sock_bind:827: sk 000000004dff667e 70:1a:b8:98:ff:a2 type 1
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_connect:875: sk 000000004dff667e
iso_connect_cis:353: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
hci_get_route:1199: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
hci_conn_add:1005: hci0 dst 28:3d:c2:4a:7e:da
iso_conn_add:140: hcon 000000007b65d182 conn 00000000daf8625e
__iso_chan_add:214: conn 00000000daf8625e
iso_connect_cfm:1700: hcon 000000007b65d182 bdaddr 28:3d:c2:4a:7e:da status 12
iso_conn_del:187: hcon 000000007b65d182 conn 00000000daf8625e, err 16
iso_sock_clear_timer:117: sock 000000004dff667e state 3
<Note: sk_state is BT_BOUND (3), so iso_connect_cis is still
running at this point>
iso_chan_del:153: sk 000000004dff667e, conn 00000000daf8625e, err 16
hci_conn_del:1151: hci0 hcon 000000007b65d182 handle 65535
hci_conn_unlink:1102: hci0: hcon 000000007b65d182
hci_chan_list_flush:2780: hcon 000000007b65d182
iso_sock_getsockopt:1376: sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getsockopt:1376: sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_shutdown:1434: sock 00000000be9b69b7, sk 000000004dff667e, how 1
__iso_sock_close:632: sk 000000004dff667e state 5 socket 00000000be9b69b7
<Note: sk_state is BT_CONNECT (5), even though iso_chan_del sets
BT_CLOSED (6). Only iso_connect_cis sets it to BT_CONNECT, so it
must be that iso_chan_del occurred between iso_chan_add and end of
iso_connect_cis.>
BUG: kernel NULL pointer dereference, address: 0000000000000000
PGD 8000000006467067 P4D 8000000006467067 PUD 3f5f067 PMD 0
Oops: 0000 [#1] PREEMPT SMP PTI
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:__iso_sock_close (net/bluetooth/iso.c:664) bluetooth
===============================================================
Trace with iso_conn_del before iso_chan_add in iso_connect_cis:
===============================================================
iso_connect_cis:356: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
...
iso_conn_add:140: hcon 0000000093bc551f conn 00000000768ae504
hci_dev_put:1487: hci0 orig refcnt 21
hci_event_packet:7607: hci0: event 0x0e
hci_cmd_complete_evt:4231: hci0: opcode 0x2062
hci_cc_le_set_cig_params:3846: hci0: status 0x07
hci_sent_cmd_data:3107: hci0 opcode 0x2062
iso_connect_cfm:1703: hcon 0000000093bc551f bdaddr 28:3d:c2:4a:7e:da status 7
iso_conn_del:187: hcon 0000000093bc551f conn 00000000768ae504, err 12
hci_conn_del:1151: hci0 hcon 0000000093bc551f handle 65535
hci_conn_unlink:1102: hci0: hcon 0000000093bc551f
hci_chan_list_flush:2780: hcon 0000000093bc551f
__iso_chan_add:214: conn 00000000768ae504
<Note: this conn was already freed in iso_conn_del above>
iso_sock_clear_timer:117: sock 0000000098323f95 state 3
general protection fault, probably for non-canonical address 0x30b29c630930aec8: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 1920 Comm: bluetoothd Tainted: G E 6.3.0-rc7+ #4
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:detach_if_pending+0x28/0xd0
Code: 90 90 0f 1f 44 00 00 48 8b 47 08 48 85 c0 0f 84 ad 00 00 00 55 89 d5 53 48 83 3f 00 48 89 fb 74 7d 66 90 48 8b 03 48 8b 53 08 <>
RSP: 0018:ffffb90841a67d08 EFLAGS: 00010007
RAX: 0000000000000000 RBX: ffff9141bd5061b8 RCX: 0000000000000000
RDX: 30b29c630930aec8 RSI: ffff9141fdd21e80 RDI: ffff9141bd5061b8
RBP: 0000000000000001 R08: 0000000000000000 R09: ffffb90841a67b88
R10: 0000000000000003 R11: ffffffff8613f558 R12: ffff9141fdd21e80
R13: 0000000000000000 R14: ffff9141b5976010 R15: ffff914185755338
FS: 00007f45768bd840(0000) GS:ffff9141fdd00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000619000424074 CR3: 0000000009f5e005 CR4: 0000000000170ee0
Call Trace:
<TASK>
timer_delete+0x48/0x80
try_to_grab_pending+0xdf/0x170
__cancel_work+0x37/0xb0
iso_connect_cis+0x141/0x400 [bluetooth]
===============================================================
Trace with NULL conn->hcon in state BT_CONNECT:
===============================================================
__iso_sock_close:619: sk 00000000f7c71fc5 state 1 socket 00000000d90c5fe5
...
__iso_sock_close:619: sk 00000000f7c71fc5 state 8 socket 00000000d90c5fe5
iso_chan_del:153: sk 00000000f7c71fc5, conn 0000000022c03a7e, err 104
...
iso_sock_connect:862: sk 00000000129b56c3
iso_connect_cis:348: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7d:2a
hci_get_route:1199: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7d:2a
hci_dev_hold:1495: hci0 orig refcnt 19
__iso_chan_add:214: conn 0000000022c03a7e
<Note: reusing old conn>
iso_sock_clear_timer:117: sock 00000000129b56c3 state 3
...
iso_sock_ready:1485: sk 00000000129b56c3
...
iso_sock_sendmsg:1077: sock 00000000e5013966, sk 00000000129b56c3
BUG: kernel NULL pointer dereference, address: 00000000000006a8
PGD 0 P4D 0
Oops: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 1403 Comm: wireplumber Tainted: G E 6.3.0-rc7+ #4
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:iso_sock_sendmsg+0x63/0x2a0 [bluetooth]
===============================================================
Fixes: 241f51931c35 ("Bluetooth: ISO: Avoid circular locking dependency")
Fixes: 6a5ad251b7cd ("Bluetooth: ISO: Fix possible circular locking dependency")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2023-06-18 22:04:33 +00:00
|
|
|
lock_sock(sk);
|
|
|
|
|
|
|
|
if (sk->sk_state != BT_CONNECTED) {
|
|
|
|
release_sock(sk);
|
2020-01-16 23:55:57 +00:00
|
|
|
return -ENOTCONN;
|
Bluetooth: ISO: fix iso_conn related locking and validity issues
sk->sk_state indicates whether iso_pi(sk)->conn is valid. Operations
that check/update sk_state and access conn should hold lock_sock,
otherwise they can race.
The order of taking locks is hci_dev_lock > lock_sock > iso_conn_lock,
which is how it is in connect/disconnect_cfm -> iso_conn_del ->
iso_chan_del.
Fix locking in iso_connect_cis/bis and sendmsg/recvmsg to take lock_sock
around updating sk_state and conn.
iso_conn_del must not occur during iso_connect_cis/bis, as it frees the
iso_conn. Hold hdev->lock longer to prevent that.
This should not reintroduce the issue fixed in commit 241f51931c35
("Bluetooth: ISO: Avoid circular locking dependency"), since the we
acquire locks in order. We retain the fix in iso_sock_connect to release
lock_sock before iso_connect_* acquires hdev->lock.
Similarly for commit 6a5ad251b7cd ("Bluetooth: ISO: Fix possible
circular locking dependency"). We retain the fix in iso_conn_ready to
not acquire iso_conn_lock before lock_sock.
iso_conn_add shall return iso_conn with valid hcon. Make it so also when
reusing an old CIS connection waiting for disconnect timeout (see
__iso_sock_close where conn->hcon is set to NULL).
Trace with iso_conn_del after iso_chan_add in iso_connect_cis:
===============================================================
iso_sock_create:771: sock 00000000be9b69b7
iso_sock_init:693: sk 000000004dff667e
iso_sock_bind:827: sk 000000004dff667e 70:1a:b8:98:ff:a2 type 1
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_connect:875: sk 000000004dff667e
iso_connect_cis:353: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
hci_get_route:1199: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
hci_conn_add:1005: hci0 dst 28:3d:c2:4a:7e:da
iso_conn_add:140: hcon 000000007b65d182 conn 00000000daf8625e
__iso_chan_add:214: conn 00000000daf8625e
iso_connect_cfm:1700: hcon 000000007b65d182 bdaddr 28:3d:c2:4a:7e:da status 12
iso_conn_del:187: hcon 000000007b65d182 conn 00000000daf8625e, err 16
iso_sock_clear_timer:117: sock 000000004dff667e state 3
<Note: sk_state is BT_BOUND (3), so iso_connect_cis is still
running at this point>
iso_chan_del:153: sk 000000004dff667e, conn 00000000daf8625e, err 16
hci_conn_del:1151: hci0 hcon 000000007b65d182 handle 65535
hci_conn_unlink:1102: hci0: hcon 000000007b65d182
hci_chan_list_flush:2780: hcon 000000007b65d182
iso_sock_getsockopt:1376: sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getsockopt:1376: sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_shutdown:1434: sock 00000000be9b69b7, sk 000000004dff667e, how 1
__iso_sock_close:632: sk 000000004dff667e state 5 socket 00000000be9b69b7
<Note: sk_state is BT_CONNECT (5), even though iso_chan_del sets
BT_CLOSED (6). Only iso_connect_cis sets it to BT_CONNECT, so it
must be that iso_chan_del occurred between iso_chan_add and end of
iso_connect_cis.>
BUG: kernel NULL pointer dereference, address: 0000000000000000
PGD 8000000006467067 P4D 8000000006467067 PUD 3f5f067 PMD 0
Oops: 0000 [#1] PREEMPT SMP PTI
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:__iso_sock_close (net/bluetooth/iso.c:664) bluetooth
===============================================================
Trace with iso_conn_del before iso_chan_add in iso_connect_cis:
===============================================================
iso_connect_cis:356: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
...
iso_conn_add:140: hcon 0000000093bc551f conn 00000000768ae504
hci_dev_put:1487: hci0 orig refcnt 21
hci_event_packet:7607: hci0: event 0x0e
hci_cmd_complete_evt:4231: hci0: opcode 0x2062
hci_cc_le_set_cig_params:3846: hci0: status 0x07
hci_sent_cmd_data:3107: hci0 opcode 0x2062
iso_connect_cfm:1703: hcon 0000000093bc551f bdaddr 28:3d:c2:4a:7e:da status 7
iso_conn_del:187: hcon 0000000093bc551f conn 00000000768ae504, err 12
hci_conn_del:1151: hci0 hcon 0000000093bc551f handle 65535
hci_conn_unlink:1102: hci0: hcon 0000000093bc551f
hci_chan_list_flush:2780: hcon 0000000093bc551f
__iso_chan_add:214: conn 00000000768ae504
<Note: this conn was already freed in iso_conn_del above>
iso_sock_clear_timer:117: sock 0000000098323f95 state 3
general protection fault, probably for non-canonical address 0x30b29c630930aec8: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 1920 Comm: bluetoothd Tainted: G E 6.3.0-rc7+ #4
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:detach_if_pending+0x28/0xd0
Code: 90 90 0f 1f 44 00 00 48 8b 47 08 48 85 c0 0f 84 ad 00 00 00 55 89 d5 53 48 83 3f 00 48 89 fb 74 7d 66 90 48 8b 03 48 8b 53 08 <>
RSP: 0018:ffffb90841a67d08 EFLAGS: 00010007
RAX: 0000000000000000 RBX: ffff9141bd5061b8 RCX: 0000000000000000
RDX: 30b29c630930aec8 RSI: ffff9141fdd21e80 RDI: ffff9141bd5061b8
RBP: 0000000000000001 R08: 0000000000000000 R09: ffffb90841a67b88
R10: 0000000000000003 R11: ffffffff8613f558 R12: ffff9141fdd21e80
R13: 0000000000000000 R14: ffff9141b5976010 R15: ffff914185755338
FS: 00007f45768bd840(0000) GS:ffff9141fdd00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000619000424074 CR3: 0000000009f5e005 CR4: 0000000000170ee0
Call Trace:
<TASK>
timer_delete+0x48/0x80
try_to_grab_pending+0xdf/0x170
__cancel_work+0x37/0xb0
iso_connect_cis+0x141/0x400 [bluetooth]
===============================================================
Trace with NULL conn->hcon in state BT_CONNECT:
===============================================================
__iso_sock_close:619: sk 00000000f7c71fc5 state 1 socket 00000000d90c5fe5
...
__iso_sock_close:619: sk 00000000f7c71fc5 state 8 socket 00000000d90c5fe5
iso_chan_del:153: sk 00000000f7c71fc5, conn 0000000022c03a7e, err 104
...
iso_sock_connect:862: sk 00000000129b56c3
iso_connect_cis:348: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7d:2a
hci_get_route:1199: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7d:2a
hci_dev_hold:1495: hci0 orig refcnt 19
__iso_chan_add:214: conn 0000000022c03a7e
<Note: reusing old conn>
iso_sock_clear_timer:117: sock 00000000129b56c3 state 3
...
iso_sock_ready:1485: sk 00000000129b56c3
...
iso_sock_sendmsg:1077: sock 00000000e5013966, sk 00000000129b56c3
BUG: kernel NULL pointer dereference, address: 00000000000006a8
PGD 0 P4D 0
Oops: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 1403 Comm: wireplumber Tainted: G E 6.3.0-rc7+ #4
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:iso_sock_sendmsg+0x63/0x2a0 [bluetooth]
===============================================================
Fixes: 241f51931c35 ("Bluetooth: ISO: Avoid circular locking dependency")
Fixes: 6a5ad251b7cd ("Bluetooth: ISO: Fix possible circular locking dependency")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2023-06-18 22:04:33 +00:00
|
|
|
}
|
|
|
|
|
2024-05-04 19:23:29 +00:00
|
|
|
mtu = iso_pi(sk)->conn->hcon->mtu;
|
Bluetooth: ISO: fix iso_conn related locking and validity issues
sk->sk_state indicates whether iso_pi(sk)->conn is valid. Operations
that check/update sk_state and access conn should hold lock_sock,
otherwise they can race.
The order of taking locks is hci_dev_lock > lock_sock > iso_conn_lock,
which is how it is in connect/disconnect_cfm -> iso_conn_del ->
iso_chan_del.
Fix locking in iso_connect_cis/bis and sendmsg/recvmsg to take lock_sock
around updating sk_state and conn.
iso_conn_del must not occur during iso_connect_cis/bis, as it frees the
iso_conn. Hold hdev->lock longer to prevent that.
This should not reintroduce the issue fixed in commit 241f51931c35
("Bluetooth: ISO: Avoid circular locking dependency"), since the we
acquire locks in order. We retain the fix in iso_sock_connect to release
lock_sock before iso_connect_* acquires hdev->lock.
Similarly for commit 6a5ad251b7cd ("Bluetooth: ISO: Fix possible
circular locking dependency"). We retain the fix in iso_conn_ready to
not acquire iso_conn_lock before lock_sock.
iso_conn_add shall return iso_conn with valid hcon. Make it so also when
reusing an old CIS connection waiting for disconnect timeout (see
__iso_sock_close where conn->hcon is set to NULL).
Trace with iso_conn_del after iso_chan_add in iso_connect_cis:
===============================================================
iso_sock_create:771: sock 00000000be9b69b7
iso_sock_init:693: sk 000000004dff667e
iso_sock_bind:827: sk 000000004dff667e 70:1a:b8:98:ff:a2 type 1
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_connect:875: sk 000000004dff667e
iso_connect_cis:353: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
hci_get_route:1199: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
hci_conn_add:1005: hci0 dst 28:3d:c2:4a:7e:da
iso_conn_add:140: hcon 000000007b65d182 conn 00000000daf8625e
__iso_chan_add:214: conn 00000000daf8625e
iso_connect_cfm:1700: hcon 000000007b65d182 bdaddr 28:3d:c2:4a:7e:da status 12
iso_conn_del:187: hcon 000000007b65d182 conn 00000000daf8625e, err 16
iso_sock_clear_timer:117: sock 000000004dff667e state 3
<Note: sk_state is BT_BOUND (3), so iso_connect_cis is still
running at this point>
iso_chan_del:153: sk 000000004dff667e, conn 00000000daf8625e, err 16
hci_conn_del:1151: hci0 hcon 000000007b65d182 handle 65535
hci_conn_unlink:1102: hci0: hcon 000000007b65d182
hci_chan_list_flush:2780: hcon 000000007b65d182
iso_sock_getsockopt:1376: sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getsockopt:1376: sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_shutdown:1434: sock 00000000be9b69b7, sk 000000004dff667e, how 1
__iso_sock_close:632: sk 000000004dff667e state 5 socket 00000000be9b69b7
<Note: sk_state is BT_CONNECT (5), even though iso_chan_del sets
BT_CLOSED (6). Only iso_connect_cis sets it to BT_CONNECT, so it
must be that iso_chan_del occurred between iso_chan_add and end of
iso_connect_cis.>
BUG: kernel NULL pointer dereference, address: 0000000000000000
PGD 8000000006467067 P4D 8000000006467067 PUD 3f5f067 PMD 0
Oops: 0000 [#1] PREEMPT SMP PTI
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:__iso_sock_close (net/bluetooth/iso.c:664) bluetooth
===============================================================
Trace with iso_conn_del before iso_chan_add in iso_connect_cis:
===============================================================
iso_connect_cis:356: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
...
iso_conn_add:140: hcon 0000000093bc551f conn 00000000768ae504
hci_dev_put:1487: hci0 orig refcnt 21
hci_event_packet:7607: hci0: event 0x0e
hci_cmd_complete_evt:4231: hci0: opcode 0x2062
hci_cc_le_set_cig_params:3846: hci0: status 0x07
hci_sent_cmd_data:3107: hci0 opcode 0x2062
iso_connect_cfm:1703: hcon 0000000093bc551f bdaddr 28:3d:c2:4a:7e:da status 7
iso_conn_del:187: hcon 0000000093bc551f conn 00000000768ae504, err 12
hci_conn_del:1151: hci0 hcon 0000000093bc551f handle 65535
hci_conn_unlink:1102: hci0: hcon 0000000093bc551f
hci_chan_list_flush:2780: hcon 0000000093bc551f
__iso_chan_add:214: conn 00000000768ae504
<Note: this conn was already freed in iso_conn_del above>
iso_sock_clear_timer:117: sock 0000000098323f95 state 3
general protection fault, probably for non-canonical address 0x30b29c630930aec8: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 1920 Comm: bluetoothd Tainted: G E 6.3.0-rc7+ #4
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:detach_if_pending+0x28/0xd0
Code: 90 90 0f 1f 44 00 00 48 8b 47 08 48 85 c0 0f 84 ad 00 00 00 55 89 d5 53 48 83 3f 00 48 89 fb 74 7d 66 90 48 8b 03 48 8b 53 08 <>
RSP: 0018:ffffb90841a67d08 EFLAGS: 00010007
RAX: 0000000000000000 RBX: ffff9141bd5061b8 RCX: 0000000000000000
RDX: 30b29c630930aec8 RSI: ffff9141fdd21e80 RDI: ffff9141bd5061b8
RBP: 0000000000000001 R08: 0000000000000000 R09: ffffb90841a67b88
R10: 0000000000000003 R11: ffffffff8613f558 R12: ffff9141fdd21e80
R13: 0000000000000000 R14: ffff9141b5976010 R15: ffff914185755338
FS: 00007f45768bd840(0000) GS:ffff9141fdd00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000619000424074 CR3: 0000000009f5e005 CR4: 0000000000170ee0
Call Trace:
<TASK>
timer_delete+0x48/0x80
try_to_grab_pending+0xdf/0x170
__cancel_work+0x37/0xb0
iso_connect_cis+0x141/0x400 [bluetooth]
===============================================================
Trace with NULL conn->hcon in state BT_CONNECT:
===============================================================
__iso_sock_close:619: sk 00000000f7c71fc5 state 1 socket 00000000d90c5fe5
...
__iso_sock_close:619: sk 00000000f7c71fc5 state 8 socket 00000000d90c5fe5
iso_chan_del:153: sk 00000000f7c71fc5, conn 0000000022c03a7e, err 104
...
iso_sock_connect:862: sk 00000000129b56c3
iso_connect_cis:348: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7d:2a
hci_get_route:1199: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7d:2a
hci_dev_hold:1495: hci0 orig refcnt 19
__iso_chan_add:214: conn 0000000022c03a7e
<Note: reusing old conn>
iso_sock_clear_timer:117: sock 00000000129b56c3 state 3
...
iso_sock_ready:1485: sk 00000000129b56c3
...
iso_sock_sendmsg:1077: sock 00000000e5013966, sk 00000000129b56c3
BUG: kernel NULL pointer dereference, address: 00000000000006a8
PGD 0 P4D 0
Oops: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 1403 Comm: wireplumber Tainted: G E 6.3.0-rc7+ #4
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:iso_sock_sendmsg+0x63/0x2a0 [bluetooth]
===============================================================
Fixes: 241f51931c35 ("Bluetooth: ISO: Avoid circular locking dependency")
Fixes: 6a5ad251b7cd ("Bluetooth: ISO: Fix possible circular locking dependency")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2023-06-18 22:04:33 +00:00
|
|
|
|
|
|
|
release_sock(sk);
|
2020-01-16 23:55:57 +00:00
|
|
|
|
Bluetooth: ISO: fix iso_conn related locking and validity issues
sk->sk_state indicates whether iso_pi(sk)->conn is valid. Operations
that check/update sk_state and access conn should hold lock_sock,
otherwise they can race.
The order of taking locks is hci_dev_lock > lock_sock > iso_conn_lock,
which is how it is in connect/disconnect_cfm -> iso_conn_del ->
iso_chan_del.
Fix locking in iso_connect_cis/bis and sendmsg/recvmsg to take lock_sock
around updating sk_state and conn.
iso_conn_del must not occur during iso_connect_cis/bis, as it frees the
iso_conn. Hold hdev->lock longer to prevent that.
This should not reintroduce the issue fixed in commit 241f51931c35
("Bluetooth: ISO: Avoid circular locking dependency"), since the we
acquire locks in order. We retain the fix in iso_sock_connect to release
lock_sock before iso_connect_* acquires hdev->lock.
Similarly for commit 6a5ad251b7cd ("Bluetooth: ISO: Fix possible
circular locking dependency"). We retain the fix in iso_conn_ready to
not acquire iso_conn_lock before lock_sock.
iso_conn_add shall return iso_conn with valid hcon. Make it so also when
reusing an old CIS connection waiting for disconnect timeout (see
__iso_sock_close where conn->hcon is set to NULL).
Trace with iso_conn_del after iso_chan_add in iso_connect_cis:
===============================================================
iso_sock_create:771: sock 00000000be9b69b7
iso_sock_init:693: sk 000000004dff667e
iso_sock_bind:827: sk 000000004dff667e 70:1a:b8:98:ff:a2 type 1
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_connect:875: sk 000000004dff667e
iso_connect_cis:353: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
hci_get_route:1199: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
hci_conn_add:1005: hci0 dst 28:3d:c2:4a:7e:da
iso_conn_add:140: hcon 000000007b65d182 conn 00000000daf8625e
__iso_chan_add:214: conn 00000000daf8625e
iso_connect_cfm:1700: hcon 000000007b65d182 bdaddr 28:3d:c2:4a:7e:da status 12
iso_conn_del:187: hcon 000000007b65d182 conn 00000000daf8625e, err 16
iso_sock_clear_timer:117: sock 000000004dff667e state 3
<Note: sk_state is BT_BOUND (3), so iso_connect_cis is still
running at this point>
iso_chan_del:153: sk 000000004dff667e, conn 00000000daf8625e, err 16
hci_conn_del:1151: hci0 hcon 000000007b65d182 handle 65535
hci_conn_unlink:1102: hci0: hcon 000000007b65d182
hci_chan_list_flush:2780: hcon 000000007b65d182
iso_sock_getsockopt:1376: sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getsockopt:1376: sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_shutdown:1434: sock 00000000be9b69b7, sk 000000004dff667e, how 1
__iso_sock_close:632: sk 000000004dff667e state 5 socket 00000000be9b69b7
<Note: sk_state is BT_CONNECT (5), even though iso_chan_del sets
BT_CLOSED (6). Only iso_connect_cis sets it to BT_CONNECT, so it
must be that iso_chan_del occurred between iso_chan_add and end of
iso_connect_cis.>
BUG: kernel NULL pointer dereference, address: 0000000000000000
PGD 8000000006467067 P4D 8000000006467067 PUD 3f5f067 PMD 0
Oops: 0000 [#1] PREEMPT SMP PTI
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:__iso_sock_close (net/bluetooth/iso.c:664) bluetooth
===============================================================
Trace with iso_conn_del before iso_chan_add in iso_connect_cis:
===============================================================
iso_connect_cis:356: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
...
iso_conn_add:140: hcon 0000000093bc551f conn 00000000768ae504
hci_dev_put:1487: hci0 orig refcnt 21
hci_event_packet:7607: hci0: event 0x0e
hci_cmd_complete_evt:4231: hci0: opcode 0x2062
hci_cc_le_set_cig_params:3846: hci0: status 0x07
hci_sent_cmd_data:3107: hci0 opcode 0x2062
iso_connect_cfm:1703: hcon 0000000093bc551f bdaddr 28:3d:c2:4a:7e:da status 7
iso_conn_del:187: hcon 0000000093bc551f conn 00000000768ae504, err 12
hci_conn_del:1151: hci0 hcon 0000000093bc551f handle 65535
hci_conn_unlink:1102: hci0: hcon 0000000093bc551f
hci_chan_list_flush:2780: hcon 0000000093bc551f
__iso_chan_add:214: conn 00000000768ae504
<Note: this conn was already freed in iso_conn_del above>
iso_sock_clear_timer:117: sock 0000000098323f95 state 3
general protection fault, probably for non-canonical address 0x30b29c630930aec8: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 1920 Comm: bluetoothd Tainted: G E 6.3.0-rc7+ #4
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:detach_if_pending+0x28/0xd0
Code: 90 90 0f 1f 44 00 00 48 8b 47 08 48 85 c0 0f 84 ad 00 00 00 55 89 d5 53 48 83 3f 00 48 89 fb 74 7d 66 90 48 8b 03 48 8b 53 08 <>
RSP: 0018:ffffb90841a67d08 EFLAGS: 00010007
RAX: 0000000000000000 RBX: ffff9141bd5061b8 RCX: 0000000000000000
RDX: 30b29c630930aec8 RSI: ffff9141fdd21e80 RDI: ffff9141bd5061b8
RBP: 0000000000000001 R08: 0000000000000000 R09: ffffb90841a67b88
R10: 0000000000000003 R11: ffffffff8613f558 R12: ffff9141fdd21e80
R13: 0000000000000000 R14: ffff9141b5976010 R15: ffff914185755338
FS: 00007f45768bd840(0000) GS:ffff9141fdd00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000619000424074 CR3: 0000000009f5e005 CR4: 0000000000170ee0
Call Trace:
<TASK>
timer_delete+0x48/0x80
try_to_grab_pending+0xdf/0x170
__cancel_work+0x37/0xb0
iso_connect_cis+0x141/0x400 [bluetooth]
===============================================================
Trace with NULL conn->hcon in state BT_CONNECT:
===============================================================
__iso_sock_close:619: sk 00000000f7c71fc5 state 1 socket 00000000d90c5fe5
...
__iso_sock_close:619: sk 00000000f7c71fc5 state 8 socket 00000000d90c5fe5
iso_chan_del:153: sk 00000000f7c71fc5, conn 0000000022c03a7e, err 104
...
iso_sock_connect:862: sk 00000000129b56c3
iso_connect_cis:348: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7d:2a
hci_get_route:1199: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7d:2a
hci_dev_hold:1495: hci0 orig refcnt 19
__iso_chan_add:214: conn 0000000022c03a7e
<Note: reusing old conn>
iso_sock_clear_timer:117: sock 00000000129b56c3 state 3
...
iso_sock_ready:1485: sk 00000000129b56c3
...
iso_sock_sendmsg:1077: sock 00000000e5013966, sk 00000000129b56c3
BUG: kernel NULL pointer dereference, address: 00000000000006a8
PGD 0 P4D 0
Oops: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 1403 Comm: wireplumber Tainted: G E 6.3.0-rc7+ #4
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:iso_sock_sendmsg+0x63/0x2a0 [bluetooth]
===============================================================
Fixes: 241f51931c35 ("Bluetooth: ISO: Avoid circular locking dependency")
Fixes: 6a5ad251b7cd ("Bluetooth: ISO: Fix possible circular locking dependency")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2023-06-18 22:04:33 +00:00
|
|
|
skb = bt_skb_sendmsg(sk, msg, len, mtu, HCI_ISO_DATA_HDR_SIZE, 0);
|
2020-01-16 23:55:57 +00:00
|
|
|
if (IS_ERR(skb))
|
|
|
|
return PTR_ERR(skb);
|
|
|
|
|
|
|
|
len -= skb->len;
|
|
|
|
|
|
|
|
BT_DBG("skb %p len %d", sk, skb->len);
|
|
|
|
|
|
|
|
/* Continuation fragments */
|
|
|
|
frag = &skb_shinfo(skb)->frag_list;
|
|
|
|
while (len) {
|
|
|
|
struct sk_buff *tmp;
|
|
|
|
|
Bluetooth: ISO: fix iso_conn related locking and validity issues
sk->sk_state indicates whether iso_pi(sk)->conn is valid. Operations
that check/update sk_state and access conn should hold lock_sock,
otherwise they can race.
The order of taking locks is hci_dev_lock > lock_sock > iso_conn_lock,
which is how it is in connect/disconnect_cfm -> iso_conn_del ->
iso_chan_del.
Fix locking in iso_connect_cis/bis and sendmsg/recvmsg to take lock_sock
around updating sk_state and conn.
iso_conn_del must not occur during iso_connect_cis/bis, as it frees the
iso_conn. Hold hdev->lock longer to prevent that.
This should not reintroduce the issue fixed in commit 241f51931c35
("Bluetooth: ISO: Avoid circular locking dependency"), since the we
acquire locks in order. We retain the fix in iso_sock_connect to release
lock_sock before iso_connect_* acquires hdev->lock.
Similarly for commit 6a5ad251b7cd ("Bluetooth: ISO: Fix possible
circular locking dependency"). We retain the fix in iso_conn_ready to
not acquire iso_conn_lock before lock_sock.
iso_conn_add shall return iso_conn with valid hcon. Make it so also when
reusing an old CIS connection waiting for disconnect timeout (see
__iso_sock_close where conn->hcon is set to NULL).
Trace with iso_conn_del after iso_chan_add in iso_connect_cis:
===============================================================
iso_sock_create:771: sock 00000000be9b69b7
iso_sock_init:693: sk 000000004dff667e
iso_sock_bind:827: sk 000000004dff667e 70:1a:b8:98:ff:a2 type 1
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_connect:875: sk 000000004dff667e
iso_connect_cis:353: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
hci_get_route:1199: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
hci_conn_add:1005: hci0 dst 28:3d:c2:4a:7e:da
iso_conn_add:140: hcon 000000007b65d182 conn 00000000daf8625e
__iso_chan_add:214: conn 00000000daf8625e
iso_connect_cfm:1700: hcon 000000007b65d182 bdaddr 28:3d:c2:4a:7e:da status 12
iso_conn_del:187: hcon 000000007b65d182 conn 00000000daf8625e, err 16
iso_sock_clear_timer:117: sock 000000004dff667e state 3
<Note: sk_state is BT_BOUND (3), so iso_connect_cis is still
running at this point>
iso_chan_del:153: sk 000000004dff667e, conn 00000000daf8625e, err 16
hci_conn_del:1151: hci0 hcon 000000007b65d182 handle 65535
hci_conn_unlink:1102: hci0: hcon 000000007b65d182
hci_chan_list_flush:2780: hcon 000000007b65d182
iso_sock_getsockopt:1376: sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getsockopt:1376: sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_shutdown:1434: sock 00000000be9b69b7, sk 000000004dff667e, how 1
__iso_sock_close:632: sk 000000004dff667e state 5 socket 00000000be9b69b7
<Note: sk_state is BT_CONNECT (5), even though iso_chan_del sets
BT_CLOSED (6). Only iso_connect_cis sets it to BT_CONNECT, so it
must be that iso_chan_del occurred between iso_chan_add and end of
iso_connect_cis.>
BUG: kernel NULL pointer dereference, address: 0000000000000000
PGD 8000000006467067 P4D 8000000006467067 PUD 3f5f067 PMD 0
Oops: 0000 [#1] PREEMPT SMP PTI
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:__iso_sock_close (net/bluetooth/iso.c:664) bluetooth
===============================================================
Trace with iso_conn_del before iso_chan_add in iso_connect_cis:
===============================================================
iso_connect_cis:356: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
...
iso_conn_add:140: hcon 0000000093bc551f conn 00000000768ae504
hci_dev_put:1487: hci0 orig refcnt 21
hci_event_packet:7607: hci0: event 0x0e
hci_cmd_complete_evt:4231: hci0: opcode 0x2062
hci_cc_le_set_cig_params:3846: hci0: status 0x07
hci_sent_cmd_data:3107: hci0 opcode 0x2062
iso_connect_cfm:1703: hcon 0000000093bc551f bdaddr 28:3d:c2:4a:7e:da status 7
iso_conn_del:187: hcon 0000000093bc551f conn 00000000768ae504, err 12
hci_conn_del:1151: hci0 hcon 0000000093bc551f handle 65535
hci_conn_unlink:1102: hci0: hcon 0000000093bc551f
hci_chan_list_flush:2780: hcon 0000000093bc551f
__iso_chan_add:214: conn 00000000768ae504
<Note: this conn was already freed in iso_conn_del above>
iso_sock_clear_timer:117: sock 0000000098323f95 state 3
general protection fault, probably for non-canonical address 0x30b29c630930aec8: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 1920 Comm: bluetoothd Tainted: G E 6.3.0-rc7+ #4
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:detach_if_pending+0x28/0xd0
Code: 90 90 0f 1f 44 00 00 48 8b 47 08 48 85 c0 0f 84 ad 00 00 00 55 89 d5 53 48 83 3f 00 48 89 fb 74 7d 66 90 48 8b 03 48 8b 53 08 <>
RSP: 0018:ffffb90841a67d08 EFLAGS: 00010007
RAX: 0000000000000000 RBX: ffff9141bd5061b8 RCX: 0000000000000000
RDX: 30b29c630930aec8 RSI: ffff9141fdd21e80 RDI: ffff9141bd5061b8
RBP: 0000000000000001 R08: 0000000000000000 R09: ffffb90841a67b88
R10: 0000000000000003 R11: ffffffff8613f558 R12: ffff9141fdd21e80
R13: 0000000000000000 R14: ffff9141b5976010 R15: ffff914185755338
FS: 00007f45768bd840(0000) GS:ffff9141fdd00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000619000424074 CR3: 0000000009f5e005 CR4: 0000000000170ee0
Call Trace:
<TASK>
timer_delete+0x48/0x80
try_to_grab_pending+0xdf/0x170
__cancel_work+0x37/0xb0
iso_connect_cis+0x141/0x400 [bluetooth]
===============================================================
Trace with NULL conn->hcon in state BT_CONNECT:
===============================================================
__iso_sock_close:619: sk 00000000f7c71fc5 state 1 socket 00000000d90c5fe5
...
__iso_sock_close:619: sk 00000000f7c71fc5 state 8 socket 00000000d90c5fe5
iso_chan_del:153: sk 00000000f7c71fc5, conn 0000000022c03a7e, err 104
...
iso_sock_connect:862: sk 00000000129b56c3
iso_connect_cis:348: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7d:2a
hci_get_route:1199: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7d:2a
hci_dev_hold:1495: hci0 orig refcnt 19
__iso_chan_add:214: conn 0000000022c03a7e
<Note: reusing old conn>
iso_sock_clear_timer:117: sock 00000000129b56c3 state 3
...
iso_sock_ready:1485: sk 00000000129b56c3
...
iso_sock_sendmsg:1077: sock 00000000e5013966, sk 00000000129b56c3
BUG: kernel NULL pointer dereference, address: 00000000000006a8
PGD 0 P4D 0
Oops: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 1403 Comm: wireplumber Tainted: G E 6.3.0-rc7+ #4
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:iso_sock_sendmsg+0x63/0x2a0 [bluetooth]
===============================================================
Fixes: 241f51931c35 ("Bluetooth: ISO: Avoid circular locking dependency")
Fixes: 6a5ad251b7cd ("Bluetooth: ISO: Fix possible circular locking dependency")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2023-06-18 22:04:33 +00:00
|
|
|
tmp = bt_skb_sendmsg(sk, msg, len, mtu, 0, 0);
|
2020-01-16 23:55:57 +00:00
|
|
|
if (IS_ERR(tmp)) {
|
|
|
|
kfree_skb(skb);
|
|
|
|
return PTR_ERR(tmp);
|
|
|
|
}
|
|
|
|
|
|
|
|
*frag = tmp;
|
|
|
|
|
|
|
|
len -= tmp->len;
|
|
|
|
|
|
|
|
skb->len += tmp->len;
|
|
|
|
skb->data_len += tmp->len;
|
|
|
|
|
|
|
|
BT_DBG("frag %p len %d", *frag, tmp->len);
|
|
|
|
|
|
|
|
frag = &(*frag)->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
lock_sock(sk);
|
|
|
|
|
|
|
|
if (sk->sk_state == BT_CONNECTED)
|
|
|
|
err = iso_send_frame(sk, skb);
|
|
|
|
else
|
|
|
|
err = -ENOTCONN;
|
|
|
|
|
|
|
|
release_sock(sk);
|
|
|
|
|
|
|
|
if (err < 0)
|
|
|
|
kfree_skb(skb);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void iso_conn_defer_accept(struct hci_conn *conn)
|
|
|
|
{
|
|
|
|
struct hci_cp_le_accept_cis cp;
|
|
|
|
struct hci_dev *hdev = conn->hdev;
|
|
|
|
|
|
|
|
BT_DBG("conn %p", conn);
|
|
|
|
|
|
|
|
conn->state = BT_CONFIG;
|
|
|
|
|
|
|
|
cp.handle = cpu_to_le16(conn->handle);
|
|
|
|
|
|
|
|
hci_send_cmd(hdev, HCI_OP_LE_ACCEPT_CIS, sizeof(cp), &cp);
|
|
|
|
}
|
|
|
|
|
2023-08-17 06:44:27 +00:00
|
|
|
static void iso_conn_big_sync(struct sock *sk)
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
struct hci_dev *hdev;
|
|
|
|
|
|
|
|
hdev = hci_get_route(&iso_pi(sk)->dst, &iso_pi(sk)->src,
|
|
|
|
iso_pi(sk)->src_type);
|
|
|
|
|
|
|
|
if (!hdev)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!test_and_set_bit(BT_SK_BIG_SYNC, &iso_pi(sk)->flags)) {
|
|
|
|
err = hci_le_big_create_sync(hdev, iso_pi(sk)->conn->hcon,
|
|
|
|
&iso_pi(sk)->qos,
|
|
|
|
iso_pi(sk)->sync_handle,
|
|
|
|
iso_pi(sk)->bc_num_bis,
|
|
|
|
iso_pi(sk)->bc_bis);
|
|
|
|
if (err)
|
|
|
|
bt_dev_err(hdev, "hci_le_big_create_sync: %d",
|
|
|
|
err);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-16 23:55:57 +00:00
|
|
|
static int iso_sock_recvmsg(struct socket *sock, struct msghdr *msg,
|
|
|
|
size_t len, int flags)
|
|
|
|
{
|
|
|
|
struct sock *sk = sock->sk;
|
|
|
|
struct iso_pinfo *pi = iso_pi(sk);
|
|
|
|
|
|
|
|
BT_DBG("sk %p", sk);
|
|
|
|
|
|
|
|
if (test_and_clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
|
Bluetooth: ISO: fix iso_conn related locking and validity issues
sk->sk_state indicates whether iso_pi(sk)->conn is valid. Operations
that check/update sk_state and access conn should hold lock_sock,
otherwise they can race.
The order of taking locks is hci_dev_lock > lock_sock > iso_conn_lock,
which is how it is in connect/disconnect_cfm -> iso_conn_del ->
iso_chan_del.
Fix locking in iso_connect_cis/bis and sendmsg/recvmsg to take lock_sock
around updating sk_state and conn.
iso_conn_del must not occur during iso_connect_cis/bis, as it frees the
iso_conn. Hold hdev->lock longer to prevent that.
This should not reintroduce the issue fixed in commit 241f51931c35
("Bluetooth: ISO: Avoid circular locking dependency"), since the we
acquire locks in order. We retain the fix in iso_sock_connect to release
lock_sock before iso_connect_* acquires hdev->lock.
Similarly for commit 6a5ad251b7cd ("Bluetooth: ISO: Fix possible
circular locking dependency"). We retain the fix in iso_conn_ready to
not acquire iso_conn_lock before lock_sock.
iso_conn_add shall return iso_conn with valid hcon. Make it so also when
reusing an old CIS connection waiting for disconnect timeout (see
__iso_sock_close where conn->hcon is set to NULL).
Trace with iso_conn_del after iso_chan_add in iso_connect_cis:
===============================================================
iso_sock_create:771: sock 00000000be9b69b7
iso_sock_init:693: sk 000000004dff667e
iso_sock_bind:827: sk 000000004dff667e 70:1a:b8:98:ff:a2 type 1
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_connect:875: sk 000000004dff667e
iso_connect_cis:353: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
hci_get_route:1199: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
hci_conn_add:1005: hci0 dst 28:3d:c2:4a:7e:da
iso_conn_add:140: hcon 000000007b65d182 conn 00000000daf8625e
__iso_chan_add:214: conn 00000000daf8625e
iso_connect_cfm:1700: hcon 000000007b65d182 bdaddr 28:3d:c2:4a:7e:da status 12
iso_conn_del:187: hcon 000000007b65d182 conn 00000000daf8625e, err 16
iso_sock_clear_timer:117: sock 000000004dff667e state 3
<Note: sk_state is BT_BOUND (3), so iso_connect_cis is still
running at this point>
iso_chan_del:153: sk 000000004dff667e, conn 00000000daf8625e, err 16
hci_conn_del:1151: hci0 hcon 000000007b65d182 handle 65535
hci_conn_unlink:1102: hci0: hcon 000000007b65d182
hci_chan_list_flush:2780: hcon 000000007b65d182
iso_sock_getsockopt:1376: sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getsockopt:1376: sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_shutdown:1434: sock 00000000be9b69b7, sk 000000004dff667e, how 1
__iso_sock_close:632: sk 000000004dff667e state 5 socket 00000000be9b69b7
<Note: sk_state is BT_CONNECT (5), even though iso_chan_del sets
BT_CLOSED (6). Only iso_connect_cis sets it to BT_CONNECT, so it
must be that iso_chan_del occurred between iso_chan_add and end of
iso_connect_cis.>
BUG: kernel NULL pointer dereference, address: 0000000000000000
PGD 8000000006467067 P4D 8000000006467067 PUD 3f5f067 PMD 0
Oops: 0000 [#1] PREEMPT SMP PTI
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:__iso_sock_close (net/bluetooth/iso.c:664) bluetooth
===============================================================
Trace with iso_conn_del before iso_chan_add in iso_connect_cis:
===============================================================
iso_connect_cis:356: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
...
iso_conn_add:140: hcon 0000000093bc551f conn 00000000768ae504
hci_dev_put:1487: hci0 orig refcnt 21
hci_event_packet:7607: hci0: event 0x0e
hci_cmd_complete_evt:4231: hci0: opcode 0x2062
hci_cc_le_set_cig_params:3846: hci0: status 0x07
hci_sent_cmd_data:3107: hci0 opcode 0x2062
iso_connect_cfm:1703: hcon 0000000093bc551f bdaddr 28:3d:c2:4a:7e:da status 7
iso_conn_del:187: hcon 0000000093bc551f conn 00000000768ae504, err 12
hci_conn_del:1151: hci0 hcon 0000000093bc551f handle 65535
hci_conn_unlink:1102: hci0: hcon 0000000093bc551f
hci_chan_list_flush:2780: hcon 0000000093bc551f
__iso_chan_add:214: conn 00000000768ae504
<Note: this conn was already freed in iso_conn_del above>
iso_sock_clear_timer:117: sock 0000000098323f95 state 3
general protection fault, probably for non-canonical address 0x30b29c630930aec8: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 1920 Comm: bluetoothd Tainted: G E 6.3.0-rc7+ #4
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:detach_if_pending+0x28/0xd0
Code: 90 90 0f 1f 44 00 00 48 8b 47 08 48 85 c0 0f 84 ad 00 00 00 55 89 d5 53 48 83 3f 00 48 89 fb 74 7d 66 90 48 8b 03 48 8b 53 08 <>
RSP: 0018:ffffb90841a67d08 EFLAGS: 00010007
RAX: 0000000000000000 RBX: ffff9141bd5061b8 RCX: 0000000000000000
RDX: 30b29c630930aec8 RSI: ffff9141fdd21e80 RDI: ffff9141bd5061b8
RBP: 0000000000000001 R08: 0000000000000000 R09: ffffb90841a67b88
R10: 0000000000000003 R11: ffffffff8613f558 R12: ffff9141fdd21e80
R13: 0000000000000000 R14: ffff9141b5976010 R15: ffff914185755338
FS: 00007f45768bd840(0000) GS:ffff9141fdd00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000619000424074 CR3: 0000000009f5e005 CR4: 0000000000170ee0
Call Trace:
<TASK>
timer_delete+0x48/0x80
try_to_grab_pending+0xdf/0x170
__cancel_work+0x37/0xb0
iso_connect_cis+0x141/0x400 [bluetooth]
===============================================================
Trace with NULL conn->hcon in state BT_CONNECT:
===============================================================
__iso_sock_close:619: sk 00000000f7c71fc5 state 1 socket 00000000d90c5fe5
...
__iso_sock_close:619: sk 00000000f7c71fc5 state 8 socket 00000000d90c5fe5
iso_chan_del:153: sk 00000000f7c71fc5, conn 0000000022c03a7e, err 104
...
iso_sock_connect:862: sk 00000000129b56c3
iso_connect_cis:348: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7d:2a
hci_get_route:1199: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7d:2a
hci_dev_hold:1495: hci0 orig refcnt 19
__iso_chan_add:214: conn 0000000022c03a7e
<Note: reusing old conn>
iso_sock_clear_timer:117: sock 00000000129b56c3 state 3
...
iso_sock_ready:1485: sk 00000000129b56c3
...
iso_sock_sendmsg:1077: sock 00000000e5013966, sk 00000000129b56c3
BUG: kernel NULL pointer dereference, address: 00000000000006a8
PGD 0 P4D 0
Oops: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 1403 Comm: wireplumber Tainted: G E 6.3.0-rc7+ #4
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:iso_sock_sendmsg+0x63/0x2a0 [bluetooth]
===============================================================
Fixes: 241f51931c35 ("Bluetooth: ISO: Avoid circular locking dependency")
Fixes: 6a5ad251b7cd ("Bluetooth: ISO: Fix possible circular locking dependency")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2023-06-18 22:04:33 +00:00
|
|
|
lock_sock(sk);
|
2020-01-16 23:55:57 +00:00
|
|
|
switch (sk->sk_state) {
|
|
|
|
case BT_CONNECT2:
|
2023-08-17 06:44:27 +00:00
|
|
|
if (pi->conn->hcon &&
|
|
|
|
test_bit(HCI_CONN_PA_SYNC, &pi->conn->hcon->flags)) {
|
|
|
|
iso_conn_big_sync(sk);
|
|
|
|
sk->sk_state = BT_LISTEN;
|
|
|
|
} else {
|
|
|
|
iso_conn_defer_accept(pi->conn->hcon);
|
|
|
|
sk->sk_state = BT_CONFIG;
|
|
|
|
}
|
2020-01-16 23:55:57 +00:00
|
|
|
release_sock(sk);
|
|
|
|
return 0;
|
2024-04-02 11:39:31 +00:00
|
|
|
case BT_CONNECTED:
|
|
|
|
if (test_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags)) {
|
|
|
|
iso_conn_big_sync(sk);
|
|
|
|
sk->sk_state = BT_LISTEN;
|
|
|
|
release_sock(sk);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
release_sock(sk);
|
|
|
|
break;
|
2020-01-16 23:55:57 +00:00
|
|
|
case BT_CONNECT:
|
Bluetooth: ISO: fix iso_conn related locking and validity issues
sk->sk_state indicates whether iso_pi(sk)->conn is valid. Operations
that check/update sk_state and access conn should hold lock_sock,
otherwise they can race.
The order of taking locks is hci_dev_lock > lock_sock > iso_conn_lock,
which is how it is in connect/disconnect_cfm -> iso_conn_del ->
iso_chan_del.
Fix locking in iso_connect_cis/bis and sendmsg/recvmsg to take lock_sock
around updating sk_state and conn.
iso_conn_del must not occur during iso_connect_cis/bis, as it frees the
iso_conn. Hold hdev->lock longer to prevent that.
This should not reintroduce the issue fixed in commit 241f51931c35
("Bluetooth: ISO: Avoid circular locking dependency"), since the we
acquire locks in order. We retain the fix in iso_sock_connect to release
lock_sock before iso_connect_* acquires hdev->lock.
Similarly for commit 6a5ad251b7cd ("Bluetooth: ISO: Fix possible
circular locking dependency"). We retain the fix in iso_conn_ready to
not acquire iso_conn_lock before lock_sock.
iso_conn_add shall return iso_conn with valid hcon. Make it so also when
reusing an old CIS connection waiting for disconnect timeout (see
__iso_sock_close where conn->hcon is set to NULL).
Trace with iso_conn_del after iso_chan_add in iso_connect_cis:
===============================================================
iso_sock_create:771: sock 00000000be9b69b7
iso_sock_init:693: sk 000000004dff667e
iso_sock_bind:827: sk 000000004dff667e 70:1a:b8:98:ff:a2 type 1
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_connect:875: sk 000000004dff667e
iso_connect_cis:353: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
hci_get_route:1199: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
hci_conn_add:1005: hci0 dst 28:3d:c2:4a:7e:da
iso_conn_add:140: hcon 000000007b65d182 conn 00000000daf8625e
__iso_chan_add:214: conn 00000000daf8625e
iso_connect_cfm:1700: hcon 000000007b65d182 bdaddr 28:3d:c2:4a:7e:da status 12
iso_conn_del:187: hcon 000000007b65d182 conn 00000000daf8625e, err 16
iso_sock_clear_timer:117: sock 000000004dff667e state 3
<Note: sk_state is BT_BOUND (3), so iso_connect_cis is still
running at this point>
iso_chan_del:153: sk 000000004dff667e, conn 00000000daf8625e, err 16
hci_conn_del:1151: hci0 hcon 000000007b65d182 handle 65535
hci_conn_unlink:1102: hci0: hcon 000000007b65d182
hci_chan_list_flush:2780: hcon 000000007b65d182
iso_sock_getsockopt:1376: sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getsockopt:1376: sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_shutdown:1434: sock 00000000be9b69b7, sk 000000004dff667e, how 1
__iso_sock_close:632: sk 000000004dff667e state 5 socket 00000000be9b69b7
<Note: sk_state is BT_CONNECT (5), even though iso_chan_del sets
BT_CLOSED (6). Only iso_connect_cis sets it to BT_CONNECT, so it
must be that iso_chan_del occurred between iso_chan_add and end of
iso_connect_cis.>
BUG: kernel NULL pointer dereference, address: 0000000000000000
PGD 8000000006467067 P4D 8000000006467067 PUD 3f5f067 PMD 0
Oops: 0000 [#1] PREEMPT SMP PTI
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:__iso_sock_close (net/bluetooth/iso.c:664) bluetooth
===============================================================
Trace with iso_conn_del before iso_chan_add in iso_connect_cis:
===============================================================
iso_connect_cis:356: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
...
iso_conn_add:140: hcon 0000000093bc551f conn 00000000768ae504
hci_dev_put:1487: hci0 orig refcnt 21
hci_event_packet:7607: hci0: event 0x0e
hci_cmd_complete_evt:4231: hci0: opcode 0x2062
hci_cc_le_set_cig_params:3846: hci0: status 0x07
hci_sent_cmd_data:3107: hci0 opcode 0x2062
iso_connect_cfm:1703: hcon 0000000093bc551f bdaddr 28:3d:c2:4a:7e:da status 7
iso_conn_del:187: hcon 0000000093bc551f conn 00000000768ae504, err 12
hci_conn_del:1151: hci0 hcon 0000000093bc551f handle 65535
hci_conn_unlink:1102: hci0: hcon 0000000093bc551f
hci_chan_list_flush:2780: hcon 0000000093bc551f
__iso_chan_add:214: conn 00000000768ae504
<Note: this conn was already freed in iso_conn_del above>
iso_sock_clear_timer:117: sock 0000000098323f95 state 3
general protection fault, probably for non-canonical address 0x30b29c630930aec8: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 1920 Comm: bluetoothd Tainted: G E 6.3.0-rc7+ #4
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:detach_if_pending+0x28/0xd0
Code: 90 90 0f 1f 44 00 00 48 8b 47 08 48 85 c0 0f 84 ad 00 00 00 55 89 d5 53 48 83 3f 00 48 89 fb 74 7d 66 90 48 8b 03 48 8b 53 08 <>
RSP: 0018:ffffb90841a67d08 EFLAGS: 00010007
RAX: 0000000000000000 RBX: ffff9141bd5061b8 RCX: 0000000000000000
RDX: 30b29c630930aec8 RSI: ffff9141fdd21e80 RDI: ffff9141bd5061b8
RBP: 0000000000000001 R08: 0000000000000000 R09: ffffb90841a67b88
R10: 0000000000000003 R11: ffffffff8613f558 R12: ffff9141fdd21e80
R13: 0000000000000000 R14: ffff9141b5976010 R15: ffff914185755338
FS: 00007f45768bd840(0000) GS:ffff9141fdd00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000619000424074 CR3: 0000000009f5e005 CR4: 0000000000170ee0
Call Trace:
<TASK>
timer_delete+0x48/0x80
try_to_grab_pending+0xdf/0x170
__cancel_work+0x37/0xb0
iso_connect_cis+0x141/0x400 [bluetooth]
===============================================================
Trace with NULL conn->hcon in state BT_CONNECT:
===============================================================
__iso_sock_close:619: sk 00000000f7c71fc5 state 1 socket 00000000d90c5fe5
...
__iso_sock_close:619: sk 00000000f7c71fc5 state 8 socket 00000000d90c5fe5
iso_chan_del:153: sk 00000000f7c71fc5, conn 0000000022c03a7e, err 104
...
iso_sock_connect:862: sk 00000000129b56c3
iso_connect_cis:348: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7d:2a
hci_get_route:1199: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7d:2a
hci_dev_hold:1495: hci0 orig refcnt 19
__iso_chan_add:214: conn 0000000022c03a7e
<Note: reusing old conn>
iso_sock_clear_timer:117: sock 00000000129b56c3 state 3
...
iso_sock_ready:1485: sk 00000000129b56c3
...
iso_sock_sendmsg:1077: sock 00000000e5013966, sk 00000000129b56c3
BUG: kernel NULL pointer dereference, address: 00000000000006a8
PGD 0 P4D 0
Oops: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 1403 Comm: wireplumber Tainted: G E 6.3.0-rc7+ #4
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:iso_sock_sendmsg+0x63/0x2a0 [bluetooth]
===============================================================
Fixes: 241f51931c35 ("Bluetooth: ISO: Avoid circular locking dependency")
Fixes: 6a5ad251b7cd ("Bluetooth: ISO: Fix possible circular locking dependency")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2023-06-18 22:04:33 +00:00
|
|
|
release_sock(sk);
|
2022-12-07 00:34:42 +00:00
|
|
|
return iso_connect_cis(sk);
|
Bluetooth: ISO: fix iso_conn related locking and validity issues
sk->sk_state indicates whether iso_pi(sk)->conn is valid. Operations
that check/update sk_state and access conn should hold lock_sock,
otherwise they can race.
The order of taking locks is hci_dev_lock > lock_sock > iso_conn_lock,
which is how it is in connect/disconnect_cfm -> iso_conn_del ->
iso_chan_del.
Fix locking in iso_connect_cis/bis and sendmsg/recvmsg to take lock_sock
around updating sk_state and conn.
iso_conn_del must not occur during iso_connect_cis/bis, as it frees the
iso_conn. Hold hdev->lock longer to prevent that.
This should not reintroduce the issue fixed in commit 241f51931c35
("Bluetooth: ISO: Avoid circular locking dependency"), since the we
acquire locks in order. We retain the fix in iso_sock_connect to release
lock_sock before iso_connect_* acquires hdev->lock.
Similarly for commit 6a5ad251b7cd ("Bluetooth: ISO: Fix possible
circular locking dependency"). We retain the fix in iso_conn_ready to
not acquire iso_conn_lock before lock_sock.
iso_conn_add shall return iso_conn with valid hcon. Make it so also when
reusing an old CIS connection waiting for disconnect timeout (see
__iso_sock_close where conn->hcon is set to NULL).
Trace with iso_conn_del after iso_chan_add in iso_connect_cis:
===============================================================
iso_sock_create:771: sock 00000000be9b69b7
iso_sock_init:693: sk 000000004dff667e
iso_sock_bind:827: sk 000000004dff667e 70:1a:b8:98:ff:a2 type 1
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_setsockopt:1289: sk 000000004dff667e
iso_sock_connect:875: sk 000000004dff667e
iso_connect_cis:353: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
hci_get_route:1199: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
hci_conn_add:1005: hci0 dst 28:3d:c2:4a:7e:da
iso_conn_add:140: hcon 000000007b65d182 conn 00000000daf8625e
__iso_chan_add:214: conn 00000000daf8625e
iso_connect_cfm:1700: hcon 000000007b65d182 bdaddr 28:3d:c2:4a:7e:da status 12
iso_conn_del:187: hcon 000000007b65d182 conn 00000000daf8625e, err 16
iso_sock_clear_timer:117: sock 000000004dff667e state 3
<Note: sk_state is BT_BOUND (3), so iso_connect_cis is still
running at this point>
iso_chan_del:153: sk 000000004dff667e, conn 00000000daf8625e, err 16
hci_conn_del:1151: hci0 hcon 000000007b65d182 handle 65535
hci_conn_unlink:1102: hci0: hcon 000000007b65d182
hci_chan_list_flush:2780: hcon 000000007b65d182
iso_sock_getsockopt:1376: sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getsockopt:1376: sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_getname:1070: sock 00000000be9b69b7, sk 000000004dff667e
iso_sock_shutdown:1434: sock 00000000be9b69b7, sk 000000004dff667e, how 1
__iso_sock_close:632: sk 000000004dff667e state 5 socket 00000000be9b69b7
<Note: sk_state is BT_CONNECT (5), even though iso_chan_del sets
BT_CLOSED (6). Only iso_connect_cis sets it to BT_CONNECT, so it
must be that iso_chan_del occurred between iso_chan_add and end of
iso_connect_cis.>
BUG: kernel NULL pointer dereference, address: 0000000000000000
PGD 8000000006467067 P4D 8000000006467067 PUD 3f5f067 PMD 0
Oops: 0000 [#1] PREEMPT SMP PTI
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:__iso_sock_close (net/bluetooth/iso.c:664) bluetooth
===============================================================
Trace with iso_conn_del before iso_chan_add in iso_connect_cis:
===============================================================
iso_connect_cis:356: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7e:da
...
iso_conn_add:140: hcon 0000000093bc551f conn 00000000768ae504
hci_dev_put:1487: hci0 orig refcnt 21
hci_event_packet:7607: hci0: event 0x0e
hci_cmd_complete_evt:4231: hci0: opcode 0x2062
hci_cc_le_set_cig_params:3846: hci0: status 0x07
hci_sent_cmd_data:3107: hci0 opcode 0x2062
iso_connect_cfm:1703: hcon 0000000093bc551f bdaddr 28:3d:c2:4a:7e:da status 7
iso_conn_del:187: hcon 0000000093bc551f conn 00000000768ae504, err 12
hci_conn_del:1151: hci0 hcon 0000000093bc551f handle 65535
hci_conn_unlink:1102: hci0: hcon 0000000093bc551f
hci_chan_list_flush:2780: hcon 0000000093bc551f
__iso_chan_add:214: conn 00000000768ae504
<Note: this conn was already freed in iso_conn_del above>
iso_sock_clear_timer:117: sock 0000000098323f95 state 3
general protection fault, probably for non-canonical address 0x30b29c630930aec8: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 1920 Comm: bluetoothd Tainted: G E 6.3.0-rc7+ #4
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:detach_if_pending+0x28/0xd0
Code: 90 90 0f 1f 44 00 00 48 8b 47 08 48 85 c0 0f 84 ad 00 00 00 55 89 d5 53 48 83 3f 00 48 89 fb 74 7d 66 90 48 8b 03 48 8b 53 08 <>
RSP: 0018:ffffb90841a67d08 EFLAGS: 00010007
RAX: 0000000000000000 RBX: ffff9141bd5061b8 RCX: 0000000000000000
RDX: 30b29c630930aec8 RSI: ffff9141fdd21e80 RDI: ffff9141bd5061b8
RBP: 0000000000000001 R08: 0000000000000000 R09: ffffb90841a67b88
R10: 0000000000000003 R11: ffffffff8613f558 R12: ffff9141fdd21e80
R13: 0000000000000000 R14: ffff9141b5976010 R15: ffff914185755338
FS: 00007f45768bd840(0000) GS:ffff9141fdd00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000619000424074 CR3: 0000000009f5e005 CR4: 0000000000170ee0
Call Trace:
<TASK>
timer_delete+0x48/0x80
try_to_grab_pending+0xdf/0x170
__cancel_work+0x37/0xb0
iso_connect_cis+0x141/0x400 [bluetooth]
===============================================================
Trace with NULL conn->hcon in state BT_CONNECT:
===============================================================
__iso_sock_close:619: sk 00000000f7c71fc5 state 1 socket 00000000d90c5fe5
...
__iso_sock_close:619: sk 00000000f7c71fc5 state 8 socket 00000000d90c5fe5
iso_chan_del:153: sk 00000000f7c71fc5, conn 0000000022c03a7e, err 104
...
iso_sock_connect:862: sk 00000000129b56c3
iso_connect_cis:348: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7d:2a
hci_get_route:1199: 70:1a:b8:98:ff:a2 -> 28:3d:c2:4a:7d:2a
hci_dev_hold:1495: hci0 orig refcnt 19
__iso_chan_add:214: conn 0000000022c03a7e
<Note: reusing old conn>
iso_sock_clear_timer:117: sock 00000000129b56c3 state 3
...
iso_sock_ready:1485: sk 00000000129b56c3
...
iso_sock_sendmsg:1077: sock 00000000e5013966, sk 00000000129b56c3
BUG: kernel NULL pointer dereference, address: 00000000000006a8
PGD 0 P4D 0
Oops: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 1403 Comm: wireplumber Tainted: G E 6.3.0-rc7+ #4
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014
RIP: 0010:iso_sock_sendmsg+0x63/0x2a0 [bluetooth]
===============================================================
Fixes: 241f51931c35 ("Bluetooth: ISO: Avoid circular locking dependency")
Fixes: 6a5ad251b7cd ("Bluetooth: ISO: Fix possible circular locking dependency")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2023-06-18 22:04:33 +00:00
|
|
|
default:
|
|
|
|
release_sock(sk);
|
|
|
|
break;
|
2020-01-16 23:55:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return bt_sock_recvmsg(sock, msg, len, flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool check_io_qos(struct bt_iso_io_qos *qos)
|
|
|
|
{
|
|
|
|
/* If no PHY is enable SDU must be 0 */
|
|
|
|
if (!qos->phy && qos->sdu)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (qos->interval && (qos->interval < 0xff || qos->interval > 0xfffff))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (qos->latency && (qos->latency < 0x05 || qos->latency > 0xfa0))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (qos->phy > BT_ISO_PHY_ANY)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2023-03-31 15:38:01 +00:00
|
|
|
static bool check_ucast_qos(struct bt_iso_qos *qos)
|
2020-01-16 23:55:57 +00:00
|
|
|
{
|
2023-08-03 21:41:46 +00:00
|
|
|
if (qos->ucast.cig > 0xef && qos->ucast.cig != BT_ISO_QOS_CIG_UNSET)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (qos->ucast.cis > 0xef && qos->ucast.cis != BT_ISO_QOS_CIS_UNSET)
|
|
|
|
return false;
|
|
|
|
|
2023-03-31 15:38:01 +00:00
|
|
|
if (qos->ucast.sca > 0x07)
|
2020-01-16 23:55:57 +00:00
|
|
|
return false;
|
|
|
|
|
2023-03-31 15:38:01 +00:00
|
|
|
if (qos->ucast.packing > 0x01)
|
2020-01-16 23:55:57 +00:00
|
|
|
return false;
|
|
|
|
|
2023-03-31 15:38:01 +00:00
|
|
|
if (qos->ucast.framing > 0x01)
|
2020-01-16 23:55:57 +00:00
|
|
|
return false;
|
|
|
|
|
2023-03-31 15:38:01 +00:00
|
|
|
if (!check_io_qos(&qos->ucast.in))
|
2020-01-16 23:55:57 +00:00
|
|
|
return false;
|
|
|
|
|
2023-03-31 15:38:01 +00:00
|
|
|
if (!check_io_qos(&qos->ucast.out))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool check_bcast_qos(struct bt_iso_qos *qos)
|
|
|
|
{
|
2024-03-13 19:43:18 +00:00
|
|
|
if (!qos->bcast.sync_factor)
|
|
|
|
qos->bcast.sync_factor = 0x01;
|
2023-03-31 15:38:01 +00:00
|
|
|
|
|
|
|
if (qos->bcast.packing > 0x01)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (qos->bcast.framing > 0x01)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (!check_io_qos(&qos->bcast.in))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (!check_io_qos(&qos->bcast.out))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (qos->bcast.encryption > 0x01)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (qos->bcast.options > 0x07)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (qos->bcast.skip > 0x01f3)
|
|
|
|
return false;
|
|
|
|
|
2024-03-13 19:43:18 +00:00
|
|
|
if (!qos->bcast.sync_timeout)
|
|
|
|
qos->bcast.sync_timeout = BT_ISO_SYNC_TIMEOUT;
|
|
|
|
|
2023-03-31 15:38:01 +00:00
|
|
|
if (qos->bcast.sync_timeout < 0x000a || qos->bcast.sync_timeout > 0x4000)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (qos->bcast.sync_cte_type > 0x1f)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (qos->bcast.mse > 0x1f)
|
|
|
|
return false;
|
|
|
|
|
2024-03-13 19:43:18 +00:00
|
|
|
if (!qos->bcast.timeout)
|
|
|
|
qos->bcast.sync_timeout = BT_ISO_SYNC_TIMEOUT;
|
|
|
|
|
2023-03-31 15:38:01 +00:00
|
|
|
if (qos->bcast.timeout < 0x000a || qos->bcast.timeout > 0x4000)
|
2020-01-16 23:55:57 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int iso_sock_setsockopt(struct socket *sock, int level, int optname,
|
|
|
|
sockptr_t optval, unsigned int optlen)
|
|
|
|
{
|
|
|
|
struct sock *sk = sock->sk;
|
2024-04-05 19:56:50 +00:00
|
|
|
int err = 0;
|
2023-03-31 15:38:01 +00:00
|
|
|
struct bt_iso_qos qos = default_qos;
|
2020-01-16 23:55:57 +00:00
|
|
|
u32 opt;
|
|
|
|
|
|
|
|
BT_DBG("sk %p", sk);
|
|
|
|
|
|
|
|
lock_sock(sk);
|
|
|
|
|
|
|
|
switch (optname) {
|
|
|
|
case BT_DEFER_SETUP:
|
|
|
|
if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
|
|
|
|
err = -EINVAL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2024-04-05 19:56:50 +00:00
|
|
|
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
|
|
|
|
if (err)
|
2020-01-16 23:55:57 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
if (opt)
|
|
|
|
set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
|
|
|
|
else
|
|
|
|
clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
|
|
|
|
break;
|
|
|
|
|
2023-07-13 21:02:37 +00:00
|
|
|
case BT_PKT_STATUS:
|
2024-04-05 19:56:50 +00:00
|
|
|
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
|
|
|
|
if (err)
|
2023-07-13 21:02:37 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
if (opt)
|
|
|
|
set_bit(BT_SK_PKT_STATUS, &bt_sk(sk)->flags);
|
|
|
|
else
|
|
|
|
clear_bit(BT_SK_PKT_STATUS, &bt_sk(sk)->flags);
|
|
|
|
break;
|
|
|
|
|
2020-01-16 23:55:57 +00:00
|
|
|
case BT_ISO_QOS:
|
|
|
|
if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND &&
|
2024-04-02 11:39:31 +00:00
|
|
|
sk->sk_state != BT_CONNECT2 &&
|
|
|
|
(!test_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags) ||
|
|
|
|
sk->sk_state != BT_CONNECTED)) {
|
2020-01-16 23:55:57 +00:00
|
|
|
err = -EINVAL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2024-04-05 19:56:50 +00:00
|
|
|
err = bt_copy_from_sockptr(&qos, sizeof(qos), optval, optlen);
|
|
|
|
if (err)
|
2020-01-16 23:55:57 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
iso_pi(sk)->qos = qos;
|
2023-03-31 15:38:01 +00:00
|
|
|
iso_pi(sk)->qos_user_set = true;
|
2020-01-16 23:55:57 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
|
2022-03-09 21:14:41 +00:00
|
|
|
case BT_ISO_BASE:
|
|
|
|
if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND &&
|
|
|
|
sk->sk_state != BT_CONNECT2) {
|
|
|
|
err = -EINVAL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (optlen > sizeof(iso_pi(sk)->base)) {
|
2024-04-05 19:56:50 +00:00
|
|
|
err = -EINVAL;
|
2022-03-09 21:14:41 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2024-04-05 19:56:50 +00:00
|
|
|
err = bt_copy_from_sockptr(iso_pi(sk)->base, optlen, optval,
|
|
|
|
optlen);
|
|
|
|
if (err)
|
2022-03-09 21:14:41 +00:00
|
|
|
break;
|
|
|
|
|
2024-04-05 19:56:50 +00:00
|
|
|
iso_pi(sk)->base_len = optlen;
|
2022-03-09 21:14:41 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
|
2020-01-16 23:55:57 +00:00
|
|
|
default:
|
|
|
|
err = -ENOPROTOOPT;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
release_sock(sk);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int iso_sock_getsockopt(struct socket *sock, int level, int optname,
|
|
|
|
char __user *optval, int __user *optlen)
|
|
|
|
{
|
|
|
|
struct sock *sk = sock->sk;
|
|
|
|
int len, err = 0;
|
2022-07-28 23:50:48 +00:00
|
|
|
struct bt_iso_qos *qos;
|
2022-03-09 21:14:41 +00:00
|
|
|
u8 base_len;
|
|
|
|
u8 *base;
|
2020-01-16 23:55:57 +00:00
|
|
|
|
|
|
|
BT_DBG("sk %p", sk);
|
|
|
|
|
|
|
|
if (get_user(len, optlen))
|
|
|
|
return -EFAULT;
|
|
|
|
|
|
|
|
lock_sock(sk);
|
|
|
|
|
|
|
|
switch (optname) {
|
|
|
|
case BT_DEFER_SETUP:
|
2022-08-03 17:17:17 +00:00
|
|
|
if (sk->sk_state == BT_CONNECTED) {
|
2020-01-16 23:55:57 +00:00
|
|
|
err = -EINVAL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (put_user(test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags),
|
|
|
|
(u32 __user *)optval))
|
|
|
|
err = -EFAULT;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
2023-07-13 21:02:37 +00:00
|
|
|
case BT_PKT_STATUS:
|
|
|
|
if (put_user(test_bit(BT_SK_PKT_STATUS, &bt_sk(sk)->flags),
|
|
|
|
(int __user *)optval))
|
|
|
|
err = -EFAULT;
|
|
|
|
break;
|
|
|
|
|
2020-01-16 23:55:57 +00:00
|
|
|
case BT_ISO_QOS:
|
2022-08-05 21:02:21 +00:00
|
|
|
qos = iso_sock_get_qos(sk);
|
2020-01-16 23:55:57 +00:00
|
|
|
|
2022-07-28 23:50:48 +00:00
|
|
|
len = min_t(unsigned int, len, sizeof(*qos));
|
|
|
|
if (copy_to_user(optval, qos, len))
|
2020-01-16 23:55:57 +00:00
|
|
|
err = -EFAULT;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
2022-03-09 21:14:41 +00:00
|
|
|
case BT_ISO_BASE:
|
2023-06-30 09:59:28 +00:00
|
|
|
if (sk->sk_state == BT_CONNECTED &&
|
|
|
|
!bacmp(&iso_pi(sk)->dst, BDADDR_ANY)) {
|
2022-03-09 21:14:41 +00:00
|
|
|
base_len = iso_pi(sk)->conn->hcon->le_per_adv_data_len;
|
|
|
|
base = iso_pi(sk)->conn->hcon->le_per_adv_data;
|
|
|
|
} else {
|
|
|
|
base_len = iso_pi(sk)->base_len;
|
|
|
|
base = iso_pi(sk)->base;
|
|
|
|
}
|
|
|
|
|
|
|
|
len = min_t(unsigned int, len, base_len);
|
|
|
|
if (copy_to_user(optval, base, len))
|
|
|
|
err = -EFAULT;
|
2023-09-28 08:02:08 +00:00
|
|
|
if (put_user(len, optlen))
|
|
|
|
err = -EFAULT;
|
2022-03-09 21:14:41 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
|
2020-01-16 23:55:57 +00:00
|
|
|
default:
|
|
|
|
err = -ENOPROTOOPT;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
release_sock(sk);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int iso_sock_shutdown(struct socket *sock, int how)
|
|
|
|
{
|
|
|
|
struct sock *sk = sock->sk;
|
|
|
|
int err = 0;
|
|
|
|
|
2022-08-18 21:31:42 +00:00
|
|
|
BT_DBG("sock %p, sk %p, how %d", sock, sk, how);
|
2020-01-16 23:55:57 +00:00
|
|
|
|
|
|
|
if (!sk)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
sock_hold(sk);
|
|
|
|
lock_sock(sk);
|
|
|
|
|
2022-08-18 21:31:42 +00:00
|
|
|
switch (how) {
|
|
|
|
case SHUT_RD:
|
|
|
|
if (sk->sk_shutdown & RCV_SHUTDOWN)
|
|
|
|
goto unlock;
|
|
|
|
sk->sk_shutdown |= RCV_SHUTDOWN;
|
|
|
|
break;
|
|
|
|
case SHUT_WR:
|
|
|
|
if (sk->sk_shutdown & SEND_SHUTDOWN)
|
|
|
|
goto unlock;
|
|
|
|
sk->sk_shutdown |= SEND_SHUTDOWN;
|
|
|
|
break;
|
|
|
|
case SHUT_RDWR:
|
|
|
|
if (sk->sk_shutdown & SHUTDOWN_MASK)
|
|
|
|
goto unlock;
|
|
|
|
sk->sk_shutdown |= SHUTDOWN_MASK;
|
|
|
|
break;
|
2020-01-16 23:55:57 +00:00
|
|
|
}
|
|
|
|
|
2022-08-18 21:31:42 +00:00
|
|
|
iso_sock_clear_timer(sk);
|
|
|
|
__iso_sock_close(sk);
|
|
|
|
|
|
|
|
if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime &&
|
|
|
|
!(current->flags & PF_EXITING))
|
|
|
|
err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);
|
|
|
|
|
|
|
|
unlock:
|
2020-01-16 23:55:57 +00:00
|
|
|
release_sock(sk);
|
|
|
|
sock_put(sk);
|
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int iso_sock_release(struct socket *sock)
|
|
|
|
{
|
|
|
|
struct sock *sk = sock->sk;
|
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
BT_DBG("sock %p, sk %p", sock, sk);
|
|
|
|
|
|
|
|
if (!sk)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
iso_sock_close(sk);
|
|
|
|
|
2023-08-19 04:06:46 +00:00
|
|
|
if (sock_flag(sk, SOCK_LINGER) && READ_ONCE(sk->sk_lingertime) &&
|
2020-01-16 23:55:57 +00:00
|
|
|
!(current->flags & PF_EXITING)) {
|
|
|
|
lock_sock(sk);
|
|
|
|
err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);
|
|
|
|
release_sock(sk);
|
|
|
|
}
|
|
|
|
|
|
|
|
sock_orphan(sk);
|
|
|
|
iso_sock_kill(sk);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void iso_sock_ready(struct sock *sk)
|
|
|
|
{
|
|
|
|
BT_DBG("sk %p", sk);
|
|
|
|
|
|
|
|
if (!sk)
|
|
|
|
return;
|
|
|
|
|
|
|
|
lock_sock(sk);
|
|
|
|
iso_sock_clear_timer(sk);
|
|
|
|
sk->sk_state = BT_CONNECTED;
|
|
|
|
sk->sk_state_change(sk);
|
|
|
|
release_sock(sk);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct iso_list_data {
|
|
|
|
struct hci_conn *hcon;
|
|
|
|
int count;
|
|
|
|
};
|
|
|
|
|
2022-03-09 21:14:41 +00:00
|
|
|
static bool iso_match_big(struct sock *sk, void *data)
|
|
|
|
{
|
|
|
|
struct hci_evt_le_big_sync_estabilished *ev = data;
|
|
|
|
|
2023-03-31 15:38:01 +00:00
|
|
|
return ev->handle == iso_pi(sk)->qos.bcast.big;
|
2022-03-09 21:14:41 +00:00
|
|
|
}
|
|
|
|
|
2023-08-17 06:44:27 +00:00
|
|
|
static bool iso_match_pa_sync_flag(struct sock *sk, void *data)
|
|
|
|
{
|
|
|
|
return test_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags);
|
|
|
|
}
|
|
|
|
|
2020-01-16 23:55:57 +00:00
|
|
|
static void iso_conn_ready(struct iso_conn *conn)
|
|
|
|
{
|
2023-08-17 06:44:27 +00:00
|
|
|
struct sock *parent = NULL;
|
2020-01-16 23:55:57 +00:00
|
|
|
struct sock *sk = conn->sk;
|
2023-08-17 06:44:27 +00:00
|
|
|
struct hci_ev_le_big_sync_estabilished *ev = NULL;
|
|
|
|
struct hci_ev_le_pa_sync_established *ev2 = NULL;
|
2024-04-02 11:39:31 +00:00
|
|
|
struct hci_ev_le_per_adv_report *ev3 = NULL;
|
2023-01-10 21:24:51 +00:00
|
|
|
struct hci_conn *hcon;
|
2020-01-16 23:55:57 +00:00
|
|
|
|
|
|
|
BT_DBG("conn %p", conn);
|
|
|
|
|
|
|
|
if (sk) {
|
|
|
|
iso_sock_ready(conn->sk);
|
|
|
|
} else {
|
2023-01-10 21:24:51 +00:00
|
|
|
hcon = conn->hcon;
|
|
|
|
if (!hcon)
|
2020-01-16 23:55:57 +00:00
|
|
|
return;
|
|
|
|
|
2023-08-17 06:44:27 +00:00
|
|
|
if (test_bit(HCI_CONN_BIG_SYNC, &hcon->flags) ||
|
|
|
|
test_bit(HCI_CONN_BIG_SYNC_FAILED, &hcon->flags)) {
|
|
|
|
ev = hci_recv_event_data(hcon->hdev,
|
|
|
|
HCI_EVT_LE_BIG_SYNC_ESTABILISHED);
|
|
|
|
|
|
|
|
/* Get reference to PA sync parent socket, if it exists */
|
2024-04-02 11:39:30 +00:00
|
|
|
parent = iso_get_sock(&hcon->src, &hcon->dst,
|
|
|
|
BT_LISTEN,
|
|
|
|
iso_match_pa_sync_flag,
|
|
|
|
NULL);
|
2023-08-17 06:44:27 +00:00
|
|
|
if (!parent && ev)
|
2024-04-02 11:39:30 +00:00
|
|
|
parent = iso_get_sock(&hcon->src,
|
|
|
|
&hcon->dst,
|
|
|
|
BT_LISTEN,
|
|
|
|
iso_match_big, ev);
|
2023-09-06 14:01:03 +00:00
|
|
|
} else if (test_bit(HCI_CONN_PA_SYNC_FAILED, &hcon->flags)) {
|
2023-08-17 06:44:27 +00:00
|
|
|
ev2 = hci_recv_event_data(hcon->hdev,
|
|
|
|
HCI_EV_LE_PA_SYNC_ESTABLISHED);
|
|
|
|
if (ev2)
|
2024-04-02 11:39:30 +00:00
|
|
|
parent = iso_get_sock(&hcon->src,
|
|
|
|
&hcon->dst,
|
|
|
|
BT_LISTEN,
|
|
|
|
iso_match_sid, ev2);
|
2023-09-06 14:01:03 +00:00
|
|
|
} else if (test_bit(HCI_CONN_PA_SYNC, &hcon->flags)) {
|
|
|
|
ev3 = hci_recv_event_data(hcon->hdev,
|
2024-04-02 11:39:31 +00:00
|
|
|
HCI_EV_LE_PER_ADV_REPORT);
|
2023-09-06 14:01:03 +00:00
|
|
|
if (ev3)
|
2024-04-02 11:39:30 +00:00
|
|
|
parent = iso_get_sock(&hcon->src,
|
|
|
|
&hcon->dst,
|
|
|
|
BT_LISTEN,
|
2024-04-02 11:39:31 +00:00
|
|
|
iso_match_sync_handle_pa_report,
|
2024-04-02 11:39:30 +00:00
|
|
|
ev3);
|
2023-08-17 06:44:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!parent)
|
2024-04-02 11:39:30 +00:00
|
|
|
parent = iso_get_sock(&hcon->src, BDADDR_ANY,
|
|
|
|
BT_LISTEN, NULL, NULL);
|
2022-03-09 21:14:41 +00:00
|
|
|
|
2023-01-10 21:24:51 +00:00
|
|
|
if (!parent)
|
2020-01-16 23:55:57 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
lock_sock(parent);
|
|
|
|
|
|
|
|
sk = iso_sock_alloc(sock_net(parent), NULL,
|
|
|
|
BTPROTO_ISO, GFP_ATOMIC, 0);
|
|
|
|
if (!sk) {
|
|
|
|
release_sock(parent);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
iso_sock_init(sk, parent);
|
|
|
|
|
2023-01-10 21:24:51 +00:00
|
|
|
bacpy(&iso_pi(sk)->src, &hcon->src);
|
2023-08-17 06:44:27 +00:00
|
|
|
|
|
|
|
/* Convert from HCI to three-value type */
|
|
|
|
if (hcon->src_type == ADDR_LE_DEV_PUBLIC)
|
|
|
|
iso_pi(sk)->src_type = BDADDR_LE_PUBLIC;
|
|
|
|
else
|
|
|
|
iso_pi(sk)->src_type = BDADDR_LE_RANDOM;
|
2022-03-09 21:14:41 +00:00
|
|
|
|
|
|
|
/* If hcon has no destination address (BDADDR_ANY) it means it
|
2023-08-17 06:44:27 +00:00
|
|
|
* was created by HCI_EV_LE_BIG_SYNC_ESTABILISHED or
|
|
|
|
* HCI_EV_LE_PA_SYNC_ESTABLISHED so we need to initialize using
|
|
|
|
* the parent socket destination address.
|
2022-03-09 21:14:41 +00:00
|
|
|
*/
|
2023-01-10 21:24:51 +00:00
|
|
|
if (!bacmp(&hcon->dst, BDADDR_ANY)) {
|
|
|
|
bacpy(&hcon->dst, &iso_pi(parent)->dst);
|
|
|
|
hcon->dst_type = iso_pi(parent)->dst_type;
|
|
|
|
hcon->sync_handle = iso_pi(parent)->sync_handle;
|
2022-03-09 21:14:41 +00:00
|
|
|
}
|
|
|
|
|
2023-09-06 14:01:03 +00:00
|
|
|
if (ev3) {
|
2023-08-17 06:44:27 +00:00
|
|
|
iso_pi(sk)->qos = iso_pi(parent)->qos;
|
2023-09-06 14:01:03 +00:00
|
|
|
hcon->iso_qos = iso_pi(sk)->qos;
|
2023-08-17 06:44:27 +00:00
|
|
|
iso_pi(sk)->bc_num_bis = iso_pi(parent)->bc_num_bis;
|
|
|
|
memcpy(iso_pi(sk)->bc_bis, iso_pi(parent)->bc_bis, ISO_MAX_NUM_BIS);
|
2023-09-06 14:01:03 +00:00
|
|
|
set_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags);
|
2023-08-17 06:44:27 +00:00
|
|
|
}
|
|
|
|
|
2023-01-10 21:24:51 +00:00
|
|
|
bacpy(&iso_pi(sk)->dst, &hcon->dst);
|
|
|
|
iso_pi(sk)->dst_type = hcon->dst_type;
|
2023-06-30 09:59:28 +00:00
|
|
|
iso_pi(sk)->sync_handle = iso_pi(parent)->sync_handle;
|
|
|
|
memcpy(iso_pi(sk)->base, iso_pi(parent)->base, iso_pi(parent)->base_len);
|
|
|
|
iso_pi(sk)->base_len = iso_pi(parent)->base_len;
|
2020-01-16 23:55:57 +00:00
|
|
|
|
2023-01-10 21:24:51 +00:00
|
|
|
hci_conn_hold(hcon);
|
|
|
|
iso_chan_add(conn, sk, parent);
|
2020-01-16 23:55:57 +00:00
|
|
|
|
2023-08-17 06:44:27 +00:00
|
|
|
if ((ev && ((struct hci_evt_le_big_sync_estabilished *)ev)->status) ||
|
|
|
|
(ev2 && ev2->status)) {
|
2023-07-03 07:02:38 +00:00
|
|
|
/* Trigger error signal on child socket */
|
|
|
|
sk->sk_err = ECONNREFUSED;
|
|
|
|
sk->sk_error_report(sk);
|
|
|
|
}
|
|
|
|
|
2020-01-16 23:55:57 +00:00
|
|
|
if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags))
|
|
|
|
sk->sk_state = BT_CONNECT2;
|
|
|
|
else
|
|
|
|
sk->sk_state = BT_CONNECTED;
|
|
|
|
|
|
|
|
/* Wake up parent */
|
|
|
|
parent->sk_data_ready(parent);
|
|
|
|
|
|
|
|
release_sock(parent);
|
2023-11-13 15:38:00 +00:00
|
|
|
sock_put(parent);
|
2020-01-16 23:55:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-09 21:14:41 +00:00
|
|
|
static bool iso_match_sid(struct sock *sk, void *data)
|
|
|
|
{
|
|
|
|
struct hci_ev_le_pa_sync_established *ev = data;
|
|
|
|
|
|
|
|
return ev->sid == iso_pi(sk)->bc_sid;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool iso_match_sync_handle(struct sock *sk, void *data)
|
|
|
|
{
|
|
|
|
struct hci_evt_le_big_info_adv_report *ev = data;
|
|
|
|
|
|
|
|
return le16_to_cpu(ev->sync_handle) == iso_pi(sk)->sync_handle;
|
|
|
|
}
|
|
|
|
|
2023-06-30 09:59:28 +00:00
|
|
|
static bool iso_match_sync_handle_pa_report(struct sock *sk, void *data)
|
|
|
|
{
|
|
|
|
struct hci_ev_le_per_adv_report *ev = data;
|
|
|
|
|
|
|
|
return le16_to_cpu(ev->sync_handle) == iso_pi(sk)->sync_handle;
|
|
|
|
}
|
|
|
|
|
2020-01-16 23:55:57 +00:00
|
|
|
/* ----- ISO interface with lower layer (HCI) ----- */
|
2022-03-09 21:14:41 +00:00
|
|
|
|
2020-01-16 23:55:57 +00:00
|
|
|
int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
|
|
|
|
{
|
2022-03-09 21:14:41 +00:00
|
|
|
struct hci_ev_le_pa_sync_established *ev1;
|
|
|
|
struct hci_evt_le_big_info_adv_report *ev2;
|
2023-06-30 09:59:28 +00:00
|
|
|
struct hci_ev_le_per_adv_report *ev3;
|
2020-01-16 23:55:57 +00:00
|
|
|
struct sock *sk;
|
|
|
|
|
2022-03-09 21:14:41 +00:00
|
|
|
bt_dev_dbg(hdev, "bdaddr %pMR", bdaddr);
|
|
|
|
|
|
|
|
/* Broadcast receiver requires handling of some events before it can
|
|
|
|
* proceed to establishing a BIG sync:
|
|
|
|
*
|
|
|
|
* 1. HCI_EV_LE_PA_SYNC_ESTABLISHED: The socket may specify a specific
|
|
|
|
* SID to listen to and once sync is estabilished its handle needs to
|
|
|
|
* be stored in iso_pi(sk)->sync_handle so it can be matched once
|
|
|
|
* receiving the BIG Info.
|
|
|
|
* 2. HCI_EVT_LE_BIG_INFO_ADV_REPORT: When connect_ind is triggered by a
|
|
|
|
* a BIG Info it attempts to check if there any listening socket with
|
|
|
|
* the same sync_handle and if it does then attempt to create a sync.
|
2023-06-30 09:59:28 +00:00
|
|
|
* 3. HCI_EV_LE_PER_ADV_REPORT: When a PA report is received, it is stored
|
|
|
|
* in iso_pi(sk)->base so it can be passed up to user, in the case of a
|
|
|
|
* broadcast sink.
|
2022-03-09 21:14:41 +00:00
|
|
|
*/
|
|
|
|
ev1 = hci_recv_event_data(hdev, HCI_EV_LE_PA_SYNC_ESTABLISHED);
|
|
|
|
if (ev1) {
|
2024-04-02 11:39:30 +00:00
|
|
|
sk = iso_get_sock(&hdev->bdaddr, bdaddr, BT_LISTEN,
|
|
|
|
iso_match_sid, ev1);
|
2023-08-17 06:44:27 +00:00
|
|
|
if (sk && !ev1->status)
|
2022-03-09 21:14:41 +00:00
|
|
|
iso_pi(sk)->sync_handle = le16_to_cpu(ev1->handle);
|
2020-01-16 23:55:57 +00:00
|
|
|
|
2022-03-09 21:14:41 +00:00
|
|
|
goto done;
|
|
|
|
}
|
2020-01-16 23:55:57 +00:00
|
|
|
|
2022-03-09 21:14:41 +00:00
|
|
|
ev2 = hci_recv_event_data(hdev, HCI_EVT_LE_BIG_INFO_ADV_REPORT);
|
|
|
|
if (ev2) {
|
2024-04-02 11:39:31 +00:00
|
|
|
/* Check if BIGInfo report has already been handled */
|
|
|
|
sk = iso_get_sock(&hdev->bdaddr, bdaddr, BT_CONNECTED,
|
|
|
|
iso_match_sync_handle, ev2);
|
|
|
|
if (sk) {
|
|
|
|
sock_put(sk);
|
|
|
|
sk = NULL;
|
|
|
|
goto done;
|
2023-12-05 16:11:40 +00:00
|
|
|
}
|
|
|
|
|
2024-04-02 11:39:31 +00:00
|
|
|
/* Try to get PA sync socket, if it exists */
|
|
|
|
sk = iso_get_sock(&hdev->bdaddr, bdaddr, BT_CONNECT2,
|
|
|
|
iso_match_sync_handle, ev2);
|
|
|
|
if (!sk)
|
|
|
|
sk = iso_get_sock(&hdev->bdaddr, bdaddr,
|
|
|
|
BT_LISTEN,
|
|
|
|
iso_match_sync_handle,
|
|
|
|
ev2);
|
|
|
|
|
2022-03-09 21:14:41 +00:00
|
|
|
if (sk) {
|
|
|
|
int err;
|
|
|
|
|
2024-04-02 11:39:31 +00:00
|
|
|
iso_pi(sk)->qos.bcast.encryption = ev2->encryption;
|
|
|
|
|
2022-03-09 21:14:41 +00:00
|
|
|
if (ev2->num_bis < iso_pi(sk)->bc_num_bis)
|
|
|
|
iso_pi(sk)->bc_num_bis = ev2->num_bis;
|
|
|
|
|
2023-08-17 06:44:27 +00:00
|
|
|
if (!test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags) &&
|
|
|
|
!test_and_set_bit(BT_SK_BIG_SYNC, &iso_pi(sk)->flags)) {
|
|
|
|
err = hci_le_big_create_sync(hdev, NULL,
|
2023-07-03 07:02:38 +00:00
|
|
|
&iso_pi(sk)->qos,
|
|
|
|
iso_pi(sk)->sync_handle,
|
|
|
|
iso_pi(sk)->bc_num_bis,
|
|
|
|
iso_pi(sk)->bc_bis);
|
|
|
|
if (err) {
|
|
|
|
bt_dev_err(hdev, "hci_le_big_create_sync: %d",
|
|
|
|
err);
|
2023-11-13 15:38:00 +00:00
|
|
|
sock_put(sk);
|
2023-07-03 07:02:38 +00:00
|
|
|
sk = NULL;
|
|
|
|
}
|
2022-03-09 21:14:41 +00:00
|
|
|
}
|
2020-01-16 23:55:57 +00:00
|
|
|
}
|
2024-04-02 11:39:31 +00:00
|
|
|
|
|
|
|
goto done;
|
2023-06-30 09:59:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ev3 = hci_recv_event_data(hdev, HCI_EV_LE_PER_ADV_REPORT);
|
|
|
|
if (ev3) {
|
2024-02-23 13:14:42 +00:00
|
|
|
size_t base_len = 0;
|
2023-09-28 08:02:08 +00:00
|
|
|
u8 *base;
|
2024-02-23 13:14:42 +00:00
|
|
|
struct hci_conn *hcon;
|
2023-09-28 08:02:08 +00:00
|
|
|
|
2024-04-02 11:39:30 +00:00
|
|
|
sk = iso_get_sock(&hdev->bdaddr, bdaddr, BT_LISTEN,
|
|
|
|
iso_match_sync_handle_pa_report, ev3);
|
2024-02-23 13:14:42 +00:00
|
|
|
if (!sk)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
hcon = iso_pi(sk)->conn->hcon;
|
|
|
|
if (!hcon)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
if (ev3->data_status == LE_PA_DATA_TRUNCATED) {
|
|
|
|
/* The controller was unable to retrieve PA data. */
|
|
|
|
memset(hcon->le_per_adv_data, 0,
|
|
|
|
HCI_MAX_PER_AD_TOT_LEN);
|
|
|
|
hcon->le_per_adv_data_len = 0;
|
|
|
|
hcon->le_per_adv_data_offset = 0;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hcon->le_per_adv_data_offset + ev3->length >
|
|
|
|
HCI_MAX_PER_AD_TOT_LEN)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
memcpy(hcon->le_per_adv_data + hcon->le_per_adv_data_offset,
|
|
|
|
ev3->data, ev3->length);
|
|
|
|
hcon->le_per_adv_data_offset += ev3->length;
|
|
|
|
|
|
|
|
if (ev3->data_status == LE_PA_DATA_COMPLETE) {
|
|
|
|
/* All PA data has been received. */
|
|
|
|
hcon->le_per_adv_data_len =
|
|
|
|
hcon->le_per_adv_data_offset;
|
|
|
|
hcon->le_per_adv_data_offset = 0;
|
|
|
|
|
|
|
|
/* Extract BASE */
|
|
|
|
base = eir_get_service_data(hcon->le_per_adv_data,
|
|
|
|
hcon->le_per_adv_data_len,
|
|
|
|
EIR_BAA_SERVICE_UUID,
|
|
|
|
&base_len);
|
|
|
|
|
|
|
|
if (!base || base_len > BASE_MAX_LENGTH)
|
|
|
|
goto done;
|
|
|
|
|
2023-09-28 08:02:08 +00:00
|
|
|
memcpy(iso_pi(sk)->base, base, base_len);
|
|
|
|
iso_pi(sk)->base_len = base_len;
|
2024-02-23 13:14:42 +00:00
|
|
|
} else {
|
|
|
|
/* This is a PA data fragment. Keep pa_data_len set to 0
|
|
|
|
* until all data has been reassembled.
|
|
|
|
*/
|
|
|
|
hcon->le_per_adv_data_len = 0;
|
2023-06-30 09:59:28 +00:00
|
|
|
}
|
2022-03-09 21:14:41 +00:00
|
|
|
} else {
|
2024-04-02 11:39:30 +00:00
|
|
|
sk = iso_get_sock(&hdev->bdaddr, BDADDR_ANY,
|
|
|
|
BT_LISTEN, NULL, NULL);
|
2020-01-16 23:55:57 +00:00
|
|
|
}
|
2022-03-09 21:14:41 +00:00
|
|
|
|
|
|
|
done:
|
|
|
|
if (!sk)
|
2024-03-02 08:30:43 +00:00
|
|
|
return 0;
|
2022-03-09 21:14:41 +00:00
|
|
|
|
|
|
|
if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
|
|
|
|
*flags |= HCI_PROTO_DEFER;
|
2020-01-16 23:55:57 +00:00
|
|
|
|
2023-11-13 15:38:00 +00:00
|
|
|
sock_put(sk);
|
|
|
|
|
2024-03-02 08:30:43 +00:00
|
|
|
return HCI_LM_ACCEPT;
|
2020-01-16 23:55:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void iso_connect_cfm(struct hci_conn *hcon, __u8 status)
|
|
|
|
{
|
|
|
|
if (hcon->type != ISO_LINK) {
|
|
|
|
if (hcon->type != LE_LINK)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Check if LE link has failed */
|
|
|
|
if (status) {
|
2023-04-11 23:02:22 +00:00
|
|
|
struct hci_link *link, *t;
|
|
|
|
|
|
|
|
list_for_each_entry_safe(link, t, &hcon->link_list,
|
|
|
|
list)
|
|
|
|
iso_conn_del(link->conn, bt_to_errno(status));
|
|
|
|
|
2020-01-16 23:55:57 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create CIS if pending */
|
2023-06-01 06:34:46 +00:00
|
|
|
hci_le_create_cis_pending(hcon->hdev);
|
2020-01-16 23:55:57 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
|
|
|
|
|
2023-08-17 06:44:27 +00:00
|
|
|
/* Similar to the success case, if HCI_CONN_BIG_SYNC_FAILED or
|
|
|
|
* HCI_CONN_PA_SYNC_FAILED is set, queue the failed connection
|
|
|
|
* into the accept queue of the listening socket and wake up
|
|
|
|
* userspace, to inform the user about the event.
|
2023-07-03 07:02:38 +00:00
|
|
|
*/
|
2023-08-17 06:44:27 +00:00
|
|
|
if (!status || test_bit(HCI_CONN_BIG_SYNC_FAILED, &hcon->flags) ||
|
|
|
|
test_bit(HCI_CONN_PA_SYNC_FAILED, &hcon->flags)) {
|
2020-01-16 23:55:57 +00:00
|
|
|
struct iso_conn *conn;
|
|
|
|
|
|
|
|
conn = iso_conn_add(hcon);
|
|
|
|
if (conn)
|
|
|
|
iso_conn_ready(conn);
|
|
|
|
} else {
|
|
|
|
iso_conn_del(hcon, bt_to_errno(status));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void iso_disconn_cfm(struct hci_conn *hcon, __u8 reason)
|
|
|
|
{
|
|
|
|
if (hcon->type != ISO_LINK)
|
|
|
|
return;
|
|
|
|
|
|
|
|
BT_DBG("hcon %p reason %d", hcon, reason);
|
|
|
|
|
|
|
|
iso_conn_del(hcon, bt_to_errno(reason));
|
|
|
|
}
|
|
|
|
|
|
|
|
void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
|
|
|
|
{
|
|
|
|
struct iso_conn *conn = hcon->iso_data;
|
|
|
|
__u16 pb, ts, len;
|
|
|
|
|
|
|
|
if (!conn)
|
|
|
|
goto drop;
|
|
|
|
|
|
|
|
pb = hci_iso_flags_pb(flags);
|
|
|
|
ts = hci_iso_flags_ts(flags);
|
|
|
|
|
|
|
|
BT_DBG("conn %p len %d pb 0x%x ts 0x%x", conn, skb->len, pb, ts);
|
|
|
|
|
|
|
|
switch (pb) {
|
|
|
|
case ISO_START:
|
|
|
|
case ISO_SINGLE:
|
|
|
|
if (conn->rx_len) {
|
|
|
|
BT_ERR("Unexpected start frame (len %d)", skb->len);
|
|
|
|
kfree_skb(conn->rx_skb);
|
|
|
|
conn->rx_skb = NULL;
|
|
|
|
conn->rx_len = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ts) {
|
2023-02-20 19:38:24 +00:00
|
|
|
struct hci_iso_ts_data_hdr *hdr;
|
|
|
|
|
2020-01-16 23:55:57 +00:00
|
|
|
/* TODO: add timestamp to the packet? */
|
|
|
|
hdr = skb_pull_data(skb, HCI_ISO_TS_DATA_HDR_SIZE);
|
|
|
|
if (!hdr) {
|
|
|
|
BT_ERR("Frame is too short (len %d)", skb->len);
|
|
|
|
goto drop;
|
|
|
|
}
|
|
|
|
|
2023-02-20 19:38:24 +00:00
|
|
|
len = __le16_to_cpu(hdr->slen);
|
2020-01-16 23:55:57 +00:00
|
|
|
} else {
|
2023-02-20 19:38:24 +00:00
|
|
|
struct hci_iso_data_hdr *hdr;
|
|
|
|
|
2020-01-16 23:55:57 +00:00
|
|
|
hdr = skb_pull_data(skb, HCI_ISO_DATA_HDR_SIZE);
|
|
|
|
if (!hdr) {
|
|
|
|
BT_ERR("Frame is too short (len %d)", skb->len);
|
|
|
|
goto drop;
|
|
|
|
}
|
2023-02-20 19:38:24 +00:00
|
|
|
|
|
|
|
len = __le16_to_cpu(hdr->slen);
|
2020-01-16 23:55:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
flags = hci_iso_data_flags(len);
|
|
|
|
len = hci_iso_data_len(len);
|
|
|
|
|
|
|
|
BT_DBG("Start: total len %d, frag len %d flags 0x%4.4x", len,
|
|
|
|
skb->len, flags);
|
|
|
|
|
|
|
|
if (len == skb->len) {
|
|
|
|
/* Complete frame received */
|
2023-07-13 21:02:37 +00:00
|
|
|
hci_skb_pkt_status(skb) = flags & 0x03;
|
2020-01-16 23:55:57 +00:00
|
|
|
iso_recv_frame(conn, skb);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pb == ISO_SINGLE) {
|
|
|
|
BT_ERR("Frame malformed (len %d, expected len %d)",
|
|
|
|
skb->len, len);
|
|
|
|
goto drop;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (skb->len > len) {
|
|
|
|
BT_ERR("Frame is too long (len %d, expected len %d)",
|
|
|
|
skb->len, len);
|
|
|
|
goto drop;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocate skb for the complete frame (with header) */
|
|
|
|
conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
|
|
|
|
if (!conn->rx_skb)
|
|
|
|
goto drop;
|
|
|
|
|
2023-07-13 21:02:37 +00:00
|
|
|
hci_skb_pkt_status(conn->rx_skb) = flags & 0x03;
|
2020-01-16 23:55:57 +00:00
|
|
|
skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
|
|
|
|
skb->len);
|
|
|
|
conn->rx_len = len - skb->len;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ISO_CONT:
|
|
|
|
BT_DBG("Cont: frag len %d (expecting %d)", skb->len,
|
|
|
|
conn->rx_len);
|
|
|
|
|
|
|
|
if (!conn->rx_len) {
|
|
|
|
BT_ERR("Unexpected continuation frame (len %d)",
|
|
|
|
skb->len);
|
|
|
|
goto drop;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (skb->len > conn->rx_len) {
|
|
|
|
BT_ERR("Fragment is too long (len %d, expected %d)",
|
|
|
|
skb->len, conn->rx_len);
|
|
|
|
kfree_skb(conn->rx_skb);
|
|
|
|
conn->rx_skb = NULL;
|
|
|
|
conn->rx_len = 0;
|
|
|
|
goto drop;
|
|
|
|
}
|
|
|
|
|
|
|
|
skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
|
|
|
|
skb->len);
|
|
|
|
conn->rx_len -= skb->len;
|
|
|
|
return;
|
|
|
|
|
|
|
|
case ISO_END:
|
|
|
|
skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
|
|
|
|
skb->len);
|
|
|
|
conn->rx_len -= skb->len;
|
|
|
|
|
|
|
|
if (!conn->rx_len) {
|
|
|
|
struct sk_buff *rx_skb = conn->rx_skb;
|
|
|
|
|
|
|
|
/* Complete frame received. iso_recv_frame
|
|
|
|
* takes ownership of the skb so set the global
|
|
|
|
* rx_skb pointer to NULL first.
|
|
|
|
*/
|
|
|
|
conn->rx_skb = NULL;
|
|
|
|
iso_recv_frame(conn, rx_skb);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
drop:
|
|
|
|
kfree_skb(skb);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct hci_cb iso_cb = {
|
|
|
|
.name = "ISO",
|
|
|
|
.connect_cfm = iso_connect_cfm,
|
|
|
|
.disconn_cfm = iso_disconn_cfm,
|
|
|
|
};
|
|
|
|
|
|
|
|
static int iso_debugfs_show(struct seq_file *f, void *p)
|
|
|
|
{
|
|
|
|
struct sock *sk;
|
|
|
|
|
|
|
|
read_lock(&iso_sk_list.lock);
|
|
|
|
|
|
|
|
sk_for_each(sk, &iso_sk_list.head) {
|
|
|
|
seq_printf(f, "%pMR %pMR %d\n", &iso_pi(sk)->src,
|
|
|
|
&iso_pi(sk)->dst, sk->sk_state);
|
|
|
|
}
|
|
|
|
|
|
|
|
read_unlock(&iso_sk_list.lock);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFINE_SHOW_ATTRIBUTE(iso_debugfs);
|
|
|
|
|
|
|
|
static struct dentry *iso_debugfs;
|
|
|
|
|
|
|
|
static const struct proto_ops iso_sock_ops = {
|
|
|
|
.family = PF_BLUETOOTH,
|
|
|
|
.owner = THIS_MODULE,
|
|
|
|
.release = iso_sock_release,
|
|
|
|
.bind = iso_sock_bind,
|
|
|
|
.connect = iso_sock_connect,
|
|
|
|
.listen = iso_sock_listen,
|
|
|
|
.accept = iso_sock_accept,
|
|
|
|
.getname = iso_sock_getname,
|
|
|
|
.sendmsg = iso_sock_sendmsg,
|
|
|
|
.recvmsg = iso_sock_recvmsg,
|
|
|
|
.poll = bt_sock_poll,
|
|
|
|
.ioctl = bt_sock_ioctl,
|
|
|
|
.mmap = sock_no_mmap,
|
|
|
|
.socketpair = sock_no_socketpair,
|
|
|
|
.shutdown = iso_sock_shutdown,
|
|
|
|
.setsockopt = iso_sock_setsockopt,
|
|
|
|
.getsockopt = iso_sock_getsockopt
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct net_proto_family iso_sock_family_ops = {
|
|
|
|
.family = PF_BLUETOOTH,
|
|
|
|
.owner = THIS_MODULE,
|
|
|
|
.create = iso_sock_create,
|
|
|
|
};
|
|
|
|
|
|
|
|
static bool iso_inited;
|
|
|
|
|
|
|
|
bool iso_enabled(void)
|
|
|
|
{
|
|
|
|
return iso_inited;
|
|
|
|
}
|
|
|
|
|
|
|
|
int iso_init(void)
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
|
|
|
BUILD_BUG_ON(sizeof(struct sockaddr_iso) > sizeof(struct sockaddr));
|
|
|
|
|
|
|
|
if (iso_inited)
|
|
|
|
return -EALREADY;
|
|
|
|
|
|
|
|
err = proto_register(&iso_proto, 0);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
err = bt_sock_register(BTPROTO_ISO, &iso_sock_family_ops);
|
|
|
|
if (err < 0) {
|
|
|
|
BT_ERR("ISO socket registration failed");
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
err = bt_procfs_init(&init_net, "iso", &iso_sk_list, NULL);
|
|
|
|
if (err < 0) {
|
|
|
|
BT_ERR("Failed to create ISO proc file");
|
|
|
|
bt_sock_unregister(BTPROTO_ISO);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
BT_INFO("ISO socket layer initialized");
|
|
|
|
|
|
|
|
hci_register_cb(&iso_cb);
|
|
|
|
|
|
|
|
if (IS_ERR_OR_NULL(bt_debugfs))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!iso_debugfs) {
|
|
|
|
iso_debugfs = debugfs_create_file("iso", 0444, bt_debugfs,
|
|
|
|
NULL, &iso_debugfs_fops);
|
|
|
|
}
|
|
|
|
|
|
|
|
iso_inited = true;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
error:
|
|
|
|
proto_unregister(&iso_proto);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
int iso_exit(void)
|
|
|
|
{
|
|
|
|
if (!iso_inited)
|
|
|
|
return -EALREADY;
|
|
|
|
|
|
|
|
bt_procfs_cleanup(&init_net, "iso");
|
|
|
|
|
|
|
|
debugfs_remove(iso_debugfs);
|
|
|
|
iso_debugfs = NULL;
|
|
|
|
|
|
|
|
hci_unregister_cb(&iso_cb);
|
|
|
|
|
|
|
|
bt_sock_unregister(BTPROTO_ISO);
|
|
|
|
|
|
|
|
proto_unregister(&iso_proto);
|
|
|
|
|
|
|
|
iso_inited = false;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|