From nobody@FreeBSD.org  Thu Feb 12 23:16:13 2009
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 1C534106566B
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 12 Feb 2009 23:16:13 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id E49818FC0A
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 12 Feb 2009 23:16:12 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id n1CNGCL6047998
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 12 Feb 2009 23:16:12 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id n1CNGCll047997;
	Thu, 12 Feb 2009 23:16:12 GMT
	(envelope-from nobody)
Message-Id: <200902122316.n1CNGCll047997@www.freebsd.org>
Date: Thu, 12 Feb 2009 23:16:12 GMT
From: Guillaume Morin <guillaume@morinfr.org>
To: freebsd-gnats-submit@FreeBSD.org
Subject: gethostbyname_r
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         131623
>Category:       kern
>Synopsis:       [libc] gethostbyname(2): output of gethostbyname_r does not distinguish between a failure to resolve and buffer length
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    ume
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Feb 12 23:20:00 UTC 2009
>Closed-Date:    Sat Aug 28 18:02:18 UTC 2010
>Last-Modified:  Sat Aug 28 18:02:18 UTC 2010
>Originator:     Guillaume Morin
>Release:        7.1-RELEASE
>Organization:
>Environment:
FreeBSD freebsd 7.1-RELEASE FreeBSD 7.1-RELEASE #0: Thu Jan  1 08:58:24 UTC 2009     root@driscoll.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  amd64
>Description:
The output parameters of gethostbyname_r do not allow to distinguish between a failure to resolve and situations where the buffer is too small.

Here is a simple program:
#include <errno.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv) {
    struct hostent h;
    char buf[BUF_LEN] = {0};
    struct hostent *result;
    int err,i;

    if (argc < 2) {
        puts("Pass an argument");
        return 1;
    }

    int ret = gethostbyname_r(argv[1], &h, buf, sizeof(buf), &result, &err);

    printf("gethostbyname_r returned ret %d, res %p, err %d, "
           "errno \"%s\" for %s\n",
           ret, result, err, strerror(errno), argv[1]);

    for (i = 0; 0 == ret && h.h_addr_list[i]; ++i) {
        if (AF_INET != h.h_addrtype) {
            continue;
        }
        int addr;
        memcpy(&addr, h.h_addr_list[i], sizeof(addr));
        addr = htonl(addr);
        char *ipBytes = (char *) &addr;
        printf("Found address: %hu.%hu.%hu.%hu\n",
               (unsigned char) ipBytes[3], (unsigned char) ipBytes[2],
               (unsigned char) ipBytes[1], (unsigned char) ipBytes[0]);
    }


    return 0;
}

gcc -DBUF_LEN=1 -Wall -o gh gethostbyname.c && ./gh sdv1
gethostbyname_r returned ret -1, res 0x0, err 2, errno "Unknown error: 0" for sdv1
$gcc -DBUF_LEN=1024 -Wall -o gh gethostbyname.c && ./gh sdv1
gethostbyname_r returned ret 0, res 0x7fffffffcf30, err 0, errno "Unknown error: 0" for sdv1
Found address: x.x.x.x (edited)


One might think that err = 2 and non-zero ret means that the buffer is too small, but: 
$gcc -DBUF_LEN=1024 -Wall -o gh gethostbyname.c && ./gh nosuchaddr
gethostbyname_r returned ret -1, res 0x0, err 2, errno "Unknown error: 0" for nosuchaddr

We got the exact same output for two different conditions.  Trying to resolve localhost shows the same kind of behavior but different values for err.

$gcc -DBUF_LEN=1 -Wall -o gh gethostbyname.c && ./gh localhost
gethostbyname_r returned ret -1, res 0x0, err 0, errno "Unknown error: 0" for localhost
$gcc -DBUF_LEN=128 -Wall -o gh gethostbyname.c && ./gh localhost
gethostbyname_r returned ret 0, res 0x7fffffffcf30, err 0, errno "Unknown error: 0" for localhost
Found address: 127.0.0.1

getservbyname_r has a similar (glibc-like) interface but returns what should be errno.  A return value == ERANGE indicates that the buffer is too small.  A similar scheme should be used here.

