Module Name: src Committed By: ozaki-r Date: Tue Mar 14 08:11:09 UTC 2017
Modified Files: src/sys/net: rtsock.c Log Message: Fix race condition in sysctl_iflist We need to use psref for the ifa iteration because iflist_addr can sleep. To generate a diff of this commit: cvs rdiff -u -r1.204 -r1.205 src/sys/net/rtsock.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/net/rtsock.c diff -u src/sys/net/rtsock.c:1.204 src/sys/net/rtsock.c:1.205 --- src/sys/net/rtsock.c:1.204 Tue Mar 14 04:25:10 2017 +++ src/sys/net/rtsock.c Tue Mar 14 08:11:09 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: rtsock.c,v 1.204 2017/03/14 04:25:10 ozaki-r Exp $ */ +/* $NetBSD: rtsock.c,v 1.205 2017/03/14 08:11:09 ozaki-r Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -61,7 +61,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.204 2017/03/14 04:25:10 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.205 2017/03/14 08:11:09 ozaki-r Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -1678,6 +1678,7 @@ sysctl_iflist(int af, struct rt_walkarg s = pserialize_read_enter(); IFNET_READER_FOREACH(ifp) { + int _s; if (w->w_arg && w->w_arg != ifp->if_index) continue; if (IFADDR_READER_EMPTY(ifp)) @@ -1694,15 +1695,25 @@ sysctl_iflist(int af, struct rt_walkarg if ((error = iflist_if(ifp, w, &info, len)) != 0) goto release_exit; } + _s = pserialize_read_enter(); IFADDR_READER_FOREACH(ifa, ifp) { + struct psref _psref; if (af && af != ifa->ifa_addr->sa_family) continue; + ifa_acquire(ifa, &_psref); + pserialize_read_exit(_s); + info.rti_info[RTAX_IFA] = ifa->ifa_addr; info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask; info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr; - if ((error = iflist_addr(w, ifa, &info)) != 0) + error = iflist_addr(w, ifa, &info); + + _s = pserialize_read_enter(); + ifa_release(ifa, &_psref); + if (error != 0) goto release_exit; } + pserialize_read_exit(_s); info.rti_info[RTAX_IFA] = info.rti_info[RTAX_NETMASK] = info.rti_info[RTAX_BRD] = NULL;