From 4933c216b2f8936930c8557095a0bf269841656d Mon Sep 17 00:00:00 2001 From: victor lum Date: Fri, 26 Apr 2013 14:36:17 +0200 Subject: [PATCH] Fix crash with duplicated initstepslew address When there are duplicate ntp servers listed on the initstepslew line, 2 SourceRecords are created (sourceA and sourceB), and two timers are created (timerA and timerB). When ntp responses are received, only sourceA is updated because of the way read_from_socket searches for a matching record. Eventually, the criteria for sourceA are met, causing timerA to stop and n_completed_sources to increment. timerB continues to trigger, sending ntp poll messages to the ntp server. Responses from that server are assigned to sourceA, triggering the criteria for sourceA and causing n_completed_sources to increment improperly. Once this happens enough times, n_complete_sources == number of servers and all SourceRecords are deleted. The next time timerB triggers, it attempts to access sourceB, which was already been deleted, causing the core. --- acquire.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/acquire.c b/acquire.c index 6b479f8..a35a09b 100644 --- a/acquire.c +++ b/acquire.c @@ -757,6 +757,7 @@ ACQ_StartAcquisition(int n, IPAddr *ip_addrs, int threshold, void (*after_hook)( { int i, ip4, ip6; + int k, duplicate_ip; saved_after_hook = after_hook; saved_after_hook_anything = anything; @@ -765,18 +766,31 @@ ACQ_StartAcquisition(int n, IPAddr *ip_addrs, int threshold, void (*after_hook)( n_started_sources = 0; n_completed_sources = 0; - n_sources = n; + n_sources = 0; sources = MallocArray(SourceRecord, n); for (i = ip4 = ip6 = 0; i < n; i++) { - sources[i].ip_addr = ip_addrs[i]; - sources[i].n_samples = 0; - sources[i].n_total_samples = 0; - sources[i].n_dead_probes = 0; - if (ip_addrs[i].family == IPADDR_INET4) - ip4++; - else if (ip_addrs[i].family == IPADDR_INET6) - ip6++; + /* check for duplicate IP addresses and ignore them */ + duplicate_ip = 0; + for (k = 0; k < i; k++) { + duplicate_ip |= UTI_CompareIPs(&(sources[k].ip_addr), + &ip_addrs[i], + NULL) == 0; + } + if (!duplicate_ip) { + sources[n_sources].ip_addr = ip_addrs[i]; + sources[n_sources].n_samples = 0; + sources[n_sources].n_total_samples = 0; + sources[n_sources].n_dead_probes = 0; + if (ip_addrs[i].family == IPADDR_INET4) + ip4++; + else if (ip_addrs[i].family == IPADDR_INET6) + ip6++; + n_sources++; + } else { + LOG(LOGS_WARN, LOGF_Acquire, "Ignoring duplicate source: %s", + UTI_IPToString(&ip_addrs[i])); + } } initialise_io((ip4 && ip6) ? IPADDR_UNSPEC : (ip4 ? IPADDR_INET4 : IPADDR_INET6));