mirror of
https://github.com/libevent/libevent.git
synced 2025-01-09 00:56:20 +08:00
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
This commit is contained in:
parent
7bcf576b39
commit
5dc88b387f
18
http.c
18
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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user