From 6ac2ec2500e004b9169bd6987e49572dc4685262 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 13 Nov 2018 21:26:12 +0300 Subject: [PATCH] Fix conceivable UAF of the bufferevent in evhttp_connection_free() Although this is not a problem, since bufferevent uses finalizers and will free itself only from the loop (well this is not a problem if you do not play games with various event_base in different threads) it generates questions, so rewrite it in more reliable way. Fixes: #712 (cherry picked from commit 5dc88b387f7baa4bcd528832e94987a85be3b263) --- http.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/http.c b/http.c index f7c6490f..8677bba1 100644 --- a/http.c +++ b/http.c @@ -1203,6 +1203,7 @@ void evhttp_connection_free(struct evhttp_connection *evcon) { struct evhttp_request *req; + int need_close = 0; /* notify interested parties that this connection is going down */ if (evcon->fd != -1) { @@ -1229,21 +1230,22 @@ evhttp_connection_free(struct evhttp_connection *evcon) event_debug_unassign(&evcon->retry_ev); } - if (evcon->bufev != NULL) - bufferevent_free(evcon->bufev); - event_deferred_cb_cancel_(get_deferred_queue(evcon), &evcon->read_more_deferred_cb); - if (evcon->fd == -1) - evcon->fd = bufferevent_getfd(evcon->bufev); + if (evcon->bufev != NULL) { + need_close = + !(bufferevent_get_options_(evcon->bufev) & BEV_OPT_CLOSE_ON_FREE); + if (evcon->fd == -1) + evcon->fd = bufferevent_getfd(evcon->bufev); + + bufferevent_free(evcon->bufev); + } if (evcon->fd != -1) { - bufferevent_disable(evcon->bufev, EV_READ|EV_WRITE); shutdown(evcon->fd, EVUTIL_SHUT_WR); - if (!(bufferevent_get_options_(evcon->bufev) & BEV_OPT_CLOSE_ON_FREE)) { + if (need_close) evutil_closesocket(evcon->fd); - } } if (evcon->bind_address != NULL)