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]

Re: gethostbyname_r broken


On Tue, Jun 29, Andreas Jaeger wrote:

> 
> The program below tests gethostbyname_r with an unknown host.  The
> function returns with 0 (instead of != 0) but doesn't set the host
> pointer:
> 
> $ ./gethst_r-test 
> gethostbyname_r returned: 0
> herr: 1
> hp is null

This is what Solaris does with all _r functions. If the entrie
doesn't exist, it returns 0, errno = 0 and the pointer is 0.
Only if the buffer is to small or another error happens they
return the errno code, but errno is always zero.

> 
> nss/getXXbyYY_r.c now has:
>   return status == NSS_STATUS_SUCCESS ? 0 : errno;
> 
> But what happens if errno is 0 and status != NSS_STATUS_SUCCESS (this
> happens with host not found in my test program)?  Before Ulrich's
> change we always returned -1 and could easily check for it.  The glibc
> manual isn't clear on this - do I have to check also the return
> pointer for NULL if the result is 0?  The POSIX documentation seems to 
> imply this.

Yes, it seems this the way POSIX handle it.

> 
> Let's look at an example from glibc (inet/rcmd.c):
> 	while (__gethostbyname_r (*ahost, &hostbuf, tmphstbuf, hstbuflen,
> 				  &hp, &herr) != 0)
> 	  if (herr != NETDB_INTERNAL || errno != ERANGE)
> 	    {
> 	      __set_h_errno (herr);
> 	      herror(*ahost);
> 	      return -1;
> 	    }
> 	  else
> 	    {
> 	      /* Enlarge the buffer.  */
> 	      hstbuflen *= 2;
> 	      tmphstbuf = __alloca (hstbuflen);
> 	    }
> 	pfd[0].events = POLLIN;
> 	pfd[1].events = POLLIN;
> 
> 	*ahost = hp->h_name;
> 
> This code segfaults accessing hp->h_name iff the host doesn't exist.
> 
> We need to add at least the following code after the loop:
> 	if (hp == NULL)
> 	  {
> 	    __set_h_errno (herr);
> 	    herror(*ahost);
> 	    return -1;
> 	  }
> 
> I'm appending a patch for inet/rcmd.c which fixes one of the three
> gethostbyname_r calls and like to get your comments on it before I fix 
> the rest.
> 

If we use the POSIX behavior for getXXbyYY_r functions, we shouldn't 
use errno. Instead we should use the return value from the function.

  Thorsten



-- 
Thorsten Kukuk      http://www.suse.de/~kukuk/        kukuk@suse.de
SuSE GmbH           Schanzaeckerstr. 10             90443 Nuernberg
Linux is like a Vorlon.  It is incredibly powerful, gives terse,
cryptic answers and has a lot of things going on in the background.

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