You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ja...@apache.org on 2026/10/26 12:38:52 UTC

(mynewt-core) 06/07: net/lora: Validate received frame size

This is an automated email from the ASF dual-hosted git repository.

sjanc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git

commit 5adab6dad7ce41d88930aff43d12ea8ede55c15f
Author: Szymon Janc <sz...@codecoup.pl>
AuthorDate: Sun Oct 25 21:59:00 2026 +0100

    net/lora: Validate received frame size
    
    Received frame size was not checked before reading MIC from the end
    of the frame. For frames shorter than MIC, bytes before the receive
    buffer were read, and for short join accept frames stale buffer data
    was decrypted and used for MIC calculation. FOpts length was not
    checked against frame size either.
    
    Drop join accept frames with size other than 17 or 33 bytes, data
    frames shorter than 12 bytes and data frames with FOpts not fitting
    in the frame.
    
    Assisted-by: Claude:claude-opus-5-5
---
 net/lora/node/src/mac/LoRaMac.c | 28 +++++++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/net/lora/node/src/mac/LoRaMac.c b/net/lora/node/src/mac/LoRaMac.c
index 866173a81..6ed73f171 100644
--- a/net/lora/node/src/mac/LoRaMac.c
+++ b/net/lora/node/src/mac/LoRaMac.c
@@ -66,6 +66,17 @@
  */
 #define LORA_MAC_COMMAND_MAX_FOPTS_LENGTH           15
 
+/*!
+ * Join accept frame size without and with CFList (MHDR + payload + MIC)
+ */
+#define LORA_MAC_JOIN_ACCEPT_LEN                    17
+#define LORA_MAC_JOIN_ACCEPT_CFLIST_LEN             33
+
+/*!
+ * Minimum data frame size (MHDR + DevAddr + FCtrl + FCnt + MIC)
+ */
+#define LORA_MAC_DATA_FRAME_MIN_LEN                 12
+
 /*!
  * LoRaMac region.
  */
@@ -585,7 +596,11 @@ lora_mac_join_accept_rxd(uint8_t *payload, uint16_t size)
         return;
     }
 
-    /* XXX: check for too small frame! */
+    if ((size != LORA_MAC_JOIN_ACCEPT_LEN) &&
+        (size != LORA_MAC_JOIN_ACCEPT_CFLIST_LEN)) {
+        STATS_INC(lora_mac_stats, rx_invalid);
+        return;
+    }
 
     LoRaMacJoinDecrypt(payload + 1, size - 1, LoRaMacAppKey,
                        LoRaMacRxPayload + 1);
@@ -982,6 +997,11 @@ lora_mac_process_radio_rx(struct os_event *ev)
                 goto process_rx_done;
             }
 
+            if (size < LORA_MAC_DATA_FRAME_MIN_LEN) {
+                STATS_INC(lora_mac_stats, rx_invalid);
+                goto process_rx_done;
+            }
+
             address = payload[hdrlen++];
             address |= ((uint32_t)payload[hdrlen++] << 8);
             address |= ((uint32_t)payload[hdrlen++] << 16);
@@ -1020,6 +1040,12 @@ lora_mac_process_radio_rx(struct os_event *ev)
 
             appPayloadStartIndex = 8 + fCtrl.Bits.FOptsLen;
 
+            /* FOpts must fit in the frame */
+            if (appPayloadStartIndex > size - LORAMAC_MFR_LEN) {
+                STATS_INC(lora_mac_stats, rx_invalid);
+                goto process_rx_done;
+            }
+
             micRx = ( uint32_t )payload[size - LORAMAC_MFR_LEN];
             micRx |= ( ( uint32_t )payload[size - LORAMAC_MFR_LEN + 1] << 8 );
             micRx |= ( ( uint32_t )payload[size - LORAMAC_MFR_LEN + 2] << 16 );