From owner-freebsd-bugs@FreeBSD.ORG Thu Feb 12 23:20:01 2009 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 3FAA61065672 for ; Thu, 12 Feb 2009 23:20:01 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 1A8868FC1E for ; Thu, 12 Feb 2009 23:20:01 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.3/8.14.3) with ESMTP id n1CNK05E030780 for ; Thu, 12 Feb 2009 23:20:00 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.3/8.14.3/Submit) id n1CNK0oe030779; Thu, 12 Feb 2009 23:20:00 GMT (envelope-from gnats) Resent-Date: Thu, 12 Feb 2009 23:20:00 GMT Resent-Message-Id: <200902122320.n1CNK0oe030779@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Guillaume Morin Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 1C534106566B for ; 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 ; 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 ; 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 To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: misc/131623: gethostbyname_r X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 12 Feb 2009 23:20:03 -0000 >Number: 131623 >Category: misc >Synopsis: gethostbyname_r >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Thu Feb 12 23:20:00 UTC 2009 >Closed-Date: >Last-Modified: >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 #include #include #include #include #include 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: >Unformatted: