This is the mail archive of the libc-hacker@sourceware.cygnus.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Fwd: Bug#42343: libc6: gethostbyaddr() can hang indefinitely


[ This is a bug report forwarded from the Debian Bug Tracking System, 
please keep 42343-forwarded@bugs.debian.org in the cc list so any 
replies are recorded by the BTS ]

-- begin forwarded text --
Subject: Bug#42343: libc6: gethostbyaddr() can hang indefinitely
Reply-To: Miquel van Smoorenburg <miquels@cistron.nl>, 42343@bugs.debian.org
Date: Mon, 2 Aug 1999 19:41:30 +0200
From: Miquel van Smoorenburg <miquels@cistron.nl>
To: submit@bugs.debian.org

Package: libc6
Version: 2.1.2-0pre2
Severity: important

This bug was not present in 2.0, but is in 2.1 and up.

The resolver routines that glibc uses use select() internally. If the
select() gets interrupted, it gets restarted, but the timeout value
is re-initialized. If you have a timer in your program that uses
signal(SIGALRM)/alarm() and it runs more often than the select timeout,
gethostbyaddr() for example will hang forever if a DNS packet gets lost.

How to reproduce:

- compile the following sample program
- add a bogus route to your nameserver, temporarily sabotaging name
   lookup. My nameserver is at 195.64.65.25, so I did:
   # route add -host 195.64.65.25 dev lo
- start the following sample program with an IP number as the first
   argument, for example ./a.out 195.64.65.25.
- You can now delete the sabotaged route with
   # route del 195.64.65.25
- the sample program will hang forever in select():

(gdb) where
#0  0x400ab9ae in select () from /lib/libc.so.6
#1  0x400ece18 in __DTOR_END__ () from /lib/libc.so.6
#2  0x400aa38f in poll () from /lib/libc.so.6
#3  0x40107739 in __res_send () from /lib/libresolv.so.2
#4  0x4010687f in res_query () from /lib/libresolv.so.2
#5  0x400fc080 in _nss_dns_gethostbyaddr_r () from /lib/libnss_dns.so.2
#6  0x400c18a2 in gethostbyaddr_r () from /lib/libc.so.6
#7  0x400c1688 in gethostbyaddr () from /lib/libc.so.6
#8  0x804863d in main ()

This is really a problem since for example rpc.mountd hangs at least
once a day on all our NFS serving Linux boxes that run glibc 2.1 and up.

#include <stdio.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>

void alrm_handler(int sig)
{
	alarm(2);
}

int main(int argc, char **argv)
{
	struct in_addr		a;
	struct hostent		*h;
	struct sigaction	sa;

	sa.sa_handler = alrm_handler;
	sa.sa_flags   = 0;
	sigemptyset(&sa.sa_mask);
	sigaction(SIGALRM, &sa, NULL);
	alarm(2);

	if (inet_aton(argv[1], &a) == 0) {
		perror(argv[1]);
		exit(1);
	}

	if ((h = gethostbyaddr(&a, sizeof(a), AF_INET)) == NULL) {
		herror(argv[1]);
		exit(1);
	}

	printf("%s\n", h->h_name);

	return 0;
}

Mike.
-- 
... somehow I have a feeling the hurting hasn't even begun yet
	-- Bill, "The Terrible Thunderlizards"
-- end forwarded text --
-- 
Joel Klecker (aka Espy)                    Debian GNU/Linux Developer
<URL:mailto:jk@espy.org>                 <URL:mailto:espy@debian.org>
<URL:http://web.espy.org/>               <URL:http://www.debian.org/>

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]