Skip to content

Commit d5441ac

Browse files
committed
Merge tag 'for-net-2025-06-11' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth
Luiz Augusto von Dentz says: ==================== bluetooth pull request for net: - eir: Fix NULL pointer deference on eir_get_service_data - eir: Fix possible crashes on eir_create_adv_data - hci_sync: Fix broadcast/PA when using an existing instance - ISO: Fix using BT_SK_PA_SYNC to detect BIS sockets - ISO: Fix not using bc_sid as advertisement SID - MGMT: Fix sparse errors * tag 'for-net-2025-06-11' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth: Bluetooth: MGMT: Fix sparse errors Bluetooth: ISO: Fix not using bc_sid as advertisement SID Bluetooth: ISO: Fix using BT_SK_PA_SYNC to detect BIS sockets Bluetooth: eir: Fix possible crashes on eir_create_adv_data Bluetooth: hci_sync: Fix broadcast/PA when using an existing instance Bluetooth: Fix NULL pointer deference on eir_get_service_data ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 43fb2b3 + 7dd38ba commit d5441ac

File tree

9 files changed

+107
-38
lines changed

9 files changed

+107
-38
lines changed

include/net/bluetooth/hci_core.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ struct adv_info {
242242
__u8 mesh;
243243
__u8 instance;
244244
__u8 handle;
245+
__u8 sid;
245246
__u32 flags;
246247
__u16 timeout;
247248
__u16 remaining_time;
@@ -1551,13 +1552,14 @@ struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,
15511552
u16 timeout);
15521553
struct hci_conn *hci_bind_cis(struct hci_dev *hdev, bdaddr_t *dst,
15531554
__u8 dst_type, struct bt_iso_qos *qos);
1554-
struct hci_conn *hci_bind_bis(struct hci_dev *hdev, bdaddr_t *dst,
1555+
struct hci_conn *hci_bind_bis(struct hci_dev *hdev, bdaddr_t *dst, __u8 sid,
15551556
struct bt_iso_qos *qos,
15561557
__u8 base_len, __u8 *base);
15571558
struct hci_conn *hci_connect_cis(struct hci_dev *hdev, bdaddr_t *dst,
15581559
__u8 dst_type, struct bt_iso_qos *qos);
15591560
struct hci_conn *hci_connect_bis(struct hci_dev *hdev, bdaddr_t *dst,
1560-
__u8 dst_type, struct bt_iso_qos *qos,
1561+
__u8 dst_type, __u8 sid,
1562+
struct bt_iso_qos *qos,
15611563
__u8 data_len, __u8 *data);
15621564
struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst,
15631565
__u8 dst_type, __u8 sid, struct bt_iso_qos *qos);
@@ -1832,14 +1834,15 @@ int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
18321834

18331835
void hci_adv_instances_clear(struct hci_dev *hdev);
18341836
struct adv_info *hci_find_adv_instance(struct hci_dev *hdev, u8 instance);
1837+
struct adv_info *hci_find_adv_sid(struct hci_dev *hdev, u8 sid);
18351838
struct adv_info *hci_get_next_instance(struct hci_dev *hdev, u8 instance);
18361839
struct adv_info *hci_add_adv_instance(struct hci_dev *hdev, u8 instance,
18371840
u32 flags, u16 adv_data_len, u8 *adv_data,
18381841
u16 scan_rsp_len, u8 *scan_rsp_data,
18391842
u16 timeout, u16 duration, s8 tx_power,
18401843
u32 min_interval, u32 max_interval,
18411844
u8 mesh_handle);
1842-
struct adv_info *hci_add_per_instance(struct hci_dev *hdev, u8 instance,
1845+
struct adv_info *hci_add_per_instance(struct hci_dev *hdev, u8 instance, u8 sid,
18431846
u32 flags, u8 data_len, u8 *data,
18441847
u32 min_interval, u32 max_interval);
18451848
int hci_set_adv_instance_data(struct hci_dev *hdev, u8 instance,

include/net/bluetooth/hci_sync.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,8 @@ int hci_enable_ext_advertising_sync(struct hci_dev *hdev, u8 instance);
115115
int hci_enable_advertising_sync(struct hci_dev *hdev);
116116
int hci_enable_advertising(struct hci_dev *hdev);
117117

118-
int hci_start_per_adv_sync(struct hci_dev *hdev, u8 instance, u8 data_len,
119-
u8 *data, u32 flags, u16 min_interval,
118+
int hci_start_per_adv_sync(struct hci_dev *hdev, u8 instance, u8 sid,
119+
u8 data_len, u8 *data, u32 flags, u16 min_interval,
120120
u16 max_interval, u16 sync_interval);
121121

122122
int hci_disable_per_advertising_sync(struct hci_dev *hdev, u8 instance);

net/bluetooth/eir.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ u8 eir_create_per_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr)
242242
return ad_len;
243243
}
244244

245-
u8 eir_create_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr)
245+
u8 eir_create_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr, u8 size)
246246
{
247247
struct adv_info *adv = NULL;
248248
u8 ad_len = 0, flags = 0;
@@ -286,7 +286,7 @@ u8 eir_create_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr)
286286
/* If flags would still be empty, then there is no need to
287287
* include the "Flags" AD field".
288288
*/
289-
if (flags) {
289+
if (flags && (ad_len + eir_precalc_len(1) <= size)) {
290290
ptr[0] = 0x02;
291291
ptr[1] = EIR_FLAGS;
292292
ptr[2] = flags;
@@ -316,7 +316,8 @@ u8 eir_create_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr)
316316
}
317317

