mirror of
https://github.com/apache/nuttx.git
synced 2026-05-23 23:28:29 +08:00
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:
committed by
Alan C. Assis
parent
f671ec648e
commit
0dc0b94380
+60
-1
@@ -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. */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user