Module Name: src Committed By: ozaki-r Date: Wed Nov 22 05:42:30 UTC 2017
Modified Files: src/sys/net: if_spppsubr.c Log Message: Protect IFADDR_READER_FOREACH and obtained ifa with psz/psref To generate a diff of this commit: cvs rdiff -u -r1.172 -r1.173 src/sys/net/if_spppsubr.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/if_spppsubr.c diff -u src/sys/net/if_spppsubr.c:1.172 src/sys/net/if_spppsubr.c:1.173 --- src/sys/net/if_spppsubr.c:1.172 Wed Nov 15 07:52:58 2017 +++ src/sys/net/if_spppsubr.c Wed Nov 22 05:42:30 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: if_spppsubr.c,v 1.172 2017/11/15 07:52:58 knakahara Exp $ */ +/* $NetBSD: if_spppsubr.c,v 1.173 2017/11/22 05:42:30 ozaki-r Exp $ */ /* * Synchronous PPP/Cisco link level subroutines. @@ -41,7 +41,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.172 2017/11/15 07:52:58 knakahara Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.173 2017/11/22 05:42:30 ozaki-r Exp $"); #if defined(_KERNEL_OPT) #include "opt_inet.h" @@ -5219,6 +5219,8 @@ sppp_get_ip_addrs(struct sppp *sp, uint3 struct ifaddr *ifa; struct sockaddr_in *si, *sm; uint32_t ssrc, ddst; + int s; + struct psref psref; sm = NULL; ssrc = ddst = 0; @@ -5227,14 +5229,18 @@ sppp_get_ip_addrs(struct sppp *sp, uint3 * aliases don't make any sense on a p2p link anyway. */ si = 0; + s = pserialize_read_enter(); IFADDR_READER_FOREACH(ifa, ifp) { if (ifa->ifa_addr->sa_family == AF_INET) { si = (struct sockaddr_in *)ifa->ifa_addr; sm = (struct sockaddr_in *)ifa->ifa_netmask; - if (si) + if (si) { + ifa_acquire(ifa, &psref); break; + } } } + pserialize_read_exit(s); if (ifa) { if (si && si->sin_addr.s_addr) { ssrc = si->sin_addr.s_addr; @@ -5245,6 +5251,7 @@ sppp_get_ip_addrs(struct sppp *sp, uint3 si = (struct sockaddr_in *)ifa->ifa_dstaddr; if (si && si->sin_addr.s_addr) ddst = si->sin_addr.s_addr; + ifa_release(ifa, &psref); } if (dst) *dst = ntohl(ddst); @@ -5457,6 +5464,8 @@ sppp_get_ip6_addrs(struct sppp *sp, stru struct ifaddr *ifa; struct sockaddr_in6 *si, *sm; struct in6_addr ssrc, ddst; + int s; + struct psref psref; sm = NULL; memset(&ssrc, 0, sizeof(ssrc)); @@ -5466,13 +5475,19 @@ sppp_get_ip6_addrs(struct sppp *sp, stru * aliases don't make any sense on a p2p link anyway. */ si = 0; - IFADDR_READER_FOREACH(ifa, ifp) + s = pserialize_read_enter(); + IFADDR_READER_FOREACH(ifa, ifp) { if (ifa->ifa_addr->sa_family == AF_INET6) { si = (struct sockaddr_in6 *)ifa->ifa_addr; sm = (struct sockaddr_in6 *)ifa->ifa_netmask; - if (si && IN6_IS_ADDR_LINKLOCAL(&si->sin6_addr)) + if (si && IN6_IS_ADDR_LINKLOCAL(&si->sin6_addr)) { + ifa_acquire(ifa, &psref); break; + } } + } + pserialize_read_exit(s); + if (ifa) { if (si && !IN6_IS_ADDR_UNSPECIFIED(&si->sin6_addr)) { memcpy(&ssrc, &si->sin6_addr, sizeof(ssrc)); @@ -5485,6 +5500,7 @@ sppp_get_ip6_addrs(struct sppp *sp, stru si = (struct sockaddr_in6 *)ifa->ifa_dstaddr; if (si && !IN6_IS_ADDR_UNSPECIFIED(&si->sin6_addr)) memcpy(&ddst, &si->sin6_addr, sizeof(ddst)); + ifa_release(ifa, &psref); } if (dst)