From: Guy Harris Date: Sat, 14 Jan 2017 03:38:41 +0000 (-0800) Subject: CVE-2017-5485/Fix lookup_nsap() to match what isonsap_string() expects. X-Git-Tag: tcpdump-4.9.0-bp~13 X-Git-Url: https://git.tcpdump.org/tcpdump/commitdiff_plain/2817174698bcd5371ff7fbc9d50b5241dd0130bd?ds=inline CVE-2017-5485/Fix lookup_nsap() to match what isonsap_string() expects. Change cddcb5632decb3fc631407b2ce0e526d17bb8ff9 changed isonsap_string() to take, as arguments, a pointer to the first octet of an NSAP and the length of the NSAP, rather than a pointer to a string of octets the first octet of which is the NSAP length and the subsequent octets are the octets of the NSAP. However, lookup_nsap() was not changed in a similar fashion, and isonsap_string() handed it a pointer to the first octet of the NSAP, which lookup_nsap() treated as the NSAP length. This should fix GitHub issue #563. --- diff --git a/addrtoname.c b/addrtoname.c index 5831b346..6975b713 100644 --- a/addrtoname.c +++ b/addrtoname.c @@ -406,14 +406,15 @@ lookup_bytestring(netdissect_options *ndo, register const u_char *bs, /* Find the hash node that corresponds the NSAP 'nsap' */ static inline struct enamemem * -lookup_nsap(netdissect_options *ndo, register const u_char *nsap) +lookup_nsap(netdissect_options *ndo, register const u_char *nsap, + register u_int nsap_length) { register u_int i, j, k; - unsigned int nlen = *nsap; struct enamemem *tp; - const u_char *ensap = nsap + nlen - 6; + const u_char *ensap; - if (nlen > 6) { + if (nsap_length > 6) { + ensap = nsap + nsap_length - 6; k = (ensap[0] << 8) | ensap[1]; j = (ensap[2] << 8) | ensap[3]; i = (ensap[4] << 8) | ensap[5]; @@ -426,19 +427,20 @@ lookup_nsap(netdissect_options *ndo, register const u_char *nsap) if (tp->e_addr0 == i && tp->e_addr1 == j && tp->e_addr2 == k && - tp->e_nsap[0] == nlen && + tp->e_nsap[0] == nsap_length && memcmp((const char *)&(nsap[1]), - (char *)&(tp->e_nsap[1]), nlen) == 0) + (char *)&(tp->e_nsap[1]), nsap_length) == 0) return tp; else tp = tp->e_nxt; tp->e_addr0 = i; tp->e_addr1 = j; tp->e_addr2 = k; - tp->e_nsap = (u_char *)malloc(nlen + 1); + tp->e_nsap = (u_char *)malloc(nsap_length + 1); if (tp->e_nsap == NULL) (*ndo->ndo_error)(ndo, "lookup_nsap: malloc"); - memcpy((char *)tp->e_nsap, (const char *)nsap, nlen + 1); + tp->e_nsap[0] = (u_char)nsap_length; /* guaranteed < ISONSAP_MAX_LENGTH */ + memcpy((char *)&tp->e_nsap[1], (const char *)nsap, nsap_length); tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp)); if (tp->e_nxt == NULL) (*ndo->ndo_error)(ndo, "lookup_nsap: calloc"); @@ -654,7 +656,7 @@ isonsap_string(netdissect_options *ndo, const u_char *nsap, if (nsap_length < 1 || nsap_length > ISONSAP_MAX_LENGTH) return ("isonsap_string: illegal length"); - tp = lookup_nsap(ndo, nsap); + tp = lookup_nsap(ndo, nsap, nsap_length); if (tp->e_name) return tp->e_name;