diff options
author | Guy Harris <guy@alum.mit.edu> | 2017-01-13 19:38:41 -0800 |
---|---|---|
committer | Francois-Xavier Le Bail <fx.lebail@yahoo.com> | 2017-01-18 09:16:42 +0100 |
commit | 2817174698bcd5371ff7fbc9d50b5241dd0130bd (patch) | |
tree | e47f95ac1b7bd7551c5e660bdfa99b35e6186ca5 /addrtoname.c | |
parent | b553848e3e2c0c466f65ab14e253af91467e561a (diff) | |
download | tcpdump-2817174698bcd5371ff7fbc9d50b5241dd0130bd.tar.gz |
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.
Diffstat (limited to 'addrtoname.c')
-rw-r--r-- | addrtoname.c | 20 |
1 files changed, 11 insertions, 9 deletions
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; |