frag6_slowtimo: push NET_LOCK into frag6_freef around icmp6_error.
authorcheloha <cheloha@openbsd.org>
Wed, 22 Aug 2018 19:48:48 +0000 (19:48 +0000)
committercheloha <cheloha@openbsd.org>
Wed, 22 Aug 2018 19:48:48 +0000 (19:48 +0000)
icmp6_error() still probably needs the NET_LOCK, as the call chain
icmp6_error -> icmp6_reflect -> rt_match -> rt_clone -> rtrequest
is possible.

The fragment discard loop in frag6_slowtimo and the other
cleanup bits in frag6_freef do not require it however.  So
push the lock down into frag6_freef around icmp6_error.

Prompted by mpi.  Discussed with bluhm and kn.  Regress test help
by bluhm.  Additional testing by kn.

ok kn@ visa@ mpi@

sys/netinet6/frag6.c

index f3abef2..38631a8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: frag6.c,v 1.82 2018/02/01 21:11:33 bluhm Exp $        */
+/*     $OpenBSD: frag6.c,v 1.83 2018/08/22 19:48:48 cheloha Exp $      */
 /*     $KAME: frag6.c,v 1.40 2002/05/27 21:40:31 itojun Exp $  */
 
 /*
@@ -540,8 +540,10 @@ frag6_freef(struct ip6q *q6)
                        ip6->ip6_src = q6->ip6q_src;
                        ip6->ip6_dst = q6->ip6q_dst;
 
+                       NET_LOCK();
                        icmp6_error(m, ICMP6_TIME_EXCEEDED,
                                    ICMP6_TIME_EXCEED_REASSEMBLY, 0);
+                       NET_UNLOCK();
                } else
                        m_freem(m);
                pool_put(&ip6af_pool, af6);
@@ -599,12 +601,8 @@ frag6_slowtimo(void)
 
        mtx_leave(&frag6_mutex);
 
-       if (!TAILQ_EMPTY(&rmq6)) {
-               NET_LOCK();
-               while ((q6 = TAILQ_FIRST(&rmq6)) != NULL) {
-                       TAILQ_REMOVE(&rmq6, q6, ip6q_queue);
-                       frag6_freef(q6);
-               }
-               NET_UNLOCK();
+       while ((q6 = TAILQ_FIRST(&rmq6)) != NULL) {
+               TAILQ_REMOVE(&rmq6, q6, ip6q_queue);
+               frag6_freef(q6);
        }
 }