mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-09 04:19:10 -04:00
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. svn:r1384
This commit is contained in:
parent
f8b527e6a1
commit
12199fa7a5
@ -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.
|
||||
|
23
evdns.c
23
evdns.c
@ -386,6 +386,7 @@ static void server_port_ready_callback(evutil_socket_t fd, short events, void *a
|
||||
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 @@ evdns_base_new(struct event_base *event_base, int initialize_nameservers)
|
||||
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,16 +3649,16 @@ evdns_err_to_string(int err)
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
/* TODO(nickm) we might need to refcount here. */
|
||||
/* Requires that we hold the lock. */
|
||||
|
||||
EVDNS_LOCK(base);
|
||||
/* TODO(nickm) we might need to refcount here. */
|
||||
|
||||
for (i = 0; i < base->n_req_heads; ++i) {
|
||||
while (base->req_heads[i]) {
|
||||
@ -3701,12 +3702,20 @@ evdns_base_free(struct evdns_base *base, int fail_requests)
|
||||
mm_free(base);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user