318318
/* Provide Tx Power only if we can provide a valid value for it */
319-
if (adv_tx_power != HCI_TX_POWER_INVALID) {
319+
if (adv_tx_power != HCI_TX_POWER_INVALID &&
320+
(ad_len + eir_precalc_len(1) <= size)) {
320321
ptr[0] = 0x02;
321322
ptr[1] = EIR_TX_POWER;
322323
ptr[2] = (u8)adv_tx_power;
@@ -366,17 +367,19 @@ u8 eir_create_scan_rsp(struct hci_dev *hdev, u8 instance, u8 *ptr)
366367

367368
void *eir_get_service_data(u8 *eir, size_t eir_len, u16 uuid, size_t *len)
368369
{
369-
while ((eir = eir_get_data(eir, eir_len, EIR_SERVICE_DATA, len))) {
370+
size_t dlen;
371+
372+
while ((eir = eir_get_data(eir, eir_len, EIR_SERVICE_DATA, &dlen))) {
370373
u16 value = get_unaligned_le16(eir);
371374

372375
if (uuid == value) {
373376
if (len)
374-
*len -= 2;
377+
*len = dlen - 2;
375378
return &eir[2];
376379
}
377380

378-
eir += *len;
379-
eir_len -= *len;
381+
eir += dlen;
382+
eir_len -= dlen;
380383
}
381384

382385
return NULL;

net/bluetooth/eir.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
void eir_create(struct hci_dev *hdev, u8 *data);
1111

12-
u8 eir_create_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr);
12+
u8 eir_create_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr, u8 size);
1313
u8 eir_create_scan_rsp(struct hci_dev *hdev, u8 instance, u8 *ptr);
1414
u8 eir_create_per_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr);
1515

net/bluetooth/hci_conn.c

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1501,8 +1501,8 @@ static int qos_set_bis(struct hci_dev *hdev, struct bt_iso_qos *qos)
15011501

15021502
/* This function requires the caller holds hdev->lock */
15031503
static struct hci_conn *hci_add_bis(struct hci_dev *hdev, bdaddr_t *dst,
1504-
struct bt_iso_qos *qos, __u8 base_len,
1505-
__u8 *base)
1504+
__u8 sid, struct bt_iso_qos *qos,
1505+
__u8 base_len, __u8 *base)
15061506
{
15071507
struct hci_conn *conn;
15081508
int err;
@@ -1543,6 +1543,7 @@ static struct hci_conn *hci_add_bis(struct hci_dev *hdev, bdaddr_t *dst,
15431543
return conn;
15441544

15451545
conn->state = BT_CONNECT;
1546+
conn->sid = sid;
15461547

15471548
hci_conn_hold(conn);
15481549
return conn;
@@ -2062,7 +2063,8 @@ static int create_big_sync(struct hci_dev *hdev, void *data)
20622063
if (qos->bcast.bis)
20632064
sync_interval = interval * 4;
20642065

2065-
err = hci_start_per_adv_sync(hdev, qos->bcast.bis, conn->le_per_adv_data_len,
2066+
err = hci_start_per_adv_sync(hdev, qos->bcast.bis, conn->sid,
2067+
conn->le_per_adv_data_len,
20662068
conn->le_per_adv_data, flags, interval,
20672069
interval, sync_interval);
20682070
if (err)
@@ -2134,7 +2136,7 @@ static void create_big_complete(struct hci_dev *hdev, void *data, int err)
21342136
}
21352137
}
21362138

2137-
struct hci_conn *hci_bind_bis(struct hci_dev *hdev, bdaddr_t *dst,
2139+
struct hci_conn *hci_bind_bis(struct hci_dev *hdev, bdaddr_t *dst, __u8 sid,
21382140
struct bt_iso_qos *qos,
21392141
__u8 base_len, __u8 *base)
21402142
{
@@ -2156,7 +2158,7 @@ struct hci_conn *hci_bind_bis(struct hci_dev *hdev, bdaddr_t *dst,
21562158
base, base_len);
21572159

21582160
/* We need hci_conn object using the BDADDR_ANY as dst */
2159-
conn = hci_add_bis(hdev, dst, qos, base_len, eir);
2161+
conn = hci_add_bis(hdev, dst, sid, qos, base_len, eir);
21602162
if (IS_ERR(conn))
21612163
return conn;
21622164

@@ -2207,20 +2209,35 @@ static void bis_mark_per_adv(struct hci_conn *conn, void *data)
22072209
}
22082210

22092211
struct hci_conn *hci_connect_bis(struct hci_dev *hdev, bdaddr_t *dst,
2210-
__u8 dst_type, struct bt_iso_qos *qos,
2212+
__u8 dst_type, __u8 sid,
2213+
struct bt_iso_qos *qos,
22112214
__u8 base_len, __u8 *base)
22122215
{
22132216
struct hci_conn *conn;
22142217
int err;
22152218
struct iso_list_data data;
22162219

2217-
conn = hci_bind_bis(hdev, dst, qos, base_len, base);
2220+
conn = hci_bind_bis(hdev, dst, sid, qos, base_len, base);
22182221
if (IS_ERR(conn))
22192222
return conn;
22202223

22212224
if (conn->state == BT_CONNECTED)
22222225
return conn;
22232226

2227+
/* Check if SID needs to be allocated then search for the first
2228+
* available.
2229+
*/
2230+
if (conn->sid == HCI_SID_INVALID) {
2231+
u8 sid;
2232+
2233+
for (sid = 0; sid <= 0x0f; sid++) {
2234+
if (!hci_find_adv_sid(hdev, sid)) {
2235+
conn->sid = sid;
2236+
break;
2237+
}
2238+
}
2239+
}
2240+
22242241
data.big = qos->bcast.big;
22252242
data.bis = qos->bcast.bis;
22262243

net/bluetooth/hci_core.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1584,6 +1584,19 @@ struct adv_info *hci_find_adv_instance(struct hci_dev *hdev, u8 instance)
15841584
return NULL;
15851585
}
15861586

1587+
/* This function requires the caller holds hdev->lock */
1588+
struct adv_info *hci_find_adv_sid(struct hci_dev *hdev, u8 sid)
1589+
{
1590+
struct adv_info *adv;
1591+
1592+
list_for_each_entry(adv, &hdev->adv_instances, list) {
1593+
if (adv->sid == sid)
1594+
return adv;
1595+
}
1596+
1597+
return NULL;
1598+
}
1599+
15871600
/* This function requires the caller holds hdev->lock */
15881601
struct adv_info *hci_get_next_instance(struct hci_dev *hdev, u8 instance)
15891602
{
@@ -1736,7 +1749,7 @@ struct adv_info *hci_add_adv_instance(struct hci_dev *hdev, u8 instance,
17361749
}
17371750

17381751
/* This function requires the caller holds hdev->lock */
1739-
struct adv_info *hci_add_per_instance(struct hci_dev *hdev, u8 instance,
1752+
struct adv_info *hci_add_per_instance(struct hci_dev *hdev, u8 instance, u8 sid,
17401753
u32 flags, u8 data_len, u8 *data,
17411754
u32 min_interval, u32 max_interval)
17421755
{
@@ -1748,6 +1761,7 @@ struct adv_info *hci_add_per_instance(struct hci_dev *hdev, u8 instance,
17481761
if (IS_ERR(adv))
17491762
return adv;
17501763

1764+
adv->sid = sid;
17511765
adv->periodic = true;
17521766
adv->per_adv_data_len = data_len;
17531767

net/bluetooth/hci_sync.c

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1261,10 +1261,12 @@ int hci_setup_ext_adv_instance_sync(struct hci_dev *hdev, u8 instance)
12611261
hci_cpu_to_le24(adv->min_interval, cp.min_interval);
12621262
hci_cpu_to_le24(adv->max_interval, cp.max_interval);
12631263
cp.tx_power = adv->tx_power;
1264+
cp.sid = adv->sid;
12641265
} else {
12651266
hci_cpu_to_le24(hdev->le_adv_min_interval, cp.min_interval);
12661267
hci_cpu_to_le24(hdev->le_adv_max_interval, cp.max_interval);
12671268
cp.tx_power = HCI_ADV_TX_POWER_NO_PREFERENCE;
1269+
cp.sid = 0x00;
12681270
}
12691271

12701272
secondary_adv = (flags & MGMT_ADV_FLAG_SEC_MASK);
@@ -1559,7 +1561,8 @@ static int hci_enable_per_advertising_sync(struct hci_dev *hdev, u8 instance)
15591561
static int hci_adv_bcast_annoucement(struct hci_dev *hdev, struct adv_info *adv)
15601562
{
15611563
u8 bid[3];
1562-
u8 ad[4 + 3];
1564+
u8 ad[HCI_MAX_EXT_AD_LENGTH];
1565+
u8 len;
15631566

15641567
/* Skip if NULL adv as instance 0x00 is used for general purpose
15651568
* advertising so it cannot used for the likes of Broadcast Announcement
@@ -1585,14 +1588,16 @@ static int hci_adv_bcast_annoucement(struct hci_dev *hdev, struct adv_info *adv)
15851588

15861589
/* Generate Broadcast ID */
15871590
get_random_bytes(bid, sizeof(bid));
1588-
eir_append_service_data(ad, 0, 0x1852, bid, sizeof(bid));
1589-
hci_set_adv_instance_data(hdev, adv->instance, sizeof(ad), ad, 0, NULL);
1591+
len = eir_append_service_data(ad, 0, 0x1852, bid, sizeof(bid));
1592+
memcpy(ad + len, adv->adv_data, adv->adv_data_len);
1593+
hci_set_adv_instance_data(hdev, adv->instance, len + adv->adv_data_len,
1594+
ad, 0, NULL);
15901595

15911596
return hci_update_adv_data_sync(hdev, adv->instance);
15921597
}
15931598

1594-
int hci_start_per_adv_sync(struct hci_dev *hdev, u8 instance, u8 data_len,
1595-
u8 *data, u32 flags, u16 min_interval,
1599+
int hci_start_per_adv_sync(struct hci_dev *hdev, u8 instance, u8 sid,
1600+
u8 data_len, u8 *data, u32 flags, u16 min_interval,
15961601
u16 max_interval, u16 sync_interval)
15971602
{
15981603
struct adv_info *adv = NULL;
@@ -1603,9 +1608,28 @@ int hci_start_per_adv_sync(struct hci_dev *hdev, u8 instance, u8 data_len,
16031608

16041609
if (instance) {
16051610
adv = hci_find_adv_instance(hdev, instance);
1606-
/* Create an instance if that could not be found */
1607-
if (!adv) {
1608-
adv = hci_add_per_instance(hdev, instance, flags,
1611+
if (adv) {
1612+
if (sid != HCI_SID_INVALID && adv->sid != sid) {
1613+
/* If the SID don't match attempt to find by
1614+
* SID.
1615+
*/
1616+
adv = hci_find_adv_sid(hdev, sid);
1617+
if (!adv) {
1618+
bt_dev_err(hdev,
1619+
"Unable to find adv_info");
1620+
return -EINVAL;
1621+
}
1622+
}
1623+
1624+
/* Turn it into periodic advertising */
1625+
adv->periodic = true;
1626+
adv->per_adv_data_len = data_len;
1627+
if (data)
1628+
memcpy(adv->per_adv_data, data, data_len);
1629+
adv->flags = flags;
1630+
} else if (!adv) {
1631+
/* Create an instance if that could not be found */
1632+
adv = hci_add_per_instance(hdev, instance, sid, flags,
16091633
data_len, data,
16101634
sync_interval,
16111635
sync_interval);
@@ -1812,7 +1836,8 @@ static int hci_set_ext_adv_data_sync(struct hci_dev *hdev, u8 instance)
18121836
return 0;
18131837
}
18141838

1815-
len = eir_create_adv_data(hdev, instance, pdu->data);
1839+
len = eir_create_adv_data(hdev, instance, pdu->data,
1840+
HCI_MAX_EXT_AD_LENGTH);
18161841

18171842
pdu->length = len;
18181843
pdu->handle = adv ? adv->handle : instance;
@@ -1843,7 +1868,7 @@ static int hci_set_adv_data_sync(struct hci_dev *hdev, u8 instance)
18431868

18441869
memset(&cp, 0, sizeof(cp));
18451870

1846-
len = eir_create_adv_data(hdev, instance, cp.data);
1871+
len = eir_create_adv_data(hdev, instance, cp.data, sizeof(cp.data));
18471872

18481873
/* There's nothing to do if the data hasn't changed */
18491874
if (hdev->adv_data_len == len &&

net/bluetooth/iso.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ static int iso_connect_bis(struct sock *sk)
336336
struct hci_dev *hdev;
337337
int err;
338338

339-
BT_DBG("%pMR", &iso_pi(sk)->src);
339+
BT_DBG("%pMR (SID 0x%2.2x)", &iso_pi(sk)->src, iso_pi(sk)->bc_sid);
340340

341341
hdev = hci_get_route(&iso_pi(sk)->dst, &iso_pi(sk)->src,
342342
iso_pi(sk)->src_type);
@@ -365,7 +365,7 @@ static int iso_connect_bis(struct sock *sk)
365365

366366
/* Just bind if DEFER_SETUP has been set */
367367
if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
368-
hcon = hci_bind_bis(hdev, &iso_pi(sk)->dst,
368+
hcon = hci_bind_bis(hdev, &iso_pi(sk)->dst, iso_pi(sk)->bc_sid,
369369
&iso_pi(sk)->qos, iso_pi(sk)->base_len,
370370
iso_pi(sk)->base);
371371
if (IS_ERR(hcon)) {
@@ -375,12 +375,16 @@ static int iso_connect_bis(struct sock *sk)
375375
} else {
376376
hcon = hci_connect_bis(hdev, &iso_pi(sk)->dst,
377377
le_addr_type(iso_pi(sk)->dst_type),
378-
&iso_pi(sk)->qos, iso_pi(sk)->base_len,
379-
iso_pi(sk)->base);
378+
iso_pi(sk)->bc_sid, &iso_pi(sk)->qos,
379+
iso_pi(sk)->base_len, iso_pi(sk)->base);
380380
if (IS_ERR(hcon)) {
381381
err = PTR_ERR(hcon);
382382
goto unlock;
383383
}
384+
385+
/* Update SID if it was not set */
386+
if (iso_pi(sk)->bc_sid == HCI_SID_INVALID)
387+
iso_pi(sk)->bc_sid = hcon->sid;
384388
}
385389

386390
conn = iso_conn_add(hcon);
@@ -1337,10 +1341,13 @@ static int iso_sock_getname(struct socket *sock, struct sockaddr *addr,
13371341
addr->sa_family = AF_BLUETOOTH;
13381342

13391343
if (peer) {
1344+
struct hci_conn *hcon = iso_pi(sk)->conn ?
1345+
iso_pi(sk)->conn->hcon : NULL;
1346+
13401347
bacpy(&sa->iso_bdaddr, &iso_pi(sk)->dst);
13411348
sa->iso_bdaddr_type = iso_pi(sk)->dst_type;
13421349

1343-
if (test_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags)) {
1350+
if (hcon && hcon->type == BIS_LINK) {
13441351
sa->iso_bc->bc_sid = iso_pi(sk)->bc_sid;
13451352
sa->iso_bc->bc_num_bis = iso_pi(sk)->bc_num_bis;
13461353
memcpy(sa->iso_bc->bc_bis, iso_pi(sk)->bc_bis,

net/bluetooth/mgmt.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5102,11 +5102,11 @@ static void mgmt_adv_monitor_added(struct sock *sk, struct hci_dev *hdev,
51025102
}
51035103

51045104
static void mgmt_adv_monitor_removed(struct sock *sk, struct hci_dev *hdev,
5105-
u16 handle)
5105+
__le16 handle)
51065106
{
51075107
struct mgmt_ev_adv_monitor_removed ev;
51085108

5109-
ev.monitor_handle = cpu_to_le16(handle);
5109+
ev.monitor_handle = handle;
51105110

51115111
mgmt_event(MGMT_EV_ADV_MONITOR_REMOVED, hdev, &ev, sizeof(ev), sk);
51125112
}

0 commit comments

Comments
 (0)