Bluetooth: controller: Fix scanner memory corruption

Fix a bug where the controller would use the length
field of the advertisement packet before checking
if the length field was valid.
It is possible that the controller has received a packet
that passes CRC check but has a length field that is invalid.
This would cause the scanner to overwrite the scan report
buffer

Fixes: #14741
Signed-off-by: Joakim Andersson <joakim.andersson@nordicsemi.no>
This commit is contained in:
Joakim Andersson 2019-03-21 17:49:29 +01:00 committed by Carles Cufí
commit 66d339a7c9
2 changed files with 23 additions and 11 deletions

View file

@ -1405,10 +1405,12 @@ static inline bool isr_scan_init_check(struct pdu_adv *pdu, u8_t rl_idx)
{
return ((((_radio.scanner.filter_policy & 0x01) != 0) ||
isr_scan_init_adva_check(pdu, rl_idx)) &&
((pdu->type == PDU_ADV_TYPE_ADV_IND) ||
((pdu->type == PDU_ADV_TYPE_DIRECT_IND) &&
(/* allow directed adv packets addressed to this device */
isr_scan_tgta_check(true, pdu, rl_idx, NULL)))));
(((pdu->type == PDU_ADV_TYPE_ADV_IND) &&
(pdu->len <= sizeof(struct pdu_adv_adv_ind))) ||
((pdu->type == PDU_ADV_TYPE_DIRECT_IND) &&
(pdu->len == sizeof(struct pdu_adv_direct_ind)) &&
(/* allow directed adv packets addressed to this device */
isr_scan_tgta_check(true, pdu, rl_idx, NULL)))));
}
static inline u32_t isr_rx_scan(u8_t devmatch_ok, u8_t devmatch_id,
@ -1712,6 +1714,7 @@ static inline u32_t isr_rx_scan(u8_t devmatch_ok, u8_t devmatch_id,
/* Active scanner */
else if (((pdu_adv_rx->type == PDU_ADV_TYPE_ADV_IND) ||
(pdu_adv_rx->type == PDU_ADV_TYPE_SCAN_IND)) &&
(pdu_adv_rx->len <= sizeof(struct pdu_adv_adv_ind)) &&
(_radio.scanner.type != 0) &&
(_radio.scanner.conn == 0)) {
struct pdu_adv *pdu_adv_tx;
@ -1776,18 +1779,21 @@ static inline u32_t isr_rx_scan(u8_t devmatch_ok, u8_t devmatch_id,
return 0;
}
/* Passive scanner or scan responses */
else if (((pdu_adv_rx->type == PDU_ADV_TYPE_ADV_IND) ||
else if (((((pdu_adv_rx->type == PDU_ADV_TYPE_ADV_IND) ||
(pdu_adv_rx->type == PDU_ADV_TYPE_NONCONN_IND) ||
(pdu_adv_rx->type == PDU_ADV_TYPE_SCAN_IND)) &&
(pdu_adv_rx->len <= sizeof(struct pdu_adv_adv_ind))) ||
((pdu_adv_rx->type == PDU_ADV_TYPE_DIRECT_IND) &&
(pdu_adv_rx->len == sizeof(struct pdu_adv_direct_ind)) &&
(/* allow directed adv packets addressed to this device */
isr_scan_tgta_check(false, pdu_adv_rx, rl_idx,
&dir_report))) ||
(pdu_adv_rx->type == PDU_ADV_TYPE_NONCONN_IND) ||
(pdu_adv_rx->type == PDU_ADV_TYPE_SCAN_IND) ||
#if defined(CONFIG_BT_CTLR_ADV_EXT)
((pdu_adv_rx->type == PDU_ADV_TYPE_EXT_IND) &&
(_radio.scanner.phy)) ||
#endif /* CONFIG_BT_CTLR_ADV_EXT */
((pdu_adv_rx->type == PDU_ADV_TYPE_SCAN_RSP) &&
(pdu_adv_rx->len <= sizeof(struct pdu_adv_scan_rsp)) &&
(_radio.scanner.state != 0) &&
isr_scan_rsp_adva_matches(pdu_adv_rx))) &&
(pdu_adv_rx->len != 0) && (!_radio.scanner.conn)) {