From: <ni...@us...> - 2009-07-28 17:11:12
|
Revision: 1384 http://levent.svn.sourceforge.net/levent/?rev=1384&view=rev Author: nickm Date: 2009-07-28 17:11:03 +0000 (Tue, 28 Jul 2009) Log Message: ----------- Fix segfault during failed allocatino of locked evdns base. We need to comb the rest of the code to make sure that we don't blindly wrap functions in LOCK(x), UNLOCK(x) when those functions might contain a FREE(x) in the middle. Rocco Carbone found and reported this bug. Modified Paths: -------------- trunk/libevent/ChangeLog trunk/libevent/evdns.c Modified: trunk/libevent/ChangeLog =================================================================== --- trunk/libevent/ChangeLog 2009-07-28 05:09:06 UTC (rev 1383) +++ trunk/libevent/ChangeLog 2009-07-28 17:11:03 UTC (rev 1384) @@ -1,6 +1,7 @@ Changes in 2.0.3-alpha: o Add a new code to support SSL/TLS on bufferevents, using the OpenSSL library (where available). o Fix a bug where we didn't allocate enough memory in event_get_supported_methods(). + o Avoid segfault during failed allocation of locked evdns_base. (Found by Rocco Carbone.) Changes in 2.0.2-alpha: o Add a new flag to bufferevents to make all callbacks automatically deferred. Modified: trunk/libevent/evdns.c =================================================================== --- trunk/libevent/evdns.c 2009-07-28 05:09:06 UTC (rev 1383) +++ trunk/libevent/evdns.c 2009-07-28 17:11:03 UTC (rev 1384) @@ -386,6 +386,7 @@ static int evdns_base_resolv_conf_parse_impl(struct evdns_base *base, int flags, const char *const filename); static int evdns_base_set_option_impl(struct evdns_base *base, const char *option, const char *val, int flags); +static void evdns_base_free_and_unlock(struct evdns_base *base, int fail_requests); static int strtoint(const char *const str); @@ -3608,8 +3609,8 @@ r = evdns_base_resolv_conf_parse(base, DNS_OPTIONS_ALL, "/etc/resolv.conf"); #endif if (r == -1) { - evdns_base_free(base, 0); - base = NULL; + evdns_base_free_and_unlock(base, 0); + return NULL; } } EVDNS_UNLOCK(base); @@ -3648,17 +3649,17 @@ } } -void -evdns_base_free(struct evdns_base *base, int fail_requests) +static void +evdns_base_free_and_unlock(struct evdns_base *base, int fail_requests) { struct nameserver *server, *server_next; struct search_domain *dom, *dom_next; int i; + /* Requires that we hold the lock. */ + /* TODO(nickm) we might need to refcount here. */ - EVDNS_LOCK(base); - for (i = 0; i < base->n_req_heads; ++i) { while (base->req_heads[i]) { if (fail_requests) @@ -3702,11 +3703,19 @@ } void +evdns_base_free(struct evdns_base *base, int fail_requests) +{ + EVDNS_LOCK(base); + evdns_base_free_and_unlock(base, fail_requests); +} + +void evdns_shutdown(int fail_requests) { if (current_base) { - evdns_base_free(current_base, fail_requests); + struct evdns_base *b = current_base; current_base = NULL; + evdns_base_free(b, fail_requests); } evdns_log_fn = NULL; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |