diff --git a/subsys/bluetooth/controller/hci/hci.c b/subsys/bluetooth/controller/hci/hci.c index 1453a62317d..ac7ccc7ea61 100644 --- a/subsys/bluetooth/controller/hci/hci.c +++ b/subsys/bluetooth/controller/hci/hci.c @@ -3728,16 +3728,23 @@ static void le_cis_request(struct pdu_data *pdu_data, { struct bt_hci_evt_le_cis_req *sep; struct node_rx_conn_iso_req *req; + void *node; if (!(event_mask & BT_EVT_MASK_LE_META_EVENT) || !(le_event_mask & BT_EVT_MASK_LE_CIS_REQ)) { return; } - req = (void *)pdu_data; - sep = meta_evt(buf, BT_HCI_EVT_LE_CIS_REQ, sizeof(*sep)); sep->acl_handle = sys_cpu_to_le16(node_rx->hdr.handle); + + /* Check for pdu field being aligned before accessing CIS established + * event. + */ + node = pdu_data; + LL_ASSERT(IS_PTR_ALIGNED(node, struct node_rx_conn_iso_estab)); + + req = node; sep->cis_handle = sys_cpu_to_le16(req->cis_handle); sep->cig_id = req->cig_id; sep->cis_id = req->cis_id; @@ -3757,6 +3764,7 @@ static void le_cis_established(struct pdu_data *pdu_data, struct ll_conn_iso_stream *cis; struct ll_conn_iso_group *cig; bool is_central; + void *node; if (!(event_mask & BT_EVT_MASK_LE_META_EVENT) || !(le_event_mask & BT_EVT_MASK_LE_CIS_ESTABLISHED)) { @@ -3769,10 +3777,16 @@ static void le_cis_established(struct pdu_data *pdu_data, is_central = cig->lll.role == BT_CONN_ROLE_CENTRAL; lll_cis_c = is_central ? &lll_cis->tx : &lll_cis->rx; lll_cis_p = is_central ? &lll_cis->rx : &lll_cis->tx; - est = (void *)pdu_data; sep = meta_evt(buf, BT_HCI_EVT_LE_CIS_ESTABLISHED, sizeof(*sep)); + /* Check for pdu field being aligned before accessing CIS established + * event. + */ + node = pdu_data; + LL_ASSERT(IS_PTR_ALIGNED(node, struct node_rx_conn_iso_estab)); + + est = node; sep->status = est->status; sep->conn_handle = sys_cpu_to_le16(est->cis_handle); sys_put_le24(cig->sync_delay, sep->cig_sync_delay); @@ -6063,6 +6077,7 @@ static void le_per_adv_sync_established(struct pdu_data *pdu_data, struct bt_hci_evt_le_per_adv_sync_established *sep; struct ll_scan_set *scan; struct node_rx_sync *se; + void *node; if (!(event_mask & BT_EVT_MASK_LE_META_EVENT) || !(le_event_mask & BT_EVT_MASK_LE_PER_ADV_SYNC_ESTABLISHED)) { @@ -6072,7 +6087,13 @@ static void le_per_adv_sync_established(struct pdu_data *pdu_data, sep = meta_evt(buf, BT_HCI_EVT_LE_PER_ADV_SYNC_ESTABLISHED, sizeof(*sep)); - se = (void *)pdu_data; + /* Check for pdu field being aligned before accessing sync established + * event. + */ + node = pdu_data; + LL_ASSERT(IS_PTR_ALIGNED(node, struct node_rx_sync)); + + se = node; sep->status = se->status; if (se->status == BT_HCI_ERR_OP_CANCELLED_BY_HOST) { @@ -6403,6 +6424,7 @@ static void le_big_sync_established(struct pdu_data *pdu, struct node_rx_sync_iso *se; struct lll_sync_iso *lll; size_t evt_size; + void *node; if (!(event_mask & BT_EVT_MASK_LE_META_EVENT) || !(le_event_mask & BT_EVT_MASK_LE_BIG_SYNC_ESTABLISHED)) { @@ -6417,7 +6439,13 @@ static void le_big_sync_established(struct pdu_data *pdu, sep = meta_evt(buf, BT_HCI_EVT_LE_BIG_SYNC_ESTABLISHED, evt_size); sep->big_handle = sys_cpu_to_le16(node_rx->hdr.handle); - se = (void *)pdu; + /* Check for pdu field being aligned before accessing ISO sync + * established event. + */ + node = pdu; + LL_ASSERT(IS_PTR_ALIGNED(node, struct node_rx_sync_iso)); + + se = node; sep->status = se->status; if (sep->status) { return; @@ -6612,9 +6640,19 @@ static void le_scan_req_received(struct pdu_data *pdu_data, static void le_conn_complete(struct pdu_data *pdu_data, uint16_t handle, struct net_buf *buf) { - struct node_rx_cc *cc = (void *)pdu_data; struct bt_hci_evt_le_conn_complete *lecc; - uint8_t status = cc->status; + struct node_rx_cc *cc; + uint8_t status; + void *node; + + /* Check for pdu field being aligned before accessing connection + * complete event. + */ + node = pdu_data; + LL_ASSERT(IS_PTR_ALIGNED(node, struct node_rx_cc)); + + cc = node; + status = cc->status; #if defined(CONFIG_BT_CTLR_PRIVACY) if (!status) { @@ -6731,6 +6769,7 @@ static void le_conn_update_complete(struct pdu_data *pdu_data, uint16_t handle, { struct bt_hci_evt_le_conn_update_complete *sep; struct node_rx_cu *cu; + void *node; if (!(event_mask & BT_EVT_MASK_LE_META_EVENT) || !(le_event_mask & BT_EVT_MASK_LE_CONN_UPDATE_COMPLETE)) { @@ -6739,7 +6778,13 @@ static void le_conn_update_complete(struct pdu_data *pdu_data, uint16_t handle, sep = meta_evt(buf, BT_HCI_EVT_LE_CONN_UPDATE_COMPLETE, sizeof(*sep)); - cu = (void *)pdu_data; + /* Check for pdu field being aligned before accessing connection + * update complete event. + */ + node = pdu_data; + LL_ASSERT(IS_PTR_ALIGNED(node, struct node_rx_cu)); + + cu = node; sep->status = cu->status; sep->handle = sys_cpu_to_le16(handle); sep->interval = sys_cpu_to_le16(cu->interval); diff --git a/subsys/bluetooth/controller/ll_sw/ull_central.c b/subsys/bluetooth/controller/ll_sw/ull_central.c index 15d0e81c510..dd34919395b 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_central.c +++ b/subsys/bluetooth/controller/ll_sw/ull_central.c @@ -807,6 +807,7 @@ void ull_central_setup(struct node_rx_hdr *rx, struct node_rx_ftr *ftr, struct ll_conn *conn; memq_link_t *link; uint8_t chan_sel; + void *node; /* Get reference to Tx-ed CONNECT_IND PDU */ pdu_tx = (void *)((struct node_rx_pdu *)rx)->pdu; @@ -820,8 +821,14 @@ void ull_central_setup(struct node_rx_hdr *rx, struct node_rx_ftr *ftr, /* This is the chan sel bit from the received adv pdu */ chan_sel = pdu_tx->chan_sel; + /* Check for pdu field being aligned before populating connection + * complete event. + */ + node = pdu_tx; + LL_ASSERT(IS_PTR_ALIGNED(node, struct node_rx_cc)); + /* Populate the fields required for connection complete event */ - cc = (void *)pdu_tx; + cc = node; cc->status = 0U; cc->role = 0U; diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn.c b/subsys/bluetooth/controller/ll_sw/ull_conn.c index 8f91ad8d658..050fcd4fc4d 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn.c @@ -2852,6 +2852,7 @@ static inline void event_conn_upd_init(struct ll_conn *conn, { uint32_t retval; + void *win_offs; /* calculate window offset that places the connection in the * next available slot after existing centrals. @@ -2870,8 +2871,12 @@ static inline void event_conn_upd_init(struct ll_conn *conn, } #endif /* CONFIG_BT_CTLR_XTAL_ADVANCED */ - conn->llcp.conn_upd.pdu_win_offset = (uint16_t *) - &pdu_ctrl_tx->llctrl.conn_update_ind.win_offset; + win_offs = &pdu_ctrl_tx->llctrl.conn_update_ind.win_offset; + /* No need to check alignment here since the pointer that gets + * stored is never derreferenced directly, only passed + * to memcpy(). + */ + conn->llcp.conn_upd.pdu_win_offset = win_offs; mfy_sched_offset->fp = fp_mfy_select_or_use; mfy_sched_offset->param = (void *)conn; @@ -3737,6 +3742,7 @@ static inline void event_conn_param_req(struct ll_conn *conn, static struct mayfly s_mfy_sched_offset = {0, 0, &s_link, NULL, ull_sched_mfy_free_win_offset_calc}; uint32_t retval; + void *win_offs; conn->llcp_conn_param.ticks_ref = ticks_at_expire; @@ -3752,7 +3758,12 @@ static inline void event_conn_param_req(struct ll_conn *conn, } #endif /* CONFIG_BT_CTLR_XTAL_ADVANCED */ - conn->llcp_conn_param.pdu_win_offset0 = (uint16_t *)&p->offset0; + win_offs = &p->offset0; + /* No need to check alignment here since the pointer that gets + * stored is never derreferenced directly, only passed + * to memcpy(). + */ + conn->llcp_conn_param.pdu_win_offset0 = win_offs; s_mfy_sched_offset.param = (void *)conn; @@ -5177,6 +5188,7 @@ static inline int reject_ind_conn_upd_recv(struct ll_conn *conn, struct pdu_data_llctrl_reject_ext_ind *rej_ext_ind; struct node_rx_cu *cu; struct lll_conn *lll; + void *node; /* Unsupported remote feature */ lll = &conn->lll; @@ -5228,8 +5240,14 @@ static inline int reject_ind_conn_upd_recv(struct ll_conn *conn, /* generate conn update complete event with error code */ rx->hdr.type = NODE_RX_TYPE_CONN_UPDATE; + /* check for pdu field being aligned before populating + * connection update complete event. + */ + node = pdu_rx; + LL_ASSERT(IS_PTR_ALIGNED(node, struct node_rx_cu)); + /* prepare connection update complete structure */ - cu = (void *)pdu_rx; + cu = node; cu->status = rej_ext_ind->error_code; cu->interval = lll->interval; cu->latency = lll->latency; @@ -6006,6 +6024,7 @@ static uint8_t cis_req_recv(struct ll_conn *conn, memq_link_t *link, struct node_rx_conn_iso_req *conn_iso_req; uint16_t cis_handle; uint8_t err; + void *node; conn->llcp_cis.cig_id = req->cig_id; conn->llcp_cis.framed = req->framed; @@ -6028,7 +6047,13 @@ static uint8_t cis_req_recv(struct ll_conn *conn, memq_link_t *link, (*rx)->hdr.type = NODE_RX_TYPE_CIS_REQUEST; - conn_iso_req = (void *)pdu; + /* check for pdu field being aligned before populating ISO + * connection request event. + */ + node = pdu; + LL_ASSERT(IS_PTR_ALIGNED(node, struct node_rx_conn_iso_req)); + + conn_iso_req = node; conn_iso_req->cig_id = req->cig_id; conn_iso_req->cis_id = req->cis_id; conn_iso_req->cis_handle = sys_le16_to_cpu(cis_handle); @@ -7014,6 +7039,7 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx, PDU_DATA_LLCTRL_TYPE_CONN_PARAM_REQ)) { struct lll_conn *lll = &conn->lll; struct node_rx_cu *cu; + void *node; /* Mark CPR as unsupported */ conn->llcp_conn_param.disabled = 1U; @@ -7061,8 +7087,14 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx, /* generate conn upd complete event with error code */ (*rx)->hdr.type = NODE_RX_TYPE_CONN_UPDATE; + /* check for pdu field being aligned before populating + * connection update complete event. + */ + node = pdu_rx; + LL_ASSERT(IS_PTR_ALIGNED(node, struct node_rx_cu)); + /* prepare connection update complete structure */ - cu = (void *)pdu_rx; + cu = node; cu->status = BT_HCI_ERR_UNSUPP_REMOTE_FEATURE; cu->interval = lll->interval; cu->latency = lll->latency; diff --git a/subsys/bluetooth/controller/ll_sw/ull_peripheral.c b/subsys/bluetooth/controller/ll_sw/ull_peripheral.c index 9c3e84a5be0..33daeb74430 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_peripheral.c +++ b/subsys/bluetooth/controller/ll_sw/ull_peripheral.c @@ -89,6 +89,7 @@ void ull_periph_setup(struct node_rx_hdr *rx, struct node_rx_ftr *ftr, memq_link_t *link; uint16_t timeout; uint8_t chan_sel; + void *node; adv = ((struct lll_adv *)ftr->param)->hdr.parent; conn = lll->hdr.parent; @@ -232,7 +233,14 @@ void ull_periph_setup(struct node_rx_hdr *rx, struct node_rx_ftr *ftr, chan_sel = pdu_adv->chan_sel; } - cc = (void *)pdu_adv; + /* Check for pdu field being aligned before populating connection + * complete event. + */ + node = pdu_adv; + LL_ASSERT(IS_PTR_ALIGNED(node, struct node_rx_cc)); + + /* Populate the fields required for connection complete event */ + cc = node; cc->status = 0U; cc->role = 1U;