Skip to content

Commit c45074d

Browse files
Vudentzholtmann
authored andcommitted
Bluetooth: Fix not generating RPA when required
Code was checking if random_addr and hdev->rpa match without first checking if the RPA has not been set (BDADDR_ANY), furthermore it was clearing HCI_RPA_EXPIRED before the command completes and the RPA is actually programmed which in case of failure would leave the expired RPA still set. Since advertising instance have a similar problem the clearing of HCI_RPA_EXPIRED has been moved to hci_event.c after checking the random address is in fact the hdev->rap and then proceed to set the expire timeout. Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
1 parent 1027931 commit c45074d

File tree

3 files changed

+61
-56
lines changed

3 files changed

+61
-56
lines changed

include/net/bluetooth/hci_core.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1413,6 +1413,10 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
14131413
!hci_dev_test_flag(dev, HCI_AUTO_OFF))
14141414
#define bredr_sc_enabled(dev) (lmp_sc_capable(dev) && \
14151415
hci_dev_test_flag(dev, HCI_SC_ENABLED))
1416+
#define rpa_valid(dev) (bacmp(&dev->rpa, BDADDR_ANY) && \
1417+
!hci_dev_test_flag(dev, HCI_RPA_EXPIRED))
1418+
#define adv_rpa_valid(adv) (bacmp(&adv->random_addr, BDADDR_ANY) && \
1419+
!adv->rpa_expired)
14161420

14171421
#define scan_1m(dev) (((dev)->le_tx_def_phys & HCI_LE_SET_PHY_1M) || \
14181422
((dev)->le_rx_def_phys & HCI_LE_SET_PHY_1M))

net/bluetooth/hci_event.c

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
#define ZERO_KEY "\x00\x00\x00\x00\x00\x00\x00\x00" \
4141
"\x00\x00\x00\x00\x00\x00\x00\x00"
4242

43+
#define secs_to_jiffies(_secs) msecs_to_jiffies((_secs) * 1000)
44+
4345
/* Handle HCI Event packets */
4446

4547
static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb,
@@ -1171,6 +1173,12 @@ static void hci_cc_le_set_random_addr(struct hci_dev *hdev, struct sk_buff *skb)
11711173

11721174
bacpy(&hdev->random_addr, sent);
11731175

1176+
if (!bacmp(&hdev->rpa, sent)) {
1177+
hci_dev_clear_flag(hdev, HCI_RPA_EXPIRED);
1178+
queue_delayed_work(hdev->workqueue, &hdev->rpa_expired,
1179+
secs_to_jiffies(hdev->rpa_timeout));
1180+
}
1181+
11741182
hci_dev_unlock(hdev);
11751183
}
11761184

