1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-15 12:19:02 +00:00

Handle ICMPv6 packets without a body

Two issues here: First, IP protocol scan can send packets with protocol
58 (ICMPv6) even over IPv4. This led to a bad interaction where the
packet was created (in build_protoscan_packet) without a data payload,
but setIP tried to set the packet's Identifier field (present in both
ICMPv6 and ICMP Echo Request packets), leading to a heap buffer
overflow. Instead, we now only try to set this identifier when the IP
version matches the ICMP version, indicating that we set the data
payload.

The other issue was a out-of-bounds read while packet tracing when an
ICMPv6 packet without a payload was sent or received, due to trying to
read the type and code. Now we check that the data length is sufficient
to contain an ICMPv6 header before attempting to read one.

Credit LLVM/Clang's AddressSanitizer with catching these bugs.
This commit is contained in:
dmiller
2016-07-28 05:11:35 +00:00
parent 2e05009ff7
commit 5d726c7733
2 changed files with 17 additions and 10 deletions

View File

@@ -181,20 +181,21 @@ void UltraProbe::setIP(u8 *ippacket, u32 len, const probespec *pspec) {
}
if (hdr == IPPROTO_TCP) {
assert(len >= 20);
assert(len >= sizeof(struct tcp_hdr));
tcp = (struct tcp_hdr *) data;
probes.IP.pd.tcp.sport = ntohs(tcp->th_sport);
probes.IP.pd.tcp.seq = ntohl(tcp->th_seq);
} else if (hdr == IPPROTO_UDP) {
assert(len >= 8);
assert(len >= sizeof(struct udp_hdr));
udp = (struct udp_hdr *) data;
probes.IP.pd.udp.sport = ntohs(udp->uh_sport);
} else if (hdr == IPPROTO_SCTP) {
assert(len >= 12);
assert(len >= sizeof(struct sctp_hdr));
sctp = (struct sctp_hdr *) data;
probes.IP.pd.sctp.sport = ntohs(sctp->sh_sport);
probes.IP.pd.sctp.vtag = ntohl(sctp->sh_vtag);
} else if (hdr == IPPROTO_ICMP || hdr == IPPROTO_ICMPV6) {
} else if ((ip->ip_v == 4 && hdr == IPPROTO_ICMP) || (ip->ip_v == 6 && hdr == IPPROTO_ICMPV6)) {
assert(len >= sizeof(struct ppkt));
icmp = (struct ppkt *) data;
probes.IP.pd.icmp.ident = ntohs(icmp->id);
}