Hi,
During regress testing I found this bug.
splassert: rip6_input: want 1 have 2
Starting stack trace...
rip6_input(1,2,d0c6b7ad,f57ff9fc) at rip6_input+0x166
rip6_input(f57ffbfc,f57ffbe8,3a,18) at rip6_input+0x166
icmp6_input(f57ffbfc,f57ffbe8,3a,18) at icmp6_input+0x66d
ip_deliver(f57ffbfc,f57ffbe8,3a,18) at ip_deliver+0xf4
ip6_input_if(f57ffbfc,f57ffbe8,29,0,d7066830) at ip6_input_if+0x88a
ipv6_input(d7066830,dafe5400) at ipv6_input+0x2b
ether_input(d7066830,dafe5400) at ether_input+0x3a9
if_input_process(d7066830,f57ffc54) at if_input_process+0x5d
ifiq_process(d7066ae0) at ifiq_process+0x57
taskq_thread(d6ff1040) at taskq_thread+0x69
End of stack trace.
ip6_input() has shared net lock. ip_deliver() needs exclusive net
lock. Use ip6_ours() to queue the packet. Move the write lock
assertion into ip_deliver() to catch such bugs earlier.
The assertion is only triggered with IPv6 multicast forwarding or
router alert hop by hop option. So nobody noticed it.
ok?
bluhm
Index: netinet/ip_input.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_input.c,v
retrieving revision 1.372
diff -u -p -r1.372 ip_input.c
--- netinet/ip_input.c 29 Jun 2022 09:01:48 -0000 1.372
+++ netinet/ip_input.c 22 Jul 2022 19:23:47 -0000
@@ -556,8 +556,6 @@ ip_local(struct mbuf **mp, int *offp, in
struct ipqent *ipqe;
int mff, hlen;
- NET_ASSERT_WLOCKED();
-
hlen = ip->ip_hl << 2;
/*
@@ -673,6 +671,8 @@ ip_deliver(struct mbuf **mp, int *offp,
#ifdef INET6
int nest = 0;
#endif /* INET6 */
+
+ NET_ASSERT_WLOCKED();
/* pf might have modified stuff, might have to chksum */
switch (af) {
Index: netinet6/ip6_input.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/ip6_input.c,v
retrieving revision 1.248
diff -u -p -r1.248 ip6_input.c
--- netinet6/ip6_input.c 29 Jun 2022 22:45:24 -0000 1.248
+++ netinet6/ip6_input.c 22 Jul 2022 19:23:17 -0000
@@ -448,8 +448,7 @@ ip6_input_if(struct mbuf **mp, int *offp
if (ours) {
if (af == AF_UNSPEC)
- nxt = ip_deliver(mp, offp, nxt,
- AF_INET6);
+ nxt = ip6_ours(mp, offp, nxt, af);
goto out;
}
goto bad;
@@ -550,7 +549,7 @@ ip6_input_if(struct mbuf **mp, int *offp
if (ours) {
if (af == AF_UNSPEC)
- nxt = ip_deliver(mp, offp, nxt, AF_INET6);
+ nxt = ip6_ours(mp, offp, nxt, af);
goto out;
}
@@ -584,8 +583,6 @@ ip6_input_if(struct mbuf **mp, int *offp
int
ip6_local(struct mbuf **mp, int *offp, int nxt, int af)
{
- NET_ASSERT_WLOCKED();
-
nxt = ip6_hbhchcheck(mp, offp, NULL);
if (nxt == IPPROTO_DONE)
return IPPROTO_DONE;