diff options
author | Peter Wu <peter@lekensteyn.nl> | 2018-11-22 21:03:18 +0100 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2018-11-23 04:10:04 +0000 |
commit | c344d454b45b8a6f4ddf84c5e5d1164bb5647374 (patch) | |
tree | 59db459540bc3f8133d9e3dad68c3c82804c2d33 /epan/addr_resolv.c | |
parent | 802d4c0121bff6ce0cb38dd15e20fa3238da183a (diff) |
addr_resolv: fix crashes in parse_ether_address_fast
When no mask is allowed, reject addresses like "aa:bb:cc:...".
Fix the type of 'cp' to avoid reading from a negative array index.
Fix parsing, a nibble is four bits, not eight.
Bug: 15297
Change-Id: Ibb0d0c17005b1e6213c09092e4b3c888a9024304
Fixes: v2.9.0rc0-2629-g3bb32ede26 ("addr_resolv: add fast path for parsing addresses from manuf")
Reviewed-on: https://code.wireshark.org/review/30768
Petri-Dish: Peter Wu <peter@lekensteyn.nl>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan/addr_resolv.c')
-rw-r--r-- | epan/addr_resolv.c | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/epan/addr_resolv.c b/epan/addr_resolv.c index e05cb2134b..0a7138be7c 100644 --- a/epan/addr_resolv.c +++ b/epan/addr_resolv.c @@ -1137,7 +1137,7 @@ host_lookup6(const ws_in6_addr *addr) * 28 or 36. Pre-condition: cp MUST be at least 21 bytes. */ static gboolean -parse_ether_address_fast(const char *cp, ether_t *eth, unsigned int *mask, +parse_ether_address_fast(const guchar *cp, ether_t *eth, unsigned int *mask, const gboolean accept_mask) { /* XXX copied from strutil.c */ @@ -1160,16 +1160,17 @@ parse_ether_address_fast(const char *cp, ether_t *eth, unsigned int *mask, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 }; + const guint8 *str_to_nibble_usg = (const guint8 *)str_to_nibble; if (cp[2] != ':' || cp[5] != ':') { /* Unexpected separators. */ return FALSE; } - int num0 = (str_to_nibble[(int)cp[0]] << 8) | str_to_nibble[(int)cp[1]]; - int num1 = (str_to_nibble[(int)cp[3]] << 8) | str_to_nibble[(int)cp[4]]; - int num2 = (str_to_nibble[(int)cp[6]] << 8) | str_to_nibble[(int)cp[7]]; - if ((num0 | num1 | num2) < 0) { + guint8 num0 = (str_to_nibble_usg[cp[0]] << 4) | str_to_nibble_usg[cp[1]]; + guint8 num1 = (str_to_nibble_usg[cp[3]] << 4) | str_to_nibble_usg[cp[4]]; + guint8 num2 = (str_to_nibble_usg[cp[6]] << 4) | str_to_nibble_usg[cp[7]]; + if (((num0 | num1 | num2) & 0x80)) { /* Not hexadecimal numbers. */ return FALSE; } @@ -1182,15 +1183,15 @@ parse_ether_address_fast(const char *cp, ether_t *eth, unsigned int *mask, /* Indicate that this is a manufacturer ID (0 is not allowed as a mask). */ *mask = 0; return TRUE; - } else if (cp[8] != ':') { + } else if (cp[8] != ':' || !accept_mask) { /* Format not handled by this fast path. */ return FALSE; } - int num3 = (str_to_nibble[(int)cp[9]] << 8) | str_to_nibble[(int)cp[10]]; - int num4 = (str_to_nibble[(int)cp[12]] << 8) | str_to_nibble[(int)cp[13]]; - int num5 = (str_to_nibble[(int)cp[15]] << 8) | str_to_nibble[(int)cp[16]]; - if ((num3 | num4 | num5) < 0 || cp[11] != ':' || cp[14] != ':') { + guint8 num3 = (str_to_nibble_usg[cp[9]] << 4) | str_to_nibble_usg[cp[10]]; + guint8 num4 = (str_to_nibble_usg[cp[12]] << 4) | str_to_nibble_usg[cp[13]]; + guint8 num5 = (str_to_nibble_usg[cp[15]] << 4) | str_to_nibble_usg[cp[16]]; + if (((num3 | num4 | num5) & 0x80) || cp[11] != ':' || cp[14] != ':') { /* Not hexadecimal numbers or invalid separators. */ return FALSE; } |