summaryrefslogtreecommitdiff
path: root/addrtoname.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2017-01-13 19:38:41 -0800
committerFrancois-Xavier Le Bail <fx.lebail@yahoo.com>2017-01-18 09:16:42 +0100
commit2817174698bcd5371ff7fbc9d50b5241dd0130bd (patch)
treee47f95ac1b7bd7551c5e660bdfa99b35e6186ca5 /addrtoname.c
parentb553848e3e2c0c466f65ab14e253af91467e561a (diff)
downloadtcpdump-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.c20
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;