From afc7389ce8fb0fd5a360cb9a48b4db874aa230e2 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Fri, 22 Nov 2019 11:55:47 +1100 Subject: [PATCH 1/3] lock disp->mgr before reading disp->mgr->buffers --- lib/dns/dispatch.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c index 4a77b7fe45..6cd2fd7fe3 100644 --- a/lib/dns/dispatch.c +++ b/lib/dns/dispatch.c @@ -1045,9 +1045,11 @@ udp_recv(isc_event_t *ev_in, dns_dispatch_t *disp, dispsocket_t *dispsock) { mgr = disp->mgr; qid = mgr->qid; + LOCK(&disp->mgr->buffer_lock); dispatch_log(disp, LVL(90), "got packet: requests %d, buffers %d, recvs %d", disp->requests, disp->mgr->buffers, disp->recv_pending); + UNLOCK(&disp->mgr->buffer_lock); if (dispsock == NULL && ev->ev_type == ISC_SOCKEVENT_RECVDONE) { /* From 011af4de71f54743e650746c9ab7db80d1636800 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Fri, 22 Nov 2019 12:55:03 +1100 Subject: [PATCH 2/3] Lock dispatch manager buffer_lock before accessing buffers; Only test buffers for UDP dispatches. --- lib/dns/dispatch.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c index 6cd2fd7fe3..2e534d26c3 100644 --- a/lib/dns/dispatch.c +++ b/lib/dns/dispatch.c @@ -1500,8 +1500,14 @@ startrecv(dns_dispatch_t *disp, dispsocket_t *dispsock) { if (disp->recv_pending != 0 && dispsock == NULL) return (ISC_R_SUCCESS); - if (disp->mgr->buffers >= disp->mgr->maxbuffers) - return (ISC_R_NOMEMORY); + if (disp->socktype == isc_sockettype_udp) { + LOCK(&disp->mgr->buffer_lock); + if (disp->mgr->buffers >= disp->mgr->maxbuffers) { + UNLOCK(&disp->mgr->buffer_lock); + return (ISC_R_NOMEMORY); + } + UNLOCK(&disp->mgr->buffer_lock); + } if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0 && dispsock == NULL) From 26a93d77aa17bea5e0a67623558cd3cdcf10009b Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Mon, 25 Nov 2019 11:38:09 +1100 Subject: [PATCH 3/3] move maxbuffers test to allocate_udp_buffer --- lib/dns/dispatch.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c index 2e534d26c3..c70ee9fa25 100644 --- a/lib/dns/dispatch.c +++ b/lib/dns/dispatch.c @@ -915,6 +915,10 @@ allocate_udp_buffer(dns_dispatch_t *disp) { void *temp; LOCK(&disp->mgr->buffer_lock); + if (disp->mgr->buffers >= disp->mgr->maxbuffers) { + UNLOCK(&disp->mgr->buffer_lock); + return (NULL); + } bpool = disp->mgr->bpool; disp->mgr->buffers++; UNLOCK(&disp->mgr->buffer_lock); @@ -1500,15 +1504,6 @@ startrecv(dns_dispatch_t *disp, dispsocket_t *dispsock) { if (disp->recv_pending != 0 && dispsock == NULL) return (ISC_R_SUCCESS); - if (disp->socktype == isc_sockettype_udp) { - LOCK(&disp->mgr->buffer_lock); - if (disp->mgr->buffers >= disp->mgr->maxbuffers) { - UNLOCK(&disp->mgr->buffer_lock); - return (ISC_R_NOMEMORY); - } - UNLOCK(&disp->mgr->buffer_lock); - } - if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0 && dispsock == NULL) return (ISC_R_SUCCESS);