Skip to content

Commit ad913df

Browse files
committed
Merge tag 'for-net-2024-12-12' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth
Luiz Augusto von Dentz says: ==================== bluetooth pull request for net: - SCO: Fix transparent voice setting - ISO: Locking fixes - hci_core: Fix sleeping function called from invalid context - hci_event: Fix using rcu_read_(un)lock while iterating - btmtk: avoid UAF in btmtk_process_coredump * tag 'for-net-2024-12-12' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth: Bluetooth: btmtk: avoid UAF in btmtk_process_coredump Bluetooth: iso: Fix circular lock in iso_conn_big_sync Bluetooth: iso: Fix circular lock in iso_listen_bis Bluetooth: SCO: Add support for 16 bits transparent voice setting Bluetooth: iso: Fix recursive locking warning Bluetooth: iso: Always release hdev at the end of iso_listen_bis Bluetooth: hci_event: Fix using rcu_read_(un)lock while iterating Bluetooth: hci_core: Fix sleeping function called from invalid context Bluetooth: Improve setsockopt() handling of malformed user input ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 36ff681 + b548f5e commit ad913df

File tree

12 files changed

+215
-154
lines changed

12 files changed

+215
-154
lines changed

drivers/bluetooth/btmtk.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ int btmtk_process_coredump(struct hci_dev *hdev, struct sk_buff *skb)
395395
{
396396
struct btmtk_data *data = hci_get_priv(hdev);
397397
int err;
398+
bool complete = false;
398399

399400
if (!IS_ENABLED(CONFIG_DEV_COREDUMP)) {
400401
kfree_skb(skb);
@@ -416,19 +417,22 @@ int btmtk_process_coredump(struct hci_dev *hdev, struct sk_buff *skb)
416417
fallthrough;
417418
case HCI_DEVCOREDUMP_ACTIVE:
418419
default:
420+
/* Mediatek coredump data would be more than MTK_COREDUMP_NUM */
421+
if (data->cd_info.cnt >= MTK_COREDUMP_NUM &&
422+
skb->len > MTK_COREDUMP_END_LEN)
423+
if (!memcmp((char *)&skb->data[skb->len - MTK_COREDUMP_END_LEN],
424+
MTK_COREDUMP_END, MTK_COREDUMP_END_LEN - 1))
425+
complete = true;
426+
419427
err = hci_devcd_append(hdev, skb);
420428
if (err < 0)
421429
break;
422430
data->cd_info.cnt++;
423431

424-
/* Mediatek coredump data would be more than MTK_COREDUMP_NUM */
425-
if (data->cd_info.cnt > MTK_COREDUMP_NUM &&
426-
skb->len > MTK_COREDUMP_END_LEN)
427-
if (!memcmp((char *)&skb->data[skb->len - MTK_COREDUMP_END_LEN],
428-
MTK_COREDUMP_END, MTK_COREDUMP_END_LEN - 1)) {
429-
bt_dev_info(hdev, "Mediatek coredump end");
430-
hci_devcd_complete(hdev);
431-
}
432+
if (complete) {
433+
bt_dev_info(hdev, "Mediatek coredump end");
434+
hci_devcd_complete(hdev);
435+
}
432436

433437
break;
434438
}

include/net/bluetooth/bluetooth.h

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ struct bt_voice {
123123

124124
#define BT_VOICE_TRANSPARENT 0x0003
125125
#define BT_VOICE_CVSD_16BIT 0x0060
126+
#define BT_VOICE_TRANSPARENT_16BIT 0x0063
126127

127128
#define BT_SNDMTU 12
128129
#define BT_RCVMTU 13
@@ -590,15 +591,6 @@ static inline struct sk_buff *bt_skb_sendmmsg(struct sock *sk,
590591
return skb;
591592
}
592593

593-
static inline int bt_copy_from_sockptr(void *dst, size_t dst_size,
594-
sockptr_t src, size_t src_size)
595-
{
596-
if (dst_size > src_size)
597-
return -EINVAL;
598-
599-
return copy_from_sockptr(dst, src, dst_size);
600-
}
601-
602594
int bt_to_errno(u16 code);
603595
__u8 bt_status(int err);
604596

include/net/bluetooth/hci_core.h

Lines changed: 70 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -804,7 +804,6 @@ struct hci_conn_params {
804804
extern struct list_head hci_dev_list;
805805
extern struct list_head hci_cb_list;
806806
extern rwlock_t hci_dev_list_lock;
807-
extern struct mutex hci_cb_list_lock;
808807

809808
#define hci_dev_set_flag(hdev, nr) set_bit((nr), (hdev)->dev_flags)
810809
#define hci_dev_clear_flag(hdev, nr) clear_bit((nr), (hdev)->dev_flags)
@@ -2017,68 +2016,103 @@ struct hci_cb {
20172016

20182017
char *name;
20192018

2019+
bool (*match) (struct hci_conn *conn);
20202020
void (*connect_cfm) (struct hci_conn *conn, __u8 status);
20212021
void (*disconn_cfm) (struct hci_conn *conn, __u8 status);
20222022
void (*security_cfm) (struct hci_conn *conn, __u8 status,
2023-
__u8 encrypt);
2023+
__u8 encrypt);
20242024
void (*key_change_cfm) (struct hci_conn *conn, __u8 status);
20252025
void (*role_switch_cfm) (struct hci_conn *conn, __u8 status, __u8 role);
20262026
};
20272027

2028+
static inline void hci_cb_lookup(struct hci_conn *conn, struct list_head *list)
2029+
{
2030+
struct hci_cb *cb, *cpy;
2031+
2032+
rcu_read_lock();
2033+
list_for_each_entry_rcu(cb, &hci_cb_list, list) {
2034+
if (cb->match && cb->match(conn)) {
2035+
cpy = kmalloc(sizeof(*cpy), GFP_ATOMIC);
2036+
if (!cpy)
2037+
break;
2038+
2039+
*cpy = *cb;
2040+
INIT_LIST_HEAD(&cpy->list);
2041+
list_add_rcu(&cpy->list, list);
2042+
}
2043+
}
2044+
rcu_read_unlock();
2045+
}
2046+
20282047
static inline void hci_connect_cfm(struct hci_conn *conn, __u8 status)
20292048
{
2030-
struct hci_cb *cb;
2049+
struct list_head list;
2050+
struct hci_cb *cb, *tmp;
2051+
2052+
INIT_LIST_HEAD(&list);
2053+
hci_cb_lookup(conn, &list);
20312054

2032-
mutex_lock(&hci_cb_list_lock);
2033-
list_for_each_entry(cb, &hci_cb_list, list) {
2055+
list_for_each_entry_safe(cb, tmp, &list, list) {
20342056
if (cb->connect_cfm)
20352057
cb->connect_cfm(conn, status);
2058+
kfree(cb);
20362059
}
2037-
mutex_unlock(&hci_cb_list_lock);
20382060

20392061
if (conn->connect_cfm_cb)
20402062
conn->connect_cfm_cb(conn, status);
20412063
}
20422064

20432065
static inline void hci_disconn_cfm(struct hci_conn *conn, __u8 reason)
20442066
{
2045-
struct hci_cb *cb;
2067+
struct list_head list;
2068+
struct hci_cb *cb, *tmp;
2069+
2070+
INIT_LIST_HEAD(&list);
2071+
hci_cb_lookup(conn, &list);
20462072

2047-
mutex_lock(&hci_cb_list_lock);
2048-
list_for_each_entry(cb, &hci_cb_list, list) {
2073+
list_for_each_entry_safe(cb, tmp, &list, list) {
20492074
if (cb->disconn_cfm)
20502075
cb->disconn_cfm(conn, reason);
2076+
kfree(cb);
20512077
}
2052-
mutex_unlock(&hci_cb_list_lock);
20532078

20542079
if (conn->disconn_cfm_cb)
20552080
conn->disconn_cfm_cb(conn, reason);
20562081
}
20572082

2058-
static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
2083+
static inline void hci_security_cfm(struct hci_conn *conn, __u8 status,
2084+
__u8 encrypt)
20592085
{
2060-
struct hci_cb *cb;
2061-
__u8 encrypt;
2062-
2063-
if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags))
2064-
return;
2086+
struct list_head list;
2087+
struct hci_cb *cb, *tmp;
20652088

2066-
encrypt = test_bit(HCI_CONN_ENCRYPT, &conn->flags) ? 0x01 : 0x00;
2089+
INIT_LIST_HEAD(&list);
2090+
hci_cb_lookup(conn, &list);
20672091

2068-
mutex_lock(&hci_cb_list_lock);
2069-
list_for_each_entry(cb, &hci_cb_list, list) {
2092+
list_for_each_entry_safe(cb, tmp, &list, list) {
20702093
if (cb->security_cfm)
20712094
cb->security_cfm(conn, status, encrypt);
2095+
kfree(cb);
20722096
}
2073-
mutex_unlock(&hci_cb_list_lock);
20742097

20752098
if (conn->security_cfm_cb)
20762099
conn->security_cfm_cb(conn, status);
20772100
}
20782101

2102+
static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
2103+
{
2104+
__u8 encrypt;
2105+
2106+
if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags))
2107+
return;
2108+
2109+
encrypt = test_bit(HCI_CONN_ENCRYPT, &conn->flags) ? 0x01 : 0x00;
2110+
2111+
hci_security_cfm(conn, status, encrypt);
2112+
}
2113+
20792114
static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status)
20802115
{
2081-
struct hci_cb *cb;
20822116
__u8 encrypt;
20832117

20842118
if (conn->state == BT_CONFIG) {
@@ -2105,40 +2139,38 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status)
21052139
conn->sec_level = conn->pending_sec_level;
21062140
}
21072141

