[PATCH] no-MMU : missing /etc/host causes getaddrinfo() crash

André Tousch andre.tousch at stepmind.com
Thu Feb 16 12:33:02 UTC 2006


Hi

Bug description:
- uClibc versions : <= 0.28
- Symptoms : crash when invoking getaddrinfo() when no /etc/host file exist
- platform : uClinux (no MMU)
- cause : This is due to an improper message error handling in  
gaih_inet(), which make memory allocations on the stack (alloca) until  
gethostbyaddr returns no error -- which will never happen if there is no  
/host file. So on no-MMU systems we get a stack overflow.

The quick and dirty patch below adresses the issue (exit with error when  
there is no /etc/host); however, a more complete solution should be found,  
since the /etc/host file presence is not mandatory. The lack of commentary  
and clarity in the code made me reluctant to do that (too much time needed  
to understand the thing).

Regards,

André


diff -Nru uClibc/libc/inet/getaddrinfo.c uClibc_ok/libc/inet/getaddrinfo.c
--- uClibc/libc/inet/getaddrinfo.c	2005-05-30 14:40:20.000000000 +0200
+++ uClibc_ok/libc/inet/getaddrinfo.c	2005-10-07 17:19:17.000000000 +0200
@@ -623,16 +623,18 @@

  		int herrno;
  		struct hostent th;
-		size_t tmpbuflen = 512;
-		char *tmpbuf;
+		size_t tmpbuflen = 1024;
+		char *tmpbuf = malloc(tmpbuflen);
+                if (tmpbuf == NULL)
+			return -EAI_MEMORY;

-		do
-		{
-		    tmpbuflen *= 2;
-		    tmpbuf = alloca (tmpbuflen);
+//		do
+//		{
+//		    tmpbuflen *= 2;
+//		    tmpbuf = alloca (tmpbuflen);

-		    if (tmpbuf == NULL)
-			return -EAI_MEMORY;
+//		    if (tmpbuf == NULL)
+//			return -EAI_MEMORY;

  		    rc = gethostbyaddr_r (at2->addr,
  					  ((at2->family == AF_INET6)
@@ -640,10 +642,10 @@
  					   : sizeof(struct in_addr)),
  					  at2->family, &th, tmpbuf, tmpbuflen,
  					  &h, &herrno);
-
-		}
-		while (rc == errno && herrno == NETDB_INTERNAL);
-
+
+//		}
+//		while (rc == errno && herrno == NETDB_INTERNAL);
+                    free(tmpbuf);
  		if (rc != 0 && herrno == NETDB_INTERNAL)
  		{
  		    __set_h_errno (herrno);



More information about the uClibc mailing list