From paul@clubi.ie Tue Jan 13 05:33:27 2004 Received: from fort-point-station.mit.edu (FORT-POINT-STATION.MIT.EDU [18.7.7.76]) by krbdev.mit.edu (8.9.3p2) with ESMTP id FAA28364; Tue, 13 Jan 2004 05:33:26 -0500 (EST) Received: from hibernia.jakma.org (hibernia.jakma.org [213.79.33.168]) by fort-point-station.mit.edu (8.12.4/8.9.2) with ESMTP id i0DAXPPg029876 for ; Tue, 13 Jan 2004 05:33:25 -0500 (EST) Received: from fogarty.jakma.org (IDENT:500@fogarty.jakma.org [192.168.0.4]) by hibernia.jakma.org (8.12.10/8.12.10) with ESMTP id i0DAXNWS003478 for ; Tue, 13 Jan 2004 10:33:24 GMT Date: Tue, 13 Jan 2004 10:33:23 +0000 (GMT) From: Paul Jakma X-X-Sender: paul@fogarty.jakma.org To: krb5-bugs@mit.edu Subject: SEGV in include/foreachaddr.c on startup Message-ID: X-NSA: iraq saddam hammas hisballah rabin ayatollah korea vietnam revolt mustard gas MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII >Submitter-Id: net >Originator: >Organization: Paul Jakma paul@clubi.ie paul@jakma.org PGP5 public key: http://www.clubi.ie/jakma/publickey.txt >Confidential: no >Synopsis: kdc segfaults in/below foreach_localaddr >Severity: serious >Priority: high >Category: krb5-kdc >Class: sw-bug >Release: krb5-1.3.1 >Environment: System: Linux hibernia.jakma.org 2.4.22-1.2140.nptl #1 Tue Jan 6 20:21:24 EST 2004 i586 i586 i386 GNU/Linux Architecture: i586 >Description: kdc segfaults on startup in 3 places below foreach_localaddr due to dereferencing incomplete interface structures. When calling addr_eq at ~ 396 and when calling the *pass1fn() callback at approx line 402. In both cases its due to the ifa_addr member of either ifp or ifp2 being NULL. SEGV in addr_eq due to ifp->ifa_addr being NULL: (gdb) bt #0 addr_eq (s1=0x0, s2=0x9a398cc) at foreachaddr.c:205 #1 0x08053796 in foreach_localaddr (data=0xbff02d28, pass1fn=0x8053d0c , betweenfn=0, pass2fn=0) at foreachaddr.c:396 #2 0x08054143 in setup_network (prog=0xbff86b6c "krb5kdc") at network.c:656 #3 0x080530ae in main (argc=1, argv=0xbff02dd4) at main.c:685 SEGV in setup_udp_port, due to passing in NULL ifp->ifa_addr. (gdb) bt #0 0x08053d31 in setup_udp_port (P_data=0xbff7c8f8, addr=0x0) at network.c:491 #1 0x08053777 in foreach_localaddr (data=0xbff7c8f8, pass1fn=0x8053d10 , betweenfn=0, pass2fn=0) at foreachaddr.c:402 #2 0x08054147 in setup_network (prog=0xbffe0b6c "krb5kdc") at network.c:656 #3 0x080530ae in main (argc=1, argv=0xbff7c9a4) at main.c:685 SEGV in addr_eq again, but ifp2->ifa_addr is NULL. (gdb) bt #0 0x080534a6 in addr_eq (s1=0x96aa9d4, s2=0x0) at foreachaddr.c:205 #1 0x080537a6 in foreach_localaddr (data=0xbff61318, pass1fn=0x8053d1c , betweenfn=0, pass2fn=0) at foreachaddr.c:398 #2 0x08054153 in setup_network (prog=0xbff92b6c "krb5kdc") at network.c:656 #3 0x080530ae in main (argc=1, argv=0xbff613c4) at main.c:685 >How-To-Repeat: I'm not sure how to repeat, but if one can arrange a system to have either ifp->ifa_addr and/or ifp2->if_addr be NULL the crash can be reproduced. The network interface setup on my system is as follows: # ip address show 1: lo: 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: mtu 1480 qdisc noop link/sit 0.0.0.0 brd 0.0.0.0 7: eth0: mtu 1500 qdisc pfifo_fast qlen 1000 link/ether 00:60:97:54:1e:c9 brd ff:ff:ff:ff:ff:ff inet 192.168.0.3/24 brd 192.168.0.255 scope global eth0 inet6 fe80::260:97ff:fe54:1ec9/64 scope link inet6 2001:770:105:1:260:97ff:fe54:1ec9/64 scope global 14: ppp0: mtu 1492 qdisc cbq qlen 3 link/ppp inet 213.79.33.168 peer 213.79.63.254/32 scope global ppp0 15: sixxs@NONE: mtu 1280 qdisc noqueue link/sit 213.79.33.168 peer 193.1.31.74 inet6 fe80::d54f:21a8/128 scope link inet6 2001:770:100:8::2/64 scope global >Fix: The below patch fixes the problem for me, by simply ignoring interfaces whose ifa_addr is NULL. To what extent it papers over a deeper problem I do not unfortunately know. --- krb5-1.3.1/src/include/foreachaddr.c.orig 2002-09-03 23:11:02.000000000 +0100 +++ krb5-1.3.1/src/include/foreachaddr.c 2004-01-13 10:10:57.000000000 +0000 @@ -380,6 +380,8 @@ #ifdef DEBUG printifaddr (ifp); #endif + if (ifp->ifa_addr == NULL) + continue; if ((ifp->ifa_flags & IFF_UP) == 0) continue; if (ifp->ifa_flags & IFF_LOOPBACK) { @@ -388,7 +390,8 @@ } /* If this address is a duplicate, punt. */ match = 0; - for (ifp2 = ifp_head; ifp2 && ifp2 != ifp; ifp2 = ifp2->ifa_next) { + for (ifp2 = ifp_head; ifp2 && ifp2->ifa_addr && ifp2 != ifp; + ifp2 = ifp2->ifa_next) { if ((ifp2->ifa_flags & IFF_UP) == 0) continue; if (ifp2->ifa_flags & IFF_LOOPBACK)