2108-
mutex_lock(&hci_cb_list_lock);
2109-
list_for_each_entry(cb, &hci_cb_list, list) {
2110-
if (cb->security_cfm)
2111-
cb->security_cfm(conn, status, encrypt);
2112-
}
2113-
mutex_unlock(&hci_cb_list_lock);
2114-
2115-
if (conn->security_cfm_cb)
2116-
conn->security_cfm_cb(conn, status);
2142+
hci_security_cfm(conn, status, encrypt);
21172143
}
21182144

21192145
static inline void hci_key_change_cfm(struct hci_conn *conn, __u8 status)
21202146
{
2121-
struct hci_cb *cb;
2147+
struct list_head list;
2148+
struct hci_cb *cb, *tmp;
2149+
2150+
INIT_LIST_HEAD(&list);
2151+
hci_cb_lookup(conn, &list);
21222152

2123-
mutex_lock(&hci_cb_list_lock);
2124-
list_for_each_entry(cb, &hci_cb_list, list) {
2153+
list_for_each_entry_safe(cb, tmp, &list, list) {
21252154
if (cb->key_change_cfm)
21262155
cb->key_change_cfm(conn, status);
2156+
kfree(cb);
21272157
}
2128-
mutex_unlock(&hci_cb_list_lock);
21292158
}
21302159

21312160
static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status,
21322161
__u8 role)
21332162
{
2134-
struct hci_cb *cb;
2163+
struct list_head list;
2164+
struct hci_cb *cb, *tmp;
2165+
2166+
INIT_LIST_HEAD(&list);
2167+
hci_cb_lookup(conn, &list);
21352168

2136-
mutex_lock(&hci_cb_list_lock);
2137-
list_for_each_entry(cb, &hci_cb_list, list) {
2169+
list_for_each_entry_safe(cb, tmp, &list, list) {
21382170
if (cb->role_switch_cfm)
21392171
cb->role_switch_cfm(conn, status, role);
2172+
kfree(cb);
21402173
}
2141-
mutex_unlock(&hci_cb_list_lock);
21422174
}
21432175

21442176
static inline bool hci_bdaddr_is_rpa(bdaddr_t *bdaddr, u8 addr_type)

net/bluetooth/hci_core.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ DEFINE_RWLOCK(hci_dev_list_lock);
5757

5858
/* HCI callback list */
5959
LIST_HEAD(hci_cb_list);
60-
DEFINE_MUTEX(hci_cb_list_lock);
6160

6261
/* HCI ID Numbering */
6362
static DEFINE_IDA(hci_index_ida);
@@ -2993,9 +2992,7 @@ int hci_register_cb(struct hci_cb *cb)
29932992
{
29942993
BT_DBG("%p name %s", cb, cb->name);
29952994

2996-
mutex_lock(&hci_cb_list_lock);
2997-
list_add_tail(&cb->list, &hci_cb_list);
2998-
mutex_unlock(&hci_cb_list_lock);
2995+
list_add_tail_rcu(&cb->list, &hci_cb_list);
29992996

30002997
return 0;
30012998
}
@@ -3005,9 +3002,8 @@ int hci_unregister_cb(struct hci_cb *cb)
30053002
{
30063003
BT_DBG("%p name %s", cb, cb->name);
30073004

3008-
mutex_lock(&hci_cb_list_lock);
3009-
list_del(&cb->list);
3010-
mutex_unlock(&hci_cb_list_lock);
3005+
list_del_rcu(&cb->list);
3006+
synchronize_rcu();
30113007

30123008
return 0;
30133009
}

net/bluetooth/hci_event.c

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6870,38 +6870,27 @@ static void hci_le_create_big_complete_evt(struct hci_dev *hdev, void *data,
68706870
return;
68716871

68726872
hci_dev_lock(hdev);
6873-
rcu_read_lock();
68746873

68756874
/* Connect all BISes that are bound to the BIG */
6876-
list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) {
6877-
if (bacmp(&conn->dst, BDADDR_ANY) ||
6878-
conn->type != ISO_LINK ||
6879-
conn->iso_qos.bcast.big != ev->handle)
6875+
while ((conn = hci_conn_hash_lookup_big_state(hdev, ev->handle,
6876+
BT_BOUND))) {
6877+
if (ev->status) {
6878+
hci_connect_cfm(conn, ev->status);
6879+
hci_conn_del(conn);
68806880
continue;
6881+
}
68816882

68826883
if (hci_conn_set_handle(conn,
68836884
__le16_to_cpu(ev->bis_handle[i++])))
68846885
continue;
68856886

6886-
if (!ev->status) {
6887-
conn->state = BT_CONNECTED;
6888-
set_bit(HCI_CONN_BIG_CREATED, &conn->flags);
6889-
rcu_read_unlock();
6890-
hci_debugfs_create_conn(conn);
6891-
hci_conn_add_sysfs(conn);
6892-
hci_iso_setup_path(conn);
6893-
rcu_read_lock();
6894-
continue;
6895-
}
6896-
6897-
hci_connect_cfm(conn, ev->status);
6898-
rcu_read_unlock();
6899-
hci_conn_del(conn);
6900-
rcu_read_lock();
6887+
conn->state = BT_CONNECTED;
6888+
set_bit(HCI_CONN_BIG_CREATED, &conn->flags);
6889+
hci_debugfs_create_conn(conn);
6890+
hci_conn_add_sysfs(conn);
6891+
hci_iso_setup_path(conn);
69016892
}
69026893

6903-
rcu_read_unlock();
6904-
69056894
if (!ev->status && !i)
69066895
/* If no BISes have been connected for the BIG,
69076896
* terminate. This is in case all bound connections

net/bluetooth/hci_sock.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1926,7 +1926,7 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg,
19261926
}
19271927

19281928
static int hci_sock_setsockopt_old(struct socket *sock, int level, int optname,
1929-
sockptr_t optval, unsigned int len)
1929+
sockptr_t optval, unsigned int optlen)
19301930
{
19311931
struct hci_ufilter uf = { .opcode = 0 };
19321932
struct sock *sk = sock->sk;
@@ -1943,7 +1943,7 @@ static int hci_sock_setsockopt_old(struct socket *sock, int level, int optname,
19431943

19441944
switch (optname) {
19451945
case HCI_DATA_DIR:
1946-
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, len);
1946+
err = copy_safe_from_sockptr(&opt, sizeof(opt), optval, optlen);
19471947
if (err)
19481948
break;
19491949

@@ -1954,7 +1954,7 @@ static int hci_sock_setsockopt_old(struct socket *sock, int level, int optname,
19541954
break;
19551955

19561956
case HCI_TIME_STAMP:
1957-
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, len);
1957+
err = copy_safe_from_sockptr(&opt, sizeof(opt), optval, optlen);
19581958
if (err)
19591959
break;
19601960

@@ -1974,7 +1974,7 @@ static int hci_sock_setsockopt_old(struct socket *sock, int level, int optname,
19741974
uf.event_mask[1] = *((u32 *) f->event_mask + 1);
19751975
}
19761976

1977-
err = bt_copy_from_sockptr(&uf, sizeof(uf), optval, len);
1977+
err = copy_safe_from_sockptr(&uf, sizeof(uf), optval, optlen);
19781978
if (err)
19791979
break;
19801980

@@ -2005,7 +2005,7 @@ static int hci_sock_setsockopt_old(struct socket *sock, int level, int optname,
20052005
}
20062006

20072007
static int hci_sock_setsockopt(struct socket *sock, int level, int optname,
2008-
sockptr_t optval, unsigned int len)
2008+
sockptr_t optval, unsigned int optlen)
20092009
{
20102010
struct sock *sk = sock->sk;
20112011
int err = 0;
@@ -2015,7 +2015,7 @@ static int hci_sock_setsockopt(struct socket *sock, int level, int optname,
20152015

20162016
if (level == SOL_HCI)
20172017
return hci_sock_setsockopt_old(sock, level, optname, optval,
2018-
len);
2018+
optlen);
20192019

20202020
if (level != SOL_BLUETOOTH)
20212021
return -ENOPROTOOPT;
@@ -2035,7 +2035,7 @@ static int hci_sock_setsockopt(struct socket *sock, int level, int optname,
20352035
goto done;
20362036
}
20372037

2038-
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, len);
2038+
err = copy_safe_from_sockptr(&opt, sizeof(opt), optval, optlen);
20392039
if (err)
20402040
break;
20412041

0 commit comments

Comments
 (0)