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)
This commit is contained in:
Azat Khuzhin 2018-11-13 21:26:12 +03:00 committed by Azat Khuzhin
parent 74517b2a11
commit 6ac2ec2500
No known key found for this signature in database
GPG Key ID: B86086848EF8686D

18
http.c
View File

@ -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)