diff --git a/CHANGES b/CHANGES index a3cdfd302a..02859da2fd 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,10 @@ +2662. [bug] lwres_getipnodebyname() and lwres_getipnodebyaddr() + returned a misleading error code when lwresd was + down. [RT #20028] + +2661. [bug] Check whether socket fd exceeds FD_SETSIZE when + creating lwres context. [RT #20029] + 2656. [func] win32: add a "tools only" check box to the installer which causes it to only install dig, host, nslookup, nsupdate and relevent dlls. [RT #19998] diff --git a/lib/lwres/context.c b/lib/lwres/context.c index 464a2cf9f2..71bc885380 100644 --- a/lib/lwres/context.c +++ b/lib/lwres/context.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: context.c,v 1.50.332.2 2008/12/30 23:46:49 tbox Exp $ */ +/* $Id: context.c,v 1.50.332.3 2009/09/01 06:03:11 each Exp $ */ /*! \file context.c lwres_context_create() creates a #lwres_context_t structure for use in @@ -471,6 +471,17 @@ lwres_context_sendrecv(lwres_context_t *ctx, result = lwres_context_send(ctx, sendbase, sendlen); if (result != LWRES_R_SUCCESS) return (result); + + /* + * If this is not checked, select() can overflow, + * causing corruption elsewhere. + */ + if (ctx->sock >= FD_SETSIZE) { + close(ctx->sock); + ctx->sock = -1; + return (LWRES_R_IOERROR); + } + again: FD_ZERO(&readfds); FD_SET(ctx->sock, &readfds); diff --git a/lib/lwres/getipnode.c b/lib/lwres/getipnode.c index c729e3d1cd..0db40ca291 100644 --- a/lib/lwres/getipnode.c +++ b/lib/lwres/getipnode.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: getipnode.c,v 1.42.332.3 2009/08/15 23:47:15 tbox Exp $ */ +/* $Id: getipnode.c,v 1.42.332.4 2009/09/01 06:03:11 each Exp $ */ /*! \file */ @@ -202,7 +202,7 @@ lwres_getipnodebyname(const char *name, int af, int flags, int *error_num) { struct in6_addr in6; struct hostent he, *he1 = NULL, *he2 = NULL, *he3 = NULL; int v4 = 0, v6 = 0; - int tmp_err; + int tmp_err = 0; lwres_context_t *lwrctx = NULL; lwres_gabnresponse_t *by = NULL; int n; @@ -275,7 +275,6 @@ lwres_getipnodebyname(const char *name, int af, int flags, int *error_num) { (void) lwres_conf_parse(lwrctx, lwres_resolv_conf); tmp_err = NO_RECOVERY; if (have_v6 && af == AF_INET6) { - n = lwres_getaddrsbyname(lwrctx, name, LWRES_ADDRTYPE_V6, &by); if (n == 0) { he1 = hostfromname(by, AF_INET6); @@ -285,7 +284,12 @@ lwres_getipnodebyname(const char *name, int af, int flags, int *error_num) { goto cleanup; } } else { - tmp_err = HOST_NOT_FOUND; + if (n == LWRES_R_NOTFOUND) + tmp_err = HOST_NOT_FOUND; + else { + *error_num = NO_RECOVERY; + goto cleanup; + } } } @@ -311,7 +315,7 @@ lwres_getipnodebyname(const char *name, int af, int flags, int *error_num) { } else *error_num = tmp_err; - he3 = copyandmerge(he1, he2, af, error_num); + he3 = copyandmerge(he1, he2, af, error_num); cleanup: if (he1 != NULL) @@ -437,9 +441,15 @@ lwres_getipnodebyaddr(const void *src, size_t len, int af, int *error_num) { if (n != 0) { lwres_conf_clear(lwrctx); lwres_context_destroy(&lwrctx); - *error_num = HOST_NOT_FOUND; + + if (n == LWRES_R_NOTFOUND) + *error_num = HOST_NOT_FOUND; + else + *error_num = NO_RECOVERY; + return (NULL); } + he1 = hostfromaddr(by, AF_INET6, src); lwres_gnbaresponse_free(lwrctx, &by); if (he1 == NULL)