Skip to content

Commit 1876479

Browse files
author
Paolo Abeni
committed
Merge tag 'for-net-2024-10-23' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth
Luiz Augusto von Dentz says: ==================== bluetooth pull request for net: - hci_core: Disable works on hci_unregister_dev - SCO: Fix UAF on sco_sock_timeout - ISO: Fix UAF on iso_sock_timeout * tag 'for-net-2024-10-23' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth: Bluetooth: ISO: Fix UAF on iso_sock_timeout Bluetooth: SCO: Fix UAF on sco_sock_timeout Bluetooth: hci_core: Disable works on hci_unregister_dev ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
2 parents 1e424d0 + 246b435 commit 1876479

File tree

6 files changed

+71
-24
lines changed

6 files changed

+71
-24
lines changed

include/net/bluetooth/bluetooth.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,7 @@ int bt_sock_register(int proto, const struct net_proto_family *ops);
403403
void bt_sock_unregister(int proto);
404404
void bt_sock_link(struct bt_sock_list *l, struct sock *s);
405405
void bt_sock_unlink(struct bt_sock_list *l, struct sock *s);
406+
bool bt_sock_linked(struct bt_sock_list *l, struct sock *s);
406407
struct sock *bt_sock_alloc(struct net *net, struct socket *sock,
407408
struct proto *prot, int proto, gfp_t prio, int kern);
408409
int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,

net/bluetooth/af_bluetooth.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,28 @@ void bt_sock_unlink(struct bt_sock_list *l, struct sock *sk)
185185
}
186186
EXPORT_SYMBOL(bt_sock_unlink);
187187

188+
bool bt_sock_linked(struct bt_sock_list *l, struct sock *s)
189+
{
190+
struct sock *sk;
191+
192+
if (!l || !s)
193+
return false;
194+
195+
read_lock(&l->lock);
196+
197+
sk_for_each(sk, &l->head) {
198+
if (s == sk) {
199+
read_unlock(&l->lock);
200+
return true;
201+
}
202+
}
203+
204+
read_unlock(&l->lock);
205+
206+
return false;
207+
}
208+
EXPORT_SYMBOL(bt_sock_linked);
209+
188210
void bt_accept_enqueue(struct sock *parent, struct sock *sk, bool bh)
189211
{
190212
const struct cred *old_cred;

net/bluetooth/hci_core.c

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1644,12 +1644,12 @@ void hci_adv_instances_clear(struct hci_dev *hdev)
16441644
struct adv_info *adv_instance, *n;
16451645

16461646
if (hdev->adv_instance_timeout) {
1647-
cancel_delayed_work(&hdev->adv_instance_expire);
1647+
disable_delayed_work(&hdev->adv_instance_expire);
16481648
hdev->adv_instance_timeout = 0;
16491649
}
16501650

16511651
list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list) {
1652-
cancel_delayed_work_sync(&adv_instance->rpa_expired_cb);
1652+
disable_delayed_work_sync(&adv_instance->rpa_expired_cb);
16531653
list_del(&adv_instance->list);
16541654
kfree(adv_instance);
16551655
}
@@ -2685,11 +2685,11 @@ void hci_unregister_dev(struct hci_dev *hdev)
26852685
list_del(&hdev->list);
26862686
write_unlock(&hci_dev_list_lock);
26872687

2688-
cancel_work_sync(&hdev->rx_work);
2689-
cancel_work_sync(&hdev->cmd_work);
2690-
cancel_work_sync(&hdev->tx_work);
2691-
cancel_work_sync(&hdev->power_on);
2692-
cancel_work_sync(&hdev->error_reset);
2688+
disable_work_sync(&hdev->rx_work);
2689+
disable_work_sync(&hdev->cmd_work);
2690+
disable_work_sync(&hdev->tx_work);
2691+
disable_work_sync(&hdev->power_on);
2692+
disable_work_sync(&hdev->error_reset);
26932693

26942694
hci_cmd_sync_clear(hdev);
26952695

@@ -2796,8 +2796,14 @@ static void hci_cancel_cmd_sync(struct hci_dev *hdev, int err)
27962796
{
27972797
bt_dev_dbg(hdev, "err 0x%2.2x", err);
27982798

2799-
cancel_delayed_work_sync(&hdev->cmd_timer);
2800-
cancel_delayed_work_sync(&hdev->ncmd_timer);
2799+
if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
2800+
disable_delayed_work_sync(&hdev->cmd_timer);
2801+
disable_delayed_work_sync(&hdev->ncmd_timer);
2802+
} else {
2803+
cancel_delayed_work_sync(&hdev->cmd_timer);
2804+
cancel_delayed_work_sync(&hdev->ncmd_timer);
2805+
}
2806+
28012807
atomic_set(&hdev->cmd_cnt, 1);
28022808

