1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-10 17:59:04 +00:00

Fixing another bug found by Ilja where a pointer in ippackethdrinfo() could have gone outside of the buffer it was referencing (reading, not writing)

This commit is contained in:
kris
2008-06-11 06:00:17 +00:00
parent 92a9b10138
commit 861f9ff24b

View File

@@ -424,8 +424,8 @@ static void tcppacketoptinfo(u8 *optp, int len, char *result, int bufsize) {
static const char *ippackethdrinfo(const u8 *packet, u32 len) { static const char *ippackethdrinfo(const u8 *packet, u32 len) {
static char protoinfo[512]; static char protoinfo[512];
struct ip *ip = (struct ip *) packet; struct ip *ip = (struct ip *) packet;
struct tcp_hdr *tcp; struct tcp_hdr *tcp = NULL;
struct udp_hdr *udp; struct udp_hdr *udp = NULL;
char ipinfo[512]; char ipinfo[512];
char srchost[INET6_ADDRSTRLEN], dsthost[INET6_ADDRSTRLEN]; char srchost[INET6_ADDRSTRLEN], dsthost[INET6_ADDRSTRLEN];
char *p; char *p;
@@ -560,15 +560,23 @@ static const char *ippackethdrinfo(const u8 *packet, u32 len) {
unsigned short checksum; unsigned short checksum;
unsigned short id; unsigned short id;
unsigned short seq; unsigned short seq;
} *ping; } *ping = NULL;
unsigned pktlen = (ip->ip_hl * 4) + sizeof(struct ppkt);
if (pktlen > len)
goto icmpbad;
ping = (struct ppkt *) ((ip->ip_hl * 4) + (char *) ip); ping = (struct ppkt *) ((ip->ip_hl * 4) + (char *) ip);
switch(ping->type) { switch(ping->type) {
case 0: case 0:
strcpy(icmptype, "echo reply"); break; strcpy(icmptype, "echo reply"); break;
case 3: case 3:
ip2 = (struct ip *) ((char *) ip + (ip->ip_hl * 4) + 8); ip2 = (struct ip *) ((char *) ip + (ip->ip_hl * 4) + 8);
pktlen += (ip2->ip_hl * 4);
if (pktlen > len)
goto icmpbad;
if (pktlen + 8 < len) {
tcp = (struct tcp_hdr *) ((char *) ip2 + (ip2->ip_hl * 4)); tcp = (struct tcp_hdr *) ((char *) ip2 + (ip2->ip_hl * 4));
udp = (struct udp_hdr *) ((char *) ip2 + (ip2->ip_hl * 4)); udp = (struct udp_hdr *) ((char *) ip2 + (ip2->ip_hl * 4));
}
ip2dst = inet_ntoa(ip2->ip_dst); ip2dst = inet_ntoa(ip2->ip_dst);
switch (ping->code) { switch (ping->code) {
case 0: case 0:
@@ -581,9 +589,9 @@ static const char *ippackethdrinfo(const u8 *packet, u32 len) {
Snprintf(icmptype, sizeof icmptype, "protocol %u unreachable", ip2->ip_p); Snprintf(icmptype, sizeof icmptype, "protocol %u unreachable", ip2->ip_p);
break; break;
case 3: case 3:
if (ip2->ip_p == IPPROTO_UDP) if (ip2->ip_p == IPPROTO_UDP && udp)
Snprintf(icmptype, sizeof icmptype, "port %u unreachable", ntohs(udp->uh_dport)); Snprintf(icmptype, sizeof icmptype, "port %u unreachable", ntohs(udp->uh_dport));
else if (ip2->ip_p == IPPROTO_TCP) else if (ip2->ip_p == IPPROTO_TCP && tcp)
Snprintf(icmptype, sizeof icmptype, "port %u unreachable", ntohs(tcp->th_dport)); Snprintf(icmptype, sizeof icmptype, "port %u unreachable", ntohs(tcp->th_dport));
else else
strcpy(icmptype, "port unreachable"); strcpy(icmptype, "port unreachable");
@@ -678,8 +686,20 @@ static const char *ippackethdrinfo(const u8 *packet, u32 len) {
strcpy(icmptype, "Unknown type"); break; strcpy(icmptype, "Unknown type"); break;
break; break;
} }
if (pktlen > len) {
icmpbad:
if (ping) {
/* We still have this information */
Snprintf(protoinfo, sizeof(protoinfo), "ICMP %s > %s (type=%d/code=%d) %s",
srchost, dsthost, ping->type, ping->code, ipinfo);
} else {
Snprintf(protoinfo, sizeof(protoinfo), "ICMP %s > %s [??] %s",
srchost, dsthost, ipinfo);
}
} else {
Snprintf(protoinfo, sizeof(protoinfo), "ICMP %s > %s %s (type=%d/code=%d) %s", Snprintf(protoinfo, sizeof(protoinfo), "ICMP %s > %s %s (type=%d/code=%d) %s",
srchost, dsthost, icmptype, ping->type, ping->code, ipinfo); srchost, dsthost, icmptype, ping->type, ping->code, ipinfo);
}
} else { } else {
Snprintf(protoinfo, sizeof(protoinfo), "Unknown protocol (%d) %s > %s: %s", Snprintf(protoinfo, sizeof(protoinfo), "Unknown protocol (%d) %s > %s: %s",
ip->ip_p, srchost, dsthost, ipinfo); ip->ip_p, srchost, dsthost, ipinfo);