@@ -1201,24 +1209,30 @@ static void hci_cc_le_set_adv_set_random_addr(struct hci_dev *hdev,
12011209
{
12021210
__u8 status = *((__u8 *) skb->data);
12031211
struct hci_cp_le_set_adv_set_rand_addr *cp;
1204-
struct adv_info *adv_instance;
1212+
struct adv_info *adv;
12051213

12061214
if (status)
12071215
return;
12081216

12091217
cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_SET_RAND_ADDR);
1210-
if (!cp)
1218+
/* Update only in case the adv instance since handle 0x00 shall be using
1219+
* HCI_OP_LE_SET_RANDOM_ADDR since that allows both extended and
1220+
* non-extended adverting.
1221+
*/
1222+
if (!cp || !cp->handle)
12111223
return;
12121224

12131225
hci_dev_lock(hdev);
12141226

1215-
if (!cp->handle) {
1216-
/* Store in hdev for instance 0 (Set adv and Directed advs) */
1217-
bacpy(&hdev->random_addr, &cp->bdaddr);
1218-
} else {
1219-
adv_instance = hci_find_adv_instance(hdev, cp->handle);
1220-
if (adv_instance)
1221-
bacpy(&adv_instance->random_addr, &cp->bdaddr);
1227+
adv = hci_find_adv_instance(hdev, cp->handle);
1228+
if (adv) {
1229+
bacpy(&adv->random_addr, &cp->bdaddr);
1230+
if (!bacmp(&hdev->rpa, &cp->bdaddr)) {
1231+
adv->rpa_expired = false;
1232+
queue_delayed_work(hdev->workqueue,
1233+
&adv->rpa_expired_cb,
1234+
secs_to_jiffies(hdev->rpa_timeout));
1235+
}
12221236
}
12231237

12241238
hci_dev_unlock(hdev);

net/bluetooth/hci_request.c

Lines changed: 34 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2072,8 +2072,6 @@ int hci_get_random_address(struct hci_dev *hdev, bool require_privacy,
20722072
* current RPA has expired then generate a new one.
20732073
*/
20742074
if (use_rpa) {
2075-
int to;
2076-
20772075
/* If Controller supports LL Privacy use own address type is
20782076
* 0x03
20792077
*/
@@ -2084,14 +2082,10 @@ int hci_get_random_address(struct hci_dev *hdev, bool require_privacy,
20842082
*own_addr_type = ADDR_LE_DEV_RANDOM;
20852083

20862084
if (adv_instance) {
2087-
if (!adv_instance->rpa_expired &&
2088-
!bacmp(&adv_instance->random_addr, &hdev->rpa))
2085+
if (adv_rpa_valid(adv_instance))
20892086
return 0;
2090-
2091-
adv_instance->rpa_expired = false;
20922087
} else {
2093-
if (!hci_dev_test_and_clear_flag(hdev, HCI_RPA_EXPIRED) &&
2094-
!bacmp(&hdev->random_addr, &hdev->rpa))
2088+
if (rpa_valid(hdev))
20952089
return 0;
20962090
}
20972091

@@ -2103,14 +2097,6 @@ int hci_get_random_address(struct hci_dev *hdev, bool require_privacy,
21032097

21042098
bacpy(rand_addr, &hdev->rpa);
21052099

2106-
to = msecs_to_jiffies(hdev->rpa_timeout * 1000);
2107-
if (adv_instance)
2108-
queue_delayed_work(hdev->workqueue,
2109-
&adv_instance->rpa_expired_cb, to);
2110-
else
2111-
queue_delayed_work(hdev->workqueue,
2112-
&hdev->rpa_expired, to);
2113-
21142100
return 0;
21152101
}
21162102

@@ -2153,6 +2139,30 @@ void __hci_req_clear_ext_adv_sets(struct hci_request *req)
21532139
hci_req_add(req, HCI_OP_LE_CLEAR_ADV_SETS, 0, NULL);
21542140
}
21552141

2142+
static void set_random_addr(struct hci_request *req, bdaddr_t *rpa)
2143+
{
2144+
struct hci_dev *hdev = req->hdev;
2145+
2146+
/* If we're advertising or initiating an LE connection we can't
2147+
* go ahead and change the random address at this time. This is
2148+
* because the eventual initiator address used for the
2149+
* subsequently created connection will be undefined (some
2150+
* controllers use the new address and others the one we had
2151+
* when the operation started).
2152+
*
2153+
* In this kind of scenario skip the update and let the random
2154+
* address be updated at the next cycle.
2155+
*/
2156+
if (hci_dev_test_flag(hdev, HCI_LE_ADV) ||
2157+
hci_lookup_le_connect(hdev)) {
2158+
bt_dev_dbg(hdev, "Deferring random address update");
2159+
hci_dev_set_flag(hdev, HCI_RPA_EXPIRED);
2160+
return;
2161+
}
2162+
2163+
hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6, rpa);
2164+
}
2165+
21562166
int __hci_req_setup_ext_adv_instance(struct hci_request *req, u8 instance)
21572167
{
21582168
struct hci_cp_le_set_ext_adv_params cp;
@@ -2255,6 +2265,13 @@ int __hci_req_setup_ext_adv_instance(struct hci_request *req, u8 instance)
22552265
} else {
22562266
if (!bacmp(&random_addr, &hdev->random_addr))
22572267
return 0;
2268+
/* Instance 0x00 doesn't have an adv_info, instead it
2269+
* uses hdev->random_addr to track its address so
2270+
* whenever it needs to be updated this also set the
2271+
* random address since hdev->random_addr is shared with
2272+
* scan state machine.
2273+
*/
2274+
set_random_addr(req, &random_addr);
22582275
}
22592276

22602277
memset(&cp, 0, sizeof(cp));
@@ -2512,30 +2529,6 @@ void hci_req_clear_adv_instance(struct hci_dev *hdev, struct sock *sk,
25122529
false);
25132530
}
25142531

2515-
static void set_random_addr(struct hci_request *req, bdaddr_t *rpa)
2516-
{
2517-
struct hci_dev *hdev = req->hdev;
2518-
2519-
/* If we're advertising or initiating an LE connection we can't
2520-
* go ahead and change the random address at this time. This is
2521-
* because the eventual initiator address used for the
2522-
* subsequently created connection will be undefined (some
2523-
* controllers use the new address and others the one we had
2524-
* when the operation started).
2525-
*
2526-
* In this kind of scenario skip the update and let the random
2527-
* address be updated at the next cycle.
2528-
*/
2529-
if (hci_dev_test_flag(hdev, HCI_LE_ADV) ||
2530-
hci_lookup_le_connect(hdev)) {
2531-
bt_dev_dbg(hdev, "Deferring random address update");
2532-
hci_dev_set_flag(hdev, HCI_RPA_EXPIRED);
2533-
return;
2534-
}
2535-
2536-
hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6, rpa);
2537-
}
2538-
25392532
int hci_update_random_address(struct hci_request *req, bool require_privacy,
25402533
bool use_rpa, u8 *own_addr_type)
25412534
{
@@ -2547,8 +2540,6 @@ int hci_update_random_address(struct hci_request *req, bool require_privacy,
25472540
* the current RPA in use, then generate a new one.
25482541
*/
25492542
if (use_rpa) {
2550-
int to;
2551-
25522543
/* If Controller supports LL Privacy use own address type is
25532544
* 0x03
25542545
*/
@@ -2558,8 +2549,7 @@ int hci_update_random_address(struct hci_request *req, bool require_privacy,
25582549
else
25592550
*own_addr_type = ADDR_LE_DEV_RANDOM;
25602551

2561-
if (!hci_dev_test_and_clear_flag(hdev, HCI_RPA_EXPIRED) &&
2562-
!bacmp(&hdev->random_addr, &hdev->rpa))
2552+
if (rpa_valid(hdev))
25632553
return 0;
25642554

25652555
err = smp_generate_rpa(hdev, hdev->irk, &hdev->rpa);
@@ -2570,9 +2560,6 @@ int hci_update_random_address(struct hci_request *req, bool require_privacy,
25702560

25712561
set_random_addr(req, &hdev->rpa);
25722562

2573-
to = msecs_to_jiffies(hdev->rpa_timeout * 1000);
2574-
queue_delayed_work(hdev->workqueue, &hdev->rpa_expired, to);
2575-
25762563
return 0;
25772564
}
25782565

0 commit comments

Comments
 (0)