From aardvark@francisco.saintaardvarkthecarpeted.com Sun Feb 8 13:25:32 2004 Return-Path: Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 6090416A4CE for ; Sun, 8 Feb 2004 13:25:32 -0800 (PST) Received: from pd3mo1so.prod.shaw.ca (shawidc-mo1.cg.shawcable.net [24.71.223.10]) by mx1.FreeBSD.org (Postfix) with ESMTP id 4F7A743D1D for ; Sun, 8 Feb 2004 13:25:32 -0800 (PST) (envelope-from aardvark@francisco.saintaardvarkthecarpeted.com) Received: from pd4mr1so.prod.shaw.ca (pd4mr1so-qfe3.prod.shaw.ca [10.0.141.212]) by l-daemon (iPlanet Messaging Server 5.2 HotFix 1.18 (built Jul 28 2003)) with ESMTP id <0HSS0022IBIJW3@l-daemon> for FreeBSD-gnats-submit@freebsd.org; Sun, 08 Feb 2004 14:25:32 -0700 (MST) Received: from pn2ml10so.prod.shaw.ca (pn2ml10so-qfe0.prod.shaw.ca [10.0.121.80]) by l-daemon (iPlanet Messaging Server 5.2 HotFix 1.18 (built Jul 28 2003)) with ESMTP id <0HSS00CFCBIJV7@l-daemon> for FreeBSD-gnats-submit@freebsd.org; Sun, 08 Feb 2004 14:25:31 -0700 (MST) Received: from francisco.saintaardvarkthecarpeted.com (h24-87-202-31.vc.shawcable.net [24.87.202.31]) by l-daemon (iPlanet Messaging Server 5.2 HotFix 1.18 (built Jul 28 2003)) with ESMTP id <0HSS00E07BIJOD@l-daemon> for FreeBSD-gnats-submit@freebsd.org; Sun, 08 Feb 2004 14:25:31 -0700 (MST) Received: from francisco.saintaardvarkthecarpeted.com (localhost [127.0.0.1]) by francisco.saintaardvarkthecarpeted.com (8.12.10/8.12.8) with ESMTP id i18LPocn048564; Sun, 08 Feb 2004 13:25:50 -0800 Received: (from aardvark@localhost) by francisco.saintaardvarkthecarpeted.com (8.12.10/8.12.8/Submit) id i18LPoXu048563; Sun, 08 Feb 2004 13:25:50 -0800 (PST) Message-Id: <200402082125.i18LPoXu048563@francisco.saintaardvarkthecarpeted.com> Date: Sun, 08 Feb 2004 13:25:50 -0800 (PST) From: Saint Aardvark the Carpeted Reply-To: Saint Aardvark the Carpeted To: FreeBSD-gnats-submit@freebsd.org Cc: Saint Aardvark the Carpeted Subject: [patch] bug in ypset(8) causes attempt to bind to weird IP addresses X-Send-Pr-Version: 3.113 X-GNATS-Notify: >Number: 62550 >Category: bin >Synopsis: [patch] bug in ypset(8) causes attempt to bind to weird IP addresses >Confidential: no >Severity: non-critical >Priority: low >Responsible: iedowse >State: closed >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sun Feb 08 13:30:15 PST 2004 >Closed-Date: Sun Feb 29 13:10:33 PST 2004 >Last-Modified: Sun Feb 29 13:10:33 PST 2004 >Originator: Saint Aardvark the Carpeted >Release: FreeBSD 4.9-RELEASE i386 >Organization: >Environment: System: FreeBSD 4.9-RELEASE FreeBSD 4.9-RELEASE #0: Mon Oct 27 17:51:09 GMT 2003 root@freebsd-stable.sentex.ca:/usr/obj/usr/src/sys/GENERIC i386 I've seen this in two separate environments: Internal box: Pentium 4 running 4.8-PRERELEASE on a private network (10.0.0.0/24) within another private network (192.168.0.0/24); default gateway has two interfaces, and forwards traffic from 10.0.0.0/24 to its gateway (192.168.0.1), which in turn does NAT and is connected to the Internet Pentium 2 ("Dagny") running either 4.8-RELEASE or 4.9-RELEASE on private network (10.0.1.0/24) connected to NAT/firewall box ("Francisco") with three interfaces (ep1 -- 10.0.1.254 attached to Dagny via crossover cable; vr0 -- 192.168.23.254 going to the rest of my home network; xl0 -- external interface attached to cable Internet connection) The first setup is at my job, and is where I first noticed this behaviour. I don't have access to it to duplicate it -- I'm just mentioning it to show that it's not solely my home network. The second is my home network, and I'm able to do what I like with it. >Description: ypset(8) attempts to bind to strange IP addresses when told to try binding to NIS server on private IP address (192.168.0.2 in first example, 192.168.23.254 in second example). I've seen three different IP addresses: 164.110.15.40, which belongs to the Washington State Department of Transportation 132.110.15.40, which belongs to the US Army National Guard Bureau 164.113.15.40, which belongs to the Kansas Research and Education Network (Information from "whois -a "). >How-To-Repeat: Francisco: ifconfig ep1 10.0.1.254 netmask 255.255.255.0 domainname foo ypserv (natd already running) Dagny: ifconfig ep1 10.0.1.1 netmask 255.255.255.0 route add default 10.0.1.254 ypset -h localhost -d foo 192.168.23.254 Francisco: "tcpdump -n -i ep1 port not 22" shows: 14:14:15.779438 10.0.1.1.1003 > 192.168.23.254.111: udp 56 14:14:15.782620 10.0.1.254.111 > 10.0.1.1.1003: udp 28 14:14:15.783349 10.0.1.1.1002 > 164.113.15.40.111: udp 56 14:14:15.884530 164.113.221.114 > 10.0.1.1: icmp: host 164.113.15.40 unreachable Packets continue to go to 164.113.15.40 for about a minute; after this, ypset on Dagny exits with this error message: ypset: can't yp_bind, reason: Can't communicate with ypbind This example is with Dagny running 4.9-RELEASE; the same behaviour is seen with 4.8-RELEASE except that the strange IP is 132.110.15.40, and there was no "icmp unreachable" response. When I first saw this at work (4.8-PRERELEASE), the strange IP was 164.110.15.40. None of these numbers are remotely close to any of the private networks in use, nor to the public IP addresses of the machines that were connected to the Internet. I compiled a debug version of ypset and stepped through it with gdb. I narrowed it down to this range of code in /usr/src/usr.sbin/ypset/ypset.c: 120 struct hostent *hent; [snip] 130 sin.sin_addr.s_addr = htonl(0x7f000001); 131 132 while ((c = getopt(argc, argv, "h:d:")) != -1) 133 switch (c) { 134 case 'd': 135 domainname = optarg; 136 break; 137 case 'h': 138 if ((sin.sin_addr.s_addr = inet_addr(optarg)) == -1) { 139 hent = gethostbyname(optarg); 140 if (hent == NULL) 141 errx(1, "host %s unknown", optarg); 142 bcopy(&hent->h_addr_list[0], &sin.sin_addr, 143 sizeof sin.sin_addr); 144 } 145 break; 146 default: 147 usage(); 148 } The CVS tag for ypset.c was: #ifndef lint static const char rcsid[] = "$FreeBSD: src/usr.sbin/ypset/ypset.c,v 1.5.2.2 2002/02/15 00:47:00 des Exp $"; #endif /* not lint */ This chunk goes over the arguments to ypset; pretty much immediately afterward, it calls bind_tohost() with sin as one of its arguments. To print hent->h_addr_list[0], I ran this in gdb: p (unsigned char)hp->h_addr_list[0][n] I changed n from 0 to 3; this printed out the numbers in the IP address, dotted-quad form without the dots. For example, if h_addr_list had 127.0.0.1, I would see 127, then 0, then 0, then 1. To print out sin.sin_addr.s_addr, I ran: p (unsigned char)((char *)&(sin.sin_addr.s_addr))[n] in gdb. Again, n went from 0 to 3. The problem seems to come in at lines 142/143: before this, sin.sin_addr.s_addr is localhost (as set at line 130), as is hent->h_addr_list[0][0]. *After* this, it's set with the Weird IP, bind_tohost() is called, and packets go off to the Weird IP. Looking through man pages and header files, it looks like hostent->h_addr_list is an array of pointers to chars (is that the right term?): char **h_addr_list and so gethostbyname is returning the IP address as the *first entry* in that list. It makes sense to me, then, that bcopy should have h_addr_list[0][0] as its first argument. >Fix: If I apply this patch: --- /usr/src/usr.sbin/ypset/ypset.c Sun Feb 8 14:10:38 2004 +++ /tmp/ypset.c Sun Feb 8 14:10:30 2004 @@ -139,7 +139,7 @@ hent = gethostbyname(optarg); if (hent == NULL) errx(1, "host %s unknown", optarg); - bcopy(&hent->h_addr_list[0], &sin.sin_addr, + bcopy(hent->h_addr_list[0], &sin.sin_addr, sizeof sin.sin_addr); } break; then the Weird IP doesn't show up in sin, and ypset only tries to bind to the IP address listed in its arguments. This is against ypset.c with the CVS tag described above, which is part of 4.9-RELEASE; however, it looks like this line is the same in 1.13, which is the version in HEAD. Please let me know if I've missed anything or can provide any more information. --- pr ends here --- >Release-Note: >Audit-Trail: State-Changed-From-To: open->patched State-Changed-By: iedowse State-Changed-When: Sun Feb 8 16:10:42 PST 2004 State-Changed-Why: Patch committed, thanks! Responsible-Changed-From-To: freebsd-bugs->iedowse Responsible-Changed-By: iedowse Responsible-Changed-When: Sun Feb 8 16:10:42 PST 2004 Responsible-Changed-Why: My reminder to merge the fix into -STABLE. http://www.freebsd.org/cgi/query-pr.cgi?pr=62550 State-Changed-From-To: patched->closed State-Changed-By: iedowse State-Changed-When: Sun Feb 29 13:09:49 PST 2004 State-Changed-Why: Patch MFC'd to -STABLE now. http://www.freebsd.org/cgi/query-pr.cgi?pr=62550 >Unformatted: