From pst@jnx.com Fri Nov 22 14:59:16 1996 Received: from red.jnx.com (red.jnx.com [208.197.169.254]) by freefall.freebsd.org (8.7.5/8.7.3) with ESMTP id OAA23819 for ; Fri, 22 Nov 1996 14:59:14 -0800 (PST) Received: from base.jnx.com (base.jnx.com [208.197.169.238]) by red.jnx.com (8.8.3/8.8.3) with ESMTP id OAA24137 for ; Fri, 22 Nov 1996 14:58:43 -0800 (PST) Received: (from pst@localhost) by base.jnx.com (8.7.6/8.7.3) id OAA08637; Fri, 22 Nov 1996 14:58:31 -0800 (PST) Message-Id: <199611222258.OAA08637@base.jnx.com> Date: Fri, 22 Nov 1996 14:58:31 -0800 (PST) From: Paul Traina Reply-To: pst@jnx.com To: FreeBSD-gnats-submit@freebsd.org Subject: libc/rpc get_myaddress() broken X-Send-Pr-Version: 3.2 >Number: 2086 >Category: bin >Synopsis: libc/rpc get_myaddress() broken >Confidential: no >Severity: serious >Priority: high >Responsible: freebsd-bugs >State: closed >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Fri Nov 22 15:00:05 PST 1996 >Closed-Date: Fri Nov 22 15:37:26 PST 1996 >Last-Modified: Fri Nov 22 15:39:26 PST 1996 >Originator: Paul Traina >Release: FreeBSD 2.2-CURRENT i386 >Organization: Juniper Networks >Environment: -current as of this week -- but probably all freebsd 2.x versions The first interface on the box has not been configured with an IP address. # ifconfig -a de0: flags=8c43 mtu 1500 ether 00:00:c0:f1:69:db ed0: flags=8843 mtu 1500 inet 208.197.169.20 netmask 0xffffff00 broadcast 208.197.169.255 ether 00:c0:26:35:04:9a ed1: flags=8843 mtu 1500 ether 00:c0:26:35:04:a7 ed2: flags=8843 mtu 1500 ether 00:c0:26:35:07:c4 lp0: flags=8810 mtu 1500 tun0: flags=8010 mtu 1500 sl0: flags=c010 mtu 552 lo0: flags=8049 mtu 16384 inet 127.0.0.1 netmask 0xff000000 ds0: flags=8008 mtu 65532 >Description: get_myaddress appears to have some bogus pointer math that was added to support variable length addresses on interfaces. It doesn't work. # gdb amd (gdb) run -a /.amd -c 1800 -k i386 -l syslog /vol /etc/auto.vols Starting program: /tmp/amd -a /.amd -c 1800 -k i386 -l syslog /vol /etc/auto.vols Breakpoint 1, get_myaddress (addr=0xefbfdcd0) at get_myaddress.c:66 66 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { (gdb) n 70 ifc.ifc_len = sizeof (buf); (gdb) n 71 ifc.ifc_buf = buf; (gdb) n 72 if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) { (gdb) n 76 ifr = ifc.ifc_req; (gdb) print *ifc Attempt to take contents of a non-pointer value. (gdb) print ifc $1 = {ifc_len = 484, ifc_ifcu = {ifcu_buf = 0xefbfd8a8 "de0", ifcu_req = 0xefbfd8a8}} (gdb) print buf $2 = "de0\000H~?oD\002\023pXXqp\024\022\001\000\006\003\006\000de0\000\000@qi[\000\000\000de0\000H~?oD\002\023pXXqp", '\000' , "ed0\000H~?oD\002\023pXXqp\024\022\002\000\006\003\006\000ed0\000@&5\004\232\000\000\000ed0\000H~?oD\002\023pXXqp\020\002\000\000PE)\024\000\000\000\000\000\000\000\000ed1\000H~?oD\002\023pXXqp\024\022\003\000\006\003\006\000ed1\000@&5\004'\000\000\000ed1\000H~?oD\002\023pXXqp", '\000' , "ed2\000H~?o"... (gdb) n 77 for (len = ifc.ifc_len; len; len -= sizeof ifreq) { (gdb) print sizeof(ifreq) $3 = 32 (gdb) n 78 ifreq = *ifr; (gdb) n 79 if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) { (gdb) print ifreq $4 = {ifr_name = "de0\000H~?oD\002\023pXXqp", ifr_ifru = {ifru_addr = { sa_len = 20 '\024', sa_family = 18 '\022', sa_data = "\001\000\006\003\006\000de0\000\000@qi"}, ifru_dstaddr = { sa_len = 20 '\024', sa_family = 18 '\022', sa_data = "\001\000\006\003\006\000de0\000\000@qi"}, ifru_broadaddr = { sa_len = 20 '\024', sa_family = 18 '\022', sa_data = "\001\000\006\003\006\000de0\000\000@qi"}, ifru_flags = 4628, ifru_metric = 70164, ifru_mtu = 70164, ifru_phys = 70164, ifru_data = 0x11214 "dir_2"}} (gdb) n 83 if ((ifreq.ifr_flags & IFF_UP) && (gdb) n 92 slop = ifr->ifr_addr.sa_len - sizeof (struct sockaddr); (gdb) list 87 break; 88 } 89 /* 90 * Deal with variable length addresses 91 */ 92 slop = ifr->ifr_addr.sa_len - sizeof (struct sockaddr); 93 if (slop) { 94 ifr = (struct ifreq *) ((caddr_t)ifr + slop); 95 len -= slop; 96 } (gdb) n 93 if (slop) { (gdb) print slop $5 = 4 (gdb) n 94 ifr = (struct ifreq *) ((caddr_t)ifr + slop); (gdb) n 95 len -= slop; (gdb) n 97 ifr++; (gdb) n 77 for (len = ifc.ifc_len; len; len -= sizeof ifreq) { (gdb) n 78 ifreq = *ifr; (gdb) n 79 if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) { (gdb) print ifreq Whoops: this should be pointing at the next interface in the list! $6 = {ifr_name = "de0\000H~?oD\002\023pXXqp", ifr_ifru = {ifru_addr = { sa_len = 0 '\000', sa_family = 0 '\000', sa_data = '\000' }, ifru_dstaddr = {sa_len = 0 '\000', sa_family = 0 '\000', sa_data = '\000' }, ifru_broadaddr = {sa_len = 0 '\000', sa_family = 0 '\000', sa_data = '\000' }, ifru_flags = 0, ifru_metric = 0, ifru_mtu = 0, ifru_phys = 0, ifru_data = 0x0}} (gdb) print ifr $7 = (struct ifreq *) 0xefbfd8cc (gdb) print *ifr $8 = {ifr_name = "de0\000H~?oD\002\023pXXqp", ifr_ifru = {ifru_addr = { sa_len = 0 '\000', sa_family = 0 '\000', sa_data = '\000' }, ifru_dstaddr = {sa_len = 0 '\000', sa_family = 0 '\000', sa_data = '\000' }, ifru_broadaddr = {sa_len = 0 '\000', sa_family = 0 '\000', sa_data = '\000' }, ifru_flags = 0, ifru_metric = 0, ifru_mtu = 0, ifru_phys = 0, ifru_data = 0x0}} (gdb) n 83 if ((ifreq.ifr_flags & IFF_UP) && (gdb) n 92 slop = ifr->ifr_addr.sa_len - sizeof (struct sockaddr); (gdb) n 93 if (slop) { (gdb) n 94 ifr = (struct ifreq *) ((caddr_t)ifr + slop); (gdb) n 95 len -= slop; (gdb) n 97 ifr++; (gdb) n 77 for (len = ifc.ifc_len; len; len -= sizeof ifreq) { The following is totally corrupt... (gdb) print *ifr $9 = {ifr_name = '\000' , ifr_ifru = {ifru_addr = { sa_len = 101 'e', sa_family = 100 'd', sa_data = "0\000H~?oD\002\023pXXqp"}, ifru_dstaddr = {sa_len = 101 'e', sa_family = 100 'd', sa_data = "0\000H~?oD\002\023pXXqp"}, ifru_broadaddr = {sa_len = 101 'e', sa_family = 100 'd', sa_data = "0\000H~?oD\002\023pXXqp"}, ifru_flags = 25701, ifru_metric = 3171429, ifru_mtu = 3171429, ifru_phys = 3171429, ifru_data = 0x306465 }} (gdb) n 78 ifreq = *ifr; (gdb) n 79 if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) { (gdb) print ifreq $10 = {ifr_name = '\000' , ifr_ifru = {ifru_addr = { sa_len = 101 'e', sa_family = 100 'd', sa_data = "0\000H~?oD\002\023pXXqp"}, ifru_dstaddr = {sa_len = 101 'e', sa_family = 100 'd', sa_data = "0\000H~?oD\002\023pXXqp"}, ifru_broadaddr = {sa_len = 101 'e', sa_family = 100 'd', sa_data = "0\000H~?oD\002\023pXXqp"}, ifru_flags = 25701, ifru_metric = 3171429, ifru_mtu = 3171429, ifru_phys = 3171429, ifru_data = 0x306465 }} (gdb) n 80 perror("get_myaddress: ioctl"); (gdb) quit >How-To-Repeat: call get_myaddress on a box with multiple interface, the first one in ifconfig -a should NOT be a valid up IP interface >Fix: I haven't tried to fix the slop math yet... unfortunately I probably won't be able to get to it for some time (sigh). >Release-Note: >Audit-Trail: State-Changed-From-To: open->closed State-Changed-By: pst State-Changed-When: Fri Nov 22 15:37:26 PST 1996 State-Changed-Why: I just fixed this in -current libc_rpc/get_myaddress.c >Unformatted: