From: Mukund Sivaraman Date: Mon, 29 Jun 2015 14:14:42 +0000 (+0530) Subject: Fix race in getaddrinfo() in libirs, which caused assertion failure in delv (#39873) X-Git-Tag: v9.11.0a1~701 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c44c77178e0bf420483b0dd0af43839bf636a6cc;p=thirdparty%2Fbind9.git Fix race in getaddrinfo() in libirs, which caused assertion failure in delv (#39873) --- diff --git a/CHANGES b/CHANGES index 0ab5a34137d..d94615460ec 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +4149. [bug] Fixed a race condition in the getaddrinfo() + implementation in libirs, which caused the delv + utility to crash with an assertion failure when using + the '@server' syntax with a hostname argument. + [RT #39899] + 4148. [bug] Fix a bug when printing zone names with '/' character in XML and JSON statistics output. [RT #39873] diff --git a/lib/irs/getaddrinfo.c b/lib/irs/getaddrinfo.c index cda7b18bff4..093af0739b9 100644 --- a/lib/irs/getaddrinfo.c +++ b/lib/irs/getaddrinfo.c @@ -138,6 +138,7 @@ #include #include #include +#include #include #include @@ -531,6 +532,7 @@ typedef struct gai_statehead { int ai_port; isc_appctx_t *actx; dns_client_t *dnsclient; + isc_mutex_t list_lock; ISC_LIST(struct gai_resstate) resstates; unsigned int activestates; } gai_statehead_t; @@ -858,6 +860,7 @@ process_answer(isc_task_t *task, isc_event_t *event) { * and have any answer, we can stop now by canceling the * others. */ + LOCK(&resstate->head->list_lock); if (resstate == ISC_LIST_HEAD(resstate->head->resstates)) { if ((resstate->trans4 != NULL && resstate->trans4->ai_sentinel.ai_next != NULL) || @@ -889,6 +892,7 @@ process_answer(isc_task_t *task, isc_event_t *event) { resstate, link); } } + UNLOCK(&resstate->head->list_lock); } } @@ -929,11 +933,19 @@ resolve_name(int family, const char *hostname, int flags, head.ai_port = port; head.actx = actx; head.dnsclient = client; + result = isc_mutex_init(&head.list_lock); + if (result != ISC_R_SUCCESS) { + return (EAI_FAIL); + } + ISC_LIST_INIT(head.resstates); result = make_resstates(mctx, hostname, &head, conf); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { + DESTROYLOCK(&head.list_lock); return (EAI_FAIL); + } + LOCK(&head.list_lock); for (resstate = ISC_LIST_HEAD(head.resstates); resstate != NULL; resstate = ISC_LIST_NEXT(resstate, link)) { if (resstate->trans4 != NULL) { @@ -967,6 +979,8 @@ resolve_name(int family, const char *hostname, int flags, resstate->trans6->is_inprogress= ISC_FALSE; } } + UNLOCK(&head.list_lock); + if (!all_fail) { /* Start all the events */ isc_app_ctxrun(actx); @@ -1038,6 +1052,7 @@ resolve_name(int family, const char *hostname, int flags, irs_context_destroy(&irsctx); #endif + DESTROYLOCK(&head.list_lock); return (error); }