From: Stephan Bosch Date: Tue, 29 Jan 2019 21:16:26 +0000 (+0100) Subject: lib-http: client: Fix segfault occurring when an idle host times out. X-Git-Tag: 2.3.9~533 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ae6a483974149e8e4c99343202b6a816505767a3;p=thirdparty%2Fdovecot%2Fcore.git lib-http: client: Fix segfault occurring when an idle host times out. This is most visible when the host is associated with an invalid host name: in that case the idle timeout is only 100ms. For valid hosts, this problem can only appear after 30 minutes idle time (default). Problem is caused by the session host object starting a new idle timeout in the shared host, while the shared and session host objects are both being destroyed. --- diff --git a/src/lib-http/http-client-host.c b/src/lib-http/http-client-host.c index 3fc7cd51cb..701558e4f5 100644 --- a/src/lib-http/http-client-host.c +++ b/src/lib-http/http-client-host.c @@ -24,6 +24,7 @@ http_client_host_lookup_failure(struct http_client_host *host, const char *error); static bool http_client_host_is_idle(struct http_client_host *host); +static void http_client_host_free_shared(struct http_client_host **_host); /* * Host (shared) @@ -281,7 +282,7 @@ void http_client_host_shared_free(struct http_client_host_shared **_hshared) /* drop client sessions */ while (hshared->hosts_list != NULL) { host = hshared->hosts_list; - http_client_host_free(&host); + http_client_host_free_shared(&host); } event_unref(&hshared->event); @@ -347,8 +348,7 @@ http_client_host_get(struct http_client *client, return host; } -void http_client_host_free( - struct http_client_host **_host) +static void http_client_host_free_shared(struct http_client_host **_host) { struct http_client_host *host = *_host; struct http_client *client = host->client; @@ -356,6 +356,8 @@ void http_client_host_free( struct http_client_queue *const *queue_idx; ARRAY_TYPE(http_client_queue) queues; + *_host = NULL; + e_debug(hshared->event, "Host session destroy"); DLLIST_REMOVE_FULL(&hshared->hosts_list, @@ -374,9 +376,16 @@ void http_client_host_free( array_free(&host->queues); i_free(host); +} + +void http_client_host_free(struct http_client_host **_host) +{ + struct http_client_host *host = *_host; + struct http_client_host_shared *hshared = host->shared; + + http_client_host_free_shared(_host); http_client_host_shared_check_idle(hshared); - *_host = NULL; } static void