From fa05c606745716b7847b99f8c9ea94607d4d474b Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Sun, 4 Sep 2022 16:06:50 +0200 Subject: [PATCH] net: l2: ieee802154: Fix logic with address types When validating a MAC command, the "src" and "dst" fields may be set to: - IEEE802154_ADDR_MODE_SHORT (0x2) - IEEE802154_ADDR_MODE_EXTENDED (0x3) - IEEE802154_ADDR_MODE_SHORT | IEEE802154_ADDR_MODE_EXTENDED (0x3) Hence when the mode check happens, any times the mode is set to SHORT the check will fail while in practice it was meant to be valid because the check is: if (src_mode == src || dst_mod == dst) Use bitfields when relevant so that when checking capabilities we use the bit offsets rather than the plain numbers. Signed-off-by: Miquel Raynal --- subsys/net/l2/ieee802154/ieee802154_frame.c | 45 +++++++++++---------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/subsys/net/l2/ieee802154/ieee802154_frame.c b/subsys/net/l2/ieee802154/ieee802154_frame.c index 07c13f19b3f..b21fee39143 100644 --- a/subsys/net/l2/ieee802154/ieee802154_frame.c +++ b/subsys/net/l2/ieee802154/ieee802154_frame.c @@ -234,15 +234,16 @@ static inline bool validate_beacon(struct ieee802154_mpdu *mpdu, uint8_t *buf, u } static inline bool validate_mac_command_cfi_to_mhr(struct ieee802154_mhr *mhr, uint8_t ar, - uint8_t comp, uint8_t src, - bool src_pan_brdcst_chk, uint8_t dst, + uint8_t comp, uint8_t src_bf, + bool src_pan_brdcst_chk, uint8_t dst_bf, bool dst_brdcst_chk) { if (mhr->fs->fc.ar != ar || mhr->fs->fc.pan_id_comp != comp) { return false; } - if ((mhr->fs->fc.src_addr_mode != src) || (mhr->fs->fc.dst_addr_mode != dst)) { + if (!(BIT(mhr->fs->fc.src_addr_mode) & src_bf) || + !(BIT(mhr->fs->fc.dst_addr_mode) & dst_bf)) { return false; } @@ -272,7 +273,7 @@ static inline bool validate_mac_command(struct ieee802154_mpdu *mpdu, uint8_t *b bool dst_brdcst_chk = false; uint8_t comp = 0U; uint8_t ar = 0U; - uint8_t src, dst; + uint8_t src_bf, dst_bf; if (*length < len) { return false; @@ -283,9 +284,9 @@ static inline bool validate_mac_command(struct ieee802154_mpdu *mpdu, uint8_t *b return false; case IEEE802154_CFI_ASSOCIATION_REQUEST: len += IEEE802154_CMD_ASSOC_REQ_LENGTH; - src = IEEE802154_ADDR_MODE_EXTENDED; + src_bf = BIT(IEEE802154_ADDR_MODE_EXTENDED); src_pan_brdcst_chk = true; - dst = IEEE802154_ADDR_MODE_SHORT | IEEE802154_ADDR_MODE_EXTENDED; + dst_bf = BIT(IEEE802154_ADDR_MODE_SHORT) | BIT(IEEE802154_ADDR_MODE_EXTENDED); break; case IEEE802154_CFI_ASSOCIATION_RESPONSE: @@ -299,51 +300,52 @@ static inline bool validate_mac_command(struct ieee802154_mpdu *mpdu, uint8_t *b case IEEE802154_CFI_PAN_ID_CONLICT_NOTIFICATION: ar = 1U; comp = 1U; - src = IEEE802154_ADDR_MODE_EXTENDED; - dst = IEEE802154_ADDR_MODE_EXTENDED; + src_bf = BIT(IEEE802154_ADDR_MODE_EXTENDED); + dst_bf = BIT(IEEE802154_ADDR_MODE_EXTENDED); break; case IEEE802154_CFI_DATA_REQUEST: ar = 1U; - src = IEEE802154_ADDR_MODE_SHORT | IEEE802154_ADDR_MODE_EXTENDED; + src_bf = BIT(IEEE802154_ADDR_MODE_SHORT) | BIT(IEEE802154_ADDR_MODE_EXTENDED); if (mpdu->mhr.fs->fc.dst_addr_mode == IEEE802154_ADDR_MODE_NONE) { - dst = IEEE802154_ADDR_MODE_NONE; + dst_bf = BIT(IEEE802154_ADDR_MODE_NONE); } else { comp = 1U; - dst = IEEE802154_ADDR_MODE_SHORT | IEEE802154_ADDR_MODE_EXTENDED; + dst_bf = BIT(IEEE802154_ADDR_MODE_SHORT) | + BIT(IEEE802154_ADDR_MODE_EXTENDED); } break; case IEEE802154_CFI_ORPHAN_NOTIFICATION: comp = 1U; - src = IEEE802154_ADDR_MODE_EXTENDED; - dst = IEEE802154_ADDR_MODE_SHORT; + src_bf = BIT(IEEE802154_ADDR_MODE_EXTENDED); + dst_bf = BIT(IEEE802154_ADDR_MODE_SHORT); break; case IEEE802154_CFI_BEACON_REQUEST: - src = IEEE802154_ADDR_MODE_NONE; - dst = IEEE802154_ADDR_MODE_SHORT; + src_bf = BIT(IEEE802154_ADDR_MODE_NONE); + dst_bf = BIT(IEEE802154_ADDR_MODE_SHORT); dst_brdcst_chk = true; break; case IEEE802154_CFI_COORDINATOR_REALIGNEMENT: len += IEEE802154_CMD_COORD_REALIGN_LENGTH; - src = IEEE802154_ADDR_MODE_EXTENDED; + src_bf = BIT(IEEE802154_ADDR_MODE_EXTENDED); if (mpdu->mhr.fs->fc.dst_addr_mode == IEEE802154_ADDR_MODE_SHORT) { - dst = IEEE802154_ADDR_MODE_SHORT; + dst_bf = BIT(IEEE802154_ADDR_MODE_SHORT); dst_brdcst_chk = true; } else { - dst = IEEE802154_ADDR_MODE_EXTENDED; + dst_bf = BIT(IEEE802154_ADDR_MODE_EXTENDED); } break; case IEEE802154_CFI_GTS_REQUEST: len += IEEE802154_GTS_REQUEST_LENGTH; ar = 1U; - src = IEEE802154_ADDR_MODE_SHORT; - dst = IEEE802154_ADDR_MODE_NONE; + src_bf = BIT(IEEE802154_ADDR_MODE_SHORT); + dst_bf = BIT(IEEE802154_ADDR_MODE_NONE); break; default: @@ -354,7 +356,8 @@ static inline bool validate_mac_command(struct ieee802154_mpdu *mpdu, uint8_t *b return false; } - if (!validate_mac_command_cfi_to_mhr(&mpdu->mhr, ar, comp, src, src_pan_brdcst_chk, dst, + if (!validate_mac_command_cfi_to_mhr(&mpdu->mhr, ar, comp, src_bf, + src_pan_brdcst_chk, dst_bf, dst_brdcst_chk)) { return false; }