File wireshark-0101-addr-resolv-Fix-a-heap-buffer-overflow.patch of Package wireshark.33433
From 108217f4bb1afb8b25fc705c2722b3e328b1ad78 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Valverde?= <j@v6e.pt>
Date: Sat, 16 Sep 2023 06:59:12 +0100
Subject: [PATCH] addr_resolv: Fix a heap buffer overflow
Make sure we always pass at least 6 bytes to ws_manuf_lookup_str().
Fixes #19344.
Signed-off-by: Robert Frohl <rfrohl@suse.com>
---
epan/addr_resolv.c | 25 +++++++++++++++++--------
epan/addr_resolv.h | 4 ++--
epan/address_types.c | 4 ++--
3 files changed, 21 insertions(+), 12 deletions(-)
Index: wireshark-2.4.16/epan/addr_resolv.c
===================================================================
--- wireshark-2.4.16.orig/epan/addr_resolv.c
+++ wireshark-2.4.16/epan/addr_resolv.c
@@ -1393,12 +1393,15 @@ add_manuf_name(const guint8 *addr, unsig
} /* add_manuf_name */
static hashmanuf_t *
-manuf_name_lookup(const guint8 *addr)
+manuf_name_lookup(const guint8 *addr, size_t size)
{
gint32 manuf_key = 0;
guint8 oct;
hashmanuf_t *manuf_value;
+ if (size < 6)
+ return NULL;
+
/* manuf needs only the 3 most significant octets of the ethernet address */
manuf_key = addr[0];
manuf_key = manuf_key<<8;
@@ -1541,6 +1544,7 @@ eth_addr_resolve(hashether_t *tp) {
ether_t *eth;
hashmanuf_t *manuf_value;
const guint8 *addr = tp->addr;
+ size_t addr_size = sizeof(tp->addr);
if ( (eth = get_ethbyaddr(addr)) != NULL) {
g_strlcpy(tp->resolved_name, eth->name, MAXNAMELEN);
@@ -1587,7 +1591,7 @@ eth_addr_resolve(hashether_t *tp) {
} while (mask--);
/* Now try looking in the manufacturer table. */
- manuf_value = manuf_name_lookup(addr);
+ manuf_value = manuf_name_lookup(addr, addr_size);
if ((manuf_value != NULL) && (manuf_value->status != HASHETHER_STATUS_UNRESOLVED)) {
g_snprintf(tp->resolved_name, MAXNAMELEN, "%s_%02x:%02x:%02x",
manuf_value->resolved_name, addr[3], addr[4], addr[5]);
@@ -3274,11 +3278,11 @@ get_vlan_name(wmem_allocator_t *allocato
} /* get_vlan_name */
const gchar *
-get_manuf_name(const guint8 *addr)
+get_manuf_name(const guint8 *addr, size_t size)
{
hashmanuf_t *manuf_value;
- manuf_value = manuf_name_lookup(addr);
+ manuf_value = manuf_name_lookup(addr, size);
if (gbl_resolv_flags.mac_name && manuf_value->status != HASHETHER_STATUS_UNRESOLVED)
return manuf_value->resolved_name;
@@ -3294,22 +3298,27 @@ uint_get_manuf_name(const guint oid)
addr[0] = (oid >> 16) & 0xFF;
addr[1] = (oid >> 8) & 0xFF;
addr[2] = (oid >> 0) & 0xFF;
- return get_manuf_name(addr);
+ return get_manuf_name(addr, sizeof(addr));
}
const gchar *
tvb_get_manuf_name(tvbuff_t *tvb, gint offset)
{
- return get_manuf_name(tvb_get_ptr(tvb, offset, 3));
+ guint8 buf[6] = { 0 };
+ tvb_memcpy(tvb, buf, offset, 3);
+ return get_manuf_name(buf, sizeof(buf));
}
const gchar *
-get_manuf_name_if_known(const guint8 *addr)
+get_manuf_name_if_known(const guint8 *addr, size_t size)
{
hashmanuf_t *manuf_value;
int manuf_key;
guint8 oct;
+ if (size < 6)
+ return NULL;
+
/* manuf needs only the 3 most significant octets of the ethernet address */
manuf_key = addr[0];
manuf_key = manuf_key<<8;
@@ -3344,7 +3353,9 @@ uint_get_manuf_name_if_known(const guint
const gchar *
tvb_get_manuf_name_if_known(tvbuff_t *tvb, gint offset)
{
- return get_manuf_name_if_known(tvb_get_ptr(tvb, offset, 3));
+ guint8 buf[6] = { 0 };
+ tvb_memcpy(tvb, buf, offset, 3);
+ return get_manuf_name_if_known(buf, sizeof(buf));
}
char* get_hash_manuf_resolved_name(hashmanuf_t* manuf)
@@ -3362,7 +3373,7 @@ eui64_to_display(wmem_allocator_t *alloc
/* Copy and convert the address to network byte order. */
*(guint64 *)(void *)(addr) = pntoh64(&(addr_eui64));
- manuf_value = manuf_name_lookup(addr);
+ manuf_value = manuf_name_lookup(addr, 8);
if (!gbl_resolv_flags.mac_name || (manuf_value->status == HASHETHER_STATUS_UNRESOLVED)) {
ret = wmem_strdup_printf(allocator, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7]);
} else {
Index: wireshark-2.4.16/epan/addr_resolv.h
===================================================================
--- wireshark-2.4.16.orig/epan/addr_resolv.h
+++ wireshark-2.4.16/epan/addr_resolv.h
@@ -211,13 +211,13 @@ const gchar *get_ether_name_if_known(con
* Given a sequence of 3 octets containing an OID, get_manuf_name()
* returns the vendor name, or "%02x:%02x:%02x" if not known.
*/
-extern const gchar *get_manuf_name(const guint8 *addr);
+extern const gchar *get_manuf_name(const guint8 *addr, size_t size);
/*
* Given a sequence of 3 octets containing an OID, get_manuf_name_if_known()
* returns the vendor name, or NULL if not known.
*/
-WS_DLL_PUBLIC const gchar *get_manuf_name_if_known(const guint8 *addr);
+WS_DLL_PUBLIC const gchar *get_manuf_name_if_known(const guint8 *addr, size_t size);
/*
* Given an integer containing a 24-bit OID, uint_get_manuf_name()
Index: wireshark-2.4.16/epan/address_types.c
===================================================================
--- wireshark-2.4.16.orig/epan/address_types.c
+++ wireshark-2.4.16/epan/address_types.c
@@ -377,7 +377,7 @@ static const gchar* fcwwn_name_res_str(c
case FC_NH_NAA_IEEE_E:
memcpy (oui, &addrp[2], 6);
- return get_manuf_name(oui);
+ return get_manuf_name(oui, sizeof(oui));
case FC_NH_NAA_IEEE_R:
oui[0] = ((addrp[0] & 0x0F) << 4) | ((addrp[1] & 0xF0) >> 4);
@@ -387,7 +387,7 @@ static const gchar* fcwwn_name_res_str(c
oui[4] = ((addrp[4] & 0x0F) << 4) | ((addrp[5] & 0xF0) >> 4);
oui[5] = ((addrp[5] & 0x0F) << 4) | ((addrp[6] & 0xF0) >> 4);
- return get_manuf_name(oui);
+ return get_manuf_name(oui, sizeof(oui));
}
return "";
Index: wireshark-2.4.16/epan/dissectors/packet-ieee80211.c
===================================================================
--- wireshark-2.4.16.orig/epan/dissectors/packet-ieee80211.c
+++ wireshark-2.4.16/epan/dissectors/packet-ieee80211.c
@@ -9777,7 +9777,7 @@ oui_base_custom(gchar *result, guint32 o
p_oui[2] = oui & 0xFF;
/* Attempt an OUI lookup. */
- manuf_name = get_manuf_name_if_known(p_oui);
+ manuf_name = get_manuf_name_if_known(p_oui, sizeof(p_oui));
if (manuf_name == NULL) {
/* Could not find an OUI. */
g_snprintf(result, ITEM_LABEL_LENGTH, "%.2x-%.2x-%.2x", p_oui[0], p_oui[1], p_oui[2]);
Index: wireshark-2.4.16/epan/dissectors/packet-ieee802a.c
===================================================================
--- wireshark-2.4.16.orig/epan/dissectors/packet-ieee802a.c
+++ wireshark-2.4.16/epan/dissectors/packet-ieee802a.c
@@ -96,7 +96,7 @@ dissect_ieee802a(tvbuff_t *tvb, packet_i
tvb_memcpy(tvb, oui, 0, 3);
oui32 = oui[0] << 16 | oui[1] << 8 | oui[2];
- manuf = get_manuf_name_if_known(oui);
+ manuf = get_manuf_name_if_known(oui, sizeof(oui));
pid = tvb_get_ntohs(tvb, 3);
col_add_fstr(pinfo->cinfo, COL_INFO, "OUI %s (%s), PID 0x%04X",
Index: wireshark-2.4.16/ui/gtk/capture_if_details_dlg_win32.c
===================================================================
--- wireshark-2.4.16.orig/ui/gtk/capture_if_details_dlg_win32.c
+++ wireshark-2.4.16/ui/gtk/capture_if_details_dlg_win32.c
@@ -1084,7 +1084,7 @@ capture_if_details_802_11_bssid_list(Gtk
mac[3], mac[4], mac[5]);
/* Vendor */
- manuf_name = get_manuf_name_if_known(mac);
+ manuf_name = get_manuf_name_if_known(mac, sizeof(mac));
if (manuf_name != NULL) {
g_strlcpy(vendor_buff, manuf_name, DETAILS_STR_MAX);
} else {
@@ -1171,7 +1171,7 @@ capture_if_details_802_11_bssid_list(Gtk
#ifdef DEBUG_IE
/* include information from epan/packet-ieee80211.c dissect_vendor_ie_wpawme() */
- manuf_name = get_manuf_name_if_known(iep);
+ manuf_name = get_manuf_name_if_known(iep, sizeof(iep));
if (manuf_name != NULL) {
g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X (%s) Type: %02X",
*(iep), *(iep+1), *(iep+2), manuf_name, *(iep+3));
@@ -1281,7 +1281,7 @@ capture_if_details_802_11(GtkWidget *gri
length = sizeof(values);
memset(values, 0, 6);
if (wpcap_packet_request(adapter, OID_802_11_BSSID, FALSE /* !set */, values, &length)) {
- manuf_name = get_manuf_name_if_known(values);
+ manuf_name = get_manuf_name_if_known(values, sizeof(values));
if (manuf_name != NULL) {
g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X:%02X:%02X:%02X (%s)",
values[0], values[1], values[2],
@@ -1533,7 +1533,7 @@ capture_if_details_802_3(GtkWidget *grid
length = sizeof(values);
if (wpcap_packet_request(adapter, OID_802_3_PERMANENT_ADDRESS, FALSE /* !set */, values, &length)) {
- manuf_name = get_manuf_name_if_known(values);
+ manuf_name = get_manuf_name_if_known(values, sizeof(values));
if (manuf_name != NULL) {
g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X:%02X:%02X:%02X (%s)",
values[0], values[1], values[2],
@@ -1552,7 +1552,7 @@ capture_if_details_802_3(GtkWidget *grid
length = sizeof(values);
if (wpcap_packet_request(adapter, OID_802_3_CURRENT_ADDRESS, FALSE /* !set */, values, &length)) {
- manuf_name = get_manuf_name_if_known(values);
+ manuf_name = get_manuf_name_if_known(values, sizeof(values));
if (manuf_name != NULL) {
g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X:%02X:%02X:%02X (%s)",
values[0], values[1], values[2],
@@ -1961,7 +1961,7 @@ capture_if_details_general(GtkWidget *gr
length = sizeof(values);
if (wpcap_packet_request(adapter, OID_GEN_VENDOR_ID, FALSE /* !set */, values, &length)) {
entries++;
- manuf_name = get_manuf_name_if_known(values);
+ manuf_name = get_manuf_name_if_known(values, sizeof(values));
if (manuf_name != NULL) {
g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X (%s) NIC: %02X",
values[0], values[1], values[2], manuf_name, values[3]);
Index: wireshark-2.4.16/epan/dissectors/packet-nhrp.c
===================================================================
--- wireshark-2.4.16.orig/epan/dissectors/packet-nhrp.c
+++ wireshark-2.4.16/epan/dissectors/packet-nhrp.c
@@ -913,10 +913,10 @@ static void dissect_nhrp_ext(tvbuff_t
tvb_memcpy(tvb, manuf, offset, 3);
vendor_tree = proto_tree_add_subtree_format(nhrp_tree, tvb, offset, len,
- ett_nhrp_vendor_ext, NULL, "Extension Data: Vendor ID=%s, Data=%s", get_manuf_name(manuf),
+ ett_nhrp_vendor_ext, NULL, "Extension Data: Vendor ID=%s, Data=%s", get_manuf_name(manuf, sizeof(manuf)),
tvb_bytes_to_str(wmem_packet_scope(), tvb, offset + 3, len - 3));
proto_tree_add_bytes_format_value(vendor_tree, hf_nhrp_vendor_ext_id, tvb,
- offset, 3, manuf, "%s", get_manuf_name(manuf));
+ offset, 3, manuf, "%s", get_manuf_name(manuf, sizeof(manuf)));
if (len > 3) {
proto_tree_add_item(vendor_tree, hf_nhrp_vendor_ext_data, tvb, offset + 3, len - 3, ENC_NA);
}