Date: Mon, 28 Apr 2014 22:48:21 GMT From: Alan Somers <asomers@freebsd.org> To: freebsd-gnats-submit@FreeBSD.org Subject: kern/189089: Panic when removing an IP address from an interface, if the same address exists on another interface Message-ID: <201404282248.s3SMmLiT008795@cgiserv.freebsd.org> Resent-Message-ID: <201404282250.s3SMo0ls029302@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 189089 >Category: kern >Synopsis: Panic when removing an IP address from an interface, if the same address exists on another interface >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Mon Apr 28 22:50:00 UTC 2014 >Closed-Date: >Last-Modified: >Originator: Alan Somers >Release: 11.0 CURRENT >Organization: Spectra Logic >Environment: FreeBSD b 11.0-CURRENT FreeBSD 11.0-CURRENT #9 r264904M: Fri Apr 25 14:46:45 PDT 2014 neel@b:/usr/obj/neel/usr/freebsd/head2/sys/GENERIC amd64 >Description: If you assign the same IP address to multiple interfaces simultaneously, then remove it from one of them, the system will panic with this message: panic: rtalloc1_fib: bad fibnum The panic was introduced by revision 264887, which changed the fibnum parameter in the call to rtalloc1_fib() in ifa_switch_loopback_route() from RT_DEFAULT_FIB to RT_ALL_FIBS. Prior to 264887 the call would always succeed, but it could corrupt the network stack if the route in question was not located in the default fib. That wasn't a big deal though, since prior to 264887 it was very difficult create that route in a nondefault fib. >How-To-Repeat: # # Set net.fibs=1 and net.add_addr_allfibs=1 # ifconfig tap0 create # ifconfig tap1 create # ifconfig tap0 192.0.0.2/24 up # ifconfig tap1 192.0.0.2/32 up # netstat -rn -f inet Routing tables Internet: Destination Gateway Flags Netif Expire default 10.1.0.1 UGS em0 10.1.0.0/20 link#1 U em0 10.1.3.220 link#1 UHS lo0 127.0.0.1 link#2 UH lo0 192.0.0.0/24 link#3 U tap0 192.0.0.2 link#3 UHS lo0 192.0.0.2/32 link#4 U tap1 # ifconfig tap1 -alias 192.0.0.2 # This line will panic! >Fix: The solution is to use the interface fib instead of either the default fib or ALL_FIBS. This will give equivalent behavior as the pre-264887 status quo for the majority of users. Patch attached with submission follows: Index: sys/netinet/in.c =================================================================== --- sys/netinet/in.c (revision 265061) +++ sys/netinet/in.c (working copy) @@ -696,11 +696,9 @@ { struct in_ifaddr *ia; struct in_addr prefix, mask, p, m; - int error = 0, fibnum; + int error = 0; struct sockaddr_in prefix0, mask0; - fibnum = rt_add_addr_allfibs ? RT_ALL_FIBS : target->ia_ifp->if_fib; - /* * Remove the loopback route to the interface address. */ @@ -712,6 +710,8 @@ eia = in_localip_more(target); if (eia != NULL) { + int fibnum = target->ia_ifp->if_fib; + error = ifa_switch_loopback_route((struct ifaddr *)eia, (struct sockaddr *)&target->ia_addr, fibnum); ifa_free(&eia->ia_ifa); @@ -736,6 +736,10 @@ } if ((target->ia_flags & IFA_ROUTE) == 0) { + int fibnum; + + fibnum = rt_add_addr_allfibs ? RT_ALL_FIBS : + target->ia_ifp->if_fib; rt_addrmsg(RTM_DELETE, &target->ia_ifa, fibnum); return (0); } Index: tests/sys/netinet/fibs_test.sh =================================================================== --- tests/sys/netinet/fibs_test.sh (revision 265061) +++ tests/sys/netinet/fibs_test.sh (working copy) @@ -213,6 +213,45 @@ } +# Regression test for a panic introduced in change 264887 +# Create two tap interfaces and assign them both the same IP address but with +# different netmasks, and both on the default FIB. Then remove one's IP +# address. Hopefully the machine won't panic. +atf_test_case same_ip_multiple_ifaces_fib0 cleanup +same_ip_multiple_ifaces_fib0_head() +{ + atf_set "descr" "Can remove an IP alias from an interface when the same IP is also assigned to another interface." + atf_set "require.user" "root" + atf_set "require.config" "fibs" +} +same_ip_multiple_ifaces_fib0_body() +{ + ADDR="192.0.2.2" + MASK0="24" + MASK1="32" + + # Unlike most of the tests in this file, this is applicable regardless + # of net.add_addr_allfibs + + # Setup the interfaces, then remove one alias. It should not panic. + setup_tap 0 ${ADDR} ${MASK0} + TAP0=${TAP} + setup_tap 0 ${ADDR} ${MASK1} + TAP1=${TAP} + ifconfig ${TAP1} -alias ${ADDR} + + # Do it again, in the opposite order. It should not panic. + setup_tap 0 ${ADDR} ${MASK0} + TAP0=${TAP} + setup_tap 0 ${ADDR} ${MASK1} + TAP1=${TAP} + ifconfig ${TAP0} -alias ${ADDR} +} +same_ip_multiple_ifaces_fib0_cleanup() +{ + cleanup_tap +} + # Regression test for kern/187550 atf_test_case subnet_route_with_multiple_fibs_on_same_subnet cleanup subnet_route_with_multiple_fibs_on_same_subnet_head() @@ -309,6 +348,7 @@ atf_add_test_case arpresolve_checks_interface_fib atf_add_test_case loopback_and_network_routes_on_nondefault_fib atf_add_test_case default_route_with_multiple_fibs_on_same_subnet + atf_add_test_case same_ip_multiple_ifaces_fib0 atf_add_test_case subnet_route_with_multiple_fibs_on_same_subnet atf_add_test_case udp_dontroute } >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201404282248.s3SMmLiT008795>