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

commit faa5c75f1196205e8dc89c495904a412093d542f
Author: Alan Carvalho de Assis <[email protected]>
AuthorDate: Sun May 3 15:37:06 2026 -0300

    net/sixlowpan: Check if g_frame_hdrlen + IPv6_HDRLEN <= iob->io_len
    
    This commit checks if the incoming 6LoWPAN frame header len + the
    IPv6_HDRLEN will fit inside the b->io_len.
    
    Signed-off-by: Alan C. Assis <[email protected]>
---
 net/sixlowpan/sixlowpan_input.c | 66 ++++++++++++++++++++++++++++++++++-------
 1 file changed, 55 insertions(+), 11 deletions(-)

diff --git a/net/sixlowpan/sixlowpan_input.c b/net/sixlowpan/sixlowpan_input.c
index 80108dc2d3a..402587c1093 100644
--- a/net/sixlowpan/sixlowpan_input.c
+++ b/net/sixlowpan/sixlowpan_input.c
@@ -141,30 +141,41 @@ static uint8_t g_bitbucket[UNCOMP_MAXHDR];
  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  *
  * Input Parameters:
+ *   iob   - Pointer to the iob struct
  *   fptr  - Pointer to the beginning of the frame under construction
  *   bptr  - Output goes here.  Normally this is a known offset into d_buf,
  *           may be redirected to g_bitbucket on the case of FRAGN frames.
- *   proto - True: Copy the protocol header following the IPv6 header too.
  *
  * Returned Value:
- *   None
+ *   On success returns 0 and a negative error otherwise
  *
  ****************************************************************************/
 
-static void sixlowpan_uncompress_ipv6hdr(FAR uint8_t *fptr,
-                                         FAR uint8_t *bptr)
+static int sixlowpan_uncompress_ipv6hdr(FAR struct iob_s *iob,
+                                        FAR uint8_t *fptr,
+                                        FAR uint8_t *bptr)
 {
   FAR struct ipv6_hdr_s *ipv6 = (FAR struct ipv6_hdr_s *)bptr;
+  FAR uint8_t *endofframe = fptr + iob->io_len;
 
   /* Put uncompressed IPv6 header in d_buf. */
 
   g_frame_hdrlen  += SIXLOWPAN_IPV6_HDR_LEN;
+
+  if (fptr + g_frame_hdrlen + IPv6_HDRLEN > endofframe)
+    {
+      nerr("ERROR: Frame too short for IPv6 header\n");
+      return -EINVAL;
+    }
+
   memcpy(ipv6, fptr + g_frame_hdrlen, IPv6_HDRLEN);
 
   /* Update g_uncomp_hdrlen and g_frame_hdrlen. */
 
   g_frame_hdrlen  += IPv6_HDRLEN;
   g_uncomp_hdrlen += IPv6_HDRLEN;
+
+  return OK;
 }
 
 /****************************************************************************
@@ -174,20 +185,22 @@ static void sixlowpan_uncompress_ipv6hdr(FAR uint8_t 
*fptr,
  *   Copy the protocol header following the IPv4 header
  *
  * Input Parameters:
+ *   iob   - Pointer to the iob struct
  *   fptr  - Pointer to the beginning of the frame under construction
  *   bptr  - Output goes here.  Normally this is a known offset into d_buf,
  *           may be redirected to g_bitbucket on the case of FRAGN frames.
- *   proto - True: Copy the protocol header following the IPv6 header too.
  *
  * Returned Value:
- *   The size of the protocol header that was copied.
+ *   The size of the protocol header that was copied or a negative error.
  *
  ****************************************************************************/
 
-static uint16_t sixlowpan_uncompress_ipv6proto(FAR uint8_t *fptr,
-                                               FAR uint8_t *bptr)
+static int sixlowpan_uncompress_ipv6proto(FAR struct iob_s *iob,
+                                          FAR uint8_t *fptr,
+                                          FAR uint8_t *bptr)
 {
   FAR struct ipv6_hdr_s *ipv6 = (FAR struct ipv6_hdr_s *)bptr;
+  FAR uint8_t *endofframe = fptr + iob->io_len;
   uint16_t protosize = 0;
 
   /* Copy the following protocol header. */
@@ -200,6 +213,14 @@ static uint16_t sixlowpan_uncompress_ipv6proto(FAR uint8_t 
*fptr,
         FAR struct tcp_hdr_s *tcp =
           (FAR struct tcp_hdr_s *)(fptr + g_frame_hdrlen);
 
+        /* Check if the frame is too short */
+
+        if (fptr + g_frame_hdrlen + sizeof(struct tcp_hdr_s) > endofframe)
+          {
+            nerr("ERROR: Frame too short for TCP header\n");
+            return -EINVAL;
+          }
+
         /* The TCP header length is encoded in the top 4 bits of the
          * tcpoffset field (in units of 32-bit words).
          */
@@ -226,6 +247,14 @@ static uint16_t sixlowpan_uncompress_ipv6proto(FAR uint8_t 
*fptr,
       return 0;
     }
 
+  /* Check if the TCP header exceeds the frame size */
+
+  if (fptr + g_frame_hdrlen + protosize > endofframe)
+    {
+      nerr("ERROR: TCP header size from tcpoffset exceeds frame bounds\n");
+      return -EINVAL;
+    }
+
   /* Copy the protocol header. */
 
   memcpy((FAR uint8_t *)ipv6 + g_uncomp_hdrlen, fptr + g_frame_hdrlen,
@@ -233,7 +262,8 @@ static uint16_t sixlowpan_uncompress_ipv6proto(FAR uint8_t 
*fptr,
 
   g_frame_hdrlen   += protosize;
   g_uncomp_hdrlen  += protosize;
-  return protosize;
+
+  return (int)protosize;
 }
 
 /****************************************************************************
@@ -485,7 +515,13 @@ static int sixlowpan_frame_process(FAR struct 
radio_driver_s *radio,
 
       /* Uncompress the IPv6 header */
 
-      sixlowpan_uncompress_ipv6hdr(fptr, bptr);
+      ret = sixlowpan_uncompress_ipv6hdr(iob, fptr, bptr);
+      if (ret < 0)
+        {
+          nerr("ERROR: Failed to uncompress IPv6 header: %d\n",
+               ret);
+          goto errout_with_reass;
+        }
 
       /* A protocol header will follow the IPv6 header only on a non-
        * fragmented packet or on the first fragment of a fragmented
@@ -494,7 +530,15 @@ static int sixlowpan_frame_process(FAR struct 
radio_driver_s *radio,
 
       if (!isfrag || isfrag1)
         {
-          protosize = sixlowpan_uncompress_ipv6proto(fptr, bptr);
+          ret = sixlowpan_uncompress_ipv6proto(iob, fptr, bptr);
+          if (ret < 0)
+            {
+              nerr("ERROR: Failed to uncompress IPv6 proto header: %d\n",
+                   ret);
+              goto errout_with_reass;
+            }
+
+          protosize = (uint8_t) ret;
         }
     }
   else

Reply via email to