28032809
hci_cmd_sync_cancel_sync(hdev, err);

net/bluetooth/hci_sync.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5131,9 +5131,15 @@ int hci_dev_close_sync(struct hci_dev *hdev)
51315131

51325132
bt_dev_dbg(hdev, "");
51335133

5134-
cancel_delayed_work(&hdev->power_off);
5135-
cancel_delayed_work(&hdev->ncmd_timer);
5136-
cancel_delayed_work(&hdev->le_scan_disable);
5134+
if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
5135+
disable_delayed_work(&hdev->power_off);
5136+
disable_delayed_work(&hdev->ncmd_timer);
5137+
disable_delayed_work(&hdev->le_scan_disable);
5138+
} else {
5139+
cancel_delayed_work(&hdev->power_off);
5140+
cancel_delayed_work(&hdev->ncmd_timer);
5141+
cancel_delayed_work(&hdev->le_scan_disable);
5142+
}
51375143

51385144
hci_cmd_sync_cancel_sync(hdev, ENODEV);
51395145

net/bluetooth/iso.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,16 +93,24 @@ static struct sock *iso_get_sock(bdaddr_t *src, bdaddr_t *dst,
9393
#define ISO_CONN_TIMEOUT (HZ * 40)
9494
#define ISO_DISCONN_TIMEOUT (HZ * 2)
9595

96+
static struct sock *iso_sock_hold(struct iso_conn *conn)
97+
{
98+
if (!conn || !bt_sock_linked(&iso_sk_list, conn->sk))
99+
return NULL;
100+
101+
sock_hold(conn->sk);
102+
103+
return conn->sk;
104+
}
105+
96106
static void iso_sock_timeout(struct work_struct *work)
97107
{
98108
struct iso_conn *conn = container_of(work, struct iso_conn,
99109
timeout_work.work);
100110
struct sock *sk;
101111

102112
iso_conn_lock(conn);
103-
sk = conn->sk;
104-
if (sk)
105-
sock_hold(sk);
113+
sk = iso_sock_hold(conn);
106114
iso_conn_unlock(conn);
107115

108116
if (!sk)
@@ -209,9 +217,7 @@ static void iso_conn_del(struct hci_conn *hcon, int err)
209217

210218
/* Kill socket */
211219
iso_conn_lock(conn);
212-
sk = conn->sk;
213-
if (sk)
214-
sock_hold(sk);
220+
sk = iso_sock_hold(conn);
215221
iso_conn_unlock(conn);
216222

217223
if (sk) {

net/bluetooth/sco.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,16 @@ struct sco_pinfo {
7676
#define SCO_CONN_TIMEOUT (HZ * 40)
7777
#define SCO_DISCONN_TIMEOUT (HZ * 2)
7878

79+
static struct sock *sco_sock_hold(struct sco_conn *conn)
80+
{
81+
if (!conn || !bt_sock_linked(&sco_sk_list, conn->sk))
82+
return NULL;
83+
84+
sock_hold(conn->sk);
85+
86+
return conn->sk;
87+
}
88+
7989
static void sco_sock_timeout(struct work_struct *work)
8090
{
8191
struct sco_conn *conn = container_of(work, struct sco_conn,
@@ -87,9 +97,7 @@ static void sco_sock_timeout(struct work_struct *work)
8797
sco_conn_unlock(conn);
8898
return;
8999
}
90-
sk = conn->sk;
91-
if (sk)
92-
sock_hold(sk);
100+
sk = sco_sock_hold(conn);
93101
sco_conn_unlock(conn);
94102

95103
if (!sk)
@@ -194,9 +202,7 @@ static void sco_conn_del(struct hci_conn *hcon, int err)
194202

195203
/* Kill socket */
196204
sco_conn_lock(conn);
197-
sk = conn->sk;
198-
if (sk)
199-
sock_hold(sk);
205+
sk = sco_sock_hold(conn);
200206
sco_conn_unlock(conn);
201207

202208
if (sk) {

0 commit comments

Comments
 (0)