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 <zhanghongyu@xiaomi.com>
This commit is contained in:
zhanghongyu
2025-09-17 15:35:37 +08:00
committed by Alan C. Assis
parent f671ec648e
commit 0dc0b94380
+60 -1
View File
@@ -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. */