Download raw body.
missing kernel lock around ip6_mforward()
Hi,
When comparing ip_output() and ip6_output() I found a missing kernel
lock around ip6_mforward(). It is not MP safe yet and locked
elsewhere.
To make future comparisons easier, sync the goto bad logic between
ip6_output() and ip6_output().
ok?
bluhm
Index: netinet/ip_output.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_output.c,v
diff -u -p -r1.419 ip_output.c
--- netinet/ip_output.c 17 Jul 2026 18:51:29 -0000 1.419
+++ netinet/ip_output.c 4 Aug 2026 18:07:44 -0000
@@ -483,8 +483,11 @@ reroute:
(error = if_output_ml(ifp, &ml, sintosa(dst), ro->ro_rt)))
goto done;
ipstat_inc(ips_fragmented);
+ goto done;
-done:
+ bad:
+ m_freem(m);
+ done:
if (ro == &iproute)
rtfree(ro->ro_rt);
if_put(ifp);
@@ -492,10 +495,6 @@ done:
tdb_unref(tdb);
#endif /* IPSEC */
return (error);
-
-bad:
- m_freem(m);
- goto done;
}
#ifdef IPSEC
Index: netinet6/ip6_output.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/ip6_output.c,v
diff -u -p -r1.306 ip6_output.c
--- netinet6/ip6_output.c 25 Jun 2026 13:16:44 -0000 1.306
+++ netinet6/ip6_output.c 4 Aug 2026 18:07:42 -0000
@@ -492,10 +492,13 @@ reroute:
if (atomic_load_int(&ip6_mforwarding) &&
ip6_mrouter[ifp->if_rdomain] &&
(flags & IPV6_FORWARDING) == 0) {
- if (ip6_mforward(ip6, ifp, m, flags) != 0) {
- m_freem(m);
- goto done;
- }
+ int rv;
+
+ KERNEL_LOCK();
+ rv = ip6_mforward(ip6, ifp, m, flags);
+ KERNEL_UNLOCK();
+ if (rv != 0)
+ goto bad;
}
}
#endif
@@ -508,10 +511,8 @@ reroute:
* destination group on the loopback interface.
*/
if (ip6->ip6_hlim == 0 || (ifp->if_flags & IFF_LOOPBACK) ||
- IN6_IS_ADDR_MC_INTFACELOCAL(&ip6->ip6_dst)) {
- m_freem(m);
- goto done;
- }
+ IN6_IS_ADDR_MC_INTFACELOCAL(&ip6->ip6_dst))
+ goto bad;
}
/*
@@ -580,8 +581,7 @@ reroute:
#if NPF > 0
if (pf_test(AF_INET6, PF_OUT, ifp, &m) != PF_PASS) {
error = EACCES;
- m_freem(m);
- goto done;
+ goto bad;
}
if (m == NULL)
goto done;
missing kernel lock around ip6_mforward()