Subject: lib/10048: /etc/hosts lookup failure
To: None <gnats-bugs@gnats.netbsd.org>
From: None <jtc@redback.com>
List: netbsd-bugs
Date: 05/04/2000 17:21:11
>Number:         10048
>Category:       lib
>Synopsis:       /etc/hosts lookup failure
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu May 04 17:22:00 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator:     
>Release:        NetBSD-current, 2000-05-01
>Organization:
RedBack Networks
>Environment:
System: NetBSD powermac 1.4X NetBSD 1.4X (GENERIC) #0: Wed May  3 09:19:49 PDT 2000     jtc@powermac:/usr/src/sys/arch/macppc/compile/GENERIC macppc

>Description:
After installing NetBSD on my powermac, I discovered some programs
were not able to look up IP addresses from hostnames in /etc/hosts
properly.  Using tcpdump, I discovered that the programs that failed
were using bogus addresses.  The addresses for a given host were not
consistant.

I tracked this down to _gethtbyname2() in gethnamaddr.c.  When the
function finds the first matching host entry, it allocates a temporary
buffer for the host name, the host aliases, and MAXADDRS addresses. It
copies the host name and aliases to the buffer, and then aligns the
pointer before appending the host address.  For subsequent matching
host entries, the host address is simply appended to the buffer.

After all the host entries have been processed, the temporary buffer
is copied to a static buffer and freed.  The buffer is then unpacked
and pointers to the host name, the host aliases, and addresses, are
extracted.  Like when the buffer was originally constructed, after 
the host name and host aliases are processed, the pointer is aligned
before the host addresses are processed.

The problem arises because the temporary buffer allocated with
malloc() and the static buffer don't necessarily have the same
alignment.  In this case, the temp buffer is going to be aligned on
an 8 byte boundry, and the static buffer may have any alignment.

I solved my immediate problem by commenting out the two lines that
align the pointer.  This may not be the most applicable solution.  I
assume the alignment is present for the combination of architectures
that don't support misaligned accesses and programs that dereference
hp->h_addr directly instead of treating it as opaque data and copies
the hp->h_length bytes at hp->h_addr.

If this is important, this could be fixed by changing:
	ptr = memcpy(hostbuf, tmpbuf, len);

To something like this:
	ptr = (char *) ALIGN(hostbuf);
	memcpy (ptr, tmpbuf, len);


>How-To-Repeat:
	
>Fix:
*** gethnamaddr.c~	Wed Apr 26 03:13:05 2000
--- gethnamaddr.c	Thu May  4 14:53:04 2000
***************
*** 891,898 ****
  				while ((*ptr++ = *src++) != '\0');
  			}
  			*ptr++ = '\0';
! 
  			ptr = (char *)(void *)ALIGN(ptr);
  		}
  
  		(void)memcpy(ptr, p->h_addr_list[0], (size_t)p->h_length);
--- 891,899 ----
  				while ((*ptr++ = *src++) != '\0');
  			}
  			*ptr++ = '\0';
! #if 0
  			ptr = (char *)(void *)ALIGN(ptr);
+ #endif
  		}
  
  		(void)memcpy(ptr, p->h_addr_list[0], (size_t)p->h_length);
***************
*** 923,929 ****
--- 924,932 ----
  	ptr++;
  	*cp = NULL;
  
+ #if 0
  	ptr = (char *)(void *)ALIGN(ptr);
+ #endif
  	cp = h_addr_ptrs;
  	while (num--) {
  		*cp++ = ptr;

>Release-Note:
>Audit-Trail:
>Unformatted:
 J.T. Conklin