From e6fbb29c35df9f323a777851f842736f47dc9060 Mon Sep 17 00:00:00 2001 From: Gerald Combs Date: Mon, 26 Nov 2012 22:35:09 +0000 Subject: Copy over revisions from the trunk: ------------------------------------------------------------------------ r45674 | darkjames | 2012-10-20 13:50:25 -0700 (Sat, 20 Oct 2012) | 2 lines Changed paths: M /trunk/epan/addr_resolv.c Make r45511 work also without HAVE_C_ARES. ------------------------------------------------------------------------ Copy over with manual intervention: ------------------------------------------------------------------------ r45511 | gerald | 2012-10-12 14:37:02 -0700 (Fri, 12 Oct 2012) | 9 lines Changed paths: M /trunk/epan/addr_resolv.c M /trunk/epan/packet.c M /trunk/wiretap/file_access.c M /trunk/wiretap/pcapng.c Use seasonal allocation for name resolution. This effectively scrubs our resolution information between capture files so that we don't leak host entries from one file to another (e.g. embarassing-host-name.example.com from file1.pcapng into a name resolution block in file2.pcapng). host_name_lookup_cleanup and host_name_lookup_init must now be called after each call to se_free_all. As a result we now end up reading our various name resolution files much more than we should. ------------------------------------------------------------------------ Update the release notes. svn path=/trunk-1.8/; revision=46211 --- docbook/release-notes.xml | 11 ++--- epan/addr_resolv.c | 103 +++++++++++++++++++++++++++------------------- epan/packet.c | 14 +++++++ wiretap/pcapng.c | 2 +- 4 files changed, 82 insertions(+), 48 deletions(-) diff --git a/docbook/release-notes.xml b/docbook/release-notes.xml index 458073206f..d244407e06 100644 --- a/docbook/release-notes.xml +++ b/docbook/release-notes.xml @@ -36,19 +36,20 @@ Wireshark Info - wnpa-sec-2012-30 + wnpa-sec-2012-30 - . - + Wireshark could leak potentially sensitive host name resolution + information when working with multiple pcap-ng files. + (Bug X) - Versions affected: 1.8.0 to 1.8.3, 1.6.0 to 1.6.11. + Versions affected: 1.8.0 to 1.8.3. - CVE-2012-X + CVE-2012-UNASSIGNED diff --git a/epan/addr_resolv.c b/epan/addr_resolv.c index efd671e3b7..d322b020f9 100644 --- a/epan/addr_resolv.c +++ b/epan/addr_resolv.c @@ -273,8 +273,8 @@ static subnet_length_entry_t subnet_length_entries[SUBNETLENGTHSIZE]; /* Ordered static gboolean have_subnet_entry = FALSE; static gboolean eth_resolution_initialized = FALSE; -static int ipxnet_resolution_initialized = 0; -static int service_resolution_initialized = 0; +static gboolean ipxnet_resolution_initialized = FALSE; +static gboolean service_resolution_initialized = FALSE; static gboolean new_resolved_objects = FALSE; static struct addrinfo *addrinfo_list = NULL; /* IPv4 and IPv6 */ @@ -453,14 +453,14 @@ add_service_name(hashport_t **proto_table, const guint port, const char *service tp = proto_table[hash_idx]; if( tp == NULL ) { - tp = proto_table[hash_idx] = (hashport_t *)g_malloc(sizeof(hashport_t)); + tp = proto_table[hash_idx] = se_new(hashport_t); } else { while(1) { if( tp->port == port ) { return; } if (tp->next == NULL) { - tp->next = (hashport_t *)g_malloc(sizeof(hashport_t)); + tp->next = se_new(hashport_t); tp = tp->next; break; } @@ -590,6 +590,7 @@ initialize_services(void) } parse_services_file(g_services_path); + service_resolution_initialized = TRUE; } /* initialize_services */ @@ -607,7 +608,6 @@ static gchar if (!service_resolution_initialized) { initialize_services(); - service_resolution_initialized = 1; } switch(proto) { @@ -637,14 +637,14 @@ static gchar tp = table[hash_idx]; if( tp == NULL ) { - tp = table[hash_idx] = (hashport_t *)g_malloc(sizeof(hashport_t)); + tp = table[hash_idx] = se_new(hashport_t); } else { while(1) { if( tp->port == port ) { return tp->name; } if (tp->next == NULL) { - tp->next = (hashport_t *)g_malloc(sizeof(hashport_t)); + tp->next = se_new(hashport_t); tp = tp->next; break; } @@ -754,7 +754,7 @@ c_ares_ghba_cb(void *arg, int status, int timeouts _U_, struct hostent *he) { static hashipv4_t * new_ipv4(const guint addr) { - hashipv4_t *tp = g_malloc(sizeof(hashipv4_t)); + hashipv4_t *tp = se_new(hashipv4_t); tp->addr = addr; tp->next = NULL; tp->resolve = FALSE; @@ -855,7 +855,7 @@ host_name_lookup(const guint addr, gboolean *found) static hashipv6_t * new_ipv6(const struct e_in6_addr *addr) { - hashipv6_t *tp = g_malloc(sizeof(hashipv6_t)); + hashipv6_t *tp = se_new(hashipv6_t); tp->addr = *addr; tp->next = NULL; tp->resolve = FALSE; @@ -1310,7 +1310,7 @@ manuf_hash_new_entry(const guint8 *addr, gchar *name) { hashmanuf_t *mtp; - mtp = (hashmanuf_t *)g_malloc(sizeof(hashmanuf_t)); + mtp = se_new(hashmanuf_t); memcpy(mtp->addr, addr, sizeof(mtp->addr)); /* The length of this name is limited (in the number of UTF-8 characters, * not bytes) in make-manuf. That doesn't mean a user can't put a longer @@ -1326,7 +1326,7 @@ wka_hash_new_entry(const guint8 *addr, gchar *name) { hashwka_t *wtp; - wtp = (hashwka_t *)g_malloc(sizeof(hashwka_t)); + wtp = se_new(hashwka_t); memcpy(wtp->addr, addr, sizeof(wtp->addr)); g_strlcpy(wtp->name, name, MAXNAMELEN); wtp->next = NULL; @@ -1377,7 +1377,7 @@ add_manuf_name(const guint8 *addr, unsigned int mask, gchar *name) well-known-address table, creating that table if necessary. */ wka_tp = wka_table[mask]; if (wka_tp == NULL) - wka_tp = wka_table[mask] = g_malloc0(sizeof *wka_table[mask]); + wka_tp = wka_table[mask] = se_alloc0(sizeof *wka_table[mask]); hash_idx = hash_eth_wka(addr, mask); @@ -1515,6 +1515,7 @@ initialize_ethers(void) end_ethent(); g_free(manuf_path); + eth_resolution_initialized = TRUE; } /* initialize_ethers */ @@ -1640,7 +1641,7 @@ static hashether_t * eth_hash_new_entry(const guint8 *addr, const gboolean resolve) { hashether_t *tp; - tp = (hashether_t *)g_malloc(sizeof(hashether_t)); + tp = se_new(hashether_t); memcpy(tp->addr, addr, sizeof(tp->addr)); tp->status = HASHETHER_STATUS_UNRESOLVED; g_strlcpy(tp->hexaddr, bytestring_to_str(addr, sizeof(tp->addr), ':'), sizeof(tp->hexaddr)); @@ -1909,6 +1910,7 @@ initialize_ipxnets(void) if (g_pipxnets_path == NULL) g_pipxnets_path = get_persconffile_path(ENAME_IPXNETS, FALSE, FALSE); + ipxnet_resolution_initialized = TRUE; } /* initialize_ipxnets */ static hashipxnet_t * @@ -1922,11 +1924,11 @@ add_ipxnet_name(guint addr, const gchar *name) tp = ipxnet_table[hash_idx]; if( tp == NULL ) { - tp = ipxnet_table[hash_idx] = (hashipxnet_t *)g_malloc(sizeof(hashipxnet_t)); + tp = ipxnet_table[hash_idx] = se_new(hashipxnet_t); } else { while(1) { if (tp->next == NULL) { - tp->next = (hashipxnet_t *)g_malloc(sizeof(hashipxnet_t)); + tp->next = se_new(hashipxnet_t); tp = tp->next; break; } @@ -1955,14 +1957,14 @@ ipxnet_name_lookup(const guint addr) tp = ipxnet_table[hash_idx]; if( tp == NULL ) { - tp = ipxnet_table[hash_idx] = (hashipxnet_t *)g_malloc(sizeof(hashipxnet_t)); + tp = ipxnet_table[hash_idx] = se_new(hashipxnet_t); } else { while(1) { if (tp->addr == addr) { return tp->name; } if (tp->next == NULL) { - tp->next = (hashipxnet_t *)g_malloc(sizeof(hashipxnet_t)); + tp->next = se_new(hashipxnet_t); tp = tp->next; break; } @@ -2259,19 +2261,19 @@ subnet_entry_set(guint32 subnet_addr, const guint32 mask_length, const gchar* na hash_idx = HASH_IPV4_ADDRESS(subnet_addr); if(NULL == entry->subnet_addresses) { - entry->subnet_addresses = g_new0(hashipv4_t*,HASHHOSTSIZE); + entry->subnet_addresses = (hashipv4_t**) se_alloc0(sizeof(hashipv4_t*) * HASHHOSTSIZE); } if(NULL != (tp = entry->subnet_addresses[hash_idx])) { if(tp->addr == subnet_addr) { return; /* XXX provide warning that an address was repeated? */ } else { - hashipv4_t * new_tp = g_new(hashipv4_t,1); + hashipv4_t * new_tp = se_new(hashipv4_t); tp->next = new_tp; tp = new_tp; } } else { - tp = entry->subnet_addresses[hash_idx] = g_new(hashipv4_t,1); + tp = entry->subnet_addresses[hash_idx] = se_new(hashipv4_t); } tp->next = NULL; @@ -2391,7 +2393,7 @@ host_name_lookup_init(void) { #endif /*GNU_ADNS */ if (!addrinfo_list) { - ai = g_malloc0(sizeof(struct addrinfo)); + ai = se_alloc0(sizeof(struct addrinfo)); addrinfo_list = addrinfo_list_last = ai; } @@ -2518,8 +2520,8 @@ host_name_lookup_process(gpointer data _U_) { return nro; } -void -host_name_lookup_cleanup(void) { +static void +_host_name_lookup_cleanup(void) { GList *cur; cur = g_list_first(async_dns_queue_head); @@ -2599,8 +2601,8 @@ host_name_lookup_process(gpointer data _U_) { return nro; } -void -host_name_lookup_cleanup(void) { +static void +_host_name_lookup_cleanup(void) { void *qdata; async_dns_queue_head = g_list_first(async_dns_queue_head); @@ -2626,12 +2628,38 @@ host_name_lookup_process(gpointer data _U_) { return nro; } -void -host_name_lookup_cleanup(void) { +static void +_host_name_lookup_cleanup(void) { } #endif /* HAVE_C_ARES */ +void +host_name_lookup_cleanup(void) { + _host_name_lookup_cleanup(); + + memset(ipv4_table, 0, sizeof(ipv4_table)); + memset(ipv6_table, 0, sizeof(ipv6_table)); + + memset(udp_port_table, 0, sizeof(udp_port_table)); + memset(tcp_port_table, 0, sizeof(tcp_port_table)); + memset(sctp_port_table, 0, sizeof(sctp_port_table)); + memset(dccp_port_table, 0, sizeof(dccp_port_table)); + memset(eth_table, 0, sizeof(eth_table)); + memset(manuf_table, 0, sizeof(manuf_table)); + memset(wka_table, 0, sizeof(wka_table)); + memset(ipxnet_table, 0, sizeof(ipxnet_table)); + memset(subnet_length_entries, 0, sizeof(subnet_length_entries)); + + addrinfo_list = addrinfo_list_last = NULL; + + have_subnet_entry = FALSE; + eth_resolution_initialized = FALSE; + ipxnet_resolution_initialized = FALSE; + service_resolution_initialized = FALSE; + new_resolved_objects = FALSE; +} + const gchar * get_hostname(const guint addr) { @@ -2699,15 +2727,15 @@ add_ipv4_name(const guint addr, const gchar *name) new_resolved_objects = TRUE; if (!addrinfo_list) { - ai = g_malloc0(sizeof(struct addrinfo)); + ai = se_alloc0(sizeof(struct addrinfo)); addrinfo_list = addrinfo_list_last = ai; } - sa4 = g_malloc0(sizeof(struct sockaddr_in)); + sa4 = se_alloc0(sizeof(struct sockaddr_in)); sa4->sin_family = AF_INET; sa4->sin_addr.s_addr = addr; - ai = g_malloc0(sizeof(struct addrinfo)); + ai = se_alloc0(sizeof(struct addrinfo)); ai->ai_family = AF_INET; ai->ai_addrlen = sizeof(struct sockaddr_in); ai->ai_canonname = (char *) tp->name; @@ -2757,15 +2785,15 @@ add_ipv6_name(const struct e_in6_addr *addrp, const gchar *name) new_resolved_objects = TRUE; if (!addrinfo_list) { - ai = g_malloc0(sizeof(struct addrinfo)); + ai = se_alloc0(sizeof(struct addrinfo)); addrinfo_list = addrinfo_list_last = ai; } - sa6 = g_malloc0(sizeof(struct sockaddr_in6)); + sa6 = se_alloc0(sizeof(struct sockaddr_in6)); sa6->sin6_family = AF_INET; memcpy(sa6->sin6_addr.s6_addr, addrp, 16); - ai = g_malloc0(sizeof(struct addrinfo)); + ai = se_alloc0(sizeof(struct addrinfo)); ai->ai_family = AF_INET6; ai->ai_addrlen = sizeof(struct sockaddr_in); ai->ai_canonname = (char *) tp->name; @@ -2898,7 +2926,6 @@ get_ether_name(const guint8 *addr) if (resolve && !eth_resolution_initialized) { initialize_ethers(); - eth_resolution_initialized = TRUE; } tp = eth_name_lookup(addr, resolve); @@ -2922,7 +2949,6 @@ get_ether_name_if_known(const guint8 *addr) if (!eth_resolution_initialized) { initialize_ethers(); - eth_resolution_initialized = TRUE; } /* eth_name_lookup will create a (resolved) hash entry if it doesn't exist */ @@ -2947,7 +2973,6 @@ get_ether_addr(const gchar *name) if (!eth_resolution_initialized) { initialize_ethers(); - eth_resolution_initialized = TRUE; } return eth_addr_lookup(name); @@ -2985,7 +3010,6 @@ get_ipxnet_name(const guint32 addr) if (!ipxnet_resolution_initialized) { initialize_ipxnets(); - ipxnet_resolution_initialized = 1; } return ipxnet_name_lookup(addr); @@ -3002,7 +3026,6 @@ get_ipxnet_addr(const gchar *name, gboolean *known) if (!ipxnet_resolution_initialized) { initialize_ipxnets(); - ipxnet_resolution_initialized = 1; } addr = ipxnet_addr_lookup(name, &success); @@ -3020,7 +3043,6 @@ get_manuf_name(const guint8 *addr) if ((gbl_resolv_flags & RESOLV_MAC) && !eth_resolution_initialized) { initialize_ethers(); - eth_resolution_initialized = TRUE; } if (!(gbl_resolv_flags & RESOLV_MAC) || ((mtp = manuf_name_lookup(addr)) == NULL)) { @@ -3056,7 +3078,6 @@ get_manuf_name_if_known(const guint8 *addr) if (!eth_resolution_initialized) { initialize_ethers(); - eth_resolution_initialized = TRUE; } if ((mtp = manuf_name_lookup(addr)) == NULL) { @@ -3096,7 +3117,6 @@ get_eui64_name(const guint64 addr_eui64) if ((gbl_resolv_flags & RESOLV_MAC) && !eth_resolution_initialized) { initialize_ethers(); - eth_resolution_initialized = TRUE; } if (!(gbl_resolv_flags & RESOLV_MAC) || ((mtp = manuf_name_lookup(addr)) == NULL)) { @@ -3121,7 +3141,6 @@ get_eui64_name_if_known(const guint64 addr_eui64) if (!eth_resolution_initialized) { initialize_ethers(); - eth_resolution_initialized = TRUE; } if ((mtp = manuf_name_lookup(addr)) == NULL) { diff --git a/epan/packet.c b/epan/packet.c index 81d64f4bba..b374b041c4 100644 --- a/epan/packet.c +++ b/epan/packet.c @@ -130,6 +130,13 @@ init_dissection(void) /* Reclaim and reinitialize all memory of seasonal scope */ se_free_all(); + /* + * Reinitialize resolution information. We do initialization here in + * case we need to resolve between captures. + */ + host_name_lookup_cleanup(); + host_name_lookup_init(); + /* Initialize the table of conversations. */ epan_conversation_init(); @@ -169,6 +176,13 @@ cleanup_dissection(void) /* Initialize the expert infos */ expert_cleanup(); + + /* + * Reinitialize resolution information. We do initialization here in + * case we need to resolve between captures. + */ + host_name_lookup_cleanup(); + host_name_lookup_init(); } /* Allow protocols to register a "cleanup" routine to be diff --git a/wiretap/pcapng.c b/wiretap/pcapng.c index 84f4db6e84..096f520c39 100644 --- a/wiretap/pcapng.c +++ b/wiretap/pcapng.c @@ -2140,7 +2140,7 @@ pcapng_open(wtap *wth, int *err, gchar **err_info) return -1; } pcapng_process_idb(wth, pcapng, &wblock); - pcapng_debug2("pcapng_open: Read IDB number_of_interfaces %u, wtap_encap %i", wth->number_of_interfaces, int_data.wtap_encap); + pcapng_debug2("pcapng_open: Read IDB number_of_interfaces %u, wtap_encap %i", wth->number_of_interfaces, *wblock.file_encap); } return 1; } -- cgit v1.2.1