>How-To-Repeat:
Compile, run the same tests
>Fix:


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->ume 
Responsible-Changed-By: ume 
Responsible-Changed-When: Sun Jul 11 17:27:28 UTC 2010 
Responsible-Changed-Why:  
I'll handle this. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=131623 
State-Changed-From-To: open->patched 
State-Changed-By: ume 
State-Changed-When: Fri Aug 13 06:49:02 UTC 2010 
State-Changed-Why:  
I've committed the fix.  I'll do MFC after 2 weeks. 
Thank you for the report. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=131623 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/131623: commit references a PR
Date: Fri, 13 Aug 2010 06:40:13 +0000 (UTC)

 Author: ume
 Date: Fri Aug 13 06:39:54 2010
 New Revision: 211276
 URL: http://svn.freebsd.org/changeset/base/211276
 
 Log:
   - When there is no room for returning the result, nss backend
     have to return ERANGE and terminate with NS_RETURN.
   - When gethostbyname_r(3) and the friends end with an error,
     set errno to the value nss backend returns, and return errno
     value.
   
   PR:		kern/131623
   MFC after:	2 weeks
 
 Modified:
   head/lib/libc/net/gethostbydns.c
   head/lib/libc/net/gethostbyht.c
   head/lib/libc/net/gethostbynis.c
   head/lib/libc/net/gethostnamadr.c
   head/lib/libc/net/getnetbydns.c
   head/lib/libc/net/getnetbyht.c
   head/lib/libc/net/getnetbynis.c
   head/lib/libc/net/getnetnamadr.c
   head/lib/libc/net/getproto.c
   head/lib/libc/net/getprotoent.c
   head/lib/libc/net/getprotoname.c
 
 Modified: head/lib/libc/net/gethostbydns.c
 ==============================================================================
 --- head/lib/libc/net/gethostbydns.c	Fri Aug 13 06:03:54 2010	(r211275)
 +++ head/lib/libc/net/gethostbydns.c	Fri Aug 13 06:39:54 2010	(r211276)
 @@ -536,9 +536,12 @@ _dns_gethostbyname(void *rval, void *cb_
  		return (NS_NOTFOUND);
  	}
  	if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
 +	RES_SET_H_ERRNO(statp, NETDB_SUCCESS);
  	*((struct hostent **)rval) = hptr;
  	return (NS_SUCCESS);
  }
 @@ -683,11 +686,13 @@ _dns_gethostbyaddr(void *rval, void *cb_
  		he.h_addrtype = AF_INET6;
  		he.h_length = NS_IN6ADDRSZ;
  	}
 -	RES_SET_H_ERRNO(statp, NETDB_SUCCESS);
  	if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
 +	RES_SET_H_ERRNO(statp, NETDB_SUCCESS);
  	*((struct hostent **)rval) = hptr;
  	return (NS_SUCCESS);
  }
 
 Modified: head/lib/libc/net/gethostbyht.c
 ==============================================================================
 --- head/lib/libc/net/gethostbyht.c	Fri Aug 13 06:03:54 2010	(r211275)
 +++ head/lib/libc/net/gethostbyht.c	Fri Aug 13 06:39:54 2010	(r211276)
 @@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
  #include <netdb.h>
  #include <stdio.h>
  #include <ctype.h>
 +#include <errno.h>
  #include <string.h>
  #include <stdarg.h>
  #include <nsswitch.h>
 @@ -192,8 +193,11 @@ gethostent_r(struct hostent *hptr, char 
  	}
  	if (gethostent_p(&he, hed, statp->options & RES_USE_INET6, statp) != 0)
  		return (-1);
 -	if (__copy_hostent(&he, hptr, buffer, buflen) != 0)
 -		return (-1);
 +	if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
 +		*h_errnop = statp->res_h_errno;
 +		return ((errno != 0) ? errno : -1);
 +	}
  	*result = hptr;
  	return (0);
  }
 @@ -268,8 +272,10 @@ found:
  		return (NS_NOTFOUND);
  	}
  	if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
  	*((struct hostent **)rval) = hptr;
  	return (NS_SUCCESS);
 @@ -323,8 +329,10 @@ _ht_gethostbyaddr(void *rval, void *cb_d
  	if (error != 0)
  		return (NS_NOTFOUND);
  	if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
  	*((struct hostent **)rval) = hptr;
  	return (NS_SUCCESS);
 
 Modified: head/lib/libc/net/gethostbynis.c
 ==============================================================================
 --- head/lib/libc/net/gethostbynis.c	Fri Aug 13 06:03:54 2010	(r211275)
 +++ head/lib/libc/net/gethostbynis.c	Fri Aug 13 06:39:54 2010	(r211276)
 @@ -288,8 +288,10 @@ _nis_gethostbyname(void *rval, void *cb_
  		return (NS_NOTFOUND);
  	}
  	if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
  	*((struct hostent **)rval) = hptr;
  	return (NS_SUCCESS);
 @@ -336,8 +338,10 @@ _nis_gethostbyaddr(void *rval, void *cb_
  		return (NS_NOTFOUND);
  	}
  	if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
  	*((struct hostent **)rval) = hptr;
  	return (NS_SUCCESS);
 
 Modified: head/lib/libc/net/gethostnamadr.c
 ==============================================================================
 --- head/lib/libc/net/gethostnamadr.c	Fri Aug 13 06:03:54 2010	(r211275)
 +++ head/lib/libc/net/gethostnamadr.c	Fri Aug 13 06:39:54 2010	(r211276)
 @@ -480,8 +480,12 @@ fakeaddr(const char *name, int af, struc
  	hed->h_addr_ptrs[0] = (char *)hed->host_addr;
  	hed->h_addr_ptrs[1] = NULL;
  	he.h_addr_list = hed->h_addr_ptrs;
 +	if (__copy_hostent(&he, hp, buf, buflen) != 0) {
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
 +		return (-1);
 +	}
  	RES_SET_H_ERRNO(statp, NETDB_SUCCESS);
 -	return (__copy_hostent(&he, hp, buf, buflen));
 +	return (0);
  }
  
  int
 @@ -528,7 +532,7 @@ gethostbyname_internal(const char *name,
      size_t buflen, struct hostent **result, int *h_errnop, res_state statp)
  {
  	const char *cp;
 -	int rval, ret_errno;
 +	int rval, ret_errno = 0;
  	char abuf[MAXDNAME];
  
  #ifdef NS_CACHING
 @@ -576,7 +580,11 @@ gethostbyname_internal(const char *name,
  	    "gethostbyname2_r", default_src, name, af, hp, buf, buflen,
  	    &ret_errno, h_errnop);
  
 -	return ((rval == NS_SUCCESS) ? 0 : -1);
 +	if (rval != NS_SUCCESS) {
 +		errno = ret_errno;
 +		return ((ret_errno != 0) ? ret_errno : -1);
 +	}
 +	return (0);
  }
  
  int
 @@ -586,7 +594,7 @@ gethostbyaddr_r(const void *addr, sockle
  	const u_char *uaddr = (const u_char *)addr;
  	const struct in6_addr *addr6;
  	socklen_t size;
 -	int rval, ret_errno;
 +	int rval, ret_errno = 0;
  	res_state statp;
  
  #ifdef NS_CACHING
 @@ -651,7 +659,11 @@ gethostbyaddr_r(const void *addr, sockle
  	    "gethostbyaddr_r", default_src, uaddr, len, af, hp, buf, buflen,
  	    &ret_errno, h_errnop);
  
 -	return ((rval == NS_SUCCESS) ? 0 : -1);
 +	if (rval != NS_SUCCESS) {
 +		errno = ret_errno;
 +		return ((ret_errno != 0) ? ret_errno : -1);
 +	}
 +	return (0);
  }
  
  struct hostent *
 
 Modified: head/lib/libc/net/getnetbydns.c
 ==============================================================================
 --- head/lib/libc/net/getnetbydns.c	Fri Aug 13 06:03:54 2010	(r211275)
 +++ head/lib/libc/net/getnetbydns.c	Fri Aug 13 06:39:54 2010	(r211276)
 @@ -355,8 +355,10 @@ _dns_getnetbyaddr(void *rval, void *cb_d
  			net >>= 8;
  		ne.n_net = net;
  		if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
 +			*errnop = errno;
 +			RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  			*h_errnop = statp->res_h_errno;
 -			return (NS_NOTFOUND);
 +			return (NS_RETURN);
  		}
  		*((struct netent **)rval) = nptr;
  		return (NS_SUCCESS);
 @@ -431,8 +433,10 @@ _dns_getnetbyname(void *rval, void *cb_d
  		return (NS_NOTFOUND);
  	}
  	if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
  	*((struct netent **)rval) = nptr;
  	return (NS_SUCCESS);
 
 Modified: head/lib/libc/net/getnetbyht.c
 ==============================================================================
 --- head/lib/libc/net/getnetbyht.c	Fri Aug 13 06:03:54 2010	(r211275)
 +++ head/lib/libc/net/getnetbyht.c	Fri Aug 13 06:39:54 2010	(r211276)
 @@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
  #include <netinet/in.h>
  #include <arpa/inet.h>
  #include <arpa/nameser.h>
 +#include <errno.h>
  #include <netdb.h>
  #include <resolv.h>
  #include <stdio.h>
 @@ -162,8 +163,11 @@ getnetent_r(struct netent *nptr, char *b
  	}
  	if (getnetent_p(&ne, ned) != 0)
  		return (-1);
 -	if (__copy_netent(&ne, nptr, buffer, buflen) != 0)
 -		return (-1);
 +	if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
 +		*h_errnop = statp->res_h_errno;
 +		return ((errno != 0) ? errno : -1);
 +	}
  	*result = nptr;
  	return (0);
  }
 @@ -226,8 +230,10 @@ found:
  		return (NS_NOTFOUND);
  	}
  	if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
  	*((struct netent **)rval) = nptr;
  	return (NS_SUCCESS);
 @@ -272,8 +278,10 @@ _ht_getnetbyaddr(void *rval, void *cb_da
  		return (NS_NOTFOUND);
  	}
  	if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
  	*((struct netent **)rval) = nptr;
  	return (NS_SUCCESS);
 
 Modified: head/lib/libc/net/getnetbynis.c
 ==============================================================================
 --- head/lib/libc/net/getnetbynis.c	Fri Aug 13 06:03:54 2010	(r211275)
 +++ head/lib/libc/net/getnetbynis.c	Fri Aug 13 06:39:54 2010	(r211276)
 @@ -160,8 +160,10 @@ _nis_getnetbyname(void *rval, void *cb_d
  		return (NS_NOTFOUND);
  	}
  	if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
  	*((struct netent **)rval) = nptr;
  	return (NS_SUCCESS);
 @@ -244,8 +246,10 @@ _nis_getnetbyaddr(void *rval, void *cb_d
  		return (NS_NOTFOUND);
  	}
  	if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
  	*((struct netent **)rval) = nptr;
  	return (NS_SUCCESS);
 
 Modified: head/lib/libc/net/getnetnamadr.c
 ==============================================================================
 --- head/lib/libc/net/getnetnamadr.c	Fri Aug 13 06:03:54 2010	(r211275)
 +++ head/lib/libc/net/getnetnamadr.c	Fri Aug 13 06:39:54 2010	(r211276)
 @@ -360,13 +360,17 @@ getnetbyname_r(const char *name, struct 
  #endif
  		{ 0 }
  	};
 -	int rval, ret_errno;
 +	int rval, ret_errno = 0;
  
  	rval = _nsdispatch((void *)result, dtab, NSDB_NETWORKS,
  	    "getnetbyname_r", default_src, name, ne, buffer, buflen,
  	    &ret_errno, h_errorp);
  
 -	return ((rval == NS_SUCCESS) ? 0 : -1);
 +	if (rval != NS_SUCCESS) {
 +		errno = ret_errno;
 +		return ((ret_errno != 0) ? ret_errno : -1);
 +	}
 +	return (0);
  }
  
  int
 @@ -388,13 +392,17 @@ getnetbyaddr_r(uint32_t addr, int af, st
  #endif
  		{ 0 }
  	};
 -	int rval, ret_errno;
 +	int rval, ret_errno = 0;
  
  	rval = _nsdispatch((void *)result, dtab, NSDB_NETWORKS,
  	    "getnetbyaddr_r", default_src, addr, af, ne, buffer, buflen,
  	    &ret_errno, h_errorp);
  
 -	return ((rval == NS_SUCCESS) ? 0 : -1);
 +	if (rval != NS_SUCCESS) {
 +		errno = ret_errno;
 +		return ((ret_errno != 0) ? ret_errno : -1);
 +	}
 +	return (0);
  }
  
  struct netent *
 
 Modified: head/lib/libc/net/getproto.c
 ==============================================================================
 --- head/lib/libc/net/getproto.c	Fri Aug 13 06:03:54 2010	(r211275)
 +++ head/lib/libc/net/getproto.c	Fri Aug 13 06:39:54 2010	(r211276)
 @@ -33,6 +33,7 @@ static char sccsid[] = "@(#)getproto.c	8
  #include <sys/cdefs.h>
  __FBSDID("$FreeBSD$");
  
 +#include <errno.h>
  #include <netdb.h>
  #include <nsswitch.h>
  #include "netdb_private.h"
 @@ -72,7 +73,7 @@ files_getprotobynumber(void *retval, voi
  	errnop = va_arg(ap, int *);
  
  	if ((ped = __protoent_data_init()) == NULL) {
 -		*errnop = -1;
 +		*errnop = errno;
  		return (NS_NOTFOUND);
  	}
  
 @@ -83,12 +84,12 @@ files_getprotobynumber(void *retval, voi
  	if (!ped->stayopen)
  		__endprotoent_p(ped);
  	if (error != 0) {
 -		*errnop = -1;
 +		*errnop = errno;
  		return (NS_NOTFOUND);
  	}
  	if (__copy_protoent(&pe, pptr, buffer, buflen) != 0) {
 -		*errnop = -1;
 -		return (NS_NOTFOUND);
 +		*errnop = errno;
 +		return (NS_RETURN);
  	}
  
  	*((struct protoent **)retval) = pptr;
 @@ -120,10 +121,11 @@ getprotobynumber_r(int proto, struct pro
  	rv = nsdispatch(result, dtab, NSDB_PROTOCOLS, "getprotobynumber_r",
  		defaultsrc, proto, pptr, buffer, buflen, &ret_errno);
  
 -	if (rv == NS_SUCCESS)
 -		return (0);
 -	else
 -		return (ret_errno);
 +	if (rv != NS_SUCCESS) {
 +		errno = ret_errno;
 +		return ((ret_errno != 0) ? ret_errno : -1);
 +	}
 +	return (0);
  }
  
  struct protoent *
 
 Modified: head/lib/libc/net/getprotoent.c
 ==============================================================================
 --- head/lib/libc/net/getprotoent.c	Fri Aug 13 06:03:54 2010	(r211275)
 +++ head/lib/libc/net/getprotoent.c	Fri Aug 13 06:39:54 2010	(r211276)
 @@ -424,8 +424,10 @@ files_getprotoent_r(void *retval, void *
  	buflen = va_arg(ap, size_t);
  	errnop = va_arg(ap, int *);
  
 -	if ((ped = __protoent_data_init()) == NULL)
 -		return (-1);
 +	if ((ped = __protoent_data_init()) == NULL) {
 +		*errnop = errno;
 +		return (NS_NOTFOUND);
 +	}
  
  	if (__getprotoent_p(&pe, ped) != 0) {
  		*errnop = errno;
 @@ -434,7 +436,7 @@ files_getprotoent_r(void *retval, void *
  
  	if (__copy_protoent(&pe, pptr, buffer, buflen) != 0) {
  		*errnop = errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
  
  	*((struct protoent **)retval) = pptr;
 @@ -490,10 +492,11 @@ getprotoent_r(struct protoent *pptr, cha
  	rv = nsdispatch(result, dtab, NSDB_PROTOCOLS, "getprotoent_r",
  	    defaultsrc, pptr, buffer, buflen, &ret_errno);
  
 -	if (rv == NS_SUCCESS)
 -		return (0);
 -	else
 -		return (ret_errno);
 +	if (rv != NS_SUCCESS) {
 +		errno = ret_errno;
 +		return ((ret_errno != 0) ? ret_errno : -1);
 +	}
 +	return (0);
  }
  
  void
 
 Modified: head/lib/libc/net/getprotoname.c
 ==============================================================================
 --- head/lib/libc/net/getprotoname.c	Fri Aug 13 06:03:54 2010	(r211275)
 +++ head/lib/libc/net/getprotoname.c	Fri Aug 13 06:39:54 2010	(r211276)
 @@ -33,6 +33,7 @@ static char sccsid[] = "@(#)getprotoname
  #include <sys/cdefs.h>
  __FBSDID("$FreeBSD$");
  
 +#include <errno.h>
  #include <netdb.h>
  #include <nsswitch.h>
  #include <string.h>
 @@ -75,7 +76,7 @@ files_getprotobyname(void *retval, void 
  
  
  	if ((ped = __protoent_data_init()) == NULL) {
 -		*errnop = -1;
 +		*errnop = errno;
  		return (NS_NOTFOUND);
  	}
  
 @@ -91,12 +92,12 @@ found:
  	if (!ped->stayopen)
  		__endprotoent_p(ped);
  	if (error != 0) {
 -		*errnop = -1;
 +		*errnop = errno;
  		return (NS_NOTFOUND);
  	}
  	if (__copy_protoent(&pe, pptr, buffer, buflen) != 0) {
 -		*errnop = -1;
 -		return (NS_NOTFOUND);
 +		*errnop = errno;
 +		return (NS_RETURN);
  	}
  
  	*((struct protoent **)retval) = pptr;
 @@ -128,10 +129,11 @@ getprotobyname_r(const char *name, struc
  	rv = nsdispatch(result, dtab, NSDB_PROTOCOLS, "getprotobyname_r",
  	    defaultsrc, name, pptr, buffer, buflen, &ret_errno);
  
 -	if (rv == NS_SUCCESS)
 -		return (0);
 -	else
 -		return (ret_errno);
 +	if (rv != NS_SUCCESS) {
 +		errno = ret_errno;
 +		return ((ret_errno != 0) ? ret_errno : -1);
 +	}
 +	return (0);
  }
  
  struct protoent *
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/131623: commit references a PR
Date: Sat, 28 Aug 2010 17:06:34 +0000 (UTC)

 Author: ume
 Date: Sat Aug 28 17:06:22 2010
 New Revision: 211938
 URL: http://svn.freebsd.org/changeset/base/211938
 
 Log:
   MFC r211276:
   - When there is no room for returning the result, nss backend
     have to return ERANGE and terminate with NS_RETURN.
   - When gethostbyname_r(3) and the friends end with an error,
     set errno to the value nss backend returns, and return errno
     value.
   
   PR:		kern/131623
 
 Modified:
   stable/8/lib/libc/net/gethostbydns.c
   stable/8/lib/libc/net/gethostbyht.c
   stable/8/lib/libc/net/gethostbynis.c
   stable/8/lib/libc/net/gethostnamadr.c
   stable/8/lib/libc/net/getnetbydns.c
   stable/8/lib/libc/net/getnetbyht.c
   stable/8/lib/libc/net/getnetbynis.c
   stable/8/lib/libc/net/getnetnamadr.c
   stable/8/lib/libc/net/getproto.c
   stable/8/lib/libc/net/getprotoent.c
   stable/8/lib/libc/net/getprotoname.c
 
 Modified: stable/8/lib/libc/net/gethostbydns.c
 ==============================================================================
 --- stable/8/lib/libc/net/gethostbydns.c	Sat Aug 28 16:57:07 2010	(r211937)
 +++ stable/8/lib/libc/net/gethostbydns.c	Sat Aug 28 17:06:22 2010	(r211938)
 @@ -536,9 +536,12 @@ _dns_gethostbyname(void *rval, void *cb_
  		return (NS_NOTFOUND);
  	}
  	if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
 +	RES_SET_H_ERRNO(statp, NETDB_SUCCESS);
  	*((struct hostent **)rval) = hptr;
  	return (NS_SUCCESS);
  }
 @@ -683,11 +686,13 @@ _dns_gethostbyaddr(void *rval, void *cb_
  		he.h_addrtype = AF_INET6;
  		he.h_length = NS_IN6ADDRSZ;
  	}
 -	RES_SET_H_ERRNO(statp, NETDB_SUCCESS);
  	if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
 +	RES_SET_H_ERRNO(statp, NETDB_SUCCESS);
  	*((struct hostent **)rval) = hptr;
  	return (NS_SUCCESS);
  }
 
 Modified: stable/8/lib/libc/net/gethostbyht.c
 ==============================================================================
 --- stable/8/lib/libc/net/gethostbyht.c	Sat Aug 28 16:57:07 2010	(r211937)
 +++ stable/8/lib/libc/net/gethostbyht.c	Sat Aug 28 17:06:22 2010	(r211938)
 @@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
  #include <netdb.h>
  #include <stdio.h>
  #include <ctype.h>
 +#include <errno.h>
  #include <string.h>
  #include <stdarg.h>
  #include <nsswitch.h>
 @@ -192,8 +193,11 @@ gethostent_r(struct hostent *hptr, char 
  	}
  	if (gethostent_p(&he, hed, statp->options & RES_USE_INET6, statp) != 0)
  		return (-1);
 -	if (__copy_hostent(&he, hptr, buffer, buflen) != 0)
 -		return (-1);
 +	if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
 +		*h_errnop = statp->res_h_errno;
 +		return ((errno != 0) ? errno : -1);
 +	}
  	*result = hptr;
  	return (0);
  }
 @@ -268,8 +272,10 @@ found:
  		return (NS_NOTFOUND);
  	}
  	if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
  	*((struct hostent **)rval) = hptr;
  	return (NS_SUCCESS);
 @@ -323,8 +329,10 @@ _ht_gethostbyaddr(void *rval, void *cb_d
  	if (error != 0)
  		return (NS_NOTFOUND);
  	if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
  	*((struct hostent **)rval) = hptr;
  	return (NS_SUCCESS);
 
 Modified: stable/8/lib/libc/net/gethostbynis.c
 ==============================================================================
 --- stable/8/lib/libc/net/gethostbynis.c	Sat Aug 28 16:57:07 2010	(r211937)
 +++ stable/8/lib/libc/net/gethostbynis.c	Sat Aug 28 17:06:22 2010	(r211938)
 @@ -288,8 +288,10 @@ _nis_gethostbyname(void *rval, void *cb_
  		return (NS_NOTFOUND);
  	}
  	if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
  	*((struct hostent **)rval) = hptr;
  	return (NS_SUCCESS);
 @@ -336,8 +338,10 @@ _nis_gethostbyaddr(void *rval, void *cb_
  		return (NS_NOTFOUND);
  	}
  	if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
  	*((struct hostent **)rval) = hptr;
  	return (NS_SUCCESS);
 
 Modified: stable/8/lib/libc/net/gethostnamadr.c
 ==============================================================================
 --- stable/8/lib/libc/net/gethostnamadr.c	Sat Aug 28 16:57:07 2010	(r211937)
 +++ stable/8/lib/libc/net/gethostnamadr.c	Sat Aug 28 17:06:22 2010	(r211938)
 @@ -480,8 +480,12 @@ fakeaddr(const char *name, int af, struc
  	hed->h_addr_ptrs[0] = (char *)hed->host_addr;
  	hed->h_addr_ptrs[1] = NULL;
  	he.h_addr_list = hed->h_addr_ptrs;
 +	if (__copy_hostent(&he, hp, buf, buflen) != 0) {
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
 +		return (-1);
 +	}
  	RES_SET_H_ERRNO(statp, NETDB_SUCCESS);
 -	return (__copy_hostent(&he, hp, buf, buflen));
 +	return (0);
  }
  
  int
 @@ -528,7 +532,7 @@ gethostbyname_internal(const char *name,
      size_t buflen, struct hostent **result, int *h_errnop, res_state statp)
  {
  	const char *cp;
 -	int rval, ret_errno;
 +	int rval, ret_errno = 0;
  	char abuf[MAXDNAME];
  
  #ifdef NS_CACHING
 @@ -576,7 +580,11 @@ gethostbyname_internal(const char *name,
  	    "gethostbyname2_r", default_src, name, af, hp, buf, buflen,
  	    &ret_errno, h_errnop);
  
 -	return ((rval == NS_SUCCESS) ? 0 : -1);
 +	if (rval != NS_SUCCESS) {
 +		errno = ret_errno;
 +		return ((ret_errno != 0) ? ret_errno : -1);
 +	}
 +	return (0);
  }
  
  int
 @@ -586,7 +594,7 @@ gethostbyaddr_r(const void *addr, sockle
  	const u_char *uaddr = (const u_char *)addr;
  	const struct in6_addr *addr6;
  	socklen_t size;
 -	int rval, ret_errno;
 +	int rval, ret_errno = 0;
  	res_state statp;
  
  #ifdef NS_CACHING
 @@ -651,7 +659,11 @@ gethostbyaddr_r(const void *addr, sockle
  	    "gethostbyaddr_r", default_src, uaddr, len, af, hp, buf, buflen,
  	    &ret_errno, h_errnop);
  
 -	return ((rval == NS_SUCCESS) ? 0 : -1);
 +	if (rval != NS_SUCCESS) {
 +		errno = ret_errno;
 +		return ((ret_errno != 0) ? ret_errno : -1);
 +	}
 +	return (0);
  }
  
  struct hostent *
 
 Modified: stable/8/lib/libc/net/getnetbydns.c
 ==============================================================================
 --- stable/8/lib/libc/net/getnetbydns.c	Sat Aug 28 16:57:07 2010	(r211937)
 +++ stable/8/lib/libc/net/getnetbydns.c	Sat Aug 28 17:06:22 2010	(r211938)
 @@ -355,8 +355,10 @@ _dns_getnetbyaddr(void *rval, void *cb_d
  			net >>= 8;
  		ne.n_net = net;
  		if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
 +			*errnop = errno;
 +			RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  			*h_errnop = statp->res_h_errno;
 -			return (NS_NOTFOUND);
 +			return (NS_RETURN);
  		}
  		*((struct netent **)rval) = nptr;
  		return (NS_SUCCESS);
 @@ -431,8 +433,10 @@ _dns_getnetbyname(void *rval, void *cb_d
  		return (NS_NOTFOUND);
  	}
  	if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
  	*((struct netent **)rval) = nptr;
  	return (NS_SUCCESS);
 
 Modified: stable/8/lib/libc/net/getnetbyht.c
 ==============================================================================
 --- stable/8/lib/libc/net/getnetbyht.c	Sat Aug 28 16:57:07 2010	(r211937)
 +++ stable/8/lib/libc/net/getnetbyht.c	Sat Aug 28 17:06:22 2010	(r211938)
 @@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
  #include <netinet/in.h>
  #include <arpa/inet.h>
  #include <arpa/nameser.h>
 +#include <errno.h>
  #include <netdb.h>
  #include <resolv.h>
  #include <stdio.h>
 @@ -162,8 +163,11 @@ getnetent_r(struct netent *nptr, char *b
  	}
  	if (getnetent_p(&ne, ned) != 0)
  		return (-1);
 -	if (__copy_netent(&ne, nptr, buffer, buflen) != 0)
 -		return (-1);
 +	if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
 +		*h_errnop = statp->res_h_errno;
 +		return ((errno != 0) ? errno : -1);
 +	}
  	*result = nptr;
  	return (0);
  }
 @@ -226,8 +230,10 @@ found:
  		return (NS_NOTFOUND);
  	}
  	if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
  	*((struct netent **)rval) = nptr;
  	return (NS_SUCCESS);
 @@ -272,8 +278,10 @@ _ht_getnetbyaddr(void *rval, void *cb_da
  		return (NS_NOTFOUND);
  	}
  	if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
  	*((struct netent **)rval) = nptr;
  	return (NS_SUCCESS);
 
 Modified: stable/8/lib/libc/net/getnetbynis.c
 ==============================================================================
 --- stable/8/lib/libc/net/getnetbynis.c	Sat Aug 28 16:57:07 2010	(r211937)
 +++ stable/8/lib/libc/net/getnetbynis.c	Sat Aug 28 17:06:22 2010	(r211938)
 @@ -160,8 +160,10 @@ _nis_getnetbyname(void *rval, void *cb_d
  		return (NS_NOTFOUND);
  	}
  	if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
  	*((struct netent **)rval) = nptr;
  	return (NS_SUCCESS);
 @@ -244,8 +246,10 @@ _nis_getnetbyaddr(void *rval, void *cb_d
  		return (NS_NOTFOUND);
  	}
  	if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
  	*((struct netent **)rval) = nptr;
  	return (NS_SUCCESS);
 
 Modified: stable/8/lib/libc/net/getnetnamadr.c
 ==============================================================================
 --- stable/8/lib/libc/net/getnetnamadr.c	Sat Aug 28 16:57:07 2010	(r211937)
 +++ stable/8/lib/libc/net/getnetnamadr.c	Sat Aug 28 17:06:22 2010	(r211938)
 @@ -360,13 +360,17 @@ getnetbyname_r(const char *name, struct 
  #endif
  		{ 0 }
  	};
 -	int rval, ret_errno;
 +	int rval, ret_errno = 0;
  
  	rval = _nsdispatch((void *)result, dtab, NSDB_NETWORKS,
  	    "getnetbyname_r", default_src, name, ne, buffer, buflen,
  	    &ret_errno, h_errorp);
  
 -	return ((rval == NS_SUCCESS) ? 0 : -1);
 +	if (rval != NS_SUCCESS) {
 +		errno = ret_errno;
 +		return ((ret_errno != 0) ? ret_errno : -1);
 +	}
 +	return (0);
  }
  
  int
 @@ -388,13 +392,17 @@ getnetbyaddr_r(uint32_t addr, int af, st
  #endif
  		{ 0 }
  	};
 -	int rval, ret_errno;
 +	int rval, ret_errno = 0;
  
  	rval = _nsdispatch((void *)result, dtab, NSDB_NETWORKS,
  	    "getnetbyaddr_r", default_src, addr, af, ne, buffer, buflen,
  	    &ret_errno, h_errorp);
  
 -	return ((rval == NS_SUCCESS) ? 0 : -1);
 +	if (rval != NS_SUCCESS) {
 +		errno = ret_errno;
 +		return ((ret_errno != 0) ? ret_errno : -1);
 +	}
 +	return (0);
  }
  
  struct netent *
 
 Modified: stable/8/lib/libc/net/getproto.c
 ==============================================================================
 --- stable/8/lib/libc/net/getproto.c	Sat Aug 28 16:57:07 2010	(r211937)
 +++ stable/8/lib/libc/net/getproto.c	Sat Aug 28 17:06:22 2010	(r211938)
 @@ -33,6 +33,7 @@ static char sccsid[] = "@(#)getproto.c	8
  #include <sys/cdefs.h>
  __FBSDID("$FreeBSD$");
  
 +#include <errno.h>
  #include <netdb.h>
  #include <nsswitch.h>
  #include "netdb_private.h"
 @@ -72,7 +73,7 @@ files_getprotobynumber(void *retval, voi
  	errnop = va_arg(ap, int *);
  
  	if ((ped = __protoent_data_init()) == NULL) {
 -		*errnop = -1;
 +		*errnop = errno;
  		return (NS_NOTFOUND);
  	}
  
 @@ -83,12 +84,12 @@ files_getprotobynumber(void *retval, voi
  	if (!ped->stayopen)
  		__endprotoent_p(ped);
  	if (error != 0) {
 -		*errnop = -1;
 +		*errnop = errno;
  		return (NS_NOTFOUND);
  	}
  	if (__copy_protoent(&pe, pptr, buffer, buflen) != 0) {
 -		*errnop = -1;
 -		return (NS_NOTFOUND);
 +		*errnop = errno;
 +		return (NS_RETURN);
  	}
  
  	*((struct protoent **)retval) = pptr;
 @@ -120,10 +121,11 @@ getprotobynumber_r(int proto, struct pro
  	rv = nsdispatch(result, dtab, NSDB_PROTOCOLS, "getprotobynumber_r",
  		defaultsrc, proto, pptr, buffer, buflen, &ret_errno);
  
 -	if (rv == NS_SUCCESS)
 -		return (0);
 -	else
 -		return (ret_errno);
 +	if (rv != NS_SUCCESS) {
 +		errno = ret_errno;
 +		return ((ret_errno != 0) ? ret_errno : -1);
 +	}
 +	return (0);
  }
  
  struct protoent *
 
 Modified: stable/8/lib/libc/net/getprotoent.c
 ==============================================================================
 --- stable/8/lib/libc/net/getprotoent.c	Sat Aug 28 16:57:07 2010	(r211937)
 +++ stable/8/lib/libc/net/getprotoent.c	Sat Aug 28 17:06:22 2010	(r211938)
 @@ -424,8 +424,10 @@ files_getprotoent_r(void *retval, void *
  	buflen = va_arg(ap, size_t);
  	errnop = va_arg(ap, int *);
  
 -	if ((ped = __protoent_data_init()) == NULL)
 -		return (-1);
 +	if ((ped = __protoent_data_init()) == NULL) {
 +		*errnop = errno;
 +		return (NS_NOTFOUND);
 +	}
  
  	if (__getprotoent_p(&pe, ped) != 0) {
  		*errnop = errno;
 @@ -434,7 +436,7 @@ files_getprotoent_r(void *retval, void *
  
  	if (__copy_protoent(&pe, pptr, buffer, buflen) != 0) {
  		*errnop = errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
  
  	*((struct protoent **)retval) = pptr;
 @@ -490,10 +492,11 @@ getprotoent_r(struct protoent *pptr, cha
  	rv = nsdispatch(result, dtab, NSDB_PROTOCOLS, "getprotoent_r",
  	    defaultsrc, pptr, buffer, buflen, &ret_errno);
  
 -	if (rv == NS_SUCCESS)
 -		return (0);
 -	else
 -		return (ret_errno);
 +	if (rv != NS_SUCCESS) {
 +		errno = ret_errno;
 +		return ((ret_errno != 0) ? ret_errno : -1);
 +	}
 +	return (0);
  }
  
  void
 
 Modified: stable/8/lib/libc/net/getprotoname.c
 ==============================================================================
 --- stable/8/lib/libc/net/getprotoname.c	Sat Aug 28 16:57:07 2010	(r211937)
 +++ stable/8/lib/libc/net/getprotoname.c	Sat Aug 28 17:06:22 2010	(r211938)
 @@ -33,6 +33,7 @@ static char sccsid[] = "@(#)getprotoname
  #include <sys/cdefs.h>
  __FBSDID("$FreeBSD$");
  
 +#include <errno.h>
  #include <netdb.h>
  #include <nsswitch.h>
  #include <string.h>
 @@ -75,7 +76,7 @@ files_getprotobyname(void *retval, void 
  
  
  	if ((ped = __protoent_data_init()) == NULL) {
 -		*errnop = -1;
 +		*errnop = errno;
  		return (NS_NOTFOUND);
  	}
  
 @@ -91,12 +92,12 @@ found:
  	if (!ped->stayopen)
  		__endprotoent_p(ped);
  	if (error != 0) {
 -		*errnop = -1;
 +		*errnop = errno;
  		return (NS_NOTFOUND);
  	}
  	if (__copy_protoent(&pe, pptr, buffer, buflen) != 0) {
 -		*errnop = -1;
 -		return (NS_NOTFOUND);
 +		*errnop = errno;
 +		return (NS_RETURN);
  	}
  
  	*((struct protoent **)retval) = pptr;
 @@ -128,10 +129,11 @@ getprotobyname_r(const char *name, struc
  	rv = nsdispatch(result, dtab, NSDB_PROTOCOLS, "getprotobyname_r",
  	    defaultsrc, name, pptr, buffer, buflen, &ret_errno);
  
 -	if (rv == NS_SUCCESS)
 -		return (0);
 -	else
 -		return (ret_errno);
 +	if (rv != NS_SUCCESS) {
 +		errno = ret_errno;
 +		return ((ret_errno != 0) ? ret_errno : -1);
 +	}
 +	return (0);
  }
  
  struct protoent *
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/131623: commit references a PR
Date: Sat, 28 Aug 2010 17:13:08 +0000 (UTC)

 Author: ume
 Date: Sat Aug 28 17:12:52 2010
 New Revision: 211939
 URL: http://svn.freebsd.org/changeset/base/211939
 
 Log:
   MFC r211276:
   - When there is no room for returning the result, nss backend
     have to return ERANGE and terminate with NS_RETURN.
   - When gethostbyname_r(3) and the friends end with an error,
     set errno to the value nss backend returns, and return errno
     value.
   
   PR:		kern/131623
 
 Modified:
   stable/7/lib/libc/net/gethostbydns.c
   stable/7/lib/libc/net/gethostbyht.c
   stable/7/lib/libc/net/gethostbynis.c
   stable/7/lib/libc/net/gethostnamadr.c
   stable/7/lib/libc/net/getnetbydns.c
   stable/7/lib/libc/net/getnetbyht.c
   stable/7/lib/libc/net/getnetbynis.c
   stable/7/lib/libc/net/getnetnamadr.c
   stable/7/lib/libc/net/getproto.c
   stable/7/lib/libc/net/getprotoent.c
   stable/7/lib/libc/net/getprotoname.c
 
 Modified: stable/7/lib/libc/net/gethostbydns.c
 ==============================================================================
 --- stable/7/lib/libc/net/gethostbydns.c	Sat Aug 28 17:06:22 2010	(r211938)
 +++ stable/7/lib/libc/net/gethostbydns.c	Sat Aug 28 17:12:52 2010	(r211939)
 @@ -536,9 +536,12 @@ _dns_gethostbyname(void *rval, void *cb_
  		return (NS_NOTFOUND);
  	}
  	if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
 +	RES_SET_H_ERRNO(statp, NETDB_SUCCESS);
  	*((struct hostent **)rval) = hptr;
  	return (NS_SUCCESS);
  }
 @@ -683,11 +686,13 @@ _dns_gethostbyaddr(void *rval, void *cb_
  		he.h_addrtype = AF_INET6;
  		he.h_length = NS_IN6ADDRSZ;
  	}
 -	RES_SET_H_ERRNO(statp, NETDB_SUCCESS);
  	if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
 +	RES_SET_H_ERRNO(statp, NETDB_SUCCESS);
  	*((struct hostent **)rval) = hptr;
  	return (NS_SUCCESS);
  }
 
 Modified: stable/7/lib/libc/net/gethostbyht.c
 ==============================================================================
 --- stable/7/lib/libc/net/gethostbyht.c	Sat Aug 28 17:06:22 2010	(r211938)
 +++ stable/7/lib/libc/net/gethostbyht.c	Sat Aug 28 17:12:52 2010	(r211939)
 @@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
  #include <netdb.h>
  #include <stdio.h>
  #include <ctype.h>
 +#include <errno.h>
  #include <string.h>
  #include <stdarg.h>
  #include <nsswitch.h>
 @@ -192,8 +193,11 @@ gethostent_r(struct hostent *hptr, char 
  	}
  	if (gethostent_p(&he, hed, statp->options & RES_USE_INET6, statp) != 0)
  		return (-1);
 -	if (__copy_hostent(&he, hptr, buffer, buflen) != 0)
 -		return (-1);
 +	if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
 +		*h_errnop = statp->res_h_errno;
 +		return ((errno != 0) ? errno : -1);
 +	}
  	*result = hptr;
  	return (0);
  }
 @@ -268,8 +272,10 @@ found:
  		return (NS_NOTFOUND);
  	}
  	if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
  	*((struct hostent **)rval) = hptr;
  	return (NS_SUCCESS);
 @@ -323,8 +329,10 @@ _ht_gethostbyaddr(void *rval, void *cb_d
  	if (error != 0)
  		return (NS_NOTFOUND);
  	if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
  	*((struct hostent **)rval) = hptr;
  	return (NS_SUCCESS);
 
 Modified: stable/7/lib/libc/net/gethostbynis.c
 ==============================================================================
 --- stable/7/lib/libc/net/gethostbynis.c	Sat Aug 28 17:06:22 2010	(r211938)
 +++ stable/7/lib/libc/net/gethostbynis.c	Sat Aug 28 17:12:52 2010	(r211939)
 @@ -288,8 +288,10 @@ _nis_gethostbyname(void *rval, void *cb_
  		return (NS_NOTFOUND);
  	}
  	if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
  	*((struct hostent **)rval) = hptr;
  	return (NS_SUCCESS);
 @@ -336,8 +338,10 @@ _nis_gethostbyaddr(void *rval, void *cb_
  		return (NS_NOTFOUND);
  	}
  	if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
  	*((struct hostent **)rval) = hptr;
  	return (NS_SUCCESS);
 
 Modified: stable/7/lib/libc/net/gethostnamadr.c
 ==============================================================================
 --- stable/7/lib/libc/net/gethostnamadr.c	Sat Aug 28 17:06:22 2010	(r211938)
 +++ stable/7/lib/libc/net/gethostnamadr.c	Sat Aug 28 17:12:52 2010	(r211939)
 @@ -480,8 +480,12 @@ fakeaddr(const char *name, int af, struc
  	hed->h_addr_ptrs[0] = (char *)hed->host_addr;
  	hed->h_addr_ptrs[1] = NULL;
  	he.h_addr_list = hed->h_addr_ptrs;
 +	if (__copy_hostent(&he, hp, buf, buflen) != 0) {
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
 +		return (-1);
 +	}
  	RES_SET_H_ERRNO(statp, NETDB_SUCCESS);
 -	return (__copy_hostent(&he, hp, buf, buflen));
 +	return (0);
  }
  
  int
 @@ -528,7 +532,7 @@ gethostbyname_internal(const char *name,
      size_t buflen, struct hostent **result, int *h_errnop, res_state statp)
  {
  	const char *cp;
 -	int rval, ret_errno;
 +	int rval, ret_errno = 0;
  	char abuf[MAXDNAME];
  
  #ifdef NS_CACHING
 @@ -576,7 +580,11 @@ gethostbyname_internal(const char *name,
  	    "gethostbyname2_r", default_src, name, af, hp, buf, buflen,
  	    &ret_errno, h_errnop);
  
 -	return ((rval == NS_SUCCESS) ? 0 : -1);
 +	if (rval != NS_SUCCESS) {
 +		errno = ret_errno;
 +		return ((ret_errno != 0) ? ret_errno : -1);
 +	}
 +	return (0);
  }
  
  int
 @@ -586,7 +594,7 @@ gethostbyaddr_r(const void *addr, sockle
  	const u_char *uaddr = (const u_char *)addr;
  	const struct in6_addr *addr6;
  	socklen_t size;
 -	int rval, ret_errno;
 +	int rval, ret_errno = 0;
  	res_state statp;
  
  #ifdef NS_CACHING
 @@ -651,7 +659,11 @@ gethostbyaddr_r(const void *addr, sockle
  	    "gethostbyaddr_r", default_src, uaddr, len, af, hp, buf, buflen,
  	    &ret_errno, h_errnop);
  
 -	return ((rval == NS_SUCCESS) ? 0 : -1);
 +	if (rval != NS_SUCCESS) {
 +		errno = ret_errno;
 +		return ((ret_errno != 0) ? ret_errno : -1);
 +	}
 +	return (0);
  }
  
  struct hostent *
 
 Modified: stable/7/lib/libc/net/getnetbydns.c
 ==============================================================================
 --- stable/7/lib/libc/net/getnetbydns.c	Sat Aug 28 17:06:22 2010	(r211938)
 +++ stable/7/lib/libc/net/getnetbydns.c	Sat Aug 28 17:12:52 2010	(r211939)
 @@ -355,8 +355,10 @@ _dns_getnetbyaddr(void *rval, void *cb_d
  			net >>= 8;
  		ne.n_net = net;
  		if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
 +			*errnop = errno;
 +			RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  			*h_errnop = statp->res_h_errno;
 -			return (NS_NOTFOUND);
 +			return (NS_RETURN);
  		}
  		*((struct netent **)rval) = nptr;
  		return (NS_SUCCESS);
 @@ -431,8 +433,10 @@ _dns_getnetbyname(void *rval, void *cb_d
  		return (NS_NOTFOUND);
  	}
  	if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
  	*((struct netent **)rval) = nptr;
  	return (NS_SUCCESS);
 
 Modified: stable/7/lib/libc/net/getnetbyht.c
 ==============================================================================
 --- stable/7/lib/libc/net/getnetbyht.c	Sat Aug 28 17:06:22 2010	(r211938)
 +++ stable/7/lib/libc/net/getnetbyht.c	Sat Aug 28 17:12:52 2010	(r211939)
 @@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
  #include <netinet/in.h>
  #include <arpa/inet.h>
  #include <arpa/nameser.h>
 +#include <errno.h>
  #include <netdb.h>
  #include <resolv.h>
  #include <stdio.h>
 @@ -162,8 +163,11 @@ getnetent_r(struct netent *nptr, char *b
  	}
  	if (getnetent_p(&ne, ned) != 0)
  		return (-1);
 -	if (__copy_netent(&ne, nptr, buffer, buflen) != 0)
 -		return (-1);
 +	if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
 +		*h_errnop = statp->res_h_errno;
 +		return ((errno != 0) ? errno : -1);
 +	}
  	*result = nptr;
  	return (0);
  }
 @@ -226,8 +230,10 @@ found:
  		return (NS_NOTFOUND);
  	}
  	if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
  	*((struct netent **)rval) = nptr;
  	return (NS_SUCCESS);
 @@ -272,8 +278,10 @@ _ht_getnetbyaddr(void *rval, void *cb_da
  		return (NS_NOTFOUND);
  	}
  	if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
  	*((struct netent **)rval) = nptr;
  	return (NS_SUCCESS);
 
 Modified: stable/7/lib/libc/net/getnetbynis.c
 ==============================================================================
 --- stable/7/lib/libc/net/getnetbynis.c	Sat Aug 28 17:06:22 2010	(r211938)
 +++ stable/7/lib/libc/net/getnetbynis.c	Sat Aug 28 17:12:52 2010	(r211939)
 @@ -160,8 +160,10 @@ _nis_getnetbyname(void *rval, void *cb_d
  		return (NS_NOTFOUND);
  	}
  	if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
  	*((struct netent **)rval) = nptr;
  	return (NS_SUCCESS);
 @@ -244,8 +246,10 @@ _nis_getnetbyaddr(void *rval, void *cb_d
  		return (NS_NOTFOUND);
  	}
  	if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
 +		*errnop = errno;
 +		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  		*h_errnop = statp->res_h_errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
  	*((struct netent **)rval) = nptr;
  	return (NS_SUCCESS);
 
 Modified: stable/7/lib/libc/net/getnetnamadr.c
 ==============================================================================
 --- stable/7/lib/libc/net/getnetnamadr.c	Sat Aug 28 17:06:22 2010	(r211938)
 +++ stable/7/lib/libc/net/getnetnamadr.c	Sat Aug 28 17:12:52 2010	(r211939)
 @@ -360,13 +360,17 @@ getnetbyname_r(const char *name, struct 
  #endif
  		{ 0 }
  	};
 -	int rval, ret_errno;
 +	int rval, ret_errno = 0;
  
  	rval = _nsdispatch((void *)result, dtab, NSDB_NETWORKS,
  	    "getnetbyname_r", default_src, name, ne, buffer, buflen,
  	    &ret_errno, h_errorp);
  
 -	return ((rval == NS_SUCCESS) ? 0 : -1);
 +	if (rval != NS_SUCCESS) {
 +		errno = ret_errno;
 +		return ((ret_errno != 0) ? ret_errno : -1);
 +	}
 +	return (0);
  }
  
  int
 @@ -388,13 +392,17 @@ getnetbyaddr_r(uint32_t addr, int af, st
  #endif
  		{ 0 }
  	};
 -	int rval, ret_errno;
 +	int rval, ret_errno = 0;
  
  	rval = _nsdispatch((void *)result, dtab, NSDB_NETWORKS,
  	    "getnetbyaddr_r", default_src, addr, af, ne, buffer, buflen,
  	    &ret_errno, h_errorp);
  
 -	return ((rval == NS_SUCCESS) ? 0 : -1);
 +	if (rval != NS_SUCCESS) {
 +		errno = ret_errno;
 +		return ((ret_errno != 0) ? ret_errno : -1);
 +	}
 +	return (0);
  }
  
  struct netent *
 
 Modified: stable/7/lib/libc/net/getproto.c
 ==============================================================================
 --- stable/7/lib/libc/net/getproto.c	Sat Aug 28 17:06:22 2010	(r211938)
 +++ stable/7/lib/libc/net/getproto.c	Sat Aug 28 17:12:52 2010	(r211939)
 @@ -33,6 +33,7 @@ static char sccsid[] = "@(#)getproto.c	8
  #include <sys/cdefs.h>
  __FBSDID("$FreeBSD$");
  
 +#include <errno.h>
  #include <netdb.h>
  #include <nsswitch.h>
  #include "netdb_private.h"
 @@ -72,7 +73,7 @@ files_getprotobynumber(void *retval, voi
  	errnop = va_arg(ap, int *);
  
  	if ((ped = __protoent_data_init()) == NULL) {
 -		*errnop = -1;
 +		*errnop = errno;
  		return (NS_NOTFOUND);
  	}
  
 @@ -83,12 +84,12 @@ files_getprotobynumber(void *retval, voi
  	if (!ped->stayopen)
  		__endprotoent_p(ped);
  	if (error != 0) {
 -		*errnop = -1;
 +		*errnop = errno;
  		return (NS_NOTFOUND);
  	}
  	if (__copy_protoent(&pe, pptr, buffer, buflen) != 0) {
 -		*errnop = -1;
 -		return (NS_NOTFOUND);
 +		*errnop = errno;
 +		return (NS_RETURN);
  	}
  
  	*((struct protoent **)retval) = pptr;
 @@ -120,10 +121,11 @@ getprotobynumber_r(int proto, struct pro
  	rv = nsdispatch(result, dtab, NSDB_PROTOCOLS, "getprotobynumber_r",
  		defaultsrc, proto, pptr, buffer, buflen, &ret_errno);
  
 -	if (rv == NS_SUCCESS)
 -		return (0);
 -	else
 -		return (ret_errno);
 +	if (rv != NS_SUCCESS) {
 +		errno = ret_errno;
 +		return ((ret_errno != 0) ? ret_errno : -1);
 +	}
 +	return (0);
  }
  
  struct protoent *
 
 Modified: stable/7/lib/libc/net/getprotoent.c
 ==============================================================================
 --- stable/7/lib/libc/net/getprotoent.c	Sat Aug 28 17:06:22 2010	(r211938)
 +++ stable/7/lib/libc/net/getprotoent.c	Sat Aug 28 17:12:52 2010	(r211939)
 @@ -424,8 +424,10 @@ files_getprotoent_r(void *retval, void *
  	buflen = va_arg(ap, size_t);
  	errnop = va_arg(ap, int *);
  
 -	if ((ped = __protoent_data_init()) == NULL)
 -		return (-1);
 +	if ((ped = __protoent_data_init()) == NULL) {
 +		*errnop = errno;
 +		return (NS_NOTFOUND);
 +	}
  
  	if (__getprotoent_p(&pe, ped) != 0) {
  		*errnop = errno;
 @@ -434,7 +436,7 @@ files_getprotoent_r(void *retval, void *
  
  	if (__copy_protoent(&pe, pptr, buffer, buflen) != 0) {
  		*errnop = errno;
 -		return (NS_NOTFOUND);
 +		return (NS_RETURN);
  	}
  
  	*((struct protoent **)retval) = pptr;
 @@ -490,10 +492,11 @@ getprotoent_r(struct protoent *pptr, cha
  	rv = nsdispatch(result, dtab, NSDB_PROTOCOLS, "getprotoent_r",
  	    defaultsrc, pptr, buffer, buflen, &ret_errno);
  
 -	if (rv == NS_SUCCESS)
 -		return (0);
 -	else
 -		return (ret_errno);
 +	if (rv != NS_SUCCESS) {
 +		errno = ret_errno;
 +		return ((ret_errno != 0) ? ret_errno : -1);
 +	}
 +	return (0);
  }
  
  void
 
 Modified: stable/7/lib/libc/net/getprotoname.c
 ==============================================================================
 --- stable/7/lib/libc/net/getprotoname.c	Sat Aug 28 17:06:22 2010	(r211938)
 +++ stable/7/lib/libc/net/getprotoname.c	Sat Aug 28 17:12:52 2010	(r211939)
 @@ -33,6 +33,7 @@ static char sccsid[] = "@(#)getprotoname
  #include <sys/cdefs.h>
  __FBSDID("$FreeBSD$");
  
 +#include <errno.h>
  #include <netdb.h>
  #include <nsswitch.h>
  #include <string.h>
 @@ -75,7 +76,7 @@ files_getprotobyname(void *retval, void 
  
  
  	if ((ped = __protoent_data_init()) == NULL) {
 -		*errnop = -1;
 +		*errnop = errno;
  		return (NS_NOTFOUND);
  	}
  
 @@ -91,12 +92,12 @@ found:
  	if (!ped->stayopen)
  		__endprotoent_p(ped);
  	if (error != 0) {
 -		*errnop = -1;
 +		*errnop = errno;
  		return (NS_NOTFOUND);
  	}
  	if (__copy_protoent(&pe, pptr, buffer, buflen) != 0) {
 -		*errnop = -1;
 -		return (NS_NOTFOUND);
 +		*errnop = errno;
 +		return (NS_RETURN);
  	}
  
  	*((struct protoent **)retval) = pptr;
 @@ -128,10 +129,11 @@ getprotobyname_r(const char *name, struc
  	rv = nsdispatch(result, dtab, NSDB_PROTOCOLS, "getprotobyname_r",
  	    defaultsrc, name, pptr, buffer, buflen, &ret_errno);
  
 -	if (rv == NS_SUCCESS)
 -		return (0);
 -	else
 -		return (ret_errno);
 +	if (rv != NS_SUCCESS) {
 +		errno = ret_errno;
 +		return ((ret_errno != 0) ? ret_errno : -1);
 +	}
 +	return (0);
  }
  
  struct protoent *
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: ume 
State-Changed-When: Sat Aug 28 18:01:21 UTC 2010 
State-Changed-Why:  
I've MFC'ed it into RELENG_8 and RELENG_7. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=131623 
>Unformatted:
