From 4db15e09a9579a5d1df7748900fdb00f01a2fbe4 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Thu, 24 Mar 2016 12:49:47 +0300 Subject: [PATCH] evdns: avoid double-free in evdns_base_free() for probing requests http/cancel_by_host_no_ns: OK ../test/regress_http.c:1384: assert(regress_dnsserver(data->base, &portnum, search_table)) OK ../test/regress_http.c:1387: assert(dns_base) OK ../test/regress_http.c:1423: assert(evcon) OK ../test/regress_http.c:1444: assert(evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/delay") != -1): 0 vs -1 OK ../test/regress_http.c:1455: assert(test_ok == 2): 2 vs 2 OK ../test/regress_http.c:1480: assert(evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") != -1): 0 vs -1[msg] Nameserver 127.0.0.1:55948 has failed: request timed out. [msg] All nameservers have failed OK ../test/regress_http.c:1274: assert(!req) OK ../test/regress_http.c:1505: assert(evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") != -1): 0 vs -1 OK ../test/regress_http.c:1274: assert(!req)==19199== Invalid read of size 8 ==19199== at 0x4CC285: evdns_cancel_request (evdns.c:2849) ==19199== by 0x4CEDB2: evdns_nameserver_free (evdns.c:4018) ==19199== by 0x4CEF5B: evdns_base_free_and_unlock (evdns.c:4052) ==19199== by 0x4CF13B: evdns_base_free (evdns.c:4088) ==19199== by 0x4617A3: http_cancel_test (regress_http.c:1518) ==19199== by 0x490A78: testcase_run_bare_ (tinytest.c:105) ==19199== by 0x490D5A: testcase_run_one (tinytest.c:252) ==19199== by 0x491699: tinytest_main (tinytest.c:434) ==19199== by 0x47E0E0: main (regress_main.c:461) ==19199== Address 0x61e56d0 is 0 bytes inside a block of size 48 free'd ==19199== at 0x4C2AE6B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==19199== by 0x4AAFFF: event_mm_free_ (event.c:3516) ==19199== by 0x4C5ADD: request_finished (evdns.c:693) ==19199== by 0x4CEE95: evdns_base_free_and_unlock (evdns.c:4040) ==19199== by 0x4CF13B: evdns_base_free (evdns.c:4088) ==19199== by 0x4617A3: http_cancel_test (regress_http.c:1518) ==19199== by 0x490A78: testcase_run_bare_ (tinytest.c:105) ==19199== by 0x490D5A: testcase_run_one (tinytest.c:252) ==19199== by 0x491699: tinytest_main (tinytest.c:434) ==19199== by 0x47E0E0: main (regress_main.c:461) ==19199== Block was alloc'd at ==19199== at 0x4C2BBD5: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==19199== by 0x4AAEB2: event_mm_calloc_ (event.c:3459) ==19199== by 0x4CAAA2: nameserver_send_probe (evdns.c:2327) ==19199== by 0x4C50FF: nameserver_prod_callback (evdns.c:494) ==19199== by 0x4A564C: event_process_active_single_queue (event.c:1646) ==19199== by 0x4A5B95: event_process_active (event.c:1738) ==19199== by 0x4A6296: event_base_loop (event.c:1961) ==19199== by 0x4A5C1D: event_base_dispatch (event.c:1772) ==19199== by 0x46172C: http_cancel_test (regress_http.c:1507) ==19199== by 0x490A78: testcase_run_bare_ (tinytest.c:105) ==19199== by 0x490D5A: testcase_run_one (tinytest.c:252) ==19199== by 0x491699: tinytest_main (tinytest.c:434) ==19199== --- evdns.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/evdns.c b/evdns.c index 152ba766..905ff6b5 100644 --- a/evdns.c +++ b/evdns.c @@ -4009,7 +4009,7 @@ static void evdns_nameserver_free(struct nameserver *server) { if (server->socket >= 0) - evutil_closesocket(server->socket); + evutil_closesocket(server->socket); (void) event_del(&server->event); event_debug_unassign(&server->event); if (server->state == 0) @@ -4049,6 +4049,8 @@ evdns_base_free_and_unlock(struct evdns_base *base, int fail_requests) for (server = base->server_head; server; server = server_next) { server_next = server->next; + /** already done something before */ + server->probe_request = NULL; evdns_nameserver_free(server); if (server_next == base->server_head) break; -- 2.50.1