Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 12 Sep 2001 09:50:07 -0700 (PDT)
From:      Lars Eggert <larse@isi.edu>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   kern/30524: 4.4-RC4: panic in icmp_reflect [WITH PATCH]
Message-ID:  <200109121650.f8CGo7D55328@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         30524
>Category:       kern
>Synopsis:       4.4-RC4: panic in icmp_reflect [WITH PATCH]
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Sep 12 10:00:01 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     Lars Eggert
>Release:        4.4-RC4
>Organization:
USC/ISI
>Environment:
FreeBSD keg.isi.edu 4.4-RC FreeBSD 4.4-RC #7: Wed Sep 12 09:07:45 PDT 2001     root@keg.isi.edu:/usr/src/sys/compile/KERNEL  i386

>Description:
My 4.4-RC4 kernel occasionally panics in icmp_reflect() at line 644.
Here's the relevant code:

	/*
	 * The following happens if the packet was not addressed to us,
	 * and was received on an interface with no IP address.
	 */
	if (ia == (struct in_ifaddr *)0)
		ia = in_ifaddrhead.tqh_first;
	t = IA_SIN(ia)->sin_addr;

The intention here is to find a valid local IP address to send the
ICMP message from.

The problem is that in_ifaddrhead.tqh_first can be zero (at least in
some cases), and dereferencing in the line following the assignment
causes a kernel panic.

The patch below fixes this, by not simply using the first local
IP address in the TAILQ, but iterating over it until a non-zero one
is found. Also, it skips sending the ICMP message when no valid
address is found in the TAILQ at all.

This bug may be triggered by a custom startup script in use here
at ISI, which uses ARP requests very early in the boot process (after
pccardd is started) to determine the network location of the machine
is at, and configuring it appropriately.
>How-To-Repeat:

>Fix:
--- plain       Wed Sep 12 09:47:58 2001
+++ ip_icmp.c   Wed Sep 12 09:37:54 2001
@@ -639,9 +639,26 @@
        /*
         * The following happens if the packet was not addressed to us,
         * and was received on an interface with no IP address.
+        *
+        * Prior versions simply set ia = in_ifaddrhead.tqh_first if it
+        * was zero here. When in_ifaddrhead.tqh_first is also zero
+        * (pointer gets dereferenced below), the kernel panics. It looks
+        * like this can happen with PC-card interfaces, but I have not
+        * investigated this fully.
+        *
+        * Instead, iterate over the TAILQ to find the first non-zero
+        * interface address, and use that. If none can be found, skip
+        * sending the ICMP packet.
+        *                                              larse@isi.edu
         */
-       if (ia == (struct in_ifaddr *)0)
-               ia = in_ifaddrhead.tqh_first;
+       if (ia == (struct in_ifaddr *)0) {
+               TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link)
+                       if (ia != (struct in_ifaddr *)0)
+                               break;
+               if (ia == (struct in_ifaddr *)0)
+                       /* did not find any valid interface address */
+                       goto done;
+       }
        t = IA_SIN(ia)->sin_addr;
        ip->ip_src = t;
        ip->ip_ttl = ip_defttl;

>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200109121650.f8CGo7D55328>