From ee2a7156303a5dff2b1f66785046fc1ce14ea929 Mon Sep 17 00:00:00 2001 From: Koen Zandberg Date: Thu, 14 Mar 2019 18:49:39 +0100 Subject: [PATCH 1/4] nrf802154: Validate frame length before dst filter --- cpu/nrf52/radio/nrf802154/nrf802154.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/cpu/nrf52/radio/nrf802154/nrf802154.c b/cpu/nrf52/radio/nrf802154/nrf802154.c index 1fb7b96e6260..d212cad8998d 100644 --- a/cpu/nrf52/radio/nrf802154/nrf802154.c +++ b/cpu/nrf52/radio/nrf802154/nrf802154.c @@ -134,6 +134,22 @@ static void _enable_tx(void) NRF_RADIO->TASKS_START = 1; } +/** + * @brief basic ieee802.15.4 data frame validation + */ +static bool _data_frame_filter(void) +{ + size_t expected_len = ieee802154_get_frame_hdr_len(&rxbuf[1]); + if (!expected_len) { + return false; + } + /* Check CRC, data type, length and destination filter */ + return ((NRF_RADIO->CRCSTATUS == 1) && + ((rxbuf[1] & IEEE802154_FCF_TYPE_MASK) == IEEE802154_FCF_TYPE_DATA) && + (rxbuf[0] > expected_len) && + (netdev_ieee802154_dst_filter(&nrf802154_dev, &rxbuf[1]) == 0)); +} + static void _set_chan(uint16_t chan) { assert((chan >= IEEE802154_CHANNEL_MIN) && (chan <= IEEE802154_CHANNEL_MAX)); @@ -428,9 +444,7 @@ void isr_radio(void) case RADIO_STATE_STATE_RxIdle: /* only process packet if event callback is set and CRC is valid */ if ((nrf802154_dev.netdev.event_callback) && - (NRF_RADIO->CRCSTATUS == 1) && - (netdev_ieee802154_dst_filter(&nrf802154_dev, - &rxbuf[1]) == 0)) { + _data_frame_filter()) { _state |= RX_COMPLETE; } else { From ae120c56f077066d49d69a6545e4902184a29995 Mon Sep 17 00:00:00 2001 From: Koen Zandberg Date: Fri, 15 Mar 2019 11:31:28 +0100 Subject: [PATCH 2/4] fixup! nrf802154: Validate frame length before dst filter --- cpu/nrf52/radio/nrf802154/nrf802154.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cpu/nrf52/radio/nrf802154/nrf802154.c b/cpu/nrf52/radio/nrf802154/nrf802154.c index d212cad8998d..d5465ee8f48e 100644 --- a/cpu/nrf52/radio/nrf802154/nrf802154.c +++ b/cpu/nrf52/radio/nrf802154/nrf802154.c @@ -139,6 +139,10 @@ static void _enable_tx(void) */ static bool _data_frame_filter(void) { + size_t psdu_len = rxbuf[0]; + if (psdu_len < IEEE802154_FCF_LEN) { + return false; + } size_t expected_len = ieee802154_get_frame_hdr_len(&rxbuf[1]); if (!expected_len) { return false; @@ -146,7 +150,7 @@ static bool _data_frame_filter(void) /* Check CRC, data type, length and destination filter */ return ((NRF_RADIO->CRCSTATUS == 1) && ((rxbuf[1] & IEEE802154_FCF_TYPE_MASK) == IEEE802154_FCF_TYPE_DATA) && - (rxbuf[0] > expected_len) && + (psdu_len > expected_len) && (netdev_ieee802154_dst_filter(&nrf802154_dev, &rxbuf[1]) == 0)); } From 38e88d12b6cfaa274641d44059194aaf22871502 Mon Sep 17 00:00:00 2001 From: Koen Zandberg Date: Tue, 28 May 2019 20:54:25 +0200 Subject: [PATCH 3/4] netdev_ieee802154: Add data frame validation filter --- drivers/include/net/netdev/ieee802154.h | 15 +++++++++++++++ drivers/netdev_ieee802154/netdev_ieee802154.c | 17 +++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/drivers/include/net/netdev/ieee802154.h b/drivers/include/net/netdev/ieee802154.h index 70da2a0a5f30..8a7236fa0a8f 100644 --- a/drivers/include/net/netdev/ieee802154.h +++ b/drivers/include/net/netdev/ieee802154.h @@ -192,6 +192,21 @@ int netdev_ieee802154_set(netdev_ieee802154_t *dev, netopt_t opt, const void *va */ int netdev_ieee802154_dst_filter(netdev_ieee802154_t *dev, const uint8_t *mhr); +/** + * @brief This function validates a data frame for minimal length and + * destination fields. It includes @ref netdev_ieee802154_dst_filter for + * validating the destination + * + * @param[in] dev network device descriptor + * @param[in] mhr mac header + * @param[in] frame_len Length of the frame as indicated by the phy + * + * @return 0 when the frame is not filtered + * @return 1 when the frame is filtered + */ +int netdev_ieee802154_data_frame_filter(netdev_ieee802154_t *dev, + const uint8_t *mhr, size_t frame_len); + #ifdef __cplusplus } #endif diff --git a/drivers/netdev_ieee802154/netdev_ieee802154.c b/drivers/netdev_ieee802154/netdev_ieee802154.c index 623604f39027..c4ea29404242 100644 --- a/drivers/netdev_ieee802154/netdev_ieee802154.c +++ b/drivers/netdev_ieee802154/netdev_ieee802154.c @@ -279,4 +279,21 @@ int netdev_ieee802154_dst_filter(netdev_ieee802154_t *dev, const uint8_t *mhr) return 1; } +int netdev_ieee802154_data_frame_filter(netdev_ieee802154_t *dev, + const uint8_t *mhr, size_t frame_len) +{ + if (frame_len < IEEE802154_FCF_LEN) { + return 1; + } + size_t expected_len = ieee802154_get_frame_hdr_len(mhr); + /* Check lenght data type, length and destination filter */ + if ((expected_len != 0) && + (frame_len > expected_len) && + ((*mhr & IEEE802154_FCF_TYPE_MASK) == IEEE802154_FCF_TYPE_DATA) && + (netdev_ieee802154_dst_filter(dev, mhr) == 0)) { + return 0; + } + return 1; +} + /** @} */ From 8e8b011fc06e9284025c6d0aecd5eb18c9c2fe12 Mon Sep 17 00:00:00 2001 From: Koen Zandberg Date: Tue, 28 May 2019 20:54:56 +0200 Subject: [PATCH 4/4] fixup! fixup! nrf802154: Validate frame length before dst filter --- cpu/nrf52/radio/nrf802154/nrf802154.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/cpu/nrf52/radio/nrf802154/nrf802154.c b/cpu/nrf52/radio/nrf802154/nrf802154.c index d5465ee8f48e..425a01dc58d7 100644 --- a/cpu/nrf52/radio/nrf802154/nrf802154.c +++ b/cpu/nrf52/radio/nrf802154/nrf802154.c @@ -139,19 +139,9 @@ static void _enable_tx(void) */ static bool _data_frame_filter(void) { - size_t psdu_len = rxbuf[0]; - if (psdu_len < IEEE802154_FCF_LEN) { - return false; - } - size_t expected_len = ieee802154_get_frame_hdr_len(&rxbuf[1]); - if (!expected_len) { - return false; - } - /* Check CRC, data type, length and destination filter */ + /* Check CRC and data frame filter*/ return ((NRF_RADIO->CRCSTATUS == 1) && - ((rxbuf[1] & IEEE802154_FCF_TYPE_MASK) == IEEE802154_FCF_TYPE_DATA) && - (psdu_len > expected_len) && - (netdev_ieee802154_dst_filter(&nrf802154_dev, &rxbuf[1]) == 0)); + netdev_ieee802154_data_frame_filter(&nrf802154_dev, &rxbuf[1], rxbuf[0])); } static void _set_chan(uint16_t chan)