aboutsummaryrefslogtreecommitdiffstats
path: root/epan/addr_resolv.c
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2018-11-22 21:03:18 +0100
committerAnders Broman <a.broman58@gmail.com>2018-11-23 04:10:04 +0000
commitc344d454b45b8a6f4ddf84c5e5d1164bb5647374 (patch)
tree59db459540bc3f8133d9e3dad68c3c82804c2d33 /epan/addr_resolv.c
parent802d4c0121bff6ce0cb38dd15e20fa3238da183a (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.c21
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;
}