commit ef5360f616876350c0edc62b79994b17bf21bcd3 Author: Ryota Ozaki Date: Fri May 11 16:58:54 2018 +0900 Protect if_input with KERNEL_LOCK diff --git a/sys/net/bpf.c b/sys/net/bpf.c index 2f162f65fc6..b4849f1ede1 100644 --- a/sys/net/bpf.c +++ b/sys/net/bpf.c @@ -837,9 +837,13 @@ bpf_write(struct file *fp, off_t *offp, struct uio *uio, error = if_output_lock(ifp, ifp, m, (struct sockaddr *) &dst, NULL); if (mc != NULL) { - if (error == 0) + if (error == 0) { + int s = splsoftnet(); + KERNEL_LOCK_UNLESS_IFP_MPSAFE(ifp); ifp->_if_input(ifp, mc); - else + KERNEL_UNLOCK_UNLESS_IFP_MPSAFE(ifp); + splx(s); + } else m_freem(mc); } /* diff --git a/sys/net/if.c b/sys/net/if.c index 2f20702d8b0..9311f528492 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -822,11 +822,13 @@ struct if_percpuq * if_percpuq_create(struct ifnet *ifp) { struct if_percpuq *ipq; + u_int flags = SOFTINT_NET; + + flags |= ISSET(ifp->if_extflags, IFEF_MPSAFE) ? SOFTINT_MPSAFE : 0; ipq = kmem_zalloc(sizeof(*ipq), KM_SLEEP); ipq->ipq_ifp = ifp; - ipq->ipq_si = softint_establish(SOFTINT_NET|SOFTINT_MPSAFE, - if_percpuq_softint, ipq); + ipq->ipq_si = softint_establish(flags, if_percpuq_softint, ipq); ipq->ipq_ifqs = percpu_alloc(sizeof(struct ifqueue)); percpu_foreach(ipq->ipq_ifqs, &if_percpuq_init_ifq, NULL); @@ -1054,11 +1056,13 @@ void if_deferred_start_init(struct ifnet *ifp, void (*func)(struct ifnet *)) { struct if_deferred_start *ids; + u_int flags = SOFTINT_NET; + + flags |= ISSET(ifp->if_extflags, IFEF_MPSAFE) ? SOFTINT_MPSAFE : 0; ids = kmem_zalloc(sizeof(*ids), KM_SLEEP); ids->ids_ifp = ifp; - ids->ids_si = softint_establish(SOFTINT_NET|SOFTINT_MPSAFE, - if_deferred_start_softint, ids); + ids->ids_si = softint_establish(flags, if_deferred_start_softint, ids); if (func != NULL) ids->ids_if_start = func; else