From 4f06e658d1a10a2782a475e76cb0c4d308e08f7c Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Wed, 9 Apr 2025 14:13:58 +0200 Subject: [PATCH] - Fix #1264: unbound 1.22.0 leaks memory when doing DoH. --- doc/Changelog | 3 ++ util/netevent.c | 82 ++++++++++++++++++++++++++++--------------------- 2 files changed, 50 insertions(+), 35 deletions(-) diff --git a/doc/Changelog b/doc/Changelog index 7d3ea168b..2276329e5 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,6 @@ +9 April 2025: Wouter + - Fix #1264: unbound 1.22.0 leaks memory when doing DoH. + 8 April 2025: Wouter - Tag for 1.23.0rc1. diff --git a/util/netevent.c b/util/netevent.c index da8430e41..f9dff1f9a 100644 --- a/util/netevent.c +++ b/util/netevent.c @@ -3057,7 +3057,7 @@ int comm_point_perform_accept(struct comm_point* c, if(verbosity >= 3) log_err_addr("accept rejected", "connection limit exceeded", addr, *addrlen); - close(new_fd); + sock_close(new_fd); return -1; } } @@ -3158,6 +3158,40 @@ static int http2_submit_settings(struct http2_session* h2_session) } #endif /* HAVE_NGHTTP2 */ +#ifdef HAVE_NGHTTP2 +/** Delete http2 stream. After session delete or stream close callback */ +static void http2_stream_delete(struct http2_session* h2_session, + struct http2_stream* h2_stream) +{ + if(h2_stream->mesh_state) { + mesh_state_remove_reply(h2_stream->mesh, h2_stream->mesh_state, + h2_session->c); + h2_stream->mesh_state = NULL; + } + http2_req_stream_clear(h2_stream); + free(h2_stream); +} +#endif /* HAVE_NGHTTP2 */ + +/** delete http2 session server. After closing connection. */ +static void http2_session_server_delete(struct http2_session* h2_session) +{ +#ifdef HAVE_NGHTTP2 + struct http2_stream* h2_stream, *next; + nghttp2_session_del(h2_session->session); /* NULL input is fine */ + h2_session->session = NULL; + for(h2_stream = h2_session->first_stream; h2_stream;) { + next = h2_stream->next; + http2_stream_delete(h2_session, h2_stream); + h2_stream = next; + } + h2_session->first_stream = NULL; + h2_session->is_drop = 0; + h2_session->postpone_drop = 0; + h2_session->c->h2_stream = NULL; +#endif + (void)h2_session; +} void comm_point_tcp_accept_callback(int fd, short event, void* arg) @@ -3196,6 +3230,8 @@ comm_point_tcp_accept_callback(int fd, short event, void* arg) if(!c_hdl->h2_session || !http2_submit_settings(c_hdl->h2_session)) { log_warn("failed to submit http2 settings"); + if(c_hdl->h2_session) + http2_session_server_delete(c_hdl->h2_session); return; } if(!c->ssl) { @@ -3213,14 +3249,23 @@ comm_point_tcp_accept_callback(int fd, short event, void* arg) } if(!c_hdl->ev->ev) { log_warn("could not ub_event_new, dropped tcp"); +#ifdef HAVE_NGHTTP2 + if(c_hdl->type == comm_http && c_hdl->h2_session) + http2_session_server_delete(c_hdl->h2_session); +#endif return; } log_assert(fd != -1); (void)fd; new_fd = comm_point_perform_accept(c, &c_hdl->repinfo.remote_addr, &c_hdl->repinfo.remote_addrlen); - if(new_fd == -1) + if(new_fd == -1) { +#ifdef HAVE_NGHTTP2 + if(c_hdl->type == comm_http && c_hdl->h2_session) + http2_session_server_delete(c_hdl->h2_session); +#endif return; + } /* Copy remote_address to client_address. * Simplest way/time for streams to do that. */ c_hdl->repinfo.client_addrlen = c_hdl->repinfo.remote_addrlen; @@ -5035,19 +5080,6 @@ struct http2_stream* http2_stream_create(int32_t stream_id) h2_stream->stream_id = stream_id; return h2_stream; } - -/** Delete http2 stream. After session delete or stream close callback */ -static void http2_stream_delete(struct http2_session* h2_session, - struct http2_stream* h2_stream) -{ - if(h2_stream->mesh_state) { - mesh_state_remove_reply(h2_stream->mesh, h2_stream->mesh_state, - h2_session->c); - h2_stream->mesh_state = NULL; - } - http2_req_stream_clear(h2_stream); - free(h2_stream); -} #endif void http2_stream_add_meshstate(struct http2_stream* h2_stream, @@ -5064,26 +5096,6 @@ void http2_stream_remove_mesh_state(struct http2_stream* h2_stream) h2_stream->mesh_state = NULL; } -/** delete http2 session server. After closing connection. */ -static void http2_session_server_delete(struct http2_session* h2_session) -{ -#ifdef HAVE_NGHTTP2 - struct http2_stream* h2_stream, *next; - nghttp2_session_del(h2_session->session); /* NULL input is fine */ - h2_session->session = NULL; - for(h2_stream = h2_session->first_stream; h2_stream;) { - next = h2_stream->next; - http2_stream_delete(h2_session, h2_stream); - h2_stream = next; - } - h2_session->first_stream = NULL; - h2_session->is_drop = 0; - h2_session->postpone_drop = 0; - h2_session->c->h2_stream = NULL; -#endif - (void)h2_session; -} - #ifdef HAVE_NGHTTP2 void http2_session_add_stream(struct http2_session* h2_session, struct http2_stream* h2_stream) -- 2.47.2