Description of problem: | # ifconfig | eth0 Link encap:Ethernet HWaddr 00:02:B3:9A:9F:C4 | inet addr:192.168.5.3 Bcast:192.168.5.255 Mask:255.255.255.0 | Segmentation fault | # gdb ifconfig | (gdb) r | Starting program: /sbin/ifconfig | eth0 Link encap:Ethernet HWaddr 00:02:B3:9A:9F:C4 | inet addr:192.168.5.3 Bcast:192.168.5.255 Mask:255.255.255.0 | | Program received signal SIGSEGV, Segmentation fault. | 0x400e0530 in *__GI_getaddrinfo (name=0xbffff420 "fe80:0000:0000:0000:0202:b3ff:fe9a:9fc4", | service=0x0, hints=0x2, pai=0xbffff32c) at ../sysdeps/posix/getaddrinfo.c:1574 | 1574 results[i].source_addr_len = results[i - 1].source_addr_len; | | (stack is crap) Available interfaces are: | # ip addr | 1: lo: <LOOPBACK,UP> mtu 16436 qdisc noqueue | link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 | inet 127.0.0.1/8 brd 127.255.255.255 scope host lo | inet6 ::1/128 scope host | 2: sit0@NONE: <NOARP> mtu 1480 qdisc noop | link/sit 0.0.0.0 brd 0.0.0.0 | 3: eth0: <BROADCAST,MULTICAST,PROMISC,UP> mtu 1500 qdisc pfifo_fast qlen 1000 | link/ether 00:02:b3:9a:9f:c4 brd ff:ff:ff:ff:ff:ff | inet 192.168.5.3/24 brd 192.168.5.255 scope global eth0 | inet 192.168.6.253/24 brd 192.168.6.255 scope global eth0 | inet 192.168.5.33/24 brd 192.168.5.255 scope global secondary eth0 | inet 192.168.5.34/24 brd 192.168.5.255 scope global secondary eth0 | inet 192.168.5.35/24 brd 192.168.5.255 scope global secondary eth0 | inet 192.168.5.36/24 brd 192.168.5.255 scope global secondary eth0 | inet 192.168.5.37/24 brd 192.168.5.255 scope global secondary eth0 | inet 192.168.5.38/24 brd 192.168.5.255 scope global secondary eth0 | inet 192.168.5.39/24 brd 192.168.5.255 scope global secondary eth0 | inet 192.168.5.40/24 brd 192.168.5.255 scope global secondary eth0 | inet 192.168.5.41/24 brd 192.168.5.255 scope global secondary eth0 | inet 192.168.5.42/24 brd 192.168.5.255 scope global secondary eth0 | inet 192.168.5.65/24 brd 192.168.5.255 scope global secondary eth0 | inet 192.168.5.66/24 brd 192.168.5.255 scope global secondary eth0 | inet 192.168.5.67/24 brd 192.168.5.255 scope global secondary eth0 | inet 192.168.5.68/24 brd 192.168.5.255 scope global secondary eth0 | inet 192.168.5.69/24 brd 192.168.5.255 scope global secondary eth0 | inet 192.168.5.70/24 brd 192.168.5.255 scope global secondary eth0 | inet 192.168.5.71/24 brd 192.168.5.255 scope global secondary eth0 | inet 192.168.5.72/24 brd 192.168.5.255 scope global secondary eth0 | inet 192.168.5.73/24 brd 192.168.5.255 scope global secondary eth0 | inet 192.168.5.74/24 brd 192.168.5.255 scope global secondary eth0 | inet 192.168.5.251/24 brd 192.168.5.255 scope global secondary eth0 | inet 192.168.5.252/24 brd 192.168.5.255 scope global secondary eth0 | inet 192.168.5.253/24 brd 192.168.5.255 scope global secondary eth0 | inet 192.168.5.43/24 brd 192.168.5.255 scope global secondary eth0 | inet 192.168.5.44/24 brd 192.168.5.255 scope global secondary eth0 | inet 192.168.5.32/24 brd 192.168.5.255 scope global secondary eth0:ftp | inet6 fe80::202:b3ff:fe9a:9fc4/64 scope link This happens on a glibc compiled for i586 target (verified on two machines). Two other machines (with i686, but NPTL-less glibc) do not show this segfault (but have different IPs also). Version-Release number of selected component (if applicable): glibc-2.3.3-55 gcc-3.4.2-2 How reproducible: 100%
afais, 'i' will never be increased in the related | 1559 for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next) loop. So the | 1572 memcpy (&results[i].source_addr, &results[i - 1].source_addr, | 1573 results[i - 1].source_addr_len); operation will be called with i==0 and 'result[-1]' be accessed.
forgot last comment; I missed the '++i'. But gdb shows that 'i' stays at '0'. valgrind says (both on working and non-working machines): # valgrind --tool=memcheck ifconfig ==9706== Conditional jump or move depends on uninitialised value(s) ==9706== at 0x1B9DA9C9: getaddrinfo (getaddrinfo.c:1572) ==9706== by 0x804CA12: (within /sbin/ifconfig) ==9706== by 0x804ED88: (within /sbin/ifconfig) ==9706== by 0x804FA71: (within /sbin/ifconfig) ==9706== ==9706== Use of uninitialised value of size 4 ==9706== at 0x1B9DA9E2: getaddrinfo (getaddrinfo.c:1572) ==9706== by 0x804CA12: (within /sbin/ifconfig) ==9706== by 0x804ED88: (within /sbin/ifconfig) ==9706== by 0x804FA71: (within /sbin/ifconfig)
When line 1579 | int fd = __socket (q->ai_family, SOCK_DGRAM, IPPROTO_IP); or (more likely) line 1583 | if (__connect (fd, q->ai_addr, q->ai_addrlen) == 0 fails, 'result[i].source_addr_len' will not be initialized and | memcpy (&results[i].source_addr, &results[i - 1].source_addr, | results[i - 1].source_addr_len); in the next loop will use uninitialized data.
Created attachment 104317 [details] prevent copying uninitialized memory This patch should avoid the copying of uninitialized memory (and possibly buffer overflows). But I still se uninitialized memory reads in valgrind, but they are reported in ifconfig itself.
Actually, the fix is enough for the valgrind messages in ifconfig. What I saw was just valgrind not being able to cope with ld.so being used as a program. The bug can be closed once we have a new glbic binary with the patch.
Fixed in current rawhide.