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

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 47a880a29bd net/sixlowpan: Fix HC06 UDP NHC decompression
47a880a29bd is described below

commit 47a880a29bd49fac81099b44816f1083cd72148d
Author: chao an <[email protected]>
AuthorDate: Thu Oct 22 22:40:57 2026 +0800

    net/sixlowpan: Fix HC06 UDP NHC decompression
    
    The HC06 decompressor accepted LOWPAN_NHC_UDP even when UDP
    support was not enabled.  For subsequent fragments,
    sixlowpan_input() decompresses headers into g_bitbucket, which is
    sized from enabled transport protocols, so reconstructing a UDP header
    can overrun that buffer in non-UDP builds.
    
    Keep UDP NHC handling behind CONFIG_NET_UDP, reject compressed next
    headers otherwise, and check the inline NHC/checksum bytes before
    consuming them.
    
    Signed-off-by: chao an <[email protected]>
---
 net/sixlowpan/sixlowpan_hc06.c | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/net/sixlowpan/sixlowpan_hc06.c b/net/sixlowpan/sixlowpan_hc06.c
index 7da821d2798..04e3ddacc50 100644
--- a/net/sixlowpan/sixlowpan_hc06.c
+++ b/net/sixlowpan/sixlowpan_hc06.c
@@ -1471,13 +1471,15 @@ int sixlowpan_uncompresshdr_hc06(FAR struct 
radio_driver_s *radio,
 
   if ((iphc0 & SIXLOWPAN_IPHC_NH) != 0)
     {
-      FAR struct udp_hdr_s *udp =
-                            (FAR struct udp_hdr_s *)(bptr + IPv6_HDRLEN);
-
       /* The next header is compressed, NHC is following */
 
+      HC06_CHECK(g_hc06ptr, 1, endofframe);
+
+#ifdef CONFIG_NET_UDP
       if ((*g_hc06ptr & SIXLOWPAN_NHC_UDP_MASK) == SIXLOWPAN_NHC_UDP_ID)
         {
+          FAR struct udp_hdr_s *udp =
+                            (FAR struct udp_hdr_s *)(bptr + IPv6_HDRLEN);
           uint8_t checksum_compressed;
 
           ipv6->proto         = IP_PROTO_UDP;
@@ -1570,6 +1572,7 @@ int sixlowpan_uncompresshdr_hc06(FAR struct 
radio_driver_s *radio,
             {
               /* Has_checksum, default */
 
+              HC06_CHECK(g_hc06ptr, 2, endofframe);
               memcpy(&udp->udpchksum, g_hc06ptr, 2);
               g_hc06ptr += 2;
 
@@ -1582,6 +1585,15 @@ int sixlowpan_uncompresshdr_hc06(FAR struct 
radio_driver_s *radio,
 
           g_uncomp_hdrlen += UDP_HDRLEN;
         }
+      else
+        {
+          nwarn("WARNING: Unsupported next header compression\n");
+          return -EPROTONOSUPPORT;
+        }
+#else
+      nwarn("WARNING: Next header compression unsupported\n");
+      return -EPROTONOSUPPORT;
+#endif /* CONFIG_NET_UDP */
     }
 
   g_frame_hdrlen = g_hc06ptr - fptr;
@@ -1604,14 +1616,17 @@ int sixlowpan_uncompresshdr_hc06(FAR struct 
radio_driver_s *radio,
       ipv6->len[1] = (iplen - IPv6_HDRLEN) & 0x00ff;
     }
 
+#ifdef CONFIG_NET_UDP
   /* Length field in UDP header */
 
   if (ipv6->proto == IP_PROTO_UDP)
     {
       FAR struct udp_hdr_s *udp =
                           (FAR struct udp_hdr_s *)(bptr + IPv6_HDRLEN);
+
       memcpy(&udp->udplen, &ipv6->len[0], 2);
     }
+#endif /* CONFIG_NET_UDP */
 
   return OK;
 }

Reply via email to