| Summary: | If no IP addresses are configured, received ping will crash the kernel. | ||
|---|---|---|---|
| Product: | Base System | Reporter: | Richard Andrades <richard> |
| Component: | kern | Assignee: | dd <dd> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | Unspecified | ||
| Hardware: | Any | ||
| OS: | Any | ||
Responsible Changed From-To: freebsd-bugs->dd I'm working on this. State Changed From-To: open->closed Fixed in rev. 1.63 of ip_icmp.c. I'll MFC this after a few weeks. |
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()