Module Name: src Committed By: ozaki-r Date: Thu Jul 28 09:03:51 UTC 2016
Modified Files: src/sys/netinet: if_arp.c in.c src/sys/netinet6: in6.c nd6_nbr.c Log Message: Fix panic on adding/deleting IP addresses under network load Adding and deleting IP addresses aren't serialized with other network opeartions, e.g., forwarding packets. So if we add or delete an IP address under network load, a kernel panic may happen on manipulating network-related shared objects such as rtentry and rtcache. To avoid such panicks, we still need to hold softnet_lock in in_control and in6_control that are called via ioctl and do network-related operations including IP address additions/deletions. Fix PR kern/51356 To generate a diff of this commit: cvs rdiff -u -r1.219 -r1.220 src/sys/netinet/if_arp.c cvs rdiff -u -r1.176 -r1.177 src/sys/netinet/in.c cvs rdiff -u -r1.211 -r1.212 src/sys/netinet6/in6.c cvs rdiff -u -r1.125 -r1.126 src/sys/netinet6/nd6_nbr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/netinet/if_arp.c diff -u src/sys/netinet/if_arp.c:1.219 src/sys/netinet/if_arp.c:1.220 --- src/sys/netinet/if_arp.c:1.219 Mon Jul 25 04:21:19 2016 +++ src/sys/netinet/if_arp.c Thu Jul 28 09:03:50 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: if_arp.c,v 1.219 2016/07/25 04:21:19 ozaki-r Exp $ */ +/* $NetBSD: if_arp.c,v 1.220 2016/07/28 09:03:50 ozaki-r Exp $ */ /*- * Copyright (c) 1998, 2000, 2008 The NetBSD Foundation, Inc. @@ -68,7 +68,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.219 2016/07/25 04:21:19 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.220 2016/07/28 09:03:50 ozaki-r Exp $"); #ifdef _KERNEL_OPT #include "opt_ddb.h" @@ -1505,7 +1505,7 @@ static void arp_dad_stoptimer(struct dadq *dp) { - callout_halt(&dp->dad_timer_ch, NULL); + callout_halt(&dp->dad_timer_ch, softnet_lock); } static void Index: src/sys/netinet/in.c diff -u src/sys/netinet/in.c:1.176 src/sys/netinet/in.c:1.177 --- src/sys/netinet/in.c:1.176 Wed Jul 20 03:36:51 2016 +++ src/sys/netinet/in.c Thu Jul 28 09:03:50 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: in.c,v 1.176 2016/07/20 03:36:51 ozaki-r Exp $ */ +/* $NetBSD: in.c,v 1.177 2016/07/28 09:03:50 ozaki-r Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -91,7 +91,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.176 2016/07/20 03:36:51 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.177 2016/07/28 09:03:50 ozaki-r Exp $"); #include "arp.h" @@ -360,8 +360,8 @@ in_len2mask(struct in_addr *mask, u_int * Ifp is 0 if not an interface-specific ioctl. */ /* ARGSUSED */ -int -in_control(struct socket *so, u_long cmd, void *data, struct ifnet *ifp) +static int +in_control0(struct socket *so, u_long cmd, void *data, struct ifnet *ifp) { struct ifreq *ifr = (struct ifreq *)data; struct in_ifaddr *ia = NULL; @@ -667,6 +667,18 @@ in_control(struct socket *so, u_long cmd return error; } +int +in_control(struct socket *so, u_long cmd, void *data, struct ifnet *ifp) +{ + int error; + + mutex_enter(softnet_lock); + error = in_control0(so, cmd, data, ifp); + mutex_exit(softnet_lock); + + return error; +} + /* Add ownaddr as loopback rtentry. */ static void in_ifaddlocal(struct ifaddr *ifa) Index: src/sys/netinet6/in6.c diff -u src/sys/netinet6/in6.c:1.211 src/sys/netinet6/in6.c:1.212 --- src/sys/netinet6/in6.c:1.211 Wed Jul 20 07:56:10 2016 +++ src/sys/netinet6/in6.c Thu Jul 28 09:03:50 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: in6.c,v 1.211 2016/07/20 07:56:10 ozaki-r Exp $ */ +/* $NetBSD: in6.c,v 1.212 2016/07/28 09:03:50 ozaki-r Exp $ */ /* $KAME: in6.c,v 1.198 2001/07/18 09:12:38 itojun Exp $ */ /* @@ -62,7 +62,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.211 2016/07/20 07:56:10 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.212 2016/07/28 09:03:50 ozaki-r Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -751,7 +751,9 @@ in6_control(struct socket *so, u_long cm } s = splnet(); + mutex_enter(softnet_lock); error = in6_control1(so , cmd, data, ifp); + mutex_exit(softnet_lock); splx(s); return error; } Index: src/sys/netinet6/nd6_nbr.c diff -u src/sys/netinet6/nd6_nbr.c:1.125 src/sys/netinet6/nd6_nbr.c:1.126 --- src/sys/netinet6/nd6_nbr.c:1.125 Mon Jul 25 04:21:20 2016 +++ src/sys/netinet6/nd6_nbr.c Thu Jul 28 09:03:50 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: nd6_nbr.c,v 1.125 2016/07/25 04:21:20 ozaki-r Exp $ */ +/* $NetBSD: nd6_nbr.c,v 1.126 2016/07/28 09:03:50 ozaki-r Exp $ */ /* $KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $ */ /* @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.125 2016/07/25 04:21:20 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.126 2016/07/28 09:03:50 ozaki-r Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -1077,7 +1077,7 @@ static void nd6_dad_stoptimer(struct dadq *dp) { - callout_halt(&dp->dad_timer_ch, NULL); + callout_halt(&dp->dad_timer_ch, softnet_lock); } /*