Projects
openEuler:22.03:LTS:LoongArch
bind
_service:tar_scm_kernel_repo:backport-0017-Dela...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm_kernel_repo:backport-0017-Delay-isc__nm_uvreq_t-deallocation-to-connection-cal.patch of Package bind
From 7b8e265a407db4adc14939acc6a3bbacda86bed1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= <ondrej@isc.org> Date: Tue, 22 Feb 2022 18:12:18 +0100 Subject: [PATCH] Delay isc__nm_uvreq_t deallocation to connection callback When the TCP, TCPDNS or TLSDNS connection times out, the isc__nm_uvreq_t would be pushed into sock->inactivereqs before the uv_tcp_connect() callback finishes. Because the isc__nmsocket_t keeps the list of inactive isc__nm_uvreq_t, this would cause use-after-free only when the sock->inactivereqs is full (which could never happen because the failure happens in connection timeout callback) or when the sock->inactivereqs mechanism is completely removed (f.e. when running under Address or Thread Sanitizer). Delay isc__nm_uvreq_t deallocation to the connection callback and only signal the connection callback should be called by shutting down the libuv socket from the connection timeout callback. (cherry picked from commit 326862791689ea7029f381b4afd05c37abbd1fe7) Conflict: NA Reference: https://gitlab.isc.org/isc-projects/bind9/-/commit/7b8e265a407db4adc14939acc6a3bbacda86bed1 --- lib/isc/netmgr/netmgr-int.h | 1 + lib/isc/netmgr/netmgr.c | 19 ++++++++----------- lib/isc/netmgr/tcp.c | 9 +++++---- lib/isc/netmgr/tcpdns.c | 11 ++++++----- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/lib/isc/netmgr/netmgr-int.h b/lib/isc/netmgr/netmgr-int.h index 23b197179a..30f4734171 100644 --- a/lib/isc/netmgr/netmgr-int.h +++ b/lib/isc/netmgr/netmgr-int.h @@ -833,6 +833,7 @@ struct isc_nmsocket { atomic_bool connected; bool accepting; bool reading; + atomic_bool timedout; isc_refcount_t references; /*% diff --git a/lib/isc/netmgr/netmgr.c b/lib/isc/netmgr/netmgr.c index 4bd45e7235..a8e3290f52 100644 --- a/lib/isc/netmgr/netmgr.c +++ b/lib/isc/netmgr/netmgr.c @@ -1509,6 +1509,7 @@ isc___nmsocket_init(isc_nmsocket_t *sock, isc_nm_t *mgr, isc_nmsocket_type type, atomic_init(&sock->connecting, false); atomic_init(&sock->keepalive, false); atomic_init(&sock->connected, false); + atomic_init(&sock->timedout, false); atomic_init(&sock->active_child_connections, 0); @@ -1936,18 +1937,14 @@ isc__nmsocket_connecttimeout_cb(uv_timer_t *timer) { isc__nmsocket_timer_stop(sock); - /* Call the connect callback directly */ - - req->cb.connect(req->handle, ISC_R_TIMEDOUT, req->cbarg); + /* + * Mark the connection as timed out and shutdown the socket. + */ - /* Timer is not running, cleanup and shutdown everything */ - if (!isc__nmsocket_timer_running(sock)) { - INSIST(atomic_compare_exchange_strong(&sock->connecting, - &(bool){ true }, false)); - isc__nm_uvreq_put(&req, sock); - isc__nmsocket_clearcb(sock); - isc__nmsocket_shutdown(sock); - } + INSIST(atomic_compare_exchange_strong(&sock->timedout, &(bool){ false }, + true)); + isc__nmsocket_clearcb(sock); + isc__nmsocket_shutdown(sock); } void diff --git a/lib/isc/netmgr/tcp.c b/lib/isc/netmgr/tcp.c index e562ef2d69..64914c29e3 100644 --- a/lib/isc/netmgr/tcp.c +++ b/lib/isc/netmgr/tcp.c @@ -239,15 +239,16 @@ tcp_connect_cb(uv_connect_t *uvreq, int status) { isc__nmsocket_timer_stop(sock); uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock); - if (!atomic_load(&sock->connecting)) { - return; - } - req = uv_handle_get_data((uv_handle_t *)uvreq); REQUIRE(VALID_UVREQ(req)); REQUIRE(VALID_NMHANDLE(req->handle)); + if (atomic_load(&sock->timedout)) { + result = ISC_R_TIMEDOUT; + goto error; + } + if (!atomic_load(&sock->connecting)) { /* * The connect was cancelled from timeout; just clean up diff --git a/lib/isc/netmgr/tcpdns.c b/lib/isc/netmgr/tcpdns.c index 61a8e6b710..8fa2a43c5f 100644 --- a/lib/isc/netmgr/tcpdns.c +++ b/lib/isc/netmgr/tcpdns.c @@ -206,22 +206,23 @@ tcpdns_connect_cb(uv_connect_t *uvreq, int status) { isc__nmsocket_timer_stop(sock); uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock); - if (!atomic_load(&sock->connecting)) { - return; - } - req = uv_handle_get_data((uv_handle_t *)uvreq); REQUIRE(VALID_UVREQ(req)); REQUIRE(VALID_NMHANDLE(req->handle)); + if (atomic_load(&sock->timedout)) { + result = ISC_R_TIMEDOUT; + goto error; + } + if (isc__nmsocket_closing(sock)) { /* Socket was closed midflight by isc__nm_tcpdns_shutdown() */ result = ISC_R_CANCELED; goto error; } else if (status == UV_ETIMEDOUT) { /* Timeout status code here indicates hard error */ - result = ISC_R_CANCELED; + result = ISC_R_TIMEDOUT; goto error; } else if (status != 0) { result = isc__nm_uverr2result(status); -- 2.23.0
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.