Date: Fri, 10 Mar 2000 21:59:30 -0800 (PST) From: Pavlin Ivanov Radoslavov <pavlin@catarina.usc.edu> To: FreeBSD-gnats-submit@freebsd.org Cc: pavlin@catarina.usc.edu Subject: misc/17310: NIS host name resolving may loop forever Message-ID: <200003110559.VAA78295@catarina.usc.edu>
next in thread | raw e-mail | index | archive | help
>Number: 17310
>Category: misc
>Synopsis: NIS host name resolving may loop forever
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Fri Mar 10 22:00:02 PST 2000
>Closed-Date:
>Last-Modified:
>Originator: Pavlin Radoslavov
>Release: FreeBSD 3.2-RELEASE i386 (but eventually true for -current)
>Organization:
USC, Dept. of CS
>Environment:
A FreeBSD NIS client. The NIS server is also FreeBSD.
FreeBSD-3.2, but I think that the same problem is in -current as well
>Description:
In some cases, resolving a host name may loop forever (inside
libc): After a NIS client sends the query to the NIS server,
if the NIS server tries to use a DNS query on its own to
resolve the name, and if the DNS query doesn't return
immediately any result (a success or a failure, i.e. it is left
to expire), the query of the NIS client itself may expire
before it gets any answer from the NIS server (which is waiting
for the DNS query to complete). However, the libc code doesn't
handle properly this situation, and it will enter an infinite
loop trying to resolve the host name.
The situation is very unplesant for programs like sendmail,
because the result will be that a sendmail process will
be blocked by this infinite loop and will not be able to
deliver the email to the rest of the recepients.
>How-To-Repeat:
Compile and execute the following code. Note that the problem
can be observed only if the particular IP address is such
that it takes at least 30-60 seconds for "nslookup" to timeout:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
int
main()
{
struct in_addr in;
struct hostent *hp;
/*
Nothing personal regarding address "200.230.88.4". It is just that
my DNS query fails for this address with "Server failed"
after approx. 30-60 seconds:
pavlin@xanadu[11] nslookup 200.230.88.4
Server: catarina.usc.edu
Address: 128.125.51.47
*** catarina.usc.edu can't find 200.230.88.4: Server failed
*/
inet_aton("200.230.88.4", &in);
hp = gethostbyaddr((char *)&in, sizeof(in), AF_INET);
if (hp) {
printf("OK\n");
} else {
printf("FAILURE\n");
}
exit (0);
}
If the chosen IP address is appropriate, you should see the loop:
pavlin@catarina[284] ./a.out
yp_match: clnt_call: RPC: Timed out
yp_match: clnt_call: RPC: Timed out
yp_match: clnt_call: RPC: Timed out
yp_match: clnt_call: RPC: Timed out
yp_match: clnt_call: RPC: Timed out
...
>Fix:
Apply the following patch to src/lib/libc/yp/yplib.c, then
recomplile libc and install it. However, this solution
will just break the infinite loop to "only" 20 loops.
A better solution is the fix the NIS server to cache
its recent results, such that after the first timeout
of the client's request, the second request will hit
the negative answer at the server, and then the
client will immediately return an error instead of looping
20 times. Note that yplib.c has a number of other places
that introduce the same potential danger for infinitive loop.
Search for "again:", and add there a similar counter
that would break the infinitive loop.
--- yplib.c.org Fri Mar 6 21:06:10 1998
+++ yplib.c Fri Mar 10 16:17:02 2000
@@ -623,6 +623,7 @@
struct timeval tv;
struct ypreq_key yprk;
int r;
+ int retries = 0;
*outval = NULL;
*outvallen = 0;
@@ -657,6 +658,11 @@
#endif
again:
+ retries++;
+ if (retries > MAX_RETRIES) {
+ xdr_free(xdr_ypresp_val, (char *)&yprv);
+ return YPERR_YPERR;
+ }
if( _yp_dobind(indomain, &ysd) != 0)
return YPERR_DOMAIN;
>Release-Note:
>Audit-Trail:
>Unformatted:
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200003110559.VAA78295>
