From 3fa8d201fa0b44366f17db224afac98942c42cd1 Mon Sep 17 00:00:00 2001 From: dmiller Date: Fri, 26 Jun 2026 22:06:04 +0000 Subject: [PATCH] Add checks for ip_hl < 5 --- libnetutil/packettrace.cc | 5 ++++- osscan2.cc | 8 ++++---- scan_engine_raw.cc | 2 +- tcpip.cc | 1 + 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/libnetutil/packettrace.cc b/libnetutil/packettrace.cc index af2fece73..79c851ebc 100644 --- a/libnetutil/packettrace.cc +++ b/libnetutil/packettrace.cc @@ -890,7 +890,10 @@ int icmppackethdrinfo (const u8 *data, unsigned int datalen, pktlen += offsetof(struct icmp_msg_quote, icmp_ip); if (datalen >= pktlen + sizeof(ip2)) { memcpy(&ip2, data + pktlen, sizeof(ip2)); - pktlen += ip2.ip_hl * 4; + if (ip2.ip_hl >= 5) + pktlen += ip2.ip_hl * 4; + else + pktlen += sizeof(ip2); } else { pktlen += sizeof(ip2); } diff --git a/osscan2.cc b/osscan2.cc index c4eed462a..30ec7b636 100644 --- a/osscan2.cc +++ b/osscan2.cc @@ -580,7 +580,7 @@ static void doSeqTests(OsScanInfo *OSI, HostOsScan *HOS) { if (bytes < sizeof(iphdr)) continue; memcpy(&iphdr, ip, sizeof(iphdr)); - if (bytes < (4 * iphdr.ip_hl) + 4U) + if (iphdr.ip_hl < 5 || bytes < (4 * iphdr.ip_hl) + 4U) continue; memset(&ss, 0, sizeof(ss)); @@ -754,7 +754,7 @@ static void doTUITests(OsScanInfo *OSI, HostOsScan *HOS) { if (bytes < sizeof(iphdr)) continue; memcpy(&iphdr, ip, sizeof(iphdr)); - if (bytes < (4 * iphdr.ip_hl) + 4U) + if (iphdr.ip_hl < 5 || bytes < (4 * iphdr.ip_hl) + 4U) continue; memset(&ss, 0, sizeof(ss)); @@ -1897,7 +1897,7 @@ bool HostOsScan::processResp(HostOsScanStats *hss, const u8 *pkt, unsigned int l return false; memcpy(&ip, pkt, sizeof(ip)); const unsigned int iphlen = 4 * ip.ip_hl; - if (len < iphlen + 4U) + if (iphlen < sizeof(ip) || len < iphlen + 4U) return false; len -= iphlen; @@ -2923,7 +2923,7 @@ bool HostOsScan::processTUdpResp(HostOsScanStats *hss, const struct ip *ip, cons const u8 *ip2pkt = icmppkt + 8; memcpy(&ip2, ip2pkt, sizeof(ip2)); unsigned int ip2hlen = 4 * ip2.ip_hl; - if (icmplen < 8 + ip2hlen + sizeof(udp)) + if (ip2hlen < sizeof(ip2) || icmplen < 8 + ip2hlen + sizeof(udp)) return false; const u8 *udppkt = ip2pkt + ip2hlen; memcpy(&udp, udppkt, sizeof(udp)); diff --git a/scan_engine_raw.cc b/scan_engine_raw.cc index 8bc3602cf..3a8b6a3fb 100644 --- a/scan_engine_raw.cc +++ b/scan_engine_raw.cc @@ -165,7 +165,7 @@ void UltraProbe::setIP(const u8 *ippacket, u32 len, const probespec *pspec) { if (ip->ip_v == 4) { data = ipv4_get_data(ippacket, &len); assert(data != NULL); - assert(len + ip->ip_hl * 4 == (u32) ntohs(ip->ip_len)); + assert(ip->ip_hl >= 5 && len + ip->ip_hl * 4 == (u32) ntohs(ip->ip_len)); probes.IP.ipid = ntohs(ip->ip_id); hdr = ip->ip_p; } else if (ip->ip_v == 6) { diff --git a/tcpip.cc b/tcpip.cc index 8428e235e..de17fcc7d 100644 --- a/tcpip.cc +++ b/tcpip.cc @@ -381,6 +381,7 @@ static int send_ipv4_packet(int sd, const struct eth_nfo *eth, assert(packet); assert((int) packetlen > 0); + assert(ip->ip_hl >= 5); /* Fragmentation requested && packet is bigger than MTU */ if (o.fragscan && !(ntohs(ip->ip_off) & IP_DF) &&