Bug 29337

Summary: If no IP addresses are configured, received ping will crash the kernel.
Product: Base System Reporter: Richard Andrades <richard>
Component: kernAssignee: dd <dd>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: Unspecified   
Hardware: Any   
OS: Any   

Description Richard Andrades 2001-07-31 01:20:00 UTC
If a FreeBSD system does not have ANY IP addresses configured
on any interface, and if it receives a unicast ping packet, it
will crash trying to dereference a NULL pointer.

Fix: 

Note: I checked the latest version and this bug has not yet been fixed.

FILE: src/sys/netinet/ip_icmp.c
Function: icmp_reflect()
-----Begin code fragment-----------------------
        /*
         * 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;
/* Begin BUG FIX */
        if (ia == (struct in_ifaddr *)0){
                m_freem(m);     
                goto done;      /* Abandon - or we will crash */
        }
/* End BUG FIX */
        t = IA_SIN(ia)->sin_addr;
--------------End code fragment-----------------


Explanation:
************

In the function ip_input() in the file src/sys/netinet/ip_input.c,
there is the following code fragment:
--------------------------------------
        /*
         * Check our list of addresses, to see if the packet is for us.
         * If we don't have any addresses, assume any unicast packet
         * we receive might be for us (and let the upper layers deal
         * with it).
         */
        if (TAILQ_EMPTY(&in_ifaddrhead) &&
            (m->m_flags & (M_MCAST|M_BCAST)) == 0)
                goto ours;
---------------------------------------

So if the system does not have any IP addresses configured and
if a ping packet arrives with a unicast destination address, the
above code fragment will hand if off to icmp_input() which
will pass it on the icmp_reflect() which will crash trying 
to deference the in_ifaddrhead pointer which is NULL.
How-To-Repeat: This problem requires some work to recreate. My kernel is
compiled to disable IPv6 support. I was unable to reproduce
it on a regular kernel with IPv6 support.

Take a FreeBSD system with NO IP addresses on ANY interface
(I could not do this if IPv6 was enabled). 
Set the loopback interface UP but do not assign it an IP
address.
Add the folloing route:
  route add 127.0.0.1 -interface lo0
Ping the address.
  ping 127.0.0.1
The kernel will crash within icmp_reflect()
Comment 1 dd freebsd_committer freebsd_triage 2001-10-01 13:45:31 UTC
Responsible Changed
From-To: freebsd-bugs->dd

I'm working on this.
Comment 2 dd freebsd_committer freebsd_triage 2001-11-27 20:02:57 UTC
State Changed
From-To: open->closed

Fixed in rev. 1.63 of ip_icmp.c.  I'll MFC this after a few weeks.