Bug 2086 - libc/rpc get_myaddress() broken
Summary: libc/rpc get_myaddress() broken
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: bin (show other bugs)
Version: 2.2-CURRENT
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-bugs (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 1996-11-22 23:00 UTC by Paul Traina
Modified: 1996-11-22 23:39 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Paul Traina 1996-11-22 23:00:05 UTC
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' <repeats 16 times>, "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' <repeats 16 times>, "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' <repeats 13 times>}, ifru_dstaddr = {sa_len = 0 '\000', 
      sa_family = 0 '\000', sa_data = '\000' <repeats 13 times>}, 
    ifru_broadaddr = {sa_len = 0 '\000', sa_family = 0 '\000', 
      sa_data = '\000' <repeats 13 times>}, 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' <repeats 13 times>}, ifru_dstaddr = {sa_len = 0 '\000', 
      sa_family = 0 '\000', sa_data = '\000' <repeats 13 times>}, 
    ifru_broadaddr = {sa_len = 0 '\000', sa_family = 0 '\000', 
      sa_data = '\000' <repeats 13 times>}, 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' <repeats 15 times>, 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 <Error reading address 0x306465: Invalid argument>}}
(gdb) n
78                      ifreq = *ifr;
(gdb) n
79                      if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
(gdb) print ifreq
$10 = {ifr_name = '\000' <repeats 15 times>, 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 <Error reading address 0x306465: Invalid argument>}}
(gdb) n
80                              perror("get_myaddress: ioctl");
(gdb) quit

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).
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
Comment 1 pst freebsd_committer freebsd_triage 1996-11-22 23:37:26 UTC
State Changed
From-To: open->closed

I just fixed this in -current libc_rpc/get_myaddress.c