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

acassis 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 0dc0b943805 net/ipv4: check whether the length of the ipv4 option is 
correct
0dc0b943805 is described below

commit 0dc0b943805fe23431f17ccd05f5bb189143dd7f
Author: zhanghongyu <[email protected]>
AuthorDate: Wed Sep 17 15:35:37 2025 +0800

    net/ipv4: check whether the length of the ipv4 option is correct
    
    This patch adds validation for IPv4 option lengths during packet processing
    to prevent malformed packets from causing undefined behavior. The new
    ipv4_check_opt() function verifies that option lengths are within valid
    bounds before processing them.
    
    Signed-off-by: zhanghongyu <[email protected]>
---
 net/devif/ipv4_input.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 60 insertions(+), 1 deletion(-)

diff --git a/net/devif/ipv4_input.c b/net/devif/ipv4_input.c
index 5ea71232e6b..7fbf8d003be 100644
--- a/net/devif/ipv4_input.c
+++ b/net/devif/ipv4_input.c
@@ -94,6 +94,7 @@
 #include <nuttx/net/netdev.h>
 #include <nuttx/net/netstats.h>
 #include <nuttx/net/ip.h>
+#include <nuttx/net/ipopt.h>
 
 #include "arp/arp.h"
 #include "inet/inet.h"
@@ -118,6 +119,53 @@
  * Private Functions
  ****************************************************************************/
 
+/****************************************************************************
+ * Name: ipv4_check_opt
+ *
+ * Description:
+ *   Check the IP options length.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_FEATURES
+static int ipv4_check_opt(FAR struct ipv4_hdr_s *ipv4)
+{
+  FAR uint8_t *opt = (FAR uint8_t *)(ipv4 + 1);
+  int optlen;
+
+  optlen = ((ipv4->vhl & IPv4_HLMASK) << 2) - IPv4_HDRLEN;
+  while (optlen > 0)
+    {
+      if (opt[0] == IPOPT_END_TYPE)
+        {
+          break;
+        }
+      else if (opt[0] == IPOPT_NOOP_TYPE)
+        {
+          opt++;
+          optlen--;
+        }
+      else if (optlen > 1)
+        {
+          int len = opt[1];
+          if (len > optlen)
+            {
+              return -EINVAL;
+            }
+
+          opt += len;
+          optlen -= len;
+        }
+      else
+        {
+          return -EINVAL;
+        }
+    }
+
+  return OK;
+}
+#endif
+
 /****************************************************************************
  * Name: ipv4_in
  *
@@ -189,7 +237,7 @@ static int ipv4_in(FAR struct net_driver_s *dev)
 
   dev->d_len -= NET_LL_HDRLEN(dev);
 
-  if (IPv4_HDRLEN > dev->d_len)
+  if (((ipv4->vhl & IPv4_HLMASK) << 2) > dev->d_len)
     {
       nwarn("WARNING: Packet shorter than IPv4 header\n");
       goto drop;
@@ -242,6 +290,17 @@ static int ipv4_in(FAR struct net_driver_s *dev)
       goto drop;
     }
 
+#ifdef CONFIG_DEBUG_FEATURES
+  if (ipv4_check_opt(ipv4) != OK)
+    {
+#ifdef CONFIG_NET_STATISTICS
+      g_netstats.ipv4.drop++;
+#endif
+      nwarn("WARNING: IP options error\n");
+      goto drop;
+    }
+#endif
+
 #ifdef CONFIG_NET_NAT44
   /* Try NAT inbound, rule matching will be performed in NAT module. */
 

Reply via email to