Skip to content

Commit 14bd22d

Browse files
cvinayaknashif
authored andcommitted
Bluetooth: controller: Fix race in create connection cancel
Fix race conditional when create connection cancel is called and actually a connection did get setup while initiator is being stopped. Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
1 parent d72a107 commit 14bd22d

File tree

4 files changed

+27
-3
lines changed

4 files changed

+27
-3
lines changed

subsys/bluetooth/controller/ll_sw/lll_conn.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ struct lll_conn {
5959
union {
6060
struct {
6161
uint8_t initiated:1;
62+
uint8_t cancelled:1;
6263
} master;
6364
#if defined(CONFIG_BT_PERIPHERAL)
6465
struct {

subsys/bluetooth/controller/ll_sw/lll_scan.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ struct lll_scan {
1212
* check ull_conn_setup how it access the connection LLL
1313
* context.
1414
*/
15-
struct lll_conn *conn;
15+
struct lll_conn *volatile conn;
1616

1717
uint8_t adv_addr[BDADDR_SIZE];
1818
uint32_t conn_win_offset_us;

subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,9 @@ static int prepare_cb(struct lll_prepare_param *p)
140140
/* Check if stopped (on connection establishment race between LLL and
141141
* ULL.
142142
*/
143-
if (unlikely(lll->conn && lll->conn->master.initiated)) {
143+
if (unlikely(lll->conn &&
144+
(lll->conn->master.initiated ||
145+
lll->conn->master.cancelled))) {
144146
int err;
145147

146148
err = lll_hfclock_off();
@@ -779,7 +781,7 @@ static inline int isr_rx_pdu(struct lll_scan *lll, struct pdu_adv *pdu_adv_rx,
779781
if (0) {
780782
#if defined(CONFIG_BT_CENTRAL)
781783
/* Initiator */
782-
} else if (lll->conn &&
784+
} else if (lll->conn && !lll->conn->master.cancelled &&
783785
isr_scan_init_check(lll, pdu_adv_rx, rl_idx)) {
784786
struct lll_conn *lll_conn;
785787
struct node_rx_ftr *ftr;

subsys/bluetooth/controller/ll_sw/ull_master.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ uint8_t ll_create_connection(uint16_t scan_interval, uint16_t scan_window,
211211
conn_lll->data_chan_use = 0;
212212
conn_lll->role = 0;
213213
conn_lll->master.initiated = 0;
214+
conn_lll->master.cancelled = 0;
214215
/* FIXME: END: Move to ULL? */
215216
#if defined(CONFIG_BT_CTLR_CONN_META)
216217
memset(&conn_lll->conn_meta, 0, sizeof(conn_lll->conn_meta));
@@ -384,8 +385,28 @@ uint8_t ll_connect_disable(void **rx)
384385
return BT_HCI_ERR_CMD_DISALLOWED;
385386
}
386387

388+
/* Check if initiator active */
387389
conn_lll = scan->lll.conn;
388390
if (!conn_lll) {
391+
/* Scanning not associated with initiation of a connection or
392+
* connection setup already complete (was set to NULL in
393+
* ull_master_setup), but HCI event not processed by host.
394+
*/
395+
return BT_HCI_ERR_CMD_DISALLOWED;
396+
}
397+
398+
/* Indicate to LLL that a cancellation is requested */
399+
conn_lll->master.cancelled = 1U;
400+
cpu_dmb();
401+
402+
/* Check if connection was established under race condition, i.e.
403+
* before the cancelled flag was set.
404+
*/
405+
conn_lll = scan->lll.conn;
406+
if (!conn_lll) {
407+
/* Connection setup completed on race condition with cancelled
408+
* flag, before it was set.
409+
*/
389410
return BT_HCI_ERR_CMD_DISALLOWED;
390411
}
391412

0 commit comments

Comments
 (0)