aboutsummaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2021-09-10 13:07:40 +0000
committerMark Johnston <markj@FreeBSD.org>2021-09-10 13:07:40 +0000
commitb1e6a792d68e9c59740d5e925405d8d4343d099b (patch)
tree247ecc7fe63c747833aaefa3b2c0b0bf244bee68 /sys/net
parent7955efd574b98601a95da45d6d8e7f452631fddd (diff)
downloadsrc-b1e6a792d68e9c59740d5e925405d8d4343d099b.tar.gz
src-b1e6a792d68e9c59740d5e925405d8d4343d099b.zip
net: Enter a net epoch around protocol if_up/down notifications
When traversing a list of interface addresses, we need to be in a net epoch section, and protocol ctlinput routines need a stable reference to the address. Reported by: syzbot+3219af764ead146a3a4e@syzkaller.appspotmail.com Reviewed by: kp, melifaro MFC after: 1 week Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D31889
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/if.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index 8d2a66471836..83a0b07805ee 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -2195,14 +2195,17 @@ static void
if_unroute(struct ifnet *ifp, int flag, int fam)
{
struct ifaddr *ifa;
+ struct epoch_tracker et;
KASSERT(flag == IFF_UP, ("if_unroute: flag != IFF_UP"));
ifp->if_flags &= ~flag;
getmicrotime(&ifp->if_lastchange);
+ NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
if (fam == PF_UNSPEC || (fam == ifa->ifa_addr->sa_family))
pfctlinput(PRC_IFDOWN, ifa->ifa_addr);
+ NET_EPOCH_EXIT(et);
ifp->if_qflush(ifp);
if (ifp->if_carp)
@@ -2218,14 +2221,17 @@ static void
if_route(struct ifnet *ifp, int flag, int fam)
{
struct ifaddr *ifa;
+ struct epoch_tracker et;
KASSERT(flag == IFF_UP, ("if_route: flag != IFF_UP"));
ifp->if_flags |= flag;
getmicrotime(&ifp->if_lastchange);
+ NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
if (fam == PF_UNSPEC || (fam == ifa->ifa_addr->sa_family))
pfctlinput(PRC_IFUP, ifa->ifa_addr);
+ NET_EPOCH_EXIT(et);
if (ifp->if_carp)
(*carp_linkstate_p)(ifp);
rt_ifmsg